Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

build-fhs-userenv: change to using bubblewrap over chrootenv #55973

Closed
wants to merge 3 commits into from

Conversation

illegalprime
Copy link
Member

@illegalprime illegalprime commented Feb 18, 2019

Motivation for this change

this makes FHS envs use bubblewrap over Nix's custom chrootenv.c which might fix issues such as #33106 but more generally gives us the ability to add many new configuration options with bwrap's added power. Maybe using bwrap will be more stable as well since it seems widely used.

I have tested this by building Yocto images by running bitbake in an FHSUserEnv but I have yet to run steam which is likely the most complicated package that utilizes this.

This comes with fixes from a lot of experience using FHS env for Yocto and attempting to run it in various environments. Namely:

  1. /host/etc is now /host-etc because systemd symlinks /etc/resolv.conf to ../run/systemd/resolve/resolv.conf so keeping /host-etc on the same level as /etc helps with that.
  2. /etc/pki is now included so fedora users can get SSL within the env
  3. Removing the mount of /host-etc (/host/etc) and directly bind-mounting all etc files and dirs, then allowing directories of etc from the generated rootfs to override the one from the host.

Applications that work:

  • applications/blockchains/mist
  • applications/editors/android-studio
  • applications/science/electronics/bitscope
  • applications/misc/houdini
  • applications/misc/lutris
  • applications/misc/sidequest
  • applications/networking/dropbox
  • applications/video/lightworks
  • development/arduino/platformio
  • games/steam
  • servers/plex
  • build-support/appimage
  • tools/package-management/appimage-run
  • tools/package-management/conda
Things done
  • Tested using sandboxing (nix.useSandbox on NixOS, or option sandbox in nix.conf on non-NixOS)
  • Built on platform(s)
    • NixOS
    • macOS
    • other Linux distributions
  • Tested via one or more NixOS test(s) if existing and applicable for the change (look inside nixos/tests)
  • Tested compilation of all pkgs that depend on this change using nix-shell -p nox --run "nox-review wip"
  • Tested execution of all binary files (usually in ./result/bin/)
  • Determined the impact on package closure size (by running nix path-info -S before and after)
  • Assured whether relevant documentation is up to date
  • Fits CONTRIBUTING.md.

@illegalprime
Copy link
Member Author

The build error is from this line:
https://github.com/NixOS/nixpkgs/pull/55973/files#diff-0e0af17bff7614ce6822d64c6863bb1fR36
but I'm not sure what the fix is, it seems that I can't readDir "${fhs-env}" during build because that path doesn't exist yet? it's weird because this works on my test fhs-env. Do i do it at runtime or can i force this directory to exist?

@hedning
Copy link
Contributor

hedning commented Feb 19, 2019

ofborg only evaluates things and it's not able to evaluate the buildFHSUserEnv without building due to readDir. The easiest fix might be calculate mounts, ro_mounts and blacklist in bwrap_cmd instead.

@illegalprime
Copy link
Member Author

did some more tests, most things didn't run because my host system's /etc/fonts/fonts.conf could not be read by these packages for some reason. Nothing that seems to be wrong with the FHS env itself.
also updated the docs.

@matthewbauer
Copy link
Member

@GrahamcOfBorg build houdini lightworks conda

@illegalprime
Copy link
Member Author

@hedning what do I need to merge this?

@hedning
Copy link
Contributor

hedning commented Feb 26, 2019

It would be good to get an OK from @yegortimoshenko or @abbradar first.

