-
Notifications
You must be signed in to change notification settings - Fork 5
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
RFC: Add support for overlay maps #106
Conversation
Codecov ReportBase: 79.71% // Head: 79.71% // No change to project coverage 👍
Additional details and impacted files@@ Coverage Diff @@
## main #106 +/- ##
=======================================
Coverage 79.71% 79.71%
=======================================
Files 6 6
Lines 567 567
=======================================
Hits 452 452
Misses 115 115
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. ☔ View full report at Codecov. |
52763d4
to
a957e3a
Compare
|
Scratch that, I've redesigned the feature after some thinking, introducing an using Sandbox
overlay = mktempdir()
config = SandboxConfig(
Dict("/" => Sandbox.debian_rootfs(),
"/root/.julia/packages" => "/home/tim/.julia/packages");
overlay_maps = Dict("/root/.julia/packages" => overlay),
stdin, stdout, stderr, persist=true, verbose=true,
)
with_executor(UnprivilegedUserNamespacesExecutor) do exe
run(exe, config, ignorestatus(`/bin/bash -c "touch /root/.julia/packages/foo"`))
end
run(`find $overlay`) The only annoying part is that this requires |
3f0e4dd
to
a9e5778
Compare
OK, made this work with @staticfloat Could you explain why you were mounting the overlayfs-backing tmpfs on |
a9e5778
to
8b0109b
Compare
77dc981
to
21b1e58
Compare
These directories aren't visible anyway since they're outside of the sandbox root.
Both work and upper need to be on the same mount anyway.
21b1e58
to
2f4dee7
Compare
FWIW, I actually started out with something simple that made read-only mounts use overlays, 3e534e1, but because it would then behave differently from the Docker executor I went with a separate |
Okay, I've been thinking about this, and while I like it, I'm not happy with the API. With this, we have the following:
IMO, this is too complicated. In terms of realistic needs, I think we only actually care about the following things:
Improved APIFrom this perspective, I think a better API would be to have the following pieces of functionality:
What we lose with this is the ability to get read-only file system errors, which I think is fine. Regarding docker compatibility, I think we can get this working in docker as well by generating an entrypoint bash script that runs the moral equivalent of: for mount in $ro_mount_list; do
workdir=$persist_dir/$(hash $mount)
mkdir -p $workdir
mount -t overlay overlay -o lowerdir=$mount,upperdir=$workdir/upper,workdir=$workdir/work $mount
done
umount $persist_dir Since we usually run with |
OK, I implemented (the core part) of that API. One problem that surfaced is that overlayfs doesn't support mounting a single file, breaking e.g. the internet tests here (which mount EDIT: pushed that hack. Makes
|
Pushed a commit that does the entrypoint hack as suggested by @staticfloat. I'm not particularly happy with that, as it only works when we have appropriate privileges, but on the other hand with EDIT:
Gah. What if we used a host dir, and implement persistence just like how it's done with the UserNS executor? Well, that works, except for the rootfs. Guess Linux doesn't like double overlayfs mounts? Using two separate persistence mechanisms works around this, but is not nice. |
b119001
to
c6ce387
Compare
c6ce387
to
49e50ef
Compare
d5896d4
to
b219cc4
Compare
Otherwise we stop executing tests as soon as we fail one executor's tests.
I'm not happy with how this turned out; the Docker entrypoint solution (in order to preserve compatibility with the UserNS sandbox) too way too messy: using two persistence mechanisms, requiring privileged containers AND overlayfs support, and likely to break when using stripped container images (say, not containing a So instead I've opted to switch PkgEval over to using OCI container engines directly, JuliaCI/PkgEval.jl#177. That gives me the control I need (pretty easy, too; instead of generating a SandboxConfig I just need to build slightly more verbose JSON), as well as many other features I would have to add to the UserNS sandbox here (notably cgroup resource limits). So I'll go ahead and close this. FWIW, I think it would make sense to remove the UserNS sandbox here and build Sandbox.jl on top of an OCI container runtime; the code from JuliaCI/PkgEval.jl#177 could help with that. It supports almost all features of Sandbox.jl, with the exception of whole-root persistence (mounting an overlay at |
Adds overlay maps to the usernamespace sandbox so that we can create overlay mounts (e.g. to make read-only mounts mutable) in a controlled manner (i.e. without having to peek into the executor's
persistence_dir
):Intended use case: PkgEval, where we need a way to mount the package store. That mount needs to be read-only, since concurrent access results in corruption, yet we need a way to catch changes and add them to the cache afterwards. We cannot use layered depots for this because compilecache files hard-code the path to the Julia sources (see JuliaCI/PkgEval.jl#158).
It would be cleaner if the overlay dir passed to the container would only be used as the upper dir, so that we can directly use the files in there, and not have to worry about removing the
work
directory (which has bad permissions that trigger a Julia bug, and may even be root-owned in the case of the PrivilegedUserNamespaceExecutor), but sadly the workdir has to live on the same filesystem as the upper dir.