Add separate unstable/stable versions and initial jq-based templating engine

This commit is contained in:
Tianon Gravi 2021-01-11 13:37:42 -08:00
parent fd4360b726
commit 584f6f7438
24 changed files with 1536 additions and 151 deletions

3
.gitattributes vendored Normal file
View File

@ -0,0 +1,3 @@
/*/**/Dockerfile linguist-generated
/*/**/Dockerfile.builder linguist-generated linguist-language=Dockerfile
/Dockerfile*.template linguist-language=Dockerfile

View File

@ -3,13 +3,20 @@ set -Eeuo pipefail
# this is a fake version of "generate-stackbrew-library.sh" just so https://github.com/docker-library/bashbrew/blob/c74be66ae6a019e0baee601287187dc6df29b384/scripts/github-actions/generate.sh can generate us a sane starter matrix
[ -f versions.json ] # run "versions.sh" first
if [ "$#" -eq 0 ]; then
dirs="$(jq -r 'to_entries | map(.key + "/" + (.value.variants[])) | map(@sh) | join(" ")' versions.json)"
eval "set -- $dirs"
fi
echo 'Maintainers: foo (@bar)'
echo 'GitRepo: https://github.com/docker-library/busybox.git'
for f in */Dockerfile.builder; do
d="$(dirname "$f")"
for d; do
commit="$(git log -1 --format='format:%H' "$d/Dockerfile")"
echo
echo "Tags: $d"
echo "Tags: ${d////-}"
echo "Directory: $d"
echo "GitCommit: $commit"
done

22
.github/workflows/verify-templating.yml vendored Normal file
View File

@ -0,0 +1,22 @@
name: Verify Templating
on:
pull_request:
push:
defaults:
run:
shell: 'bash -Eeuo pipefail -x {0}'
jobs:
apply-templates:
name: Check For Uncomitted Changes
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Apply Templates
run: ./apply-templates.sh
- name: Check Git Status
run: |
status="$(git status --short)"
[ -z "$status" ]

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
.jq-template.awk

415
Dockerfile-builder.template Normal file
View File

