build --exec will keep /bin/sh even with --include-shell=false
Expected Behavior
When using the build command with --include-shell=false the shell script(s) should be removed from the image
Actual Behavior
It appears as if the shell used to run the --exec script will be included in the assets to keep (probably because it is actually running at the time of analysis)
Steps to Reproduce the Problem
- Minimize a standard unbuntu image, do not run any script:
>~/apps/dist_linux/slim build --http-probe=false --include-shell=false ubuntu:22.04
Try to execute a shell inside the minimized image, as expected, docker will complain:
>docker run --rm -ti ubuntu.slim /bin/sh
docker: Error response from daemon: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "/bin/sh": stat /bin/sh: no such file or directory: unknown.
- Fake a script run:
~/apps/dist_linux/slim build --http-probe=false --include-shell=false --exec /bin/true ubuntu:22.04
Run the /bin/sh shell inside the trimmed image (you get a shell prompt):
>docker run --rm -ti ubuntu.slim /bin/sh
#
This is probably not a bug but an unexpected side-effect of the build internal implementation.
Maybe an additional option like --run dedicated to run binary files bypassing the shell (like ENTRYPOINT do with its json array arguments) would clarify the intent and preserve the semantics of --include-shell ?
Specifications
slim version linux|Transformer|1.40.3|155f1b79556b7d100726f5ef4633f81a6ed27a2b|2023-07-13_07:46:40AM
- Platform:
- Distributor ID: Ubuntu Description: Ubuntu 22.04.2 LTS Release: 22.04 Codename: jammy
Yes, this is the expected behavior (will be good to document it in the real me as a clarification), but there's an opportunity to customize the behavior and introduce something similar to the exec Dockerfile instruction mode (with square brackets) to avoid using a shell (e.g., slim build --http-probe=false --include-shell=false --exec '["/usr/bin/uname","-a"]' ubuntu:22.04 ).
Hi,
That would be great!
I stumbled on this because I was looking for a simple way to:
1/ stop continue-after to wait for my input as there is nothing to analyze (the entrypoint is a statically compiled binary)
2/ remove some binaries, at least the shells, in the image
For 1/ only --exec ... seemed to be the only way to avoid waiting (--continue-after 0 did not worked as a timeout value as suggested in the doc)
--exclude-pattern /usr/bin/sh however did the trick for 2/