forked from wrenn/wrenn
Inject a statically-linked socat binary into rootfs images. envd's port forwarder requires socat to bridge localhost-listening services (e.g. Jupyter kernel) to the guest TAP interface. Both scripts follow the same 3-step resolution: check rootfs, check host, build from source (http://www.dest-unreach.org/socat/ v1.8.1.1). Static linkage is verified before injection. This is an intermediate state — needs further work for the full code interpreter feature.
141 lines
4.4 KiB
Bash
Executable File
141 lines
4.4 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
#
|
|
# update-debug-rootfs.sh — Build envd and inject it (plus wrenn-init) into the debug rootfs.
|
|
#
|
|
# This script:
|
|
# 1. Builds a fresh envd static binary via make
|
|
# 2. Mounts the rootfs image
|
|
# 3. Copies envd and wrenn-init into the image
|
|
# 4. Unmounts cleanly
|
|
#
|
|
# Usage:
|
|
# bash scripts/update-debug-rootfs.sh [rootfs_path]
|
|
#
|
|
# Defaults to /var/lib/wrenn/images/minimal/rootfs.ext4
|
|
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
|
|
ROOTFS="${1:-/var/lib/wrenn/images/minimal/rootfs.ext4}"
|
|
MOUNT_DIR="/tmp/wrenn-rootfs-update"
|
|
|
|
if [ ! -f "${ROOTFS}" ]; then
|
|
echo "ERROR: Rootfs not found at ${ROOTFS}"
|
|
exit 1
|
|
fi
|
|
|
|
# Step 1: Build envd.
|
|
echo "==> Building envd..."
|
|
cd "${PROJECT_ROOT}"
|
|
make build-envd
|
|
ENVD_BIN="${PROJECT_ROOT}/builds/envd"
|
|
|
|
if [ ! -f "${ENVD_BIN}" ]; then
|
|
echo "ERROR: envd binary not found at ${ENVD_BIN}"
|
|
exit 1
|
|
fi
|
|
|
|
# Verify it's statically linked.
|
|
if ! file "${ENVD_BIN}" | grep -q "statically linked"; then
|
|
echo "ERROR: envd is not statically linked!"
|
|
exit 1
|
|
fi
|
|
|
|
# Step 2: Mount the rootfs.
|
|
echo "==> Mounting rootfs at ${MOUNT_DIR}..."
|
|
mkdir -p "${MOUNT_DIR}"
|
|
sudo mount -o loop "${ROOTFS}" "${MOUNT_DIR}"
|
|
|
|
cleanup() {
|
|
echo "==> Unmounting rootfs..."
|
|
sudo umount "${MOUNT_DIR}" 2>/dev/null || true
|
|
rmdir "${MOUNT_DIR}" 2>/dev/null || true
|
|
}
|
|
trap cleanup EXIT
|
|
|
|
# Step 3: Copy files into rootfs.
|
|
echo "==> Installing envd..."
|
|
sudo mkdir -p "${MOUNT_DIR}/usr/local/bin"
|
|
sudo cp "${ENVD_BIN}" "${MOUNT_DIR}/usr/local/bin/envd"
|
|
sudo chmod 755 "${MOUNT_DIR}/usr/local/bin/envd"
|
|
|
|
echo "==> Installing wrenn-init..."
|
|
sudo cp "${PROJECT_ROOT}/images/wrenn-init.sh" "${MOUNT_DIR}/usr/local/bin/wrenn-init"
|
|
sudo chmod 755 "${MOUNT_DIR}/usr/local/bin/wrenn-init"
|
|
|
|
echo "==> Installing tini..."
|
|
TINI_BIN=""
|
|
# 1. Already in the rootfs?
|
|
for p in "${MOUNT_DIR}/usr/bin/tini" "${MOUNT_DIR}/sbin/tini" "${MOUNT_DIR}/usr/local/bin/tini"; do
|
|
if [ -f "$p" ]; then TINI_BIN="$p"; break; fi
|
|
done
|
|
# 2. Available on the host?
|
|
if [ -z "${TINI_BIN}" ]; then
|
|
for p in /usr/bin/tini /usr/local/bin/tini /sbin/tini; do
|
|
if [ -f "$p" ]; then TINI_BIN="$p"; break; fi
|
|
done
|
|
fi
|
|
# 3. Download from GitHub releases.
|
|
if [ -z "${TINI_BIN}" ]; then
|
|
ARCH="$(uname -m)"
|
|
case "${ARCH}" in
|
|
x86_64) TINI_ARCH="amd64" ;;
|
|
aarch64) TINI_ARCH="arm64" ;;
|
|
*) echo "ERROR: Unsupported architecture: ${ARCH}"; exit 1 ;;
|
|
esac
|
|
TINI_VERSION="v0.19.0"
|
|
TINI_URL="https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini-${TINI_ARCH}"
|
|
TINI_TMP="/tmp/tini-${TINI_ARCH}"
|
|
echo " Downloading tini ${TINI_VERSION} (${TINI_ARCH})..."
|
|
curl -fsSL "${TINI_URL}" -o "${TINI_TMP}"
|
|
chmod +x "${TINI_TMP}"
|
|
TINI_BIN="${TINI_TMP}"
|
|
fi
|
|
sudo mkdir -p "${MOUNT_DIR}/sbin"
|
|
sudo cp "${TINI_BIN}" "${MOUNT_DIR}/sbin/tini"
|
|
sudo chmod 755 "${MOUNT_DIR}/sbin/tini"
|
|
|
|
echo "==> Installing socat..."
|
|
SOCAT_BIN=""
|
|
# 1. Already in the rootfs?
|
|
for p in "${MOUNT_DIR}/usr/bin/socat" "${MOUNT_DIR}/usr/local/bin/socat"; do
|
|
if [ -f "$p" ]; then SOCAT_BIN="$p"; break; fi
|
|
done
|
|
# 2. Available on the host?
|
|
if [ -z "${SOCAT_BIN}" ]; then
|
|
for p in /usr/bin/socat /usr/local/bin/socat; do
|
|
if [ -f "$p" ]; then SOCAT_BIN="$p"; break; fi
|
|
done
|
|
fi
|
|
# 3. Build from source.
|
|
if [ -z "${SOCAT_BIN}" ]; then
|
|
SOCAT_VERSION="1.8.1.1"
|
|
SOCAT_URL="http://www.dest-unreach.org/socat/download/socat-${SOCAT_VERSION}.tar.gz"
|
|
SOCAT_BUILD_DIR="/tmp/socat-build"
|
|
echo " Building socat ${SOCAT_VERSION} from source..."
|
|
rm -rf "${SOCAT_BUILD_DIR}"
|
|
mkdir -p "${SOCAT_BUILD_DIR}"
|
|
curl -fsSL "${SOCAT_URL}" | tar xz -C "${SOCAT_BUILD_DIR}" --strip-components=1
|
|
(cd "${SOCAT_BUILD_DIR}" && LDFLAGS="-static" ./configure --quiet && make -j"$(nproc)" -s)
|
|
SOCAT_BIN="${SOCAT_BUILD_DIR}/socat"
|
|
if [ ! -f "${SOCAT_BIN}" ]; then
|
|
echo "ERROR: socat build failed"
|
|
exit 1
|
|
fi
|
|
if ! file "${SOCAT_BIN}" | grep -q "statically linked"; then
|
|
echo "ERROR: socat is not statically linked!"
|
|
exit 1
|
|
fi
|
|
fi
|
|
sudo cp "${SOCAT_BIN}" "${MOUNT_DIR}/usr/local/bin/socat"
|
|
sudo chmod 755 "${MOUNT_DIR}/usr/local/bin/socat"
|
|
|
|
# Step 4: Verify.
|
|
echo ""
|
|
echo "==> Installed files:"
|
|
ls -la "${MOUNT_DIR}/usr/local/bin/envd" "${MOUNT_DIR}/usr/local/bin/wrenn-init" "${MOUNT_DIR}/sbin/tini" "${MOUNT_DIR}/usr/local/bin/socat"
|
|
|
|
echo ""
|
|
echo "==> Done. Rootfs updated: ${ROOTFS}"
|