Slim doesn't properly parse image history with HEALTHCHECK if the layer was inserted by buildah bud
crcady opened this issue · comments
Expected Behavior
When processing an image built with buildah bud
, slim
should not crash.
Actual Behavior
slim
panics when attempting to process a HEALTHCHECK
inserted into the image history using buildah bud
.
Steps to Reproduce the Problem
- Have
slim
andbuildah
installed - Create a Dockerfile that has a Healthcheck command
# cat Dockerfile
FROM docker.io/nginx:latest
HEALTHCHECK --interval=5m --timeout=3s \
CMD curl -f http://localhost/ || exit 1
- Build the image with
buildah bud
buildah bud -t nginx-healthcheck-bud .
The output should be something like the below (I stripper the layers out for ease of reading)
STEP 1/2: FROM docker.io/nginx:latest
STEP 2/2: HEALTHCHECK --interval=5m --timeout=3s CMD curl -f http://localhost/ || exit 1
COMMIT nginx-healthcheck-bud
WARN[0000] Healthcheck is not supported for OCI image format and will be ignored. Must use `docker` format
Getting image source signatures
...
Writing manifest to image destination
Storing signatures
--> 1a8a069331c
Successfully tagged localhost/nginx-healthcheck-bud:latest
1a8a069331c7df36e4d71659f8bc8afe4520f23e3ef88037498f799c5483a680
- Push the image to somewhere that
slim
can access it
buildah push localhost/nginx-healthcheck-bud docker-daemon:nginx-healthcheck-bud:latest
You should see buildah
walk through the layers and then push into the registry:
Getting image source signatures
Copying blob ... done [snipped]
Writing manifest to image destination
Storing signatures
- Run a
slim
command that processes the image history (xray
,build
, etc.)
slim xray nginx-healthcheck-bud
results in the following output:
app='slim' message='Join the Gitter channel to ask questions or to share your feedback' info='https://gitter.im/docker-slim/community'
app='slim' message='Join the Discord server to ask questions or to share your feedback' info='https://discord.gg/9tDyxYS'
app='slim' message='GitHub Discussions' info='https://github.com/slimtoolkit/slim/discussions'
cmd=xray state=started
cmd=xray info=params add-image-config='false' rm-file-artifacts='false' target='nginx-healthcheck-bud' add-image-manifest='false'
cmd=xray state=image.api.inspection.start
cmd=xray info=image id='sha256:5f8467158bb77c8fa0b38998f8bdabd1f9146657327667bf071e3b143a2e93f3' size.bytes='142129665' size.human='142 MB' architecture='amd64'
app='slim' message='Join the Gitter channel to ask questions or to share your feedback' info='https://gitter.im/docker-slim/community'
app='slim' message='Join the Discord server to ask questions or to share your feedback' info='https://discord.gg/9tDyxYS'
app='slim' message='GitHub Discussions' info='https://github.com/slimtoolkit/slim/discussions'
panic: runtime error: index out of range [1] with length 1
goroutine 1 [running]:
github.com/docker-slim/docker-slim/pkg/docker/dockerfile/reverse.deserialiseHealtheckInstruction({0xc0003b93c2?, 0x4f?})
github.com/docker-slim/docker-slim/pkg/docker/dockerfile/reverse/reverse.go:732 +0x1226
github.com/docker-slim/docker-slim/pkg/docker/dockerfile/reverse.DockerfileFromHistoryStruct({0xc0006a7500, 0x10, 0x13})
github.com/docker-slim/docker-slim/pkg/docker/dockerfile/reverse/reverse.go:469 +0x2b69
github.com/docker-slim/docker-slim/pkg/docker/dockerfile/reverse.DockerfileFromHistory(0xc00075de40?, {0x7fff0bf64729?, 0xc00075e688?})
github.com/docker-slim/docker-slim/pkg/docker/dockerfile/reverse/reverse.go:210 +0x3c
github.com/docker-slim/docker-slim/pkg/app/master/inspectors/image.(*Inspector).ProcessCollectedData(0xc00075de40)
github.com/docker-slim/docker-slim/pkg/app/master/inspectors/image/image_inspector.go:306 +0x45
github.com/docker-slim/docker-slim/pkg/app/master/commands/xray.OnCommand(0xc00075f1b0, 0xc0005887e0, {0x7fff0bf64729, _}, _, {_, _}, {_, _}, {0x0, ...}, ...)
github.com/docker-slim/docker-slim/pkg/app/master/commands/xray/handler.go:192 +0x1625
github.com/docker-slim/docker-slim/pkg/app/master/commands/xray.glob..func1(0xc00004f080)
github.com/docker-slim/docker-slim/pkg/app/master/commands/xray/cli.go:229 +0x14ca
github.com/urfave/cli/v2.(*Command).Run(0x2d4a7a0, 0xc00061e540)
github.com/urfave/cli/v2@v2.3.0/command.go:163 +0x5dc
github.com/urfave/cli/v2.(*App).RunContext(0xc0005a2680, {0x1f46a50?, 0xc000040068}, {0xc00003e090, 0x3, 0x3})
github.com/urfave/cli/v2@v2.3.0/app.go:313 +0xb7d
github.com/urfave/cli/v2.(*App).Run(...)
github.com/urfave/cli/v2@v2.3.0/app.go:224
github.com/docker-slim/docker-slim/pkg/app/master.Run()
github.com/docker-slim/docker-slim/pkg/app/master/app.go:15 +0x46
main.main()
github.com/docker-slim/docker-slim/cmd/slim/main.go:15 +0x18
Specifications
- Version: 1.40.1
slim --version
slim version linux|Transformer|1.40.1|9c5e69ab1fd4564b0a5426d47be038155e63e4c1|2023-04-05_11:22:53PM
- Platform: Linux AMD64
uname -a
Linux slim 5.15.0-67-generic #74-Ubuntu SMP Wed Feb 22 14:14:39 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux
It looks like the reason this happens is that buildah bud
doesn't serialize the HEALTHCHECK instruction in this history:
docker history nginx-healthcheck-bud
IMAGE CREATED CREATED BY SIZE COMMENT
1a8a069331c7 11 minutes ago /bin/sh -c #(nop) HEALTHCHECK --interval=5m … 0B FROM docker.io/library/nginx:latest
# rest of the image history stripped for clarity
If you build the same image with docker build
, you get a serialized HEALTHCHECK:
docker history nginx-healthcheck-docker
IMAGE CREATED CREATED BY SIZE COMMENT
8752c36a0f7a 11 days ago HEALTHCHECK &{["CMD-SHELL" "curl -f http://l… 0B buildkit.dockerfile.v0
# rest of the image history stripped for clarity
I think the simplest way to avoid this is to check for serialization in pkg/docker/dockerfile/reverse.go
(probably here), and if it doesn't look like a serialized command just emit the instruction wholesale. If that makes sense, I'll gin up a PR and submit it.
@crcady thanks for sharing the bug! can you also add the non-truncated history for the HEALTHCHECK instruction from the buildah bud
generated image?
@kcq Here's the output from a super-minimal example (this one is from scratch because the NGINX no-truncate history was murdering my terminal) - it's exactly the same example as above, except the source image in the FROM line is scratch
instead of docker.io/nginx:latest
. It looks like buildah bud
puts the entirety of the HEALTHCHECK in there after stripping out line continuations.
docker image history --no-trunc scratch-healthcheck:latest
IMAGE CREATED CREATED BY SIZE COMMENT
sha256:39e7ba3a2d3586e5b21a5685c364a479ad93e847ed5bffd9a8e945a3875e8ee2 About a minute ago /bin/sh -c #(nop) HEALTHCHECK --interval=5m --timeout=3s CMD curl -f http://localhost/ || exit 1 0B
@crcady thanks! will have a new release in a couple of days. it'll be good to test again
@crcady the problem should have been addressed in the 1.40.2 release. Now there's also 1.40.3 where it has more useful enhancements including an experimental 'merge' command. Check it out. Let me know if you have any other buildah related problems and if the new enhancements look interesting to you.