rust-lang / docker-rust

The official Docker images for Rust
448 stars 90 forks source link

Adding `libudev-dev` to image #9

Closed abitrolly closed 7 years ago

abitrolly commented 7 years ago

Can't compile https://github.com/paritytech/hidapi-rs dependency for Parity Ethereum node without it.

sfackler commented 7 years ago

You can add the dependency yourself with an apt-get update && apt-get install -y libudev-dev. I don't really want to be adding every dependency any library could possibly use since that adds to the overall image size for everyone.

abitrolly commented 7 years ago

I understand your concern about build image that is already 1.32Gb right now, even though it is not something that users download every day, but rather cached by CI systems. Still libudev is an essential part of Linux core for accessing hardware devices and not just any library out there.

I sent request upstream two weeks ago https://github.com/docker-library/buildpack-deps/pull/67 but there is no response yet.

abitrolly commented 7 years ago

Workaround with chaining apt doesn't work with standard build command

E: List directory /var/lib/apt/lists/partial is missing. - Acquire (13: Permission denied)

https://travis-ci.org/cyberFund/cybernode/builds/281670782#L747

sfackler commented 7 years ago

If you're not running as the root user you'll need to stick a sudo in there.

abitrolly commented 7 years ago

Docker runs under a different user for the same reason why this user comes without sudo.

sfackler commented 7 years ago

What is that reason? This is AFAIKT a transient container that's used to build parity and then thrown away.

There are literally hundreds of libraries that are "an essential part of Linux core for doing X and not just any library out there". I don't want to be adding libraries on top of what buildpack-deps ships with.

abitrolly commented 7 years ago

As a DevOps, I build an open source build system for containers, and while we currently use Travis CI for testing incoming PR, it is also possible to run CI jobs on own hardware. Exposing build scripts that test unreviewed code under root is a security threat.

Another issue with rooted builds is that they create target/release directories that users without root privileges can not remove.

For the value that libudev provides, the core feature of Linux back in the days was open access to hardware, so what part of generic docker buildpack libs collection covers hardware discovery? I mean that system level languages have extended requirements for libraries that should be included compared to standard apps that are packed into isolated containers without access to hardware to be run on the web.

abitrolly commented 7 years ago

Running docker with root also makes Travis caching fail https://travis-ci.org/cyberFund/cybernode/builds/282176168#L6694

sfackler commented 7 years ago

Root in a docker container is very different from root on the host. With the right constraints (in particular, not mounting the docker socket into the container), you can run arbitrarily code in the container in a sufficiently isolated manner.

You can chown the volume contents if needed to make the caching work. You could define a Dockerfile that's based off of the rust image and installs the libraries you need, and use that to run your builds as a nonprivileged user.

Docker images are designed to be extended. buildpack-deps includes a couple of common libraries as a convenience for people using them. It is expected that it will not contain everything that people need to link to, and that they will pull the things they need to use. If we weren't using buildpack-deps, we'd be using buildpack-scm, which has no development packages installed.

sfackler commented 7 years ago

Again, if you want to push for libudev-dev to be included, the place to do that is buildpack-deps. We are not going to be pulling in extra libraries in this image.

abitrolly commented 7 years ago

With all above said, how to run apt-get -y install libudev-dev without executing docker run as root?

andre-richter commented 7 years ago

You could define a Dockerfile that's based off of the rust image and installs the libraries you need, and use that to run your builds as a nonprivileged user.

abitrolly commented 7 years ago

@andre-richter that Dockerfile should be built as root as well, or there is a way non-privileged users to build it?

andre-richter commented 7 years ago

I am not sure why building is a concern? Ideally, you build the image on a trusted setup, push it to dockerhub (or let dockerhub build it itself, e.g. from a Dockerfile in your github repo), and the machine that starts the clients pulls the image from there. Would be the same flow as you have with @sfackler image now.

abitrolly commented 7 years ago

@andre-richter my system should able to rebuild itself on user's machine without root privileges. I will have to upload custom build image for rust and other systems that would need dependencies, but if it is possible to avoid lifecycle with extra images by building local one in user session - that would save me a lot of pain in the future.

sfackler commented 7 years ago

You don't need root to launch a docker image, regardless of the ID of the inner user. The user in the docker image is distinct from the user in the host. I would suggest reviewing documentation on how Docker works, in particular https://docs.docker.com/engine/security/security/.

abitrolly commented 7 years ago

@sfackler yes, in general case root is not needed to run image, but if somebody needs apt-get update && apt get install to be run inside that image then that somebody needs root.

abitrolly commented 7 years ago

I would appreciate if you can list command that allow me to extend this rust image with libudev-dev on user machine without root priviliges, because I don't see the way.

sfackler commented 7 years ago

You don't need root on the host to be a root user in a container

build-image/Dockerfile:

FROM rust:1.20.0

RUN apt-get update && apt-get install -y libudev-dev
$ docker build -t rust-with-udev build-image/
$ docker run --rm -it --user 2000:2000 -v $PWD:/scratch -w /scratch rust-with-udev ./compile-things-using-libudev.sh
abitrolly commented 7 years ago

I checked this once more. You're right - it looks like docker build is executed with user privileges on host, but apt-get commands run there as root

anatoli  27782  0.1  0.2 156560 16496 pts/1    SNl  20:07   0:00  |       \_ /usr/bin/docker-current build .

As for docker run command, executing apt-get there requires root privileges on both guest and host.

The only disadvantage for that is that a separate Dockerfile should be created for apt-get install.

sfackler commented 7 years ago

docker run behaves just like docker build. If you don't pass --user, you'll be running as root.

abitrolly commented 7 years ago

There is no --user flag for docker build.

sfackler commented 7 years ago

Uh, sure.

Is there any outstanding request on this repo at this point?