NVIDIA / enroot

A simple yet powerful tool to turn traditional container/OS images into unprivileged sandboxes.
Apache License 2.0
648 stars 94 forks source link

/etc/rc omits CMD arguments #112

Open mjg0 opened 3 years ago

mjg0 commented 3 years ago

When I package up a container with enroot that has the following CMD line:

CMD ./run.sh arg1 arg2 arg2

...it results in this command being run by /etc/rc within the extracted container:

exec /usr/local/bin/nvidia_enrtypoint.sh /bin/sh -c ./run.sh arg1 arg2 arg3

Notice the lack of quotes--run.sh is run without arguments, which causes it to die immediately. When I put quotes around ./run.sh arg1 arg2 arg3, or remove /bin/sh -c, it works as expected. From what I've read, that CMD invocation is legitimate, so I would advocate for the removal of /bin/sh -c from the exec command.

3XX0 commented 3 years ago

There is no sh -c being generated by enroot: https://github.com/NVIDIA/enroot/blob/2f0c49e44d48b317854635a1922566dca6a3c909/src/docker.sh#L237-L241

It comes from Docker, this is the difference between: CMD ["command","param1","param2"] and CMD command param1 param2, the latter will be prefixed by sh -c

mjg0 commented 3 years ago

Sorry, I should have read the docs a bit closer--it explicitly says that "the <command> will execute in /bin/sh -c" when using shell form.

Since it seems like the behavior of Docker and enroot differ with this form, though, I made a minimal reproducible example with this Dockerfile:

FROM ubuntu:latest

RUN 'echo "Args:"; for arg in "$@"; do echo "$arg"; done; echo "-----"' > /printargs.sh
RUN chmod +x /printargs.sh

CMD /printargs.sh arg1 'arg 2' "arg \"3\""

...built it with Docker, and ran it. As expected, the resultant output is:

Args:
arg1
arg 2
arg "3"
-----

When I use enroot, though:

enroot import dockerd://dockercmdtest
enroot start dockercmdtest

...the resultant output is:

Args:
-----

It doesn't seem totally clear from the documentation, though, that this is "wrong" and the observed behavior is "right"--it's implied that the line will be quoted, but it doesn't actually say that anywhere. Nevertheless, I think trying to mirror Docker's behavior would limit confusion when this kind of case is encountered--would it be feasible to quote the full string that's passed to /bin/sh -c such that enroot treats CMDs in shell form similarly?