</term>
<listitem>
<para>
Any extra arguments tp pass to bubblewrap (which is now the underlying
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo: tp -> to

Copy link
Member

@lukateras lukateras left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer if bwrap replacement were to replace chrootenv without extending API.

@@ -50,6 +50,58 @@
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<literal>automount</literal>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this should be an option, not for buildFHSUserEnv, that is: it should really be the only behavior, because isolation is not the goal (FHS compat is).

Later, we can get to sandboxing of individual derivations, XDG portals, etc. That said, it will certainly require a complete redesign of buildFHSUserEnv and will have to be carefully thought out.

</term>
<listitem>
<para>
Set to <literal>"$(pwd)"</literal> by default, this option determines
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to be orthogonal to FHS emulation (and can be/is implemented in wrappers).

@illegalprime
Copy link
Member Author

@yegortimoshenko if I wanted to edit the bwrap options for my own uses, how should I implement this to make that possible? Maybe I should include it as an arg in the derivation and use overrideAttrs? Or maybe I should just make my own custom FHSUserEnv, but I want to re-use as much upstream code as I can.

@lukateras
Copy link
Member

lukateras commented May 28, 2019

It's just that I worry that we might need to switch back at some point, if we ever need anything bubblewrap doesn't implement or if it proves to be suboptimal in some regard. If we were to expose bubblewrap options, we will never be able to change underlying implementation without breaking reverse compat.

@abbradar
Copy link
Member

abbradar commented May 28, 2019 via email

@abbradar
Copy link
Member

I didn't yet review the PR itself yet, only bubblewrap -- it's quite more complicated but we should definitely try using it; the code is readable too.

One concern of mine is if nested bubblewrap would work okay, especially if it would blow /proc/mounts. This needs to be tested.

Another thing -- we explicitly don't want any kind of isolation that bubblewrap does, including no automount, any other namespaces etc, and we also don't want to expose it as an implementation. I think we could hit both birds by adding buildBwrapUserEnv upon which old buildFHSUserEnv resides. The former would have all the bubblewrap options exposed and the latter would enforce the old behaviour.

@lukateras
Copy link
Member

lukateras commented May 30, 2019

Wrt naming: User seems to be redundant, maybe buildBwrapEnv? Sounds good otherwise.

@abbradar
Copy link
Member

Maybe; don't have big preferences here. @illegalprime can choose the naming ~_^

@matthewbauer matthewbauer added this to the 19.09 milestone May 30, 2019
@vcunat
Copy link
Member

vcunat commented Aug 18, 2019

For reference, the relocation error messages from above are claimed to be gone since glibc 2.30, which has a WIP PR.

@illegalprime
Copy link
Member Author

I'm back!
@yegortimoshenko I updated this branch to not introduce any new options and I also changed /host/etc to /host-etc because /etc/resolv.conf is symlinked to ../run/ in systemd. Fedora also stores its SSL certificates as a symlink to somewhere not included in the current etc package so that should be investigated too.

@illegalprime
Copy link
Member Author

OK Fedora stores its SSL certs in /etc/pki so I've added that to the environment.

@illegalprime
Copy link
Member Author

I added a commit which removes /host/etc (or /host-etc) and bind-mounts specific files or directories from the host's /etc to the chroot. It then will look inside the generated root filesystem's /etc and bind mount subdirectories of it. because this is all subdirectories of etc the generated etc and the host etc are "merged" somewhat at runtime.

This helps avoid weird symlink bugs when nesting chroots like in this commit 06f27dc and in general simplifies things (IMO)

@zimbatm
Copy link
Member

zimbatm commented Feb 5, 2020

👍 really cool work. What can I do to help finish this PR?

@bachp
Copy link
Member

bachp commented Apr 14, 2020

@illegalprime Are you still working on this. Looks very promising

@Atemu
Copy link
Member

Atemu commented Jul 28, 2020

Rebased on top of nixos-unstable here: https://github.com/Atemu/nixpkgs/tree/chrootenv2bubblewrap

--unshare-all \
--share-net \
--die-with-parent \
--ro-bind /nix /nix \
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would this break single user nix?

@raboof
Copy link
Member

raboof commented Jul 31, 2020

Nice!

(I don't really feel qualified to review the rest so this is just a comment ;) )

@Atemu
Copy link
Member

Atemu commented Jul 31, 2020

Since the compatibility is not 100% yet, perhaps we should limit bubblewrap use to the programs which are known to work first and move over the rest in later PRs.

Making all of these work feels like too large of a scope to me.

@Mic92
Copy link
Member

Mic92 commented Jul 31, 2020

We could call it v2 and migrate everything to it and at some point delete the old version.

@Atemu
Copy link
Member

Atemu commented Jul 31, 2020

I did some rebase magic to do just that in a transparent manner https://github.com/Atemu/nixpkgs/tree/buildFHSUserEnvBw
I also ported three of the FHS packages that I know work fine.

Should I open a new PR?

Once we've ported all packages over, we can simply rename the function to the old name. This name should be temporary.

@Mic92
Copy link
Member

Mic92 commented Aug 1, 2020

I did some rebase magic to do just that in a transparent manner Atemu/nixpkgs@buildFHSUserEnvBw
I also ported three of the FHS packages that I know work fine.

Should I open a new PR?

Once we've ported all packages over, we can simply rename the function to the old name. This name should be temporary.

bring it on.

@xaverdh
Copy link
Contributor

xaverdh commented Sep 8, 2020

With #94442 merged, should this be closed now?

@siraben
Copy link
Member

siraben commented Apr 10, 2021

#94442 seems to subsume this PR, closing.

@siraben siraben closed this Apr 10, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet