@@ -8,12 +8,131 @@ if [ "$#" -eq 0 ]; then
88 eval " set -- $dirs "
99fi
1010
11+ [ -n " $BASHBREW_ARCH " ]
12+ platformString=" $( bashbrew cat --format ' {{ ociPlatform arch }}' <( echo ' Maintainers: empty hack (@example)' ) ) "
13+ platform=" $( bashbrew cat --format ' {{ ociPlatform arch | json }}' <( echo ' Maintainers: empty hack (@example)' ) ) "
14+
1115for dir; do
12- base=" busybox:${dir//// -} "
16+ variant=" $( basename " $dir " ) "
17+ base=" busybox:${dir//// -} -$BASHBREW_ARCH "
18+
19+ froms=" $( awk ' toupper($1) == "FROM" { print $2 }' " $dir /Dockerfile.builder" ) "
20+ for from in " $froms " ; do
21+ if ! bashbrew remote arches --json " $from " | jq -e ' .arches | has(env.BASHBREW_ARCH)' > /dev/null; then
22+ echo >&2 " warning: '$base ' is 'FROM $from ' which does not support '$BASHBREW_ARCH '; skipping"
23+ continue 2
24+ fi
25+ done
26+
1327 (
1428 set -x
15- docker build -t " $base -builder" -f " $dir /Dockerfile.builder" " $dir "
16- docker run --rm " $base -builder" tar cC rootfs . | xz -T0 -z9 > " $dir /busybox.tar.xz"
29+
30+ # TODO save the output of "bashbrew remote arches" above so we can "--build-context" here?
31+ docker buildx build \
32+ --progress=plain \
33+ --platform " $platformString " \
34+ --pull \
35+ --load \
36+ --tag " $base -builder" \
37+ --file " $dir /Dockerfile.builder" \
38+ " $dir "
39+
40+ oci=" $dir /$BASHBREW_ARCH "
41+ rm -rf " $oci "
42+ mkdir " $oci " " $oci /blobs" " $oci /blobs/sha256"
43+
44+ docker run --rm " $base -builder" \
45+ tar \
46+ --create \
47+ --directory rootfs \
48+ --numeric-owner \
49+ --transform ' s,^./,,' \
50+ --sort name \
51+ --mtime /usr/src/busybox.SOURCE_DATE_EPOCH --clamp-mtime \
52+ . \
53+ > " $oci /rootfs.tar"
54+
55+ # if we gzip separately, we can calculate the diffid without decompressing
56+ diffId=" $( sha256sum " $oci /rootfs.tar" | cut -d' ' -f1) "
57+ diffId=" sha256:$diffId "
58+
59+ # we need to use the container's gzip so it's more likely reproducible over time (and using busybox's own gzip is a cute touch 😀)
60+ docker run -i --rm " $base -builder" chroot rootfs gzip -c < " $oci /rootfs.tar" > " $oci /rootfs.tar.gz"
61+ rm " $oci /rootfs.tar"
62+ rootfs=" $( sha256sum " $oci /rootfs.tar.gz" | cut -d' ' -f1) "
63+ ln -svfT --relative " $oci /rootfs.tar.gz" " $oci /blobs/sha256/$rootfs "
64+ rootfsSize=" $( stat --format ' %s' --dereference " $oci /blobs/sha256/$rootfs " ) "
65+ rootfs=" sha256:$rootfs "
66+
67+ SOURCE_DATE_EPOCH=" $( docker run --rm " $base -builder" cat /usr/src/busybox.SOURCE_DATE_EPOCH) "
68+ createdBy=" $( docker run --rm --env variant=" $variant " " $base -builder" sh -euc ' . /etc/os-release && echo "BusyBox $BUSYBOX_VERSION ($variant)${BUILDROOT_VERSION:+, Buildroot $BUILDROOT_VERSION}, ${NAME%% *} ${VERSION_ID:-$VERSION_CODENAME}"' ) "
69+ jq -n --tab --arg SOURCE_DATE_EPOCH " $SOURCE_DATE_EPOCH " --arg diffId " $diffId " --arg createdBy " $createdBy " --argjson platform " $platform " '
70+ ($SOURCE_DATE_EPOCH | tonumber | strftime("%Y-%m-%dT%H:%M:%SZ")) as $created
71+ | {
72+ config: {
73+ Cmd: [ "sh" ],
74+ },
75+ created: $created,
76+ history: [ {
77+ created: $created,
78+ created_by: $createdBy,
79+ } ],
80+ rootfs: {
81+ type: "layers",
82+ diff_ids: [ $diffId ],
83+ },
84+ } + $platform
85+ ' > " $oci /image-config.json"
86+ config=" $( sha256sum " $oci /image-config.json" | cut -d' ' -f1) "
87+ ln -svfT --relative " $oci /image-config.json" " $oci /blobs/sha256/$config "
88+ configSize=" $( stat --format ' %s' --dereference " $oci /blobs/sha256/$config " ) "
89+ config=" sha256:$config "
90+
91+ version=" $( cut <<< " $createdBy" -d' ' -f2) " # a better way to scrape the BusyBox version? maybe this is fine (want to avoid yet another container run)
92+ jq -n --tab --arg version " $version " --arg variant " $variant " --arg config " $config " --arg configSize " $configSize " --arg rootfs " $rootfs " --arg rootfsSize " $rootfsSize " '
93+ {
94+ schemaVersion: 2,
95+ mediaType: "application/vnd.oci.image.manifest.v1+json",
96+ config: {
97+ mediaType: "application/vnd.oci.image.config.v1+json",
98+ digest: $config,
99+ size: ($configSize | tonumber),
100+ },
101+ layers: [ {
102+ mediaType: "application/vnd.oci.image.layer.v1.tar+gzip",
103+ digest: $rootfs,
104+ size: ($rootfsSize | tonumber),
105+ } ],
106+ annotations: {
107+ "org.opencontainers.image.url": "https://github.com/docker-library/busybox",
108+ "org.opencontainers.image.version": ($version + "-" + $variant),
109+ },
110+ }
111+ ' > " $oci /image-manifest.json"
112+ manifest=" $( sha256sum " $oci /image-manifest.json" | cut -d' ' -f1) "
113+ ln -svfT --relative " $oci /image-manifest.json" " $oci /blobs/sha256/$manifest "
114+ manifestSize=" $( stat --format ' %s' --dereference " $oci /blobs/sha256/$manifest " ) "
115+ manifest=" sha256:$manifest "
116+
117+ jq -nc ' { imageLayoutVersion:"1.0.0" }' > " $oci /oci-layout"
118+ jq -n --tab --arg version " $version " --arg variant " $variant " --arg manifest " $manifest " --arg manifestSize " $manifestSize " --argjson platform " $platform " '
119+ {
120+ schemaVersion: 2,
121+ mediaType: "application/vnd.oci.image.index.v1+json",
122+ manifests: [ {
123+ mediaType: "application/vnd.oci.image.manifest.v1+json",
124+ digest: $manifest,
125+ size: ($manifestSize | tonumber),
126+ platform: $platform,
127+ annotations: {
128+ "org.opencontainers.image.ref.name": ("busybox:" + $version + "-" + $variant),
129+ "io.containerd.image.name": ("busybox:" + $version + "-" + $variant),
130+ },
131+ } ],
132+ }
133+ ' > " $oci /index.json"
134+
135+ ln -svfT --relative " $oci /rootfs.tar.gz" " $dir /busybox.tar.gz"
17136 docker build -t " $base -test" " $dir "
18137 docker run --rm " $base -test" sh -xec ' true'
19138
0 commit comments