@ -0,0 +1,415 @@
{{ if env.variant == "musl" then ( -}}
FROM alpine:3.12
RUN set -eux; \
apk add --no-cache \
bzip2 \
coreutils \
curl \
gcc \
gnupg \
linux-headers \
make \
musl-dev \
tzdata \
;
{{ ) else ( -}}
FROM debian:buster-slim
RUN set -eux; \
apt-get update; \
apt-get install -y \
bzip2 \
curl \
gcc \
gnupg dirmngr \
make \
; \
rm -rf /var/lib/apt/lists/*
{{ ) end -}}
{{ if env.variant == "uclibc" then ( -}}
# grab/use buildroot for its uClibc toolchain
RUN set -eux; \
apt-get update; \
apt-get install -y \
bc \
cpio \
dpkg-dev \
g++ \
patch \
perl \
python \
rsync \
unzip \
wget \
; \
rm -rf /var/lib/apt/lists/*
# pub 1024D/59C36319 2009-01-15
# Key fingerprint = AB07 D806 D2CE 741F B886 EE50 B025 BA8B 59C3 6319
# uid Peter Korsgaard <jacmet@uclibc.org>
# sub 2048g/45428075 2009-01-15
RUN gpg --batch --keyserver ha.pool.sks-keyservers.net --recv-keys AB07D806D2CE741FB886EE50B025BA8B59C36319
# https://buildroot.org/download.html
# https://buildroot.org/downloads/?C=M;O=D
ENV BUILDROOT_VERSION {{ .buildroot.version }}
RUN set -eux; \
tarball="buildroot-${BUILDROOT_VERSION}.tar.bz2"; \
curl -fL -o buildroot.tar.bz2 "https://buildroot.org/downloads/$tarball"; \
curl -fL -o buildroot.tar.bz2.sign "https://buildroot.org/downloads/$tarball.sign"; \
gpg --batch --decrypt --output buildroot.tar.bz2.txt buildroot.tar.bz2.sign; \
awk '$1 == "SHA1:" && $2 ~ /^[0-9a-f]+$/ && $3 == "'"$tarball"'" { print $2, "*buildroot.tar.bz2" }' buildroot.tar.bz2.txt > buildroot.tar.bz2.sha1; \
test -s buildroot.tar.bz2.sha1; \
sha1sum -c buildroot.tar.bz2.sha1; \
mkdir -p /usr/src/buildroot; \
tar -xf buildroot.tar.bz2 -C /usr/src/buildroot --strip-components 1; \
rm buildroot.tar.bz2*
RUN set -eux; \
\
cd /usr/src/buildroot; \
\
setConfs=' \
BR2_STATIC_LIBS=y \
BR2_TOOLCHAIN_BUILDROOT_UCLIBC=y \
BR2_TOOLCHAIN_BUILDROOT_WCHAR=y \
'; \
\
unsetConfs=' \
BR2_SHARED_LIBS \
'; \
\
# buildroot arches: https://git.busybox.net/buildroot/tree/arch
# buildroot+uclibc arches: https://git.busybox.net/buildroot/tree/toolchain/toolchain-buildroot/Config.in ("config BR2_TOOLCHAIN_BUILDROOT_UCLIBC")
dpkgArch="$(dpkg --print-architecture)"; \
case "$dpkgArch" in \
amd64) \
setConfs="$setConfs \
BR2_x86_64=y \
"; \
;; \
\
arm64) \
setConfs="$setConfs \
BR2_aarch64=y \
"; \
;; \
\
# https://wiki.debian.org/ArmEabiPort#Choice_of_minimum_CPU
# https://github.com/free-electrons/toolchains-builder/blob/db259641eaf5bbcf13f4a3c5003e5436e806770c/configs/arch/armv5-eabi.config
# https://git.busybox.net/buildroot/tree/arch/Config.in.arm
# (Debian minimums at ARMv4, we minimum at ARMv5 instead)
armel) \
setConfs="$setConfs \
BR2_arm=y \
BR2_arm926t=y \
BR2_ARM_EABI=y \
BR2_ARM_INSTRUCTIONS_THUMB=y \
BR2_ARM_SOFT_FLOAT=y \
"; \
;; \
\
# "Currently the Debian armhf port requires at least an ARMv7 CPU with Thumb-2 and VFP3D16."
# https://wiki.debian.org/ArmHardFloatPort#Supported_devices
# https://github.com/free-electrons/toolchains-builder/blob/db259641eaf5bbcf13f4a3c5003e5436e806770c/configs/arch/armv7-eabihf.config
# https://git.busybox.net/buildroot/tree/arch/Config.in.arm
armhf) \
setConfs="$setConfs \
BR2_arm=y \
BR2_cortex_a9=y \
BR2_ARM_EABIHF=y \
BR2_ARM_ENABLE_VFP=y \
BR2_ARM_FPU_VFPV3D16=y \
BR2_ARM_INSTRUCTIONS_THUMB2=y \
"; \
unsetConfs="$unsetConfs BR2_ARM_SOFT_FLOAT"; \
;; \
\
i386) \
setConfs="$setConfs \
BR2_i386=y \
"; \
;; \
\
mips64el) \
setConfs="$setConfs \
BR2_mips64el=y \
BR2_mips_64r2=y \
BR2_MIPS_NABI64=y \
"; \
unsetConfs="$unsetConfs \
BR2_MIPS_SOFT_FLOAT \
" \
;; \
\
# TODO ppc64el ? (needs BR2_TOOLCHAIN_BUILDROOT_UCLIBC support)
\
# TODO s390x ? (needs BR2_TOOLCHAIN_BUILDROOT_UCLIBC support)
\
*) \
echo >&2 "error: unsupported architecture '$dpkgArch'!"; \
exit 1; \
;; \
esac; \
if [ "$dpkgArch" != 'i386' ]; then \
unsetConfs="$unsetConfs BR2_i386"; \
fi; \
\
make defconfig; \
\
for conf in $unsetConfs; do \
sed -i \
-e "s!^$conf=.*\$!# $conf is not set!" \
.config; \
done; \
\
for confV in $setConfs; do \
conf="${confV%=*}"; \
sed -i \
-e "s!^$conf=.*\$!$confV!" \
-e "s!^# $conf is not set\$!$confV!" \
.config; \
if ! grep -q "^$confV\$" .config; then \
echo "$confV" >> .config; \
fi; \
done; \
\
make oldconfig; \
\
# trust, but verify
for conf in $unsetConfs; do \
! grep -q "^$conf=" .config; \
done; \
for confV in $setConfs; do \
grep -q "^$confV\$" .config; \
done;
# https://www.finnie.org/2014/02/13/compiling-busybox-with-uclibc/
RUN set -eux; \
# force a particular GNU arch for "host-gmp" (otherwise it fails on some arches)
gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \
make -C /usr/src/buildroot \
HOST_GMP_CONF_OPTS="--build='"$gnuArch"'" \
# building host-tar:
# configure: error: you should not run configure as root (set FORCE_UNSAFE_CONFIGURE=1 in environment to bypass this check)
FORCE_UNSAFE_CONFIGURE=1 \
-j "$(nproc)" \
toolchain
ENV PATH /usr/src/buildroot/output/host/usr/bin:$PATH
{{ ) else "" end -}}
# pub 1024D/ACC9965B 2006-12-12
# Key fingerprint = C9E9 416F 76E6 10DB D09D 040F 47B7 0C55 ACC9 965B
# uid Denis Vlasenko <vda.linux@googlemail.com>
# sub 1024g/2C766641 2006-12-12
RUN gpg --batch --keyserver ha.pool.sks-keyservers.net --recv-keys C9E9416F76E610DBD09D040F47B70C55ACC9965B
ENV BUSYBOX_VERSION {{ .version }}
ENV BUSYBOX_SHA256 {{ .sha256 }}
RUN set -eux; \
tarball="busybox-${BUSYBOX_VERSION}.tar.bz2"; \
curl -fL -o busybox.tar.bz2.sig "https://busybox.net/downloads/$tarball.sig"; \
curl -fL -o busybox.tar.bz2 "https://busybox.net/downloads/$tarball"; \
echo "$BUSYBOX_SHA256 *busybox.tar.bz2" | sha256sum -c -; \
gpg --batch --verify busybox.tar.bz2.sig busybox.tar.bz2; \
mkdir -p /usr/src/busybox; \
tar -xf busybox.tar.bz2 -C /usr/src/busybox --strip-components 1; \
rm busybox.tar.bz2*
WORKDIR /usr/src/busybox
RUN set -eux; \
\
setConfs=' \
CONFIG_AR=y \
CONFIG_FEATURE_AR_CREATE=y \
CONFIG_FEATURE_AR_LONG_FILENAMES=y \
# CONFIG_LAST_SUPPORTED_WCHAR: see https://github.com/docker-library/busybox/issues/13 (UTF-8 input)
CONFIG_LAST_SUPPORTED_WCHAR=0 \
{{ if env.variant == "glibc" then ( -}}
# As long as we rely on libnss (see below), we have to have libc.so anyhow, so we've removed CONFIG_STATIC here... :cry:
{{ ) else ( -}}
CONFIG_STATIC=y \
{{ ) end -}}
'; \
\
unsetConfs=' \
CONFIG_FEATURE_SYNC_FANCY \
{{ if env.variant == "musl" then ( -}}
\
# see https://wiki.musl-libc.org/wiki/Building_Busybox
CONFIG_FEATURE_HAVE_RPC \
CONFIG_FEATURE_INETD_RPC \
CONFIG_FEATURE_UTMP \
CONFIG_FEATURE_WTMP \
{{ ) else "" end -}}
'; \
\
make defconfig; \
\
for conf in $unsetConfs; do \
sed -i \
-e "s!^$conf=.*\$!# $conf is not set!" \
.config; \
done; \
\
for confV in $setConfs; do \
conf="${confV%=*}"; \
sed -i \
-e "s!^$conf=.*\$!$confV!" \
-e "s!^# $conf is not set\$!$confV!" \
.config; \
if ! grep -q "^$confV\$" .config; then \
echo "$confV" >> .config; \
fi; \
done; \
\
make oldconfig; \
\
# trust, but verify
for conf in $unsetConfs; do \
! grep -q "^$conf=" .config; \
done; \
for confV in $setConfs; do \
grep -q "^$confV\$" .config; \
done
RUN set -eux; \
nproc="$(nproc)"; \
{{ if env.variant == "uclibc" then ( -}}
CROSS_COMPILE="$(basename /usr/src/buildroot/output/host/usr/*-buildroot-linux-uclibc*)"; \
export CROSS_COMPILE="$CROSS_COMPILE-"; \
{{ ) else "" end -}}
make -j "$nproc" busybox; \
./busybox --help; \
mkdir -p rootfs/bin; \
ln -vL busybox rootfs/bin/; \
\
{{ if env.variant == "uclibc" then ( -}}
# copy "getconf" from buildroot
ln -vL ../buildroot/output/target/usr/bin/getconf rootfs/bin/; \
{{ ) elif env.variant == "glibc" then ( -}}
# copy "getconf" from Debian
getconf="$(which getconf)"; \
ln -vL "$getconf" rootfs/bin/getconf; \
\
# hack hack hack hack hack
# with glibc, busybox (static or not) uses libnss for DNS resolution :(
mkdir -p rootfs/etc; \
cp /etc/nsswitch.conf rootfs/etc/; \
mkdir -p rootfs/lib; \
ln -sT lib rootfs/lib64; \
gccMultiarch="$(gcc -print-multiarch)"; \
set -- \
rootfs/bin/busybox \
rootfs/bin/getconf \
/lib/"$gccMultiarch"/libnss*.so.* \
# libpthread is part of glibc: https://stackoverflow.com/a/11210463/433558
/lib/"$gccMultiarch"/libpthread*.so.* \
; \
while [ "$#" -gt 0 ]; do \
f="$1"; shift; \
fn="$(basename "$f")"; \
if [ -e "rootfs/lib/$fn" ]; then continue; fi; \
if [ "${f#rootfs/}" = "$f" ]; then \
if [ "${fn#ld-}" = "$fn" ]; then \
ln -vL "$f" "rootfs/lib/$fn"; \
else \
cp -v "$f" "rootfs/lib/$fn"; \
fi; \
fi; \
ldd="$(ldd "$f" | awk ' \
$1 ~ /^\// { print $1; next } \
$2 == "=>" && $3 ~ /^\// { print $3; next } \
')"; \
set -- "$@" $ldd; \
done; \
{{ ) elif env.variant == "musl" then ( -}}
# copy simplified getconf port from Alpine
aportsVersion="v$(cat /etc/alpine-release)"; \
curl -fsSL \
"https://git.alpinelinux.org/cgit/aports/plain/main/musl/getconf.c?h=${aportsVersion}" \
-o /usr/src/getconf.c \
; \
gcc -o rootfs/bin/getconf -static -Os /usr/src/getconf.c; \
{{ ) else "" end -}}
chroot rootfs /bin/getconf _NPROCESSORS_ONLN; \
\
chroot rootfs /bin/busybox --install /bin
# install a few extra files from buildroot (/etc/passwd, etc)
RUN set -eux; \
{{ if env.variant == "uclibc" then "" else ( -}}
buildrootVersion={{ .buildroot.version | @sh }}; \
for file in \
system/device_table.txt \
system/skeleton/etc/group \
system/skeleton/etc/passwd \
system/skeleton/etc/shadow \
; do \
dir="$(dirname "$file")"; \
mkdir -p "../buildroot/$dir"; \
curl -fL -o "../buildroot/$file" "https://git.busybox.net/buildroot/plain/$file?id=$buildrootVersion"; \
[ -s "../buildroot/$file" ]; \
done; \
\
{{ ) end -}}
mkdir -p rootfs/etc; \
ln -vL \
../buildroot/system/skeleton/etc/group \
../buildroot/system/skeleton/etc/passwd \
../buildroot/system/skeleton/etc/shadow \
rootfs/etc/ \
; \
# CVE-2019-5021, https://github.com/docker-library/official-images/pull/5880#issuecomment-490681907
grep -E '^root::' rootfs/etc/shadow; \
sed -ri -e 's/^root::/root:*:/' rootfs/etc/shadow; \
grep -E '^root:[*]:' rootfs/etc/shadow; \
# set expected permissions, etc too (https://git.busybox.net/buildroot/tree/system/device_table.txt)
awk ' \
!/^#/ { \
if ($2 != "d" && $2 != "f") { \
printf "error: unknown type \"%s\" encountered in line %d: %s\n", $2, NR, $0 > "/dev/stderr"; \
exit 1; \
} \
sub(/^\/?/, "rootfs/", $1); \
if ($2 == "d") { \
printf "mkdir -p %s\n", $1; \
} \
printf "chmod %s %s\n", $3, $1; \
} \
' ../buildroot/system/device_table.txt | sh -eux
# create missing home directories
RUN set -eux; \
cd rootfs; \
for userHome in $(awk -F ':' '{ print $3 ":" $4 "=" $6 }' etc/passwd); do \
user="${userHome%%=*}"; \
home="${userHome#*=}"; \
home="./${home#/}"; \
if [ ! -d "$home" ]; then \
mkdir -p "$home"; \
chown "$user" "$home"; \
chmod 755 "$home"; \
fi; \
done
# test and make sure it works
RUN chroot rootfs /bin/sh -xec 'true'
# ensure correct timezone (UTC)
RUN set -eux; \
ln -vL /usr/share/zoneinfo/UTC rootfs/etc/localtime; \
[ "$(chroot rootfs date +%Z)" = 'UTC' ]
# test and make sure DNS works too
RUN cp -L /etc/resolv.conf rootfs/etc/; \
chroot rootfs /bin/sh -xec 'nslookup google.com'; \
rm rootfs/etc/resolv.conf
# vim:set ft=dockerfile:

49
apply-templates.sh Executable file
View File

@ -0,0 +1,49 @@
#!/usr/bin/env bash
set -Eeuo pipefail
[ -f versions.json ] # run "versions.sh" first
cd "$(dirname "$(readlink -f "$BASH_SOURCE")")"
jqt='.jq-template.awk'
if [ -n "${BASHBREW_SCRIPTS:-}" ]; then
jqt="$BASHBREW_SCRIPTS/jq-template.awk"
elif [ "$BASH_SOURCE" -nt "$jqt" ]; then
wget -qO "$jqt" 'https://github.com/docker-library/bashbrew/raw/5f0c26381fb7cc78b2d217d58007800bdcfbcfa1/scripts/jq-template.awk'
fi
if [ "$#" -eq 0 ]; then
versions="$(jq -r 'keys | map(@sh) | join(" ")' versions.json)"
eval "set -- $versions"
fi
generated_warning() {
cat <<-EOH
#
# NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh"
#
# PLEASE DO NOT EDIT IT DIRECTLY.
#
EOH
}
for version; do
export version
variants="$(jq -r '.[env.version].variants | map(@sh) | join(" ")' versions.json)"
eval "variants=( $variants )"
for variant in "${variants[@]}"; do
export variant
echo "processing $version/$variant ..."
{
generated_warning
gawk -f "$jqt" Dockerfile-builder.template
} > "$version/$variant/Dockerfile.builder"
cp Dockerfile.template "$version/$variant/Dockerfile"
done
done

View File

@ -1,40 +1,38 @@
#!/bin/bash
set -e
#!/usr/bin/env bash
set -Eeuo pipefail
cd "$(readlink -f "$(dirname "$BASH_SOURCE")")"
[ -f versions.json ] # run "versions.sh" first
versions=( "$@" )
if [ ${#versions[@]} -eq 0 ]; then
versions=( */ )
if [ "$#" -eq 0 ]; then
dirs="$(jq -r 'to_entries | map(.key + "/" + (.value.variants[])) | map(@sh) | join(" ")' versions.json)"
eval "set -- $dirs"
fi
versions=( "${versions[@]%/}" )
base='busybox:'
for version in "${versions[@]}"; do
[ -f "$version/Dockerfile.builder" ] || continue
for dir; do
base="busybox:${dir////-}"
(
set -x
docker build -t "$base$version-builder" -f "$version/Dockerfile.builder" "$version"
docker run --rm "$base$version-builder" tar cC rootfs . | xz -T0 -z9 > "$version/busybox.tar.xz"
docker build -t "$base$version-test" "$version"
docker run --rm "$base$version-test" sh -xec 'true'
docker build -t "$base-builder" -f "$dir/Dockerfile.builder" "$dir"
docker run --rm "$base-builder" tar cC rootfs . | xz -T0 -z9 > "$dir/busybox.tar.xz"
docker build -t "$base-test" "$dir"
docker run --rm "$base-test" sh -xec 'true'
# detect whether the current host _can_ ping
# (QEMU user-mode networking does not route ping traffic)
shouldPing=
if docker run --rm "$base$version-builder" ping -c 1 google.com &> /dev/null; then
if docker run --rm "$base-builder" ping -c 1 google.com &> /dev/null; then
shouldPing=1
fi
if [ -n "$shouldPing" ]; then
if ! docker run --rm "$base$version-test" ping -c 1 google.com; then
if ! docker run --rm "$base-test" ping -c 1 google.com; then
sleep 1
docker run --rm "$base$version-test" ping -c 1 google.com
docker run --rm "$base-test" ping -c 1 google.com
fi
else
docker run --rm "$base$version-test" nslookup google.com
docker run --rm "$base-test" nslookup google.com
fi
docker images "$base$version-test"
docker images "$base-test"
)
done

