mirror of
https://github.com/mhx/dwarfs.git
synced 2025-09-15 15:26:19 -04:00
chore: add CI for FreeBSD
This commit is contained in:
parent
addc222511
commit
32ed073cb2
33
.docker/build-freebsd.sh
Normal file
33
.docker/build-freebsd.sh
Normal file
@ -0,0 +1,33 @@
|
||||
#!/bin/sh
|
||||
set -eux
|
||||
|
||||
export HOME=/root
|
||||
export PATH=/usr/local/bin:/usr/local/sbin:/bin:/usr/bin:/sbin:/usr/sbin
|
||||
export CCACHE_DIR=/ccache
|
||||
export RUNNER_TEMP=/runner_temp
|
||||
export RUNNER_WORKSPACE=/work
|
||||
export GITHUB_RUN_NUMBER="${GITHUB_RUN_NUMBER:-0}"
|
||||
export BUILD_MODE="${BUILD_MODE:-Release}"
|
||||
export CMAKE_ARGS="${CMAKE_ARGS:-}"
|
||||
|
||||
# Source tarball path (NFS is nullfs-mounted from host)
|
||||
SRC_TARBALL="/mnt/opensource/artifacts/dwarfs/cache/dwarfs-source-${GITHUB_RUN_NUMBER}.tar.zst"
|
||||
test -r "${SRC_TARBALL}"
|
||||
|
||||
cd "$HOME"
|
||||
rm -rf dwarfs dwarfs-*
|
||||
tar xf "${SRC_TARBALL}"
|
||||
ln -sfn dwarfs-* dwarfs
|
||||
|
||||
rm -rf "${RUNNER_TEMP}/build"
|
||||
cmake --fresh \
|
||||
-B"${RUNNER_TEMP}/build" \
|
||||
-S"${HOME}/dwarfs" \
|
||||
-DCMAKE_BUILD_TYPE="${BUILD_MODE}" \
|
||||
-DWITH_TESTS=ON \
|
||||
-DWITH_PXATTR=ON \
|
||||
${CMAKE_ARGS}
|
||||
|
||||
cmake --build "${RUNNER_TEMP}/build" -j"$(sysctl -n hw.ncpu)"
|
||||
ctest --test-dir "${RUNNER_TEMP}/build" --output-on-failure -j"$(sysctl -n hw.ncpu)"
|
||||
cmake --build "${RUNNER_TEMP}/build" --target realclean
|
189
.github/scripts/freebsd_jail_build.sh
vendored
Normal file
189
.github/scripts/freebsd_jail_build.sh
vendored
Normal file
@ -0,0 +1,189 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -eu
|
||||
|
||||
# ----------------------------
|
||||
# Config / Inputs (env-driven)
|
||||
# ----------------------------
|
||||
FREEBSD_VER_TAG="${FREEBSD_VERSION:-14_3}"
|
||||
SNAP_LABEL="${FREEBSD_SNAPSHOT:-base-20250809}"
|
||||
ZPOOL="${ZPOOL:-zroot}"
|
||||
JAILS_DS="${JAILS_DS:-${ZPOOL}/z/jails}"
|
||||
JAILS_MP="${JAILS_MP:-/z/jails}"
|
||||
|
||||
GITHUB_RUN_ID="${GITHUB_RUN_ID:-localrun}"
|
||||
GITHUB_RUN_ATTEMPT="${GITHUB_RUN_ATTEMPT:-1}"
|
||||
|
||||
BUILD_MODE="${BUILD_MODE:-Release}"
|
||||
CMAKE_ARGS="${CMAKE_ARGS:-}"
|
||||
|
||||
BASE_DS="${JAILS_DS}/${FREEBSD_VER_TAG}"
|
||||
RUN_DS="${JAILS_DS}/ci-${FREEBSD_VER_TAG}-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}"
|
||||
RUN_MP="${JAILS_MP}/ci-${FREEBSD_VER_TAG}-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}"
|
||||
JAIL="ci_${FREEBSD_VER_TAG}_${GITHUB_RUN_ID}_${GITHUB_RUN_ATTEMPT}"
|
||||
|
||||
# ----------------------------
|
||||
# Helpers
|
||||
# ----------------------------
|
||||
log() { printf '%s %s\n' "[freebsd-jail]" "$*" >&2; }
|
||||
|
||||
# Stop a jail if it's running; kill any lingering processes by JID if needed
|
||||
stop_stale_jail() {
|
||||
jname="$1"
|
||||
if jls -j "$jname" >/dev/null 2>&1; then
|
||||
log "Stopping stale jail: $jname"
|
||||
if ! sudo jail -r "$jname" 2>/dev/null; then
|
||||
JID="$(jls -j "$jname" jid -h 2>/dev/null || true)"
|
||||
if [ -n "$JID" ]; then
|
||||
sudo killall -j "$JID" -TERM 2>/dev/null || true
|
||||
sleep 1
|
||||
sudo killall -j "$JID" -KILL 2>/dev/null || true
|
||||
fi
|
||||
sudo jail -r "$jname" 2>/dev/null || true
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Unmount everything under a mountpoint (deepest-first)
|
||||
umount_tree() {
|
||||
rootmp="$1"
|
||||
# List mounted paths under $rootmp, deepest-first
|
||||
# shellcheck disable=SC2016
|
||||
for m in $(mount | awk -v p="$rootmp" '$3 ~ ("^"p) { print length, $3 }' | sort -rn | cut -d" " -f2-); do
|
||||
sudo umount -f "$m" 2>/dev/null || true
|
||||
done
|
||||
}
|
||||
|
||||
# Destroy a cloned dataset (after umount)
|
||||
destroy_dataset() {
|
||||
ds="$1"
|
||||
if sudo zfs list -H "$ds" >/dev/null 2>&1; then
|
||||
mp="$(sudo zfs get -H -o value mountpoint "$ds" 2>/dev/null || echo "")"
|
||||
if [ -n "$mp" ] && [ "$mp" != "-" ]; then
|
||||
umount_tree "$mp"
|
||||
fi
|
||||
log "Destroying dataset: $ds"
|
||||
sudo zfs destroy -r "$ds"
|
||||
fi
|
||||
}
|
||||
|
||||
# Remove stale jail + dataset that match our run IDs
|
||||
cleanup_stale_before_start() {
|
||||
stop_stale_jail "$JAIL"
|
||||
destroy_dataset "$RUN_DS"
|
||||
}
|
||||
|
||||
# Full cleanup for traps: stop jail, unmount, destroy dataset
|
||||
cleanup_on_exit() {
|
||||
# Be idempotent; ignore errors
|
||||
stop_stale_jail "$JAIL"
|
||||
destroy_dataset "$RUN_DS"
|
||||
}
|
||||
|
||||
# Generate an env file inside jail that exports safe GitHub env vars
|
||||
write_gha_env() {
|
||||
out="$1"
|
||||
# Allow common CI vars; deny obvious secrets
|
||||
# Adjust allow/deny as needed for your org.
|
||||
ALLOW='GITHUB_* RUNNER_* CI ACTIONS_* INPUT_* MATRIX_* BUILD_MODE CMAKE_ARGS'
|
||||
DENY='*TOKEN* *SECRET* *PASSWORD* *PASS* *KEY* *CERT* AWS_* AZURE_* GCP_*'
|
||||
|
||||
# Function to test name against allow/deny (POSIX sh compatible inline)
|
||||
is_allowed() {
|
||||
name="$1"
|
||||
case "$name" in
|
||||
GITHUB_*|RUNNER_*|CI|ACTIONS_*|INPUT_*|MATRIX_*|BUILD_MODE|CMAKE_ARGS) : ;;
|
||||
*) return 1 ;;
|
||||
esac
|
||||
case "$name" in
|
||||
*TOKEN*|*SECRET*|*PASSWORD*|*PASS*|*KEY*|*CERT*|AWS_*|AZURE_*|GCP_* ) return 1 ;;
|
||||
esac
|
||||
return 0
|
||||
}
|
||||
|
||||
tmp="$(mktemp)"
|
||||
{
|
||||
echo "# Autogenerated; sourced by /root/build.sh"
|
||||
# Ensure our two common knobs are present even if not in env
|
||||
printf "export BUILD_MODE='%s'\n" "$BUILD_MODE"
|
||||
# Escape single quotes in CMAKE_ARGS
|
||||
esc_ca=$(printf "%s" "$CMAKE_ARGS" | sed "s/'/'\"'\"'/g")
|
||||
printf "export CMAKE_ARGS='%s'\n" "$esc_ca"
|
||||
|
||||
env | while IFS='=' read -r name value; do
|
||||
if is_allowed "$name"; then
|
||||
esc=$(printf "%s" "$value" | sed "s/'/'\"'\"'/g")
|
||||
printf "export %s='%s'\n" "$name" "$esc"
|
||||
fi
|
||||
done
|
||||
} > "$tmp"
|
||||
sudo mkdir -p "$(dirname "$out")"
|
||||
sudo cp "$tmp" "$out"
|
||||
sudo chmod 0644 "$out"
|
||||
rm -f "$tmp"
|
||||
}
|
||||
|
||||
# ----------------------------
|
||||
# Trap: ensure cleanup on any exit
|
||||
# ----------------------------
|
||||
trap cleanup_on_exit EXIT INT TERM HUP
|
||||
|
||||
# ----------------------------
|
||||
# Prep: nuke stale, then clone snapshot
|
||||
# ----------------------------
|
||||
cleanup_stale_before_start
|
||||
|
||||
log "Cloning ${BASE_DS}@${SNAP_LABEL} -> ${RUN_DS}"
|
||||
sudo zfs clone "${BASE_DS}@${SNAP_LABEL}" "${RUN_DS}"
|
||||
|
||||
# ----------------------------
|
||||
# Bootstrapping jail root: DNS + mounts
|
||||
# ----------------------------
|
||||
# DNS for networking inside jail
|
||||
sudo mkdir -p "${RUN_MP}/etc"
|
||||
sudo cp /etc/resolv.conf "${RUN_MP}/etc/resolv.conf"
|
||||
[ -f /etc/hosts ] && sudo cp /etc/hosts "${RUN_MP}/etc/hosts"
|
||||
[ -f /etc/nsswitch.conf ] && sudo cp /etc/nsswitch.conf "${RUN_MP}/etc/nsswitch.conf"
|
||||
|
||||
# Core mounts
|
||||
sudo mount -t devfs devfs "${RUN_MP}/dev"
|
||||
sudo mount -t fdescfs fdesc "${RUN_MP}/dev/fd"
|
||||
sudo mount -t procfs proc "${RUN_MP}/proc"
|
||||
sudo mount -t tmpfs tmpfs "${RUN_MP}/tmp"
|
||||
|
||||
# Workspace / temp / ccache / NFS from host
|
||||
RUNNER_WORKSPACE="${RUNNER_WORKSPACE:-$PWD}"
|
||||
RUNNER_TEMP="${RUNNER_TEMP:-/tmp/runner_temp}"
|
||||
mkdir -p "${RUNNER_TEMP}" "${HOME}/.ccache"
|
||||
|
||||
sudo mkdir -p "${RUN_MP}/work" "${RUN_MP}/runner_temp" "${RUN_MP}/ccache" "${RUN_MP}/mnt/opensource"
|
||||
sudo mount -t nullfs -o rw "${RUNNER_WORKSPACE}" "${RUN_MP}/work"
|
||||
sudo mount -t nullfs -o rw "${RUNNER_TEMP}" "${RUN_MP}/runner_temp"
|
||||
sudo mount -t nullfs -o rw "${HOME}/github-ccache" "${RUN_MP}/ccache"
|
||||
sudo mount -t nullfs -o rw "/mnt/opensource" "${RUN_MP}/mnt/opensource"
|
||||
|
||||
# ----------------------------
|
||||
# Start jail (FUSE enabled)
|
||||
# ----------------------------
|
||||
log "Starting jail: ${JAIL}"
|
||||
sudo jail -c name="${JAIL}" host.hostname="${JAIL}" \
|
||||
path="${RUN_MP}" persist \
|
||||
mount.devfs devfs_ruleset=5 enforce_statfs=1 \
|
||||
allow.mount allow.mount.fusefs \
|
||||
allow.raw_sockets \
|
||||
ip4=inherit ip6=inherit
|
||||
|
||||
# ----------------------------
|
||||
# Inject env + build script, then run it
|
||||
# ----------------------------
|
||||
write_gha_env "${RUN_MP}/root/gha_env.sh"
|
||||
|
||||
sudo cp ".docker/build-freebsd.sh" "${RUN_MP}/root/build.sh"
|
||||
sudo chmod +x "${RUN_MP}/root/build.sh"
|
||||
|
||||
# Run inside the jail with env sourced
|
||||
log "Executing build inside jail…"
|
||||
sudo jexec "${JAIL}" /bin/sh -lc '. /root/gha_env.sh; exec /root/build.sh'
|
||||
|
||||
log "Build finished successfully."
|
||||
# Cleanup happens automatically via trap on EXIT.
|
67
.github/scripts/freebsd_setup_base.sh
vendored
Executable file
67
.github/scripts/freebsd_setup_base.sh
vendored
Executable file
@ -0,0 +1,67 @@
|
||||
#!/bin/sh
|
||||
set -euo pipefail
|
||||
|
||||
# ===== Config =====
|
||||
FREEBSD_REL="${FREEBSD_REL:-14.3-RELEASE}"
|
||||
FREEBSD_VER_TAG="${FREEBSD_VER_TAG:-14_3}"
|
||||
|
||||
SNAP_LABEL="${SNAP_LABEL:-base-$(date +%Y%m%d)}"
|
||||
|
||||
ZPOOL="${ZPOOL:-zroot}"
|
||||
JAILS_DS="${JAILS_DS:-${ZPOOL}/z/jails}"
|
||||
JAILS_MP="${JAILS_MP:-/z/jails}"
|
||||
|
||||
PKG_REPO_URL='pkg+http://pkg.FreeBSD.org/${ABI}/latest'
|
||||
|
||||
PKGS="boost-all brotli ccache cmake date double-conversion flac fuse fusefs-libs fusefs-libs3 glog gnulibiberty libarchive liblz4 mold ninja nlohmann-json openssl parallel-hashmap pkgconf range-v3 utf8cpp xxhash zstd ca_root_nss git"
|
||||
|
||||
# ===== Layout =====
|
||||
sudo zfs list -H "${ZPOOL}" >/dev/null 2>&1 || { echo "No pool ${ZPOOL}"; exit 1; }
|
||||
sudo zfs create -o mountpoint=/z "${ZPOOL}/z" >/dev/null 2>&1 || true
|
||||
sudo zfs create -o mountpoint=/z/jails "${JAILS_DS}" >/dev/null 2>&1 || true
|
||||
|
||||
BASE_DS="${JAILS_DS}/${FREEBSD_VER_TAG}"
|
||||
BASE_MP="${JAILS_MP}/${FREEBSD_VER_TAG}"
|
||||
|
||||
if ! sudo zfs list -H "${BASE_DS}" >/dev/null 2>&1; then
|
||||
sudo zfs create -o mountpoint="${BASE_MP}" "${BASE_DS}"
|
||||
fi
|
||||
|
||||
# ===== Fetch & extract base.txz =====
|
||||
if [ ! -f "${BASE_MP}/.seeded" ]; then
|
||||
TMPDIR="$(mktemp -d)"
|
||||
trap 'rm -rf "$TMPDIR"' EXIT
|
||||
fetch -o "${TMPDIR}/base.txz" "https://download.freebsd.org/releases/amd64/${FREEBSD_REL}/base.txz"
|
||||
sudo tar -xpf "${TMPDIR}/base.txz" -C "${BASE_MP}"
|
||||
sudo touch "${BASE_MP}/.seeded"
|
||||
fi
|
||||
|
||||
# ===== Provide networking config to the chroot =====
|
||||
sudo mkdir -p "${BASE_MP}/etc"
|
||||
# copy DNS + name service config from host so pkg can resolve names
|
||||
sudo cp /etc/resolv.conf "${BASE_MP}/etc/resolv.conf"
|
||||
[ -f /etc/hosts ] && sudo cp /etc/hosts "${BASE_MP}/etc/hosts"
|
||||
[ -f /etc/nsswitch.conf ] && sudo cp /etc/nsswitch.conf "${BASE_MP}/etc/nsswitch.conf"
|
||||
|
||||
# ===== Preinstall deps inside the tree =====
|
||||
sudo mount -t devfs devfs "${BASE_MP}/dev"
|
||||
sudo mount -t fdescfs fdesc "${BASE_MP}/dev/fd"
|
||||
sudo mount -t procfs proc "${BASE_MP}/proc"
|
||||
|
||||
sudo chroot "${BASE_MP}" /bin/sh -lc "
|
||||
set -e
|
||||
env ASSUME_ALWAYS_YES=yes pkg bootstrap -f
|
||||
mkdir -p /usr/local/etc/pkg/repos
|
||||
echo 'FreeBSD: { url: \"${PKG_REPO_URL}\" }' > /usr/local/etc/pkg/repos/FreeBSD.conf
|
||||
pkg update
|
||||
pkg install -y ${PKGS}
|
||||
mkdir -p /root/.ccache
|
||||
"
|
||||
|
||||
sudo umount -f "${BASE_MP}/proc" || true
|
||||
sudo umount -f "${BASE_MP}/dev/fd" || true
|
||||
sudo umount -f "${BASE_MP}/dev" || true
|
||||
|
||||
# ===== Snapshot =====
|
||||
sudo zfs snapshot "${BASE_DS}@${SNAP_LABEL}"
|
||||
echo "Snapshot created: ${BASE_DS}@${SNAP_LABEL}"
|
31
.github/workflows/build.yml
vendored
31
.github/workflows/build.yml
vendored
@ -490,3 +490,34 @@ jobs:
|
||||
rm -rf dwarfs-*/
|
||||
rm -f dwarfs-source-*.tar.zst
|
||||
rm -f dwarfs
|
||||
|
||||
################################################################################
|
||||
|
||||
freebsd:
|
||||
needs: package-source
|
||||
|
||||
runs-on:
|
||||
- self-hosted
|
||||
- freebsd
|
||||
- ${{ matrix.arch }}
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
arch:
|
||||
- amd64
|
||||
build_mode:
|
||||
- Release
|
||||
- Debug
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: 'false'
|
||||
fetch-depth: '0'
|
||||
ref: ${{ github.ref }}
|
||||
|
||||
- name: Run Build
|
||||
run: |
|
||||
BUILD_MODE=${{ matrix.build_mode }} \
|
||||
sh .github/scripts/freebsd_jail_build.sh
|
||||
|
Loading…
x
Reference in New Issue
Block a user