Skip to content

Implement containerization from scratch #11

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open

Conversation

vadorovsky
Copy link
Member

@vadorovsky vadorovsky commented Apr 14, 2025

Drop the dependency on container engines like Docker or Podman by using unshare syscall to implement rootless containers, oci-spec crate toread OCI image specifications, reqwest and tar-rs to download the images. This way, we can keep all the container logic in our binary.

That solves the major problem we had with Docker - file ownership in bind mounted volumes - where new files created inside container in a volume with source code were owned by root and therefore inaccessible for a regular user calling icedragon.

After this change, regular container engines are still used for building the images.

Fixes #7


This change is Reviewable

@vadorovsky vadorovsky marked this pull request as draft April 14, 2025 16:33
@vadorovsky
Copy link
Member Author

Of course hitting an issue reproducible only on Github Actions 😭

[ERROR libcontainer::namespaces] failed to unshare namespace err=Nix(EPERM) namespace=LinuxNamespace { typ: Pid, path: None }
[ERROR libcontainer::process::container_main_process] failed to run intermediate process EPERM: Operation not permitted
[ERROR libcontainer::container::builder_impl] failed to run container process intermediate process error EPERM: Operation not permitted
[WARN  libcgroups::common] cannot configure rootless cgroup using the cgroupfs manager

thread 'tokio-runtime-worker' panicked at src/main.rs:627:18:
called `Result::unwrap()` on an `Err` value: CreateContainerError(CreateContainerError(MainProcess(Channel(OtherError("EPERM: Operation not permitted"))), None))

Rootless podman works fine, so either:

  • Podman just skips the namespace-related errors (if that's the case, we should too).
  • nix does something weird when unsharing the pidns (unlikely, it looks like pure unshare(pid))

@vadorovsky
Copy link
Member Author

OK, it's AppArmor.

sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0

is a sufficient workaround. Will think of something better, but I might stick to it if I'm out of options.

@vadorovsky vadorovsky marked this pull request as ready for review April 15, 2025 14:14
@vadorovsky vadorovsky requested review from Copilot and tamird April 16, 2025 05:21
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

Copy link
Collaborator

@tamird tamird left a comment

Choose a reason for hiding this comment

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

Reviewed 1 of 1 files at r2.
Reviewable status: 1 of 4 files reviewed, 2 unresolved discussions (waiting on @copilot-pull-request-reviewer[bot])


Cargo.toml line 33 at r2 (raw file):

oci-client = { version = "0.14", default-features = false, features = ["rustls-tls"] }
# libcontainer fails to build with newer versions. Not a direct dependency of
# icedragon.

link to a bug?


Cargo.toml line 56 at r2 (raw file):

# https://github.com/youki-dev/youki/issues/3144
# https://github.com/youki-dev/youki/pull/3146
libcontainer = { git = "https://github.com/vadorovsky/youki", branch = "cgroupfs-rootless-warning" }

this should probably wait until these are resolved in some way?

Copy link
Member Author

@vadorovsky vadorovsky left a comment

Choose a reason for hiding this comment

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

Reviewable status: 1 of 4 files reviewed, 2 unresolved discussions (waiting on @copilot-pull-request-reviewer[bot] and @tamird)


Cargo.toml line 33 at r2 (raw file):

Previously, tamird (Tamir Duberstein) wrote…

link to a bug?

Good call, I didn't make one before:

checkpoint-restore/rust-criu#25


Cargo.toml line 56 at r2 (raw file):

Previously, tamird (Tamir Duberstein) wrote…

this should probably wait until these are resolved in some way?

Might take very long, given no response.

Actually, given that working with youki crates turns out to be a bit annoying, I might try going even deeper and creating a "container" by issuing bunch of unshare syscalls myself, avoiding to use these deps. I will give it a though today and if I get convinced that's not too crazy, I will do that.

To be precise, the annoying things are:

  • Hard dependency on systemd.
  • The protobuf issue.
  • Lack of possibility to pass a Spec without saving it on disk.

Drop the dependency on container engines like Docker or Podman by using
`unshare` syscall to implement rootless containers, `oci-spec` crate to
read OCI image specifications, `reqwest` and `tar-rs` to download the
images. This way, we can keep all the container logic in our binary.

That solves the major problem we had with Docker - file ownership in
bind mounted volumes - where new files created inside container in a
volume with source code were owned by `root` and therefore inaccessible
for a regular user calling `icedragon`.

After this change, regular container engines are still used for building
the images.

Fixes #7
Copy link
Member Author

@vadorovsky vadorovsky left a comment

Choose a reason for hiding this comment

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

Reviewable status: 1 of 4 files reviewed, 2 unresolved discussions (waiting on @copilot-pull-request-reviewer[bot] and @tamird)


Cargo.toml line 56 at r2 (raw file):

Previously, vadorovsky (Michal Rostecki) wrote…

Might take very long, given no response.

Actually, given that working with youki crates turns out to be a bit annoying, I might try going even deeper and creating a "container" by issuing bunch of unshare syscalls myself, avoiding to use these deps. I will give it a though today and if I get convinced that's not too crazy, I will do that.

To be precise, the annoying things are:

  • Hard dependency on systemd.
  • The protobuf issue.
  • Lack of possibility to pass a Spec without saving it on disk.

I managed to get rid of youki/libcontainer and do everything with mount and unshare through nix! \o/

Going zzz now. My last push will be most likely red, I will polish it tomorrow.

@vadorovsky vadorovsky changed the title Use libcontainer for running containers Implement containerization from scratch Apr 23, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Make sure that the built artifacts are owned by the user who calls icedragon
2 participants