Advance forge rollout, Ethereum rails, and NBC sources
This commit is contained in:
parent
be26313225
commit
7d84510eac
88 changed files with 11230 additions and 302 deletions
|
|
@ -4,14 +4,20 @@ set -euo pipefail
|
|||
root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
cd "${root}"
|
||||
|
||||
forge_host="${EVERY_CHANNEL_FORGE_HOST:-https://forge.every.channel}"
|
||||
forge_host="${EVERY_CHANNEL_FORGE_HOST:-https://git.every.channel}"
|
||||
forge_repo="${EVERY_CHANNEL_FORGE_REPO:-every-channel/every.channel}"
|
||||
release_tag="${EVERY_CHANNEL_NETBOOT_RELEASE_TAG:-}"
|
||||
local_tarball="${EVERY_CHANNEL_NETBOOT_TARBALL:-}"
|
||||
out_root="${EVERY_CHANNEL_NETBOOT_ROOT:-tmp/netboot}"
|
||||
ipxe_efi_url="${EVERY_CHANNEL_IPXE_EFI_URL:-https://boot.ipxe.org/snponly.efi}"
|
||||
ipxe_efi_path="${EVERY_CHANNEL_IPXE_EFI_PATH:-}"
|
||||
ipxe_efi_filename="${EVERY_CHANNEL_IPXE_EFI_FILENAME:-ipxe.efi}"
|
||||
netboot_hostname="${EVERY_CHANNEL_NETBOOT_HOSTNAME:-boot.every.channel}"
|
||||
http_port="${EVERY_CHANNEL_NETBOOT_HTTP_PORT:-8080}"
|
||||
verify_release_checksums="${EVERY_CHANNEL_NETBOOT_VERIFY_RELEASE_CHECKSUMS:-true}"
|
||||
allow_remote_ipxe="${EVERY_CHANNEL_NETBOOT_ALLOW_REMOTE_IPXE:-false}"
|
||||
ipxe_efi_sha256="${EVERY_CHANNEL_IPXE_EFI_SHA256:-}"
|
||||
chain_token="${EVERY_CHANNEL_NETBOOT_CHAIN_TOKEN:-}"
|
||||
token="${EVERY_CHANNEL_FORGE_TOKEN:-${FORGE_TOKEN:-${CODEBERG_TOKEN:-}}}"
|
||||
|
||||
need_cmd() {
|
||||
|
|
@ -26,6 +32,54 @@ need_cmd curl
|
|||
need_cmd tar
|
||||
need_cmd python3
|
||||
|
||||
bool_norm() {
|
||||
local raw
|
||||
raw="$(printf '%s' "${1:-}" | tr '[:upper:]' '[:lower:]')"
|
||||
case "${raw}" in
|
||||
''|true|1|yes|y|on) echo "true" ;;
|
||||
false|0|no|n|off) echo "false" ;;
|
||||
*)
|
||||
echo "error: invalid boolean value '${1}'" >&2
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
check_sha256() {
|
||||
local file_path="$1"
|
||||
local expected="$2"
|
||||
local actual
|
||||
|
||||
if command -v sha256sum >/dev/null 2>&1; then
|
||||
actual="$(sha256sum "${file_path}" | awk '{print $1}')"
|
||||
elif command -v shasum >/dev/null 2>&1; then
|
||||
actual="$(shasum -a 256 "${file_path}" | awk '{print $1}')"
|
||||
else
|
||||
echo "error: checksum verification requested but no sha256 tool is available" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
if [[ "${actual}" != "${expected}" ]]; then
|
||||
echo "error: checksum mismatch for ${file_path}" >&2
|
||||
exit 2
|
||||
fi
|
||||
echo "$(basename "${file_path}"): OK"
|
||||
}
|
||||
|
||||
validate_chain_token() {
|
||||
local value="$1"
|
||||
if [[ -z "${value}" ]]; then
|
||||
return 0
|
||||
fi
|
||||
if [[ ! "${value}" =~ ^[A-Za-z0-9._~-]{16,128}$ ]]; then
|
||||
echo "error: EVERY_CHANNEL_NETBOOT_CHAIN_TOKEN must match [A-Za-z0-9._~-]{16,128}" >&2
|
||||
exit 2
|
||||
fi
|
||||
}
|
||||
|
||||
allow_remote_ipxe="$(bool_norm "${allow_remote_ipxe}")"
|
||||
validate_chain_token "${chain_token}"
|
||||
|
||||
tmp_dir="$(mktemp -d)"
|
||||
cleanup() {
|
||||
rm -rf "${tmp_dir}"
|
||||
|
|
@ -34,6 +88,8 @@ trap cleanup EXIT
|
|||
|
||||
archive_path="${tmp_dir}/netboot.tar.gz"
|
||||
release_asset_url=""
|
||||
release_asset_name=""
|
||||
checksum_asset_url=""
|
||||
|
||||
if [[ -n "${local_tarball}" ]]; then
|
||||
if [[ ! -f "${local_tarball}" ]]; then
|
||||
|
|
@ -56,7 +112,7 @@ else
|
|||
release_json="${tmp_dir}/release.json"
|
||||
curl -fsSL "${auth_args[@]}" "${release_endpoint}" -o "${release_json}"
|
||||
|
||||
release_asset_url="$(
|
||||
parsed_assets="$(
|
||||
python3 - "${release_json}" <<'PY'
|
||||
import json
|
||||
import sys
|
||||
|
|
@ -77,9 +133,20 @@ if not candidates:
|
|||
|
||||
# Pick newest by release ordering if API already sorted; otherwise prefer largest id.
|
||||
chosen = sorted(candidates, key=lambda x: x.get("id", 0))[-1]
|
||||
checksum_asset = None
|
||||
for asset in assets:
|
||||
if asset.get("name") == "SHA256SUMS.txt":
|
||||
checksum_asset = asset
|
||||
break
|
||||
|
||||
print(chosen.get("name", ""))
|
||||
print(chosen.get("browser_download_url", ""))
|
||||
print("" if checksum_asset is None else checksum_asset.get("browser_download_url", ""))
|
||||
PY
|
||||
)"
|
||||
release_asset_name="$(printf '%s\n' "${parsed_assets}" | sed -n '1p')"
|
||||
release_asset_url="$(printf '%s\n' "${parsed_assets}" | sed -n '2p')"
|
||||
checksum_asset_url="$(printf '%s\n' "${parsed_assets}" | sed -n '3p')"
|
||||
|
||||
if [[ -z "${release_asset_url}" ]]; then
|
||||
echo "error: unable to find x86_64 netboot asset in release" >&2
|
||||
|
|
@ -87,6 +154,28 @@ PY
|
|||
fi
|
||||
|
||||
curl -fsSL "${auth_args[@]}" -o "${archive_path}" "${release_asset_url}"
|
||||
|
||||
verify_release_checksums_lc="$(printf '%s' "${verify_release_checksums}" | tr '[:upper:]' '[:lower:]')"
|
||||
if [[ "${verify_release_checksums_lc}" != "false" && -n "${checksum_asset_url}" ]]; then
|
||||
checksum_file="${tmp_dir}/SHA256SUMS.txt"
|
||||
curl -fsSL "${auth_args[@]}" -o "${checksum_file}" "${checksum_asset_url}"
|
||||
if command -v sha256sum >/dev/null 2>&1; then
|
||||
(
|
||||
cd "${tmp_dir}"
|
||||
grep -F " ${release_asset_name}" "${checksum_file}" | sha256sum -c -
|
||||
)
|
||||
elif command -v shasum >/dev/null 2>&1; then
|
||||
expected="$(grep -F " ${release_asset_name}" "${checksum_file}" | awk '{print $1}')"
|
||||
actual="$(shasum -a 256 "${archive_path}" | awk '{print $1}')"
|
||||
if [[ -z "${expected}" || "${expected}" != "${actual}" ]]; then
|
||||
echo "error: checksum mismatch for ${release_asset_name}" >&2
|
||||
exit 2
|
||||
fi
|
||||
echo "${release_asset_name}: OK"
|
||||
else
|
||||
echo "warning: no sha256 tool available; skipping checksum verification"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
http_dir="${out_root}/http"
|
||||
|
|
@ -103,23 +192,47 @@ for required in kernel initrd netboot.ipxe; do
|
|||
fi
|
||||
done
|
||||
|
||||
curl -fsSL -o "${tftp_dir}/ipxe.efi" "${ipxe_efi_url}"
|
||||
if [[ -n "${ipxe_efi_path}" ]]; then
|
||||
if [[ ! -f "${ipxe_efi_path}" ]]; then
|
||||
echo "error: iPXE file path not found: ${ipxe_efi_path}" >&2
|
||||
exit 2
|
||||
fi
|
||||
ipxe_dest="${tftp_dir}/${ipxe_efi_filename}"
|
||||
src_resolved="$(realpath -m "${ipxe_efi_path}")"
|
||||
dst_resolved="$(realpath -m "${ipxe_dest}")"
|
||||
# When embedded iPXE already wrote to the destination path, skip self-copy.
|
||||
if [[ "${src_resolved}" != "${dst_resolved}" ]]; then
|
||||
cp -f "${ipxe_efi_path}" "${ipxe_dest}"
|
||||
fi
|
||||
else
|
||||
if [[ "${allow_remote_ipxe}" != "true" ]]; then
|
||||
echo "error: remote iPXE download is disabled by default" >&2
|
||||
echo "hint: build local iPXE with ./scripts/netboot-build-ipxe.sh and set EVERY_CHANNEL_IPXE_EFI_PATH" >&2
|
||||
echo "hint: if you must download from URL, set EVERY_CHANNEL_NETBOOT_ALLOW_REMOTE_IPXE=true" >&2
|
||||
exit 2
|
||||
fi
|
||||
curl -fsSL -o "${tftp_dir}/${ipxe_efi_filename}" "${ipxe_efi_url}"
|
||||
fi
|
||||
if [[ -n "${ipxe_efi_sha256}" ]]; then
|
||||
check_sha256 "${tftp_dir}/${ipxe_efi_filename}" "${ipxe_efi_sha256}"
|
||||
fi
|
||||
cp -f "${http_dir}/netboot.ipxe" "${tftp_dir}/netboot.ipxe"
|
||||
|
||||
cat > "${tftp_dir}/bootstrap.ipxe" <<'EOF'
|
||||
chain_url="http://${netboot_hostname}:${http_port}/netboot.ipxe"
|
||||
if [[ -n "${chain_token}" ]]; then
|
||||
chain_url="${chain_url}?token=${chain_token}"
|
||||
fi
|
||||
|
||||
cat > "${tftp_dir}/bootstrap.ipxe" <<EOF
|
||||
#!ipxe
|
||||
dhcp
|
||||
chain http://__NETBOOT_HOST__:__HTTP_PORT__/netboot.ipxe
|
||||
chain ${chain_url}
|
||||
EOF
|
||||
sed -i.bak \
|
||||
-e "s#__NETBOOT_HOST__#${netboot_hostname}#g" \
|
||||
-e "s#__HTTP_PORT__#${http_port}#g" \
|
||||
"${tftp_dir}/bootstrap.ipxe"
|
||||
rm -f "${tftp_dir}/bootstrap.ipxe.bak"
|
||||
|
||||
echo "ok: staged netboot content"
|
||||
echo "ok: http root: ${http_dir}"
|
||||
echo "ok: tftp root: ${tftp_dir}"
|
||||
echo "ok: boot filename: ${ipxe_efi_filename}"
|
||||
echo "ok: netboot hostname: ${netboot_hostname}"
|
||||
echo "ok: netboot http port: ${http_port}"
|
||||
if [[ -n "${release_asset_url}" ]]; then
|
||||
|
|
@ -127,4 +240,7 @@ if [[ -n "${release_asset_url}" ]]; then
|
|||
else
|
||||
echo "ok: source asset: ${local_tarball}"
|
||||
fi
|
||||
echo "hint: run sudo ./scripts/netboot-serve.sh to expose HTTP+TFTP+ProxyDHCP"
|
||||
if [[ -n "${chain_token}" ]]; then
|
||||
echo "ok: chain token enabled"
|
||||
fi
|
||||
echo "hint: run sudo ./scripts/netboot-serve.sh to expose HTTP+TFTP (+ optional ProxyDHCP)"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue