This is an MRE for an issue I ran into recently. I originally posted on StackOverflow, but that didn't get any traction, possibly because my example was too complicated.
I found examples online that use older versions of the OCI rules. I'm either doing something wrong or they only work because of the version difference.
I want to build container images using Bazel.
The recommended Bazel rules for this use case is Aspect's rules_oci
.
rules_oci
mostly provides a way to build the images (which I can do successfully),
but the project recommends using container_structure_test
to test the image structure.
I'm reluctant to test against the oci_image
output because it's not the final artifact.
As far as I understand, you always have to use oci_tarball
to generate the final artifact,
so testing against oci_image
is inherently lower-fidelity.
I'm using an Apple Silicon Mac, but you should be able to run this on most ARM Linux machines.
- Install Bazelisk
- Install Docker Engine or Docker Desktop
- Clone this repository somewhere.
Run the following commands from the repo directory. They should both succeed.
bazel build //my_package:empty_file_image_tarball
bazel run //my_package:empty_file_image_tarball
The run command should've loaded the tarball image into Docker. You should now be able to open a bash session and see the empty file.
➜ mre-container-tar-test git:(main) ✗ docker run -it empty_file:latest bash
ubuntu@eacee0e03d58:/$ ls
bin boot dev empty-file.txt etc home lib media mnt opt proc root run sbin srv sys tmp usr var
ubuntu@eacee0e03d58:/$ stat empty-file.txt
File: empty-file.txt
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: 0,59 Inode: 527936 Links: 1
Access: (0555/-r-xr-xr-x) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2000-01-01 00:00:00.000000000 +0000
Modify: 2000-01-01 00:00:00.000000000 +0000
Change: 2024-06-14 02:55:51.692770004 +0000
Birth: 2024-06-14 02:55:51.692770004 +0000
Running against the intermediary image is fine.
We can see this by running bazel test //my_package:empty_file_layer_test
.
➜ mre-container-tar-test git:(main) ✗ bazel test //my_package:empty_file_layer_test
INFO: Analyzed target //my_package:empty_file_layer_test (1 packages loaded, 5 targets configured).
INFO: Found 1 test target...
Target //my_package:empty_file_layer_test up-to-date:
bazel-bin/my_package/empty_file_layer_test.sh
INFO: Elapsed time: 0.817s, Critical Path: 0.73s
INFO: 5 processes: 5 darwin-sandbox.
INFO: Build completed successfully, 5 total actions
//my_package:empty_file_layer_test PASSED in 0.4s
Executed 1 out of 1 test: 1 test passes.
There were tests whose specified size is too big. Use the --test_verbose_timeout_warnings command line option to see which ones these are.
Running bazel test //my_package:empty_file_image_tarball_test
should fail to run the test.
Bazel should complain that the tarball doesn't end in .tar
.
➜ mre-container-tar-test git:(main) ✗ bazel test //my_package:empty_file_image_tarball_test
ERROR: /Users/josalvatorre/code/mre-container-tar-test/my_package/BUILD.bazel:26:25: in container_structure_test rule //my_package:empty_file_image_tarball_test:
Traceback (most recent call last):
File "/private/var/tmp/_bazel_josalvatorre/bb1e2552732b81b1b69870fcd931a2e6/external/container_structure_test~/bazel/container_structure_test.bzl", line 55, column 17, in _structure_test_impl
fail("when the 'driver' attribute is not 'docker', then the image must be a .tar file")
Error in fail: when the 'driver' attribute is not 'docker', then the image must be a .tar file
ERROR: /Users/josalvatorre/code/mre-container-tar-test/my_package/BUILD.bazel:26:25: Analysis of target '//my_package:empty_file_image_tarball_test' failed
ERROR: Analysis of target '//my_package:empty_file_image_tarball_test' failed; build aborted
INFO: Elapsed time: 0.079s, Critical Path: 0.00s
INFO: 1 process: 1 internal.
ERROR: Build did NOT complete successfully
ERROR: No test targets were found, yet testing was requested