vendor: update cxos-vendor-busybox

This commit is contained in:
cx-git-agent
2026-04-26 16:35:08 +00:00
committed by GitHub
parent ee2f5dba75
commit ada078f5b3
5 changed files with 280 additions and 3 deletions
+16
View File
@@ -0,0 +1,16 @@
{
"schema": "cxos.vendor.busybox/v1",
"version": "1.36.1",
"tarball_url": "https://busybox.net/downloads/busybox-1.36.1.tar.bz2",
"signature_url": "https://busybox.net/downloads/busybox-1.36.1.tar.bz2.sig",
"sha256": "b8cc24c9574d809e7279c3be349795c5d5ceb6fdf19ca709f80cde50e47de314",
"gpg_signing_keys": [
{
"name": "Denys Vlasenko",
"email": "vda.linux@googlemail.com",
"fingerprint": "C9E9416F76E610DBD09D040F47B70C55ACC9965B"
}
],
"extracted_dir": "busybox-1.36.1",
"notes": "CxOS Tier-0 userland — single static binary providing /sbin/init, getty, login, sh, ls, ps, cat, mount, ip, ifconfig, dhcpc, plus ~300 more applets. Built with --static to avoid libc. Update version + sha256 together; verify via 'shasum -a 256 busybox-1.36.1.tar.bz2'."
}
-3
View File
@@ -1,3 +0,0 @@
# cxos-vendor-busybox
CxOS vendor: busybox
Executable
+85
View File
@@ -0,0 +1,85 @@
#!/usr/bin/env bash
# cxos/vendor/busybox/build.sh — build a static busybox + install into rootfs.
#
# Usage:
# build.sh # x86_64, install into dist/cxos/rootfs
# build.sh --arch aarch64
# build.sh --rootfs /path/to/rootfs
# build.sh --dry
#
# After install:
# <rootfs>/bin/busybox static binary (~1 MB)
# <rootfs>/bin/* ./sbin/* symlinks to busybox (one per applet)
set -euo pipefail
ARCH="x86_64"
DRY=0
ROOTFS=""
for ((i=1; i<=$#; i++)); do
case "${!i}" in
--arch) ((i++)); ARCH="${!i}" ;;
--rootfs) ((i++)); ROOTFS="${!i}" ;;
--dry) DRY=1 ;;
-h|--help) sed -n '2,12p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;;
*) echo "build.sh: unknown arg: ${!i}" >&2; exit 2 ;;
esac
done
HERE="$(cd "$(dirname "$0")" && pwd)"
REPO_ROOT="$(cd "$HERE/../../.." && pwd)"
PINNED="$HERE/PINNED.json"
FRAGMENT="$HERE/cxos.config.fragment"
VERSION="$(python3 -c 'import json,sys;print(json.load(open(sys.argv[1]))["version"])' "$PINNED")"
EXTRACTED_DIR="$(python3 -c 'import json,sys;print(json.load(open(sys.argv[1]))["extracted_dir"])' "$PINNED")"
SRC="$HERE/src/$EXTRACTED_DIR"
ROOTFS="${ROOTFS:-$REPO_ROOT/dist/cxos/rootfs}"
case "$ARCH" in
x86_64) CROSS="" ;;
aarch64) CROSS="${CROSS_COMPILE:-aarch64-linux-gnu-}" ;;
*) echo "build.sh: unsupported arch: $ARCH" >&2; exit 2 ;;
esac
JOBS="${JOBS:-$(nproc 2>/dev/null || echo 2)}"
echo "==> busybox ${VERSION} (${ARCH}) -> ${ROOTFS}"
echo " src : ${SRC}"
echo " fragment: ${FRAGMENT}"
echo " cross : ${CROSS:-<native>}"
echo " jobs : ${JOBS}"
if [[ "$DRY" == "1" ]]; then
echo "==> dry-run; not compiling"
exit 0
fi
[[ -d "$SRC" ]] || { echo "build.sh: source not extracted; run fetch.sh first" >&2; exit 1; }
cd "$SRC"
make CROSS_COMPILE="$CROSS" defconfig
# Apply fragment overrides line-by-line. Lines that start with '#' or are
# blank are skipped. KEY=VALUE lines replace any existing KEY= line, or are
# appended if absent.
while IFS= read -r line; do
[[ -z "$line" || "$line" == \#* ]] && continue
key="${line%%=*}"
if grep -qE "^# ${key} is not set$|^${key}=" .config; then
sed -i -E "s|^# ${key} is not set\$|${line}|; s|^${key}=.*|${line}|" .config
else
printf '%s\n' "$line" >> .config
fi
done < "$FRAGMENT"
make CROSS_COMPILE="$CROSS" oldconfig
make CROSS_COMPILE="$CROSS" -j"$JOBS" busybox
mkdir -p "$ROOTFS"
make CROSS_COMPILE="$CROSS" CONFIG_PREFIX="$ROOTFS" install
# busybox install creates /linuxrc symlink — pointless on initramfs (we have
# our own /init). Drop it.
rm -f "$ROOTFS/linuxrc"
echo "==> installed: $(find "$ROOTFS/bin" "$ROOTFS/sbin" -maxdepth 1 -mindepth 1 2>/dev/null | wc -l) applets"
+93
View File
@@ -0,0 +1,93 @@
# cxos.config.fragment — busybox additions on top of `defconfig`.
#
# Statically linked, no debug, sufficient applets to bring up CxOS Tier-0.
# Merged via plain `sed -i` overrides in build.sh (busybox uses Kconfig but
# its config files are flat KEY=VALUE; we apply each line as 'set or add').
CONFIG_STATIC=y
CONFIG_INSTALL_NO_USR=n
# --- Init / login / shell ---
CONFIG_INIT=y
CONFIG_GETTY=y
CONFIG_LOGIN=y
CONFIG_FEATURE_SHADOWPASSWDS=y
CONFIG_USE_BB_SHADOW=y
CONFIG_PASSWD=y
CONFIG_ASH=y
CONFIG_FEATURE_SH_IS_ASH=y
# --- coreutils ---
CONFIG_LS=y
CONFIG_CAT=y
CONFIG_CP=y
CONFIG_MV=y
CONFIG_RM=y
CONFIG_MKDIR=y
CONFIG_RMDIR=y
CONFIG_LN=y
CONFIG_PWD=y
CONFIG_ECHO=y
CONFIG_PRINTF=y
CONFIG_TRUE=y
CONFIG_FALSE=y
CONFIG_SLEEP=y
CONFIG_DATE=y
CONFIG_UNAME=y
CONFIG_HOSTNAME=y
CONFIG_TOUCH=y
CONFIG_HEAD=y
CONFIG_TAIL=y
CONFIG_GREP=y
CONFIG_SED=y
CONFIG_AWK=y
CONFIG_FIND=y
CONFIG_TR=y
CONFIG_SORT=y
CONFIG_UNIQ=y
CONFIG_WC=y
CONFIG_TEE=y
CONFIG_DD=y
CONFIG_CHMOD=y
CONFIG_CHOWN=y
CONFIG_SHA256SUM=y
CONFIG_MD5SUM=y
# --- Process / system ---
CONFIG_PS=y
CONFIG_TOP=y
CONFIG_KILL=y
CONFIG_PIDOF=y
CONFIG_FREE=y
CONFIG_DMESG=y
CONFIG_MOUNT=y
CONFIG_UMOUNT=y
CONFIG_DF=y
CONFIG_DU=y
CONFIG_LSMOD=y
CONFIG_INSMOD=y
CONFIG_RMMOD=y
CONFIG_REBOOT=y
CONFIG_HALT=y
CONFIG_POWEROFF=y
CONFIG_SWITCH_ROOT=y
# --- Networking ---
CONFIG_IP=y
CONFIG_IPADDR=y
CONFIG_IPLINK=y
CONFIG_IPROUTE=y
CONFIG_IFCONFIG=y
CONFIG_ROUTE=y
CONFIG_PING=y
CONFIG_NSLOOKUP=y
CONFIG_UDHCPC=y
CONFIG_WGET=y
# --- Misc ---
CONFIG_VI=y
CONFIG_LESS=y
CONFIG_TAR=y
CONFIG_GZIP=y
CONFIG_GUNZIP=y
CONFIG_XZ=n
Executable
+86
View File
@@ -0,0 +1,86 @@
#!/usr/bin/env bash
# cxos/vendor/busybox/fetch.sh — download + verify + extract busybox tarball.
# Mirrors cxos/vendor/linux/fetch.sh shape (PINNED.json driven, --dry, --gpg).
set -euo pipefail
DRY=0
GPG=0
for arg in "$@"; do
case "$arg" in
--dry) DRY=1 ;;
--gpg) GPG=1 ;;
-h|--help) sed -n '2,4p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;;
*) echo "fetch.sh: unknown arg: $arg" >&2; exit 2 ;;
esac
done
HERE="$(cd "$(dirname "$0")" && pwd)"
PINNED="$HERE/PINNED.json"
[[ -f "$PINNED" ]] || { echo "fetch.sh: missing $PINNED" >&2; exit 1; }
read -r VERSION TARBALL_URL SIG_URL SHA256 EXTRACTED_DIR < <(
python3 - "$PINNED" <<'PY'
import json, sys
d = json.load(open(sys.argv[1]))
print(d["version"], d["tarball_url"], d["signature_url"],
d["sha256"], d["extracted_dir"])
PY
)
TARBALL="$HERE/busybox-${VERSION}.tar.bz2"
SIGNATURE="$HERE/busybox-${VERSION}.tar.bz2.sig"
SRC_DIR="$HERE/src"
echo "==> busybox ${VERSION}"
echo " tarball: ${TARBALL_URL}"
echo " sha256 : ${SHA256}"
echo " extract: ${SRC_DIR}/${EXTRACTED_DIR}"
if [[ "$DRY" == "1" ]]; then
echo "==> dry-run; nothing fetched"
exit 0
fi
mkdir -p "$SRC_DIR"
if [[ ! -f "$TARBALL" ]]; then
echo "==> downloading"
curl -fsSL --retry 3 -o "$TARBALL" "$TARBALL_URL"
fi
echo "==> verifying sha256"
ACTUAL_SHA="$(sha256sum "$TARBALL" | awk '{print $1}')"
if [[ "$ACTUAL_SHA" != "$SHA256" ]]; then
echo "fetch.sh: SHA-256 mismatch" >&2
echo " expected: $SHA256" >&2
echo " actual : $ACTUAL_SHA" >&2
rm -f "$TARBALL"
exit 1
fi
echo " ok"
if [[ "$GPG" == "1" ]]; then
command -v gpg >/dev/null 2>&1 || { echo "fetch.sh: --gpg requested but gpg not installed" >&2; exit 1; }
[[ -f "$SIGNATURE" ]] || curl -fsSL --retry 3 -o "$SIGNATURE" "$SIG_URL"
FINGERPRINTS="$(python3 -c '
import json,sys
for k in json.load(open(sys.argv[1]))["gpg_signing_keys"]:
print(k["fingerprint"])' "$PINNED")"
for fp in $FINGERPRINTS; do
gpg --keyserver hkps://keys.openpgp.org --recv-keys "$fp" >/dev/null 2>&1 || true
done
echo "==> verifying gpg signature"
if ! gpg --verify "$SIGNATURE" "$TARBALL" 2>&1 \
| grep -qE 'Good signature.*('"$(echo "$FINGERPRINTS" | tr '\n' '|' | sed 's/|$//')"')'; then
echo "fetch.sh: GPG verification failed" >&2
exit 1
fi
echo " ok"
fi
if [[ ! -d "$SRC_DIR/$EXTRACTED_DIR" ]]; then
echo "==> extracting"
tar -xjf "$TARBALL" -C "$SRC_DIR"
fi
echo "==> busybox source ready: $SRC_DIR/$EXTRACTED_DIR"