View File

@ -1,19 +1,16 @@
#!/bin/bash
#!/usr/bin/env bash
set -Eeuo pipefail
self="$(basename "$BASH_SOURCE")"
cd "$(dirname "$(readlink -f "$BASH_SOURCE")")"
gitHubUrl='https://github.com/docker-library/busybox'
rawGitUrl="$gitHubUrl/raw"
# prefer uclibc, but if it's unavailable use glibc if possible since it's got less "edge case" behavior, especially around DNS
variants=(
uclibc
glibc
musl
)
# (order here determines "preference" for representing "latest")
self="$(basename "$BASH_SOURCE")"
cd "$(dirname "$(readlink -f "$BASH_SOURCE")")"
if [ "$#" -eq 0 ]; then
versions="$(jq -r 'keys | map(@sh) | join(" ")' versions.json)"
eval "set -- $versions"
fi
archMaps=( $(
git ls-remote --heads "${gitHubUrl}.git" \
@ -55,57 +52,89 @@ join() {
echo "${out#$sep}"
}
# pre-flight sanity checks
fullVersion=
for variant in "${variants[@]}"; do
[ -f "$variant/Dockerfile.builder" ]
oldVersion="$fullVersion"
fullVersion="$(awk '$1 == "ENV" && $2 == "BUSYBOX_VERSION" { print $3; exit }' "$variant/Dockerfile.builder")"
[ -n "$fullVersion" ]
[ "$fullVersion" = "${oldVersion:-$fullVersion}" ]
done
versionAliases=()
while [ "${fullVersion%.*}" != "$fullVersion" ]; do
versionAliases+=( $fullVersion )
fullVersion="${fullVersion%.*}"
done
versionAliases+=(
$fullVersion
latest
)
# if stable is 1.32.1 and unstable is 1.33.0, we want busybox:1.33 to point to unstable but busybox:1 (and busybox:latest) to point to stable
# since stable always comes first, we'll just let it take all the tags it calculates, and use this to remove any overlap when we process unstable :)
declare -A usedTags=()
_tags() {
local tag first=
for tag; do
[ -z "${usedTags[$tag]:-}" ] || continue
usedTags[$tag]=1
if [ -z "$first" ]; then
echo
echo -n 'Tags: '
first=1
else
echo -n ', '
fi
echo -n "$tag"
done
if [ -z "$first" ]; then
return 1
fi
echo
return 0
}
declare -A archLatest=()
for variant in "${variants[@]}"; do
variantAliases=( "${versionAliases[@]/%/-$variant}" )
variantAliases=( "${variantAliases[@]//latest-/}" )
allVersions=()
for version; do
export version
variantArches=()
for arch in "${arches[@]}"; do
archCommit="${archCommits[$arch]}"
if wget --quiet --spider -O /dev/null -o /dev/null "$rawGitUrl/$archCommit/$variant/busybox.tar.xz"; then
variantArches+=( "$arch" )
if [ -z "${archLatest[$arch]:-}" ]; then
archLatest[$arch]="$variant"
variants="$(jq -r '.[env.version].variants | map(@sh) | join(" ")' versions.json)"
eval "variants=( $variants )"
fullVersion="$(jq -r '.[env.version].version' versions.json)"
allVersions+=( "$fullVersion" )
latestVersion="$(xargs -n1 <<<"${allVersions[*]}" | sort -V | tail -1)"
if [ "$latestVersion" != "$fullVersion" ]; then
# if "unstable" is older than "stable" (1.32.0 unstable vs 1.32.1 stable, for example), skip unstable
continue
fi
versionAliases=()
while [ "${fullVersion%.*}" != "$fullVersion" ]; do
versionAliases+=( $fullVersion )
fullVersion="${fullVersion%.*}"
done
versionAliases+=(
$fullVersion
$version # "stable", "unstable"
latest
)
declare -A archLatestDir=()
for variant in "${variants[@]}"; do
dir="$version/$variant"
variantAliases=( "${versionAliases[@]/%/-$variant}" )
variantAliases=( "${variantAliases[@]//latest-/}" )
variantArches=()
for arch in "${arches[@]}"; do
archCommit="${archCommits[$arch]}"
if wget --quiet --spider -O /dev/null -o /dev/null "$rawGitUrl/$archCommit/$dir/busybox.tar.xz"; then
variantArches+=( "$arch" )
: "${archLatestDir[$arch]:=$dir}" # record the first supported directory per architecture for "latest" and friends
fi
done
if _tags "${variantAliases[@]}"; then
cat <<-EOE
Architectures: $(join ', ' "${variantArches[@]}")
Directory: $dir
EOE
fi
done
echo
cat <<-EOE
Tags: $(join ', ' "${variantAliases[@]}")
Architectures: $(join ', ' "${variantArches[@]}")
Directory: $variant
EOE
done
echo
cat <<-EOE
Tags: $(join ', ' "${versionAliases[@]}")
Architectures: $(join ', ' "${arches[@]}")
EOE
for arch in "${arches[@]}"; do
archVariant="${archLatest[$arch]}"
cat <<-EOA
${arch}-Directory: $archVariant
EOA
if _tags "${versionAliases[@]}"; then
cat <<-EOE
Architectures: $(join ', ' "${arches[@]}")
EOE
for arch in "${arches[@]}"; do
archDir="${archLatestDir[$arch]}"
cat <<-EOA
${arch}-Directory: $archDir
EOA
done
fi
done

199
stable/glibc/Dockerfile.builder generated Normal file
View File

@ -0,0 +1,199 @@
#
# NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh"
#
# PLEASE DO NOT EDIT IT DIRECTLY.
#
FROM debian:buster-slim
RUN set -eux; \
apt-get update; \
apt-get install -y \
bzip2 \
curl \
gcc \
gnupg dirmngr \
make \
; \
rm -rf /var/lib/apt/lists/*
# pub 1024D/ACC9965B 2006-12-12
# Key fingerprint = C9E9 416F 76E6 10DB D09D 040F 47B7 0C55 ACC9 965B
# uid Denis Vlasenko <vda.linux@googlemail.com>
# sub 1024g/2C766641 2006-12-12
RUN gpg --batch --keyserver ha.pool.sks-keyservers.net --recv-keys C9E9416F76E610DBD09D040F47B70C55ACC9965B
ENV BUSYBOX_VERSION 1.32.1
ENV BUSYBOX_SHA256 9d57c4bd33974140fd4111260468af22856f12f5b5ef7c70c8d9b75c712a0dee
RUN set -eux; \
tarball="busybox-${BUSYBOX_VERSION}.tar.bz2"; \
curl -fL -o busybox.tar.bz2.sig "https://busybox.net/downloads/$tarball.sig"; \
curl -fL -o busybox.tar.bz2 "https://busybox.net/downloads/$tarball"; \
echo "$BUSYBOX_SHA256 *busybox.tar.bz2" | sha256sum -c -; \
gpg --batch --verify busybox.tar.bz2.sig busybox.tar.bz2; \
mkdir -p /usr/src/busybox; \
tar -xf busybox.tar.bz2 -C /usr/src/busybox --strip-components 1; \
rm busybox.tar.bz2*
WORKDIR /usr/src/busybox
RUN set -eux; \
\
setConfs=' \
CONFIG_AR=y \
CONFIG_FEATURE_AR_CREATE=y \
CONFIG_FEATURE_AR_LONG_FILENAMES=y \
# CONFIG_LAST_SUPPORTED_WCHAR: see https://github.com/docker-library/busybox/issues/13 (UTF-8 input)
CONFIG_LAST_SUPPORTED_WCHAR=0 \
# As long as we rely on libnss (see below), we have to have libc.so anyhow, so we've removed CONFIG_STATIC here... :cry:
'; \
\
unsetConfs=' \
CONFIG_FEATURE_SYNC_FANCY \
'; \
\
make defconfig; \
\
for conf in $unsetConfs; do \
sed -i \
-e "s!^$conf=.*\$!# $conf is not set!" \
.config; \
done; \
\
for confV in $setConfs; do \
conf="${confV%=*}"; \
sed -i \
-e "s!^$conf=.*\$!$confV!" \
-e "s!^# $conf is not set\$!$confV!" \
.config; \
if ! grep -q "^$confV\$" .config; then \
echo "$confV" >> .config; \
fi; \
done; \
\
make oldconfig; \
\
# trust, but verify
for conf in $unsetConfs; do \
! grep -q "^$conf=" .config; \
done; \
for confV in $setConfs; do \
grep -q "^$confV\$" .config; \
done
RUN set -eux; \
nproc="$(nproc)"; \
make -j "$nproc" busybox; \
./busybox --help; \
mkdir -p rootfs/bin; \
ln -vL busybox rootfs/bin/; \
\
# copy "getconf" from Debian
getconf="$(which getconf)"; \
ln -vL "$getconf" rootfs/bin/getconf; \
\
# hack hack hack hack hack
# with glibc, busybox (static or not) uses libnss for DNS resolution :(
mkdir -p rootfs/etc; \
cp /etc/nsswitch.conf rootfs/etc/; \
mkdir -p rootfs/lib; \
ln -sT lib rootfs/lib64; \
gccMultiarch="$(gcc -print-multiarch)"; \
set -- \
rootfs/bin/busybox \
rootfs/bin/getconf \
/lib/"$gccMultiarch"/libnss*.so.* \
# libpthread is part of glibc: https://stackoverflow.com/a/11210463/433558
/lib/"$gccMultiarch"/libpthread*.so.* \
; \
while [ "$#" -gt 0 ]; do \
f="$1"; shift; \
fn="$(basename "$f")"; \
if [ -e "rootfs/lib/$fn" ]; then continue; fi; \
if [ "${f#rootfs/}" = "$f" ]; then \
if [ "${fn#ld-}" = "$fn" ]; then \
ln -vL "$f" "rootfs/lib/$fn"; \
else \
cp -v "$f" "rootfs/lib/$fn"; \
fi; \
fi; \
ldd="$(ldd "$f" | awk ' \
$1 ~ /^\// { print $1; next } \
$2 == "=>" && $3 ~ /^\// { print $3; next } \
')"; \
set -- "$@" $ldd; \
done; \
chroot rootfs /bin/getconf _NPROCESSORS_ONLN; \
\
chroot rootfs /bin/busybox --install /bin
# install a few extra files from buildroot (/etc/passwd, etc)
RUN set -eux; \
buildrootVersion='2020.11.1'; \
for file in \
system/device_table.txt \
system/skeleton/etc/group \
system/skeleton/etc/passwd \
system/skeleton/etc/shadow \
; do \
dir="$(dirname "$file")"; \
mkdir -p "../buildroot/$dir"; \
curl -fL -o "../buildroot/$file" "https://git.busybox.net/buildroot/plain/$file?id=$buildrootVersion"; \
[ -s "../buildroot/$file" ]; \
done; \
\
mkdir -p rootfs/etc; \
ln -vL \
../buildroot/system/skeleton/etc/group \
../buildroot/system/skeleton/etc/passwd \
../buildroot/system/skeleton/etc/shadow \
rootfs/etc/ \
; \
# CVE-2019-5021, https://github.com/docker-library/official-images/pull/5880#issuecomment-490681907
grep -E '^root::' rootfs/etc/shadow; \
sed -ri -e 's/^root::/root:*:/' rootfs/etc/shadow; \
grep -E '^root:[*]:' rootfs/etc/shadow; \
# set expected permissions, etc too (https://git.busybox.net/buildroot/tree/system/device_table.txt)
awk ' \
!/^#/ { \
if ($2 != "d" && $2 != "f") { \
printf "error: unknown type \"%s\" encountered in line %d: %s\n", $2, NR, $0 > "/dev/stderr"; \
exit 1; \
} \
sub(/^\/?/, "rootfs/", $1); \
if ($2 == "d") { \
printf "mkdir -p %s\n", $1; \
} \
printf "chmod %s %s\n", $3, $1; \
} \
' ../buildroot/system/device_table.txt | sh -eux
# create missing home directories
RUN set -eux; \
cd rootfs; \
for userHome in $(awk -F ':' '{ print $3 ":" $4 "=" $6 }' etc/passwd); do \
user="${userHome%%=*}"; \
home="${userHome#*=}"; \
home="./${home#/}"; \
if [ ! -d "$home" ]; then \
mkdir -p "$home"; \
chown "$user" "$home"; \
chmod 755 "$home"; \
fi; \
done
# test and make sure it works
RUN chroot rootfs /bin/sh -xec 'true'
# ensure correct timezone (UTC)
RUN set -eux; \
ln -vL /usr/share/zoneinfo/UTC rootfs/etc/localtime; \
[ "$(chroot rootfs date +%Z)" = 'UTC' ]
# test and make sure DNS works too
RUN cp -L /etc/resolv.conf rootfs/etc/; \
chroot rootfs /bin/sh -xec 'nslookup google.com'; \
rm rootfs/etc/resolv.conf
# vim:set ft=dockerfile:

179
stable/musl/Dockerfile.builder generated Normal file
View File

@ -0,0 +1,179 @@
#
# NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh"
#
# PLEASE DO NOT EDIT IT DIRECTLY.
#
FROM alpine:3.12
RUN set -eux; \
apk add --no-cache \
bzip2 \
coreutils \
curl \
gcc \
gnupg \
linux-headers \
make \
musl-dev \
tzdata \
;
# pub 1024D/ACC9965B 2006-12-12
# Key fingerprint = C9E9 416F 76E6 10DB D09D 040F 47B7 0C55 ACC9 965B
# uid Denis Vlasenko <vda.linux@googlemail.com>
# sub 1024g/2C766641 2006-12-12
RUN gpg --batch --keyserver ha.pool.sks-keyservers.net --recv-keys C9E9416F76E610DBD09D040F47B70C55ACC9965B
ENV BUSYBOX_VERSION 1.32.1
ENV BUSYBOX_SHA256 9d57c4bd33974140fd4111260468af22856f12f5b5ef7c70c8d9b75c712a0dee
RUN set -eux; \
tarball="busybox-${BUSYBOX_VERSION}.tar.bz2"; \
curl -fL -o busybox.tar.bz2.sig "https://busybox.net/downloads/$tarball.sig"; \
curl -fL -o busybox.tar.bz2 "https://busybox.net/downloads/$tarball"; \
echo "$BUSYBOX_SHA256 *busybox.tar.bz2" | sha256sum -c -; \
gpg --batch --verify busybox.tar.bz2.sig busybox.tar.bz2; \
mkdir -p /usr/src/busybox; \
tar -xf busybox.tar.bz2 -C /usr/src/busybox --strip-components 1; \
rm busybox.tar.bz2*
WORKDIR /usr/src/busybox
RUN set -eux; \
\
setConfs=' \
CONFIG_AR=y \
CONFIG_FEATURE_AR_CREATE=y \
CONFIG_FEATURE_AR_LONG_FILENAMES=y \
# CONFIG_LAST_SUPPORTED_WCHAR: see https://github.com/docker-library/busybox/issues/13 (UTF-8 input)
CONFIG_LAST_SUPPORTED_WCHAR=0 \
CONFIG_STATIC=y \
'; \
\
unsetConfs=' \
CONFIG_FEATURE_SYNC_FANCY \
\
# see https://wiki.musl-libc.org/wiki/Building_Busybox
CONFIG_FEATURE_HAVE_RPC \
CONFIG_FEATURE_INETD_RPC \
CONFIG_FEATURE_UTMP \
CONFIG_FEATURE_WTMP \
'; \
\
make defconfig; \
\
for conf in $unsetConfs; do \
sed -i \
-e "s!^$conf=.*\$!# $conf is not set!" \
.config; \
done; \
\
for confV in $setConfs; do \
conf="${confV%=*}"; \
sed -i \
-e "s!^$conf=.*\$!$confV!" \
-e "s!^# $conf is not set\$!$confV!" \
.config; \
if ! grep -q "^$confV\$" .config; then \
echo "$confV" >> .config; \
fi; \
done; \
\
make oldconfig; \
\
# trust, but verify
for conf in $unsetConfs; do \
! grep -q "^$conf=" .config; \
done; \
for confV in $setConfs; do \
grep -q "^$confV\$" .config; \
done
RUN set -eux; \
nproc="$(nproc)"; \
make -j "$nproc" busybox; \
./busybox --help; \
mkdir -p rootfs/bin; \
ln -vL busybox rootfs/bin/; \
\
# copy simplified getconf port from Alpine
aportsVersion="v$(cat /etc/alpine-release)"; \
curl -fsSL \
"https://git.alpinelinux.org/cgit/aports/plain/main/musl/getconf.c?h=${aportsVersion}" \
-o /usr/src/getconf.c \
; \
gcc -o rootfs/bin/getconf -static -Os /usr/src/getconf.c; \
chroot rootfs /bin/getconf _NPROCESSORS_ONLN; \
\
chroot rootfs /bin/busybox --install /bin
# install a few extra files from buildroot (/etc/passwd, etc)
RUN set -eux; \
buildrootVersion='2020.11.1'; \
for file in \
system/device_table.txt \
system/skeleton/etc/group \
system/skeleton/etc/passwd \
system/skeleton/etc/shadow \
; do \
dir="$(dirname "$file")"; \
mkdir -p "../buildroot/$dir"; \
curl -fL -o "../buildroot/$file" "https://git.busybox.net/buildroot/plain/$file?id=$buildrootVersion"; \
[ -s "../buildroot/$file" ]; \
done; \
\
mkdir -p rootfs/etc; \
ln -vL \
../buildroot/system/skeleton/etc/group \
../buildroot/system/skeleton/etc/passwd \
../buildroot/system/skeleton/etc/shadow \
rootfs/etc/ \
; \
# CVE-2019-5021, https://github.com/docker-library/official-images/pull/5880#issuecomment-490681907
grep -E '^root::' rootfs/etc/shadow; \
sed -ri -e 's/^root::/root:*:/' rootfs/etc/shadow; \
grep -E '^root:[*]:' rootfs/etc/shadow; \
# set expected permissions, etc too (https://git.busybox.net/buildroot/tree/system/device_table.txt)
awk ' \
!/^#/ { \
if ($2 != "d" && $2 != "f") { \
printf "error: unknown type \"%s\" encountered in line %d: %s\n", $2, NR, $0 > "/dev/stderr"; \
exit 1; \
} \
sub(/^\/?/, "rootfs/", $1); \
if ($2 == "d") { \
printf "mkdir -p %s\n", $1; \
} \
printf "chmod %s %s\n", $3, $1; \
} \
' ../buildroot/system/device_table.txt | sh -eux
# create missing home directories
RUN set -eux; \
cd rootfs; \
for userHome in $(awk -F ':' '{ print $3 ":" $4 "=" $6 }' etc/passwd); do \
user="${userHome%%=*}"; \
home="${userHome#*=}"; \
home="./${home#/}"; \
if [ ! -d "$home" ]; then \
mkdir -p "$home"; \
chown "$user" "$home"; \
chmod 755 "$home"; \
fi; \
done
# test and make sure it works
RUN chroot rootfs /bin/sh -xec 'true'
# ensure correct timezone (UTC)
RUN set -eux; \
ln -vL /usr/share/zoneinfo/UTC rootfs/etc/localtime; \
[ "$(chroot rootfs date +%Z)" = 'UTC' ]
# test and make sure DNS works too
RUN cp -L /etc/resolv.conf rootfs/etc/; \
chroot rootfs /bin/sh -xec 'nslookup google.com'; \
rm rootfs/etc/resolv.conf
# vim:set ft=dockerfile:

3
stable/uclibc/Dockerfile generated Normal file
View File

@ -0,0 +1,3 @@
FROM scratch
ADD busybox.tar.xz /
CMD ["sh"]

327
stable/uclibc/Dockerfile.builder generated Normal file
View File

@ -0,0 +1,327 @@
#
# NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh"
#
# PLEASE DO NOT EDIT IT DIRECTLY.
#
FROM debian:buster-slim
RUN set -eux; \
apt-get update; \
apt-get install -y \
bzip2 \
curl \
gcc \
gnupg dirmngr \
make \
; \
rm -rf /var/lib/apt/lists/*
# grab/use buildroot for its uClibc toolchain
RUN set -eux; \
apt-get update; \
apt-get install -y \
bc \
cpio \
dpkg-dev \
g++ \
patch \
perl \
python \
rsync \
unzip \
wget \
; \
rm -rf /var/lib/apt/lists/*
# pub 1024D/59C36319 2009-01-15
# Key fingerprint = AB07 D806 D2CE 741F B886 EE50 B025 BA8B 59C3 6319
# uid Peter Korsgaard <jacmet@uclibc.org>
# sub 2048g/45428075 2009-01-15
RUN gpg --batch --keyserver ha.pool.sks-keyservers.net --recv-keys AB07D806D2CE741FB886EE50B025BA8B59C36319
# https://buildroot.org/download.html
# https://buildroot.org/downloads/?C=M;O=D
ENV BUILDROOT_VERSION 2020.11.1
RUN set -eux; \
tarball="buildroot-${BUILDROOT_VERSION}.tar.bz2"; \
curl -fL -o buildroot.tar.bz2 "https://buildroot.org/downloads/$tarball"; \
curl -fL -o buildroot.tar.bz2.sign "https://buildroot.org/downloads/$tarball.sign"; \
gpg --batch --decrypt --output buildroot.tar.bz2.txt buildroot.tar.bz2.sign; \
awk '$1 == "SHA1:" && $2 ~ /^[0-9a-f]+$/ && $3 == "'"$tarball"'" { print $2, "*buildroot.tar.bz2" }' buildroot.tar.bz2.txt > buildroot.tar.bz2.sha1; \
test -s buildroot.tar.bz2.sha1; \
sha1sum -c buildroot.tar.bz2.sha1; \
mkdir -p /usr/src/buildroot; \
tar -xf buildroot.tar.bz2 -C /usr/src/buildroot --strip-components 1; \
rm buildroot.tar.bz2*
RUN set -eux; \
\
cd /usr/src/buildroot; \
\
setConfs=' \
BR2_STATIC_LIBS=y \
BR2_TOOLCHAIN_BUILDROOT_UCLIBC=y \
BR2_TOOLCHAIN_BUILDROOT_WCHAR=y \
'; \
\
unsetConfs=' \
BR2_SHARED_LIBS \
'; \
\
# buildroot arches: https://git.busybox.net/buildroot/tree/arch
# buildroot+uclibc arches: https://git.busybox.net/buildroot/tree/toolchain/toolchain-buildroot/Config.in ("config BR2_TOOLCHAIN_BUILDROOT_UCLIBC")
dpkgArch="$(dpkg --print-architecture)"; \
case "$dpkgArch" in \
amd64) \
setConfs="$setConfs \
BR2_x86_64=y \
"; \
;; \
\
arm64) \
setConfs="$setConfs \
BR2_aarch64=y \
"; \
;; \
\
# https://wiki.debian.org/ArmEabiPort#Choice_of_minimum_CPU
# https://github.com/free-electrons/toolchains-builder/blob/db259641eaf5bbcf13f4a3c5003e5436e806770c/configs/arch/armv5-eabi.config
# https://git.busybox.net/buildroot/tree/arch/Config.in.arm
# (Debian minimums at ARMv4, we minimum at ARMv5 instead)
armel) \
setConfs="$setConfs \
BR2_arm=y \
BR2_arm926t=y \
BR2_ARM_EABI=y \
BR2_ARM_INSTRUCTIONS_THUMB=y \
BR2_ARM_SOFT_FLOAT=y \
"; \
;; \
\
# "Currently the Debian armhf port requires at least an ARMv7 CPU with Thumb-2 and VFP3D16."
# https://wiki.debian.org/ArmHardFloatPort#Supported_devices
# https://github.com/free-electrons/toolchains-builder/blob/db259641eaf5bbcf13f4a3c5003e5436e806770c/configs/arch/armv7-eabihf.config
# https://git.busybox.net/buildroot/tree/arch/Config.in.arm
armhf) \
setConfs="$setConfs \
BR2_arm=y \
BR2_cortex_a9=y \
BR2_ARM_EABIHF=y \
BR2_ARM_ENABLE_VFP=y \
BR2_ARM_FPU_VFPV3D16=y \
BR2_ARM_INSTRUCTIONS_THUMB2=y \
"; \
unsetConfs="$unsetConfs BR2_ARM_SOFT_FLOAT"; \
;; \
\
i386) \
setConfs="$setConfs \
BR2_i386=y \
"; \
;; \
\
mips64el) \
setConfs="$setConfs \
BR2_mips64el=y \
BR2_mips_64r2=y \
BR2_MIPS_NABI64=y \
"; \
unsetConfs="$unsetConfs \
BR2_MIPS_SOFT_FLOAT \
" \
;; \
\
# TODO ppc64el ? (needs BR2_TOOLCHAIN_BUILDROOT_UCLIBC support)
\
# TODO s390x ? (needs BR2_TOOLCHAIN_BUILDROOT_UCLIBC support)
\
*) \
echo >&2 "error: unsupported architecture '$dpkgArch'!"; \
exit 1; \
;; \
esac; \
if [ "$dpkgArch" != 'i386' ]; then \
unsetConfs="$unsetConfs BR2_i386"; \
fi; \
\
make defconfig; \
\
for conf in $unsetConfs; do \
sed -i \
-e "s!^$conf=.*\$!# $conf is not set!" \
.config; \
done; \
\
for confV in $setConfs; do \
conf="${confV%=*}"; \
sed -i \
-e "s!^$conf=.*\$!$confV!" \
-e "s!^# $conf is not set\$!$confV!" \
.config; \
if ! grep -q "^$confV\$" .config; then \
echo "$confV" >> .config; \
fi; \
done; \
\
make oldconfig; \
\
# trust, but verify
for conf in $unsetConfs; do \
! grep -q "^$conf=" .config; \
done; \
for confV in $setConfs; do \
grep -q "^$confV\$" .config; \
done;
# https://www.finnie.org/2014/02/13/compiling-busybox-with-uclibc/
RUN set -eux; \
# force a particular GNU arch for "host-gmp" (otherwise it fails on some arches)
gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \
make -C /usr/src/buildroot \
HOST_GMP_CONF_OPTS="--build='"$gnuArch"'" \
# building host-tar:
# configure: error: you should not run configure as root (set FORCE_UNSAFE_CONFIGURE=1 in environment to bypass this check)
FORCE_UNSAFE_CONFIGURE=1 \
-j "$(nproc)" \
toolchain
ENV PATH /usr/src/buildroot/output/host/usr/bin:$PATH
# pub 1024D/ACC9965B 2006-12-12
# Key fingerprint = C9E9 416F 76E6 10DB D09D 040F 47B7 0C55 ACC9 965B
# uid Denis Vlasenko <vda.linux@googlemail.com>
# sub 1024g/2C766641 2006-12-12
RUN gpg --batch --keyserver ha.pool.sks-keyservers.net --recv-keys C9E9416F76E610DBD09D040F47B70C55ACC9965B
ENV BUSYBOX_VERSION 1.32.1
ENV BUSYBOX_SHA256 9d57c4bd33974140fd4111260468af22856f12f5b5ef7c70c8d9b75c712a0dee
RUN set -eux; \
tarball="busybox-${BUSYBOX_VERSION}.tar.bz2"; \
curl -fL -o busybox.tar.bz2.sig "https://busybox.net/downloads/$tarball.sig"; \
curl -fL -o busybox.tar.bz2 "https://busybox.net/downloads/$tarball"; \
echo "$BUSYBOX_SHA256 *busybox.tar.bz2" | sha256sum -c -; \
gpg --batch --verify busybox.tar.bz2.sig busybox.tar.bz2; \
mkdir -p /usr/src/busybox; \
tar -xf busybox.tar.bz2 -C /usr/src/busybox --strip-components 1; \
rm busybox.tar.bz2*
WORKDIR /usr/src/busybox
RUN set -eux; \
\
setConfs=' \
CONFIG_AR=y \
CONFIG_FEATURE_AR_CREATE=y \
CONFIG_FEATURE_AR_LONG_FILENAMES=y \
# CONFIG_LAST_SUPPORTED_WCHAR: see https://github.com/docker-library/busybox/issues/13 (UTF-8 input)
CONFIG_LAST_SUPPORTED_WCHAR=0 \
CONFIG_STATIC=y \
'; \
\
unsetConfs=' \
CONFIG_FEATURE_SYNC_FANCY \
'; \
\
make defconfig; \
\
for conf in $unsetConfs; do \
sed -i \
-e "s!^$conf=.*\$!# $conf is not set!" \
.config; \
done; \
\
for confV in $setConfs; do \
conf="${confV%=*}"; \
sed -i \
-e "s!^$conf=.*\$!$confV!" \
-e "s!^# $conf is not set\$!$confV!" \
.config; \
if ! grep -q "^$confV\$" .config; then \
echo "$confV" >> .config; \
fi; \
done; \
\
make oldconfig; \
\
# trust, but verify
for conf in $unsetConfs; do \
! grep -q "^$conf=" .config; \
done; \
for confV in $setConfs; do \
grep -q "^$confV\$" .config; \
done
RUN set -eux; \
nproc="$(nproc)"; \
CROSS_COMPILE="$(basename /usr/src/buildroot/output/host/usr/*-buildroot-linux-uclibc*)"; \
export CROSS_COMPILE="$CROSS_COMPILE-"; \
make -j "$nproc" busybox; \
./busybox --help; \
mkdir -p rootfs/bin; \
ln -vL busybox rootfs/bin/; \
\
# copy "getconf" from buildroot
ln -vL ../buildroot/output/target/usr/bin/getconf rootfs/bin/; \
chroot rootfs /bin/getconf _NPROCESSORS_ONLN; \
\
chroot rootfs /bin/busybox --install /bin
# install a few extra files from buildroot (/etc/passwd, etc)
RUN set -eux; \
mkdir -p rootfs/etc; \
ln -vL \
../buildroot/system/skeleton/etc/group \
../buildroot/system/skeleton/etc/passwd \
../buildroot/system/skeleton/etc/shadow \
rootfs/etc/ \
; \
# CVE-2019-5021, https://github.com/docker-library/official-images/pull/5880#issuecomment-490681907
grep -E '^root::' rootfs/etc/shadow; \
sed -ri -e 's/^root::/root:*:/' rootfs/etc/shadow; \
grep -E '^root:[*]:' rootfs/etc/shadow; \
# set expected permissions, etc too (https://git.busybox.net/buildroot/tree/system/device_table.txt)
awk ' \
!/^#/ { \
if ($2 != "d" && $2 != "f") { \
printf "error: unknown type \"%s\" encountered in line %d: %s\n", $2, NR, $0 > "/dev/stderr"; \
exit 1; \
} \
sub(/^\/?/, "rootfs/", $1); \
if ($2 == "d") { \
printf "mkdir -p %s\n", $1; \
} \
printf "chmod %s %s\n", $3, $1; \
} \
' ../buildroot/system/device_table.txt | sh -eux
# create missing home directories
RUN set -eux; \
cd rootfs; \
for userHome in $(awk -F ':' '{ print $3 ":" $4 "=" $6 }' etc/passwd); do \
user="${userHome%%=*}"; \
home="${userHome#*=}"; \
home="./${home#/}"; \
if [ ! -d "$home" ]; then \
mkdir -p "$home"; \
chown "$user" "$home"; \
chmod 755 "$home"; \
fi; \
done
# test and make sure it works
RUN chroot rootfs /bin/sh -xec 'true'
# ensure correct timezone (UTC)
RUN set -eux; \
ln -vL /usr/share/zoneinfo/UTC rootfs/etc/localtime; \
[ "$(chroot rootfs date +%Z)" = 'UTC' ]
# test and make sure DNS works too
RUN cp -L /etc/resolv.conf rootfs/etc/; \
chroot rootfs /bin/sh -xec 'nslookup google.com'; \
rm rootfs/etc/resolv.conf
# vim:set ft=dockerfile:

3
unstable/glibc/Dockerfile generated Normal file
View File

@ -0,0 +1,3 @@
FROM scratch
ADD busybox.tar.xz /
CMD ["sh"]

View File

@ -1,3 +1,9 @@
#
# NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh"
#
# PLEASE DO NOT EDIT IT DIRECTLY.
#
FROM debian:buster-slim
RUN set -eux; \
@ -18,11 +24,13 @@ RUN set -eux; \
RUN gpg --batch --keyserver ha.pool.sks-keyservers.net --recv-keys C9E9416F76E610DBD09D040F47B70C55ACC9965B
ENV BUSYBOX_VERSION 1.33.0
ENV BUSYBOX_SHA256 d568681c91a85edc6710770cebc1e80e042ad74d305b5c2e6d57a5f3de3b8fbd
RUN set -eux; \
tarball="busybox-${BUSYBOX_VERSION}.tar.bz2"; \
curl -fL -o busybox.tar.bz2 "https://busybox.net/downloads/$tarball"; \
curl -fL -o busybox.tar.bz2.sig "https://busybox.net/downloads/$tarball.sig"; \
curl -fL -o busybox.tar.bz2 "https://busybox.net/downloads/$tarball"; \
echo "$BUSYBOX_SHA256 *busybox.tar.bz2" | sha256sum -c -; \
gpg --batch --verify busybox.tar.bz2.sig busybox.tar.bz2; \
mkdir -p /usr/src/busybox; \
tar -xf busybox.tar.bz2 -C /usr/src/busybox --strip-components 1; \
@ -30,16 +38,15 @@ RUN set -eux; \
WORKDIR /usr/src/busybox
# CONFIG_LAST_SUPPORTED_WCHAR: see https://github.com/docker-library/busybox/issues/13 (UTF-8 input)
RUN set -eux; \
\
setConfs=' \
CONFIG_AR=y \
CONFIG_FEATURE_AR_CREATE=y \
CONFIG_FEATURE_AR_LONG_FILENAMES=y \
# CONFIG_LAST_SUPPORTED_WCHAR: see https://github.com/docker-library/busybox/issues/13 (UTF-8 input)
CONFIG_LAST_SUPPORTED_WCHAR=0 \
# As long as we rely on libnss, we have to have libc.so anyhow, so
# we've removed CONFIG_STATIC here for now... :cry:
# As long as we rely on libnss (see below), we have to have libc.so anyhow, so we've removed CONFIG_STATIC here... :cry:
'; \
\
unsetConfs=' \
@ -73,30 +80,32 @@ RUN set -eux; \
done; \
for confV in $setConfs; do \
grep -q "^$confV\$" .config; \
done;
done
RUN set -eux; \
make -j "$(nproc)" \
busybox \
; \
nproc="$(nproc)"; \
make -j "$nproc" busybox; \
./busybox --help; \
mkdir -p rootfs/bin; \
ln -vL busybox rootfs/bin/; \
\
ln -vL "$(which getconf)" rootfs/bin/getconf; \
# copy "getconf" from Debian
getconf="$(which getconf)"; \
ln -vL "$getconf" rootfs/bin/getconf; \
\
# hack hack hack hack hack
# with glibc, static busybox uses libnss for DNS resolution :(
# with glibc, busybox (static or not) uses libnss for DNS resolution :(
mkdir -p rootfs/etc; \
cp /etc/nsswitch.conf rootfs/etc/; \
mkdir -p rootfs/lib; \
ln -sT lib rootfs/lib64; \
gccMultiarch="$(gcc -print-multiarch)"; \
set -- \
rootfs/bin/busybox \
rootfs/bin/getconf \
/lib/"$(gcc -print-multiarch)"/libnss*.so.* \
/lib/"$gccMultiarch"/libnss*.so.* \
# libpthread is part of glibc: https://stackoverflow.com/a/11210463/433558
/lib/"$(gcc -print-multiarch)"/libpthread*.so.* \
/lib/"$gccMultiarch"/libpthread*.so.* \
; \
while [ "$#" -gt 0 ]; do \
f="$1"; shift; \
@ -109,29 +118,43 @@ RUN set -eux; \
cp -v "$f" "rootfs/lib/$fn"; \
fi; \
fi; \
set -- "$@" $(ldd "$f" | awk ' \
ldd="$(ldd "$f" | awk ' \
$1 ~ /^\// { print $1; next } \
$2 == "=>" && $3 ~ /^\// { print $3; next } \
'); \
')"; \
set -- "$@" $ldd; \
done; \
\
chroot rootfs /bin/getconf _NPROCESSORS_ONLN; \
\
chroot rootfs /bin/busybox --install /bin
# download a few extra files from buildroot (/etc/passwd, etc)
# install a few extra files from buildroot (/etc/passwd, etc)
RUN set -eux; \
buildrootVersion='2020.11.1'; \
mkdir -p rootfs/etc; \
for f in passwd shadow group; do \
curl -fL -o "rootfs/etc/$f" "https://git.busybox.net/buildroot/plain/system/skeleton/etc/$f?id=$buildrootVersion"; \
for file in \
system/device_table.txt \
system/skeleton/etc/group \
system/skeleton/etc/passwd \
system/skeleton/etc/shadow \
; do \
dir="$(dirname "$file")"; \
mkdir -p "../buildroot/$dir"; \
curl -fL -o "../buildroot/$file" "https://git.busybox.net/buildroot/plain/$file?id=$buildrootVersion"; \
[ -s "../buildroot/$file" ]; \
done; \
\
mkdir -p rootfs/etc; \
ln -vL \
../buildroot/system/skeleton/etc/group \
../buildroot/system/skeleton/etc/passwd \
../buildroot/system/skeleton/etc/shadow \
rootfs/etc/ \
; \
# CVE-2019-5021, https://github.com/docker-library/official-images/pull/5880#issuecomment-490681907
grep -E '^root::' rootfs/etc/shadow; \
sed -ri -e 's/^root::/root:*:/' rootfs/etc/shadow; \
grep -E '^root:[*]:' rootfs/etc/shadow; \
# set expected permissions, etc too (https://git.busybox.net/buildroot/tree/system/device_table.txt)
curl -fL -o buildroot-device-table.txt "https://git.busybox.net/buildroot/plain/system/device_table.txt?id=$buildrootVersion"; \
awk ' \
!/^#/ { \
if ($2 != "d" && $2 != "f") { \
@ -144,8 +167,7 @@ RUN set -eux; \
} \
printf "chmod %s %s\n", $3, $1; \
} \
' buildroot-device-table.txt | bash -Eeuo pipefail -x; \
rm buildroot-device-table.txt
' ../buildroot/system/device_table.txt | sh -eux
# create missing home directories
RUN set -eux; \

3
unstable/musl/Dockerfile generated Normal file
View File

@ -0,0 +1,3 @@
FROM scratch
ADD busybox.tar.xz /
CMD ["sh"]

View File

@ -1,6 +1,13 @@
#
# NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh"
#
# PLEASE DO NOT EDIT IT DIRECTLY.
#
FROM alpine:3.12
RUN apk add --no-cache \
RUN set -eux; \
apk add --no-cache \
bzip2 \
coreutils \
curl \
@ -9,7 +16,8 @@ RUN apk add --no-cache \
linux-headers \
make \
musl-dev \
tzdata
tzdata \
;
# pub 1024D/ACC9965B 2006-12-12
# Key fingerprint = C9E9 416F 76E6 10DB D09D 040F 47B7 0C55 ACC9 965B
@ -18,11 +26,13 @@ RUN apk add --no-cache \
RUN gpg --batch --keyserver ha.pool.sks-keyservers.net --recv-keys C9E9416F76E610DBD09D040F47B70C55ACC9965B
ENV BUSYBOX_VERSION 1.33.0
ENV BUSYBOX_SHA256 d568681c91a85edc6710770cebc1e80e042ad74d305b5c2e6d57a5f3de3b8fbd
RUN set -eux; \
tarball="busybox-${BUSYBOX_VERSION}.tar.bz2"; \
curl -fL -o busybox.tar.bz2 "https://busybox.net/downloads/$tarball"; \
curl -fL -o busybox.tar.bz2.sig "https://busybox.net/downloads/$tarball.sig"; \
curl -fL -o busybox.tar.bz2 "https://busybox.net/downloads/$tarball"; \
echo "$BUSYBOX_SHA256 *busybox.tar.bz2" | sha256sum -c -; \
gpg --batch --verify busybox.tar.bz2.sig busybox.tar.bz2; \
mkdir -p /usr/src/busybox; \
tar -xf busybox.tar.bz2 -C /usr/src/busybox --strip-components 1; \
@ -30,18 +40,13 @@ RUN set -eux; \
WORKDIR /usr/src/busybox
# https://www.mail-archive.com/toybox@lists.landley.net/msg02528.html
# https://www.mail-archive.com/toybox@lists.landley.net/msg02526.html
RUN sed -i 's/^struct kconf_id \*$/static &/g' scripts/kconfig/zconf.hash.c_shipped
# CONFIG_LAST_SUPPORTED_WCHAR: see https://github.com/docker-library/busybox/issues/13 (UTF-8 input)
# see https://wiki.musl-libc.org/wiki/Building_Busybox
RUN set -eux; \
\
setConfs=' \
CONFIG_AR=y \
CONFIG_FEATURE_AR_CREATE=y \
CONFIG_FEATURE_AR_LONG_FILENAMES=y \
# CONFIG_LAST_SUPPORTED_WCHAR: see https://github.com/docker-library/busybox/issues/13 (UTF-8 input)
CONFIG_LAST_SUPPORTED_WCHAR=0 \
CONFIG_STATIC=y \
'; \
@ -49,6 +54,7 @@ RUN set -eux; \
unsetConfs=' \
CONFIG_FEATURE_SYNC_FANCY \
\
# see https://wiki.musl-libc.org/wiki/Building_Busybox
CONFIG_FEATURE_HAVE_RPC \
CONFIG_FEATURE_INETD_RPC \
CONFIG_FEATURE_UTMP \
@ -82,40 +88,53 @@ RUN set -eux; \
done; \
for confV in $setConfs; do \
grep -q "^$confV\$" .config; \
done;
done
RUN set -eux; \
make -j "$(nproc)" \
busybox \
; \
nproc="$(nproc)"; \
make -j "$nproc" busybox; \
./busybox --help; \
mkdir -p rootfs/bin; \
ln -vL busybox rootfs/bin/; \
chroot rootfs /bin/busybox --install /bin
# grab a simplified getconf port from Alpine we can statically compile
RUN set -eux; \
\
# copy simplified getconf port from Alpine
aportsVersion="v$(cat /etc/alpine-release)"; \
curl -fsSL \
"https://git.alpinelinux.org/cgit/aports/plain/main/musl/getconf.c?h=${aportsVersion}" \
-o /usr/src/getconf.c \
; \
gcc -o rootfs/bin/getconf -static -Os /usr/src/getconf.c; \
chroot rootfs /bin/getconf _NPROCESSORS_ONLN
chroot rootfs /bin/getconf _NPROCESSORS_ONLN; \
\
chroot rootfs /bin/busybox --install /bin
# download a few extra files from buildroot (/etc/passwd, etc)
# install a few extra files from buildroot (/etc/passwd, etc)
RUN set -eux; \
buildrootVersion='2020.11.1'; \
mkdir -p rootfs/etc; \
for f in passwd shadow group; do \
curl -fL -o "rootfs/etc/$f" "https://git.busybox.net/buildroot/plain/system/skeleton/etc/$f?id=$buildrootVersion"; \
for file in \
system/device_table.txt \
system/skeleton/etc/group \
system/skeleton/etc/passwd \
system/skeleton/etc/shadow \
; do \
dir="$(dirname "$file")"; \
mkdir -p "../buildroot/$dir"; \
curl -fL -o "../buildroot/$file" "https://git.busybox.net/buildroot/plain/$file?id=$buildrootVersion"; \
[ -s "../buildroot/$file" ]; \
done; \
\
mkdir -p rootfs/etc; \
ln -vL \
../buildroot/system/skeleton/etc/group \
../buildroot/system/skeleton/etc/passwd \
../buildroot/system/skeleton/etc/shadow \
rootfs/etc/ \
; \
# CVE-2019-5021, https://github.com/docker-library/official-images/pull/5880#issuecomment-490681907
grep -E '^root::' rootfs/etc/shadow; \
sed -ri -e 's/^root::/root:*:/' rootfs/etc/shadow; \
grep -E '^root:[*]:' rootfs/etc/shadow; \
# set expected permissions, etc too (https://git.busybox.net/buildroot/tree/system/device_table.txt)
curl -fL -o buildroot-device-table.txt "https://git.busybox.net/buildroot/plain/system/device_table.txt?id=$buildrootVersion"; \
awk ' \
!/^#/ { \
if ($2 != "d" && $2 != "f") { \
@ -128,8 +147,7 @@ RUN set -eux; \
} \
printf "chmod %s %s\n", $3, $1; \
} \
' buildroot-device-table.txt | sh -eux; \
rm buildroot-device-table.txt
' ../buildroot/system/device_table.txt | sh -eux
# create missing home directories
RUN set -eux; \

3
unstable/uclibc/Dockerfile generated Normal file
View File

@ -0,0 +1,3 @@
FROM scratch
ADD busybox.tar.xz /
CMD ["sh"]

View File

@ -1,3 +1,9 @@
#
# NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh"
#
# PLEASE DO NOT EDIT IT DIRECTLY.
#
FROM debian:buster-slim
RUN set -eux; \
@ -8,8 +14,14 @@ RUN set -eux; \
gcc \
gnupg dirmngr \
make \
\
# buildroot
; \
rm -rf /var/lib/apt/lists/*
# grab/use buildroot for its uClibc toolchain
RUN set -eux; \
apt-get update; \
apt-get install -y \
bc \
cpio \
dpkg-dev \
@ -23,8 +35,6 @@ RUN set -eux; \
; \
rm -rf /var/lib/apt/lists/*
# we grab buildroot for it's uClibc toolchain
# pub 1024D/59C36319 2009-01-15
# Key fingerprint = AB07 D806 D2CE 741F B886 EE50 B025 BA8B 59C3 6319
# uid Peter Korsgaard <jacmet@uclibc.org>
@ -186,11 +196,13 @@ ENV PATH /usr/src/buildroot/output/host/usr/bin:$PATH
RUN gpg --batch --keyserver ha.pool.sks-keyservers.net --recv-keys C9E9416F76E610DBD09D040F47B70C55ACC9965B
ENV BUSYBOX_VERSION 1.33.0
ENV BUSYBOX_SHA256 d568681c91a85edc6710770cebc1e80e042ad74d305b5c2e6d57a5f3de3b8fbd
RUN set -eux; \
tarball="busybox-${BUSYBOX_VERSION}.tar.bz2"; \
curl -fL -o busybox.tar.bz2 "https://busybox.net/downloads/$tarball"; \
curl -fL -o busybox.tar.bz2.sig "https://busybox.net/downloads/$tarball.sig"; \
curl -fL -o busybox.tar.bz2 "https://busybox.net/downloads/$tarball"; \
echo "$BUSYBOX_SHA256 *busybox.tar.bz2" | sha256sum -c -; \
gpg --batch --verify busybox.tar.bz2.sig busybox.tar.bz2; \
mkdir -p /usr/src/busybox; \
tar -xf busybox.tar.bz2 -C /usr/src/busybox --strip-components 1; \
@ -198,13 +210,13 @@ RUN set -eux; \
WORKDIR /usr/src/busybox
# CONFIG_LAST_SUPPORTED_WCHAR: see https://github.com/docker-library/busybox/issues/13 (UTF-8 input)
RUN set -eux; \
\
setConfs=' \
CONFIG_AR=y \
CONFIG_FEATURE_AR_CREATE=y \
CONFIG_FEATURE_AR_LONG_FILENAMES=y \
# CONFIG_LAST_SUPPORTED_WCHAR: see https://github.com/docker-library/busybox/issues/13 (UTF-8 input)
CONFIG_LAST_SUPPORTED_WCHAR=0 \
CONFIG_STATIC=y \
'; \
@ -240,19 +252,19 @@ RUN set -eux; \
done; \
for confV in $setConfs; do \
grep -q "^$confV\$" .config; \
done;
done
RUN set -eux; \
make -j "$(nproc)" \
CROSS_COMPILE="$(basename /usr/src/buildroot/output/host/usr/*-buildroot-linux-uclibc*)-" \
busybox \
; \
nproc="$(nproc)"; \
CROSS_COMPILE="$(basename /usr/src/buildroot/output/host/usr/*-buildroot-linux-uclibc*)"; \
export CROSS_COMPILE="$CROSS_COMPILE-"; \
make -j "$nproc" busybox; \
./busybox --help; \
mkdir -p rootfs/bin; \
ln -vL busybox rootfs/bin/; \
\
# copy "getconf" from buildroot
ln -vL ../buildroot/output/target/usr/bin/getconf rootfs/bin/; \
\
chroot rootfs /bin/getconf _NPROCESSORS_ONLN; \
\
chroot rootfs /bin/busybox --install /bin
@ -260,11 +272,12 @@ RUN set -eux; \
# install a few extra files from buildroot (/etc/passwd, etc)
RUN set -eux; \
mkdir -p rootfs/etc; \
for f in passwd shadow group; do \
ln -vL \
"../buildroot/system/skeleton/etc/$f" \
"rootfs/etc/$f"; \
done; \
ln -vL \
../buildroot/system/skeleton/etc/group \
../buildroot/system/skeleton/etc/passwd \
../buildroot/system/skeleton/etc/shadow \
rootfs/etc/ \
; \
# CVE-2019-5021, https://github.com/docker-library/official-images/pull/5880#issuecomment-490681907
grep -E '^root::' rootfs/etc/shadow; \
sed -ri -e 's/^root::/root:*:/' rootfs/etc/shadow; \
@ -282,7 +295,7 @@ RUN set -eux; \
} \
printf "chmod %s %s\n", $3, $1; \
} \
' ../buildroot/system/device_table.txt | bash -Eeuo pipefail -x
' ../buildroot/system/device_table.txt | sh -eux
# create missing home directories
RUN set -eux; \

View File

@ -1,9 +1,7 @@
#!/bin/bash
set -eo pipefail
#!/usr/bin/env bash
set -Eeuo pipefail
cd "$(dirname "$(readlink -f "$BASH_SOURCE")")"
upstreamVersion="$(curl -fsSL --compressed 'https://busybox.net/downloads/' | grep -E '<a href="busybox-[0-9][^"/]*.tar.bz2"' | sed -r 's!.*<a href="busybox-([0-9][^"/]*).tar.bz2".*!\1!' | sort -V | tail -1)"
set -x
sed -ri 's/^(ENV BUSYBOX_VERSION) .*/\1 '"$upstreamVersion"'/' */Dockerfile.builder
./versions.sh "$@"
./apply-templates.sh "$@"

26
versions.json Normal file
View File

@ -0,0 +1,26 @@
{
"stable": {
"buildroot": {
"version": "2020.11.1"
},
"sha256": "9d57c4bd33974140fd4111260468af22856f12f5b5ef7c70c8d9b75c712a0dee",
"variants": [
"uclibc",
"glibc",
"musl"
],
"version": "1.32.1"
},
"unstable": {
"buildroot": {
"version": "2020.11.1"
},
"sha256": "d568681c91a85edc6710770cebc1e80e042ad74d305b5c2e6d57a5f3de3b8fbd",
"variants": [
"uclibc",
"glibc",
"musl"
],
"version": "1.33.0"
}
}

67
versions.sh Executable file
View File

@ -0,0 +1,67 @@
#!/usr/bin/env bash
set -Eeuo pipefail
cd "$(dirname "$(readlink -f "$BASH_SOURCE")")"
versions=( "$@" )
if [ "${#versions[@]}" -eq 0 ]; then
versions=( stable unstable )
json='{}'
else
json="$(< versions.json)"
fi
versions=( "${versions[@]%/}" )
busyboxVersions="$(
wget -qO- 'https://busybox.net' \
| grep -ioE ' -- BusyBox [0-9.]+ [(](un)?stable[)]' \
| cut -d' ' -f4-
)"
# "1.32.1 (stable)"
# "1.33.0 (unstable)"
# ...
buildrootVersion="$(
git ls-remote --tags https://git.busybox.net/buildroot \
| cut -d/ -f3 \
| cut -d^ -f1 \
| grep -E '^[0-9]+' \
| grep -vE -- '[-_]rc' \
| sort -uV \
| tail -1
)"
export buildrootVersion
for version in "${versions[@]}"; do
export version
if ! fullVersion="$(grep -m1 -F " ($version)" <<<"$busyboxVersions")" || [ -z "$fullVersion" ]; then
echo >&2 "error: failed to find latest '$version' release"
exit 1
fi
fullVersion="${fullVersion%% *}"
export fullVersion
sha256="$(wget -qO- "https://busybox.net/downloads/busybox-$fullVersion.tar.bz2.sha256" | cut -d' ' -f1)"
export sha256
echo "$version: $fullVersion"
json="$(
jq <<<"$json" -c '
.[env.version] = {
version: env.fullVersion,
sha256: env.sha256,
buildroot: {
version: env.buildrootVersion,
},
# prefer uclibc, but if unavailable use glibc since it has less "edge case" behavior
# https://busybox.net/FAQ.html#libc
variants: [ "uclibc", "glibc", "musl" ],
# (order here determines "preference" for representing "latest")
}
'
)"
done
jq <<<"$json" -S . > versions.json