From a183957d4d8b536bf8fe2bd67b09ccfbbabba7bd Mon Sep 17 00:00:00 2001 From: MauroFab Date: Thu, 11 Jun 2026 15:33:36 -0300 Subject: [PATCH 1/2] fix infra LLVM toolchain for RISC-V asm --- Makefile | 8 ++++++-- README.md | 2 +- infra/README.md | 1 + infra/provision.sh | 33 ++++++++++++++++++++++++++++++--- 4 files changed, 38 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index f29ec030a..fb4782497 100644 --- a/Makefile +++ b/Makefile @@ -56,6 +56,10 @@ SYSROOT_URL := https://lambda.alignedlayer.com/lambda-vm-sysroot-rv64im.tar.gz # $(abspath ...) because the build rule cd's into the program dir before invoking cargo. SYSROOT_CFLAGS := --target=riscv64 -march=rv64im -mabi=lp64 --sysroot=$(abspath $(SYSROOT_DIR)) +CLANG ?= clang +ASM_CFLAGS ?= --target=riscv64 -march=rv64im -mabi=lp64 +ASM_LDFLAGS ?= -fuse-ld=lld -nostdlib -Wl,-e,main + # Custom RV64IM target spec location RV64_TARGET_SPEC=$(CURDIR)/executor/programs/riscv64im-lambda-vm-elf.json @@ -94,8 +98,8 @@ prepare-sysroot: compile-programs-asm: @mkdir -p $(ASM_ARTIFACTS_DIR) @set -e; for src in $(ASM_PROGRAMS); do \ - echo "clang --target=riscv64 -fuse-ld=lld -nostdlib -Wl,-e,main $$src -o $(ASM_ARTIFACTS_DIR)/$$(basename $$src .s).elf"; \ - clang --target=riscv64 -fuse-ld=lld -nostdlib -Wl,-e,main $$src -o $(ASM_ARTIFACTS_DIR)/$$(basename $$src .s).elf; \ + echo "$(CLANG) $(ASM_CFLAGS) $(ASM_LDFLAGS) $$src -o $(ASM_ARTIFACTS_DIR)/$$(basename $$src .s).elf"; \ + $(CLANG) $(ASM_CFLAGS) $(ASM_LDFLAGS) $$src -o $(ASM_ARTIFACTS_DIR)/$$(basename $$src .s).elf; \ done compile-programs-rust: prepare-sysroot $(RUST_ARTIFACTS) diff --git a/README.md b/README.md index f63d3b3ec..2e96d7fc0 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ The **[public roadmap](https://yetanotherco.github.io/lambda_vm_roadmap/)** lays - Rust nightly with `rust-src` component - Clang with RISC-V target support and LLD linker (used by `make compile-programs-asm`) - **macOS**: `brew install llvm` (the Homebrew LLVM includes `clang` and `lld` with RISC-V support) - - **Linux**: `apt install clang lld` (or equivalent for your distribution) + - **Linux**: use LLVM 21+ from apt.llvm.org or your distribution; older distro clang packages may reject the assembly fixtures' RISC-V ISA attributes ### Dev dependencies diff --git a/infra/README.md b/infra/README.md index 7d12dace0..93ef13702 100644 --- a/infra/README.md +++ b/infra/README.md @@ -88,6 +88,7 @@ Everything has a working default; override via env var only when needed. | `READY_TIMEOUT` | `1800` (s) | `rent_baremetal.sh` | How long to wait for `status=ready && install.status=completed`. | | `PROVISION_FILE` | `/provision.sh` | both wrappers | Path to the remote provisioning script. | | `SSH_USER` | `root` | `provision_server.sh` | Switch to `admin` for re-runs after sshd hardening. | +| `LLVM_VERSION` | `21` | `provision.sh` | LLVM major installed from apt.llvm.org for RISC-V assembly builds. | ### `SCW_TYPE` options diff --git a/infra/provision.sh b/infra/provision.sh index 405fd38d3..1896d2526 100755 --- a/infra/provision.sh +++ b/infra/provision.sh @@ -13,6 +13,7 @@ log() { printf '\n=== %s ===\n' "$*"; } log "apt update + upgrade" export DEBIAN_FRONTEND=noninteractive APT_OPTS=(-y -o Dpkg::Options::=--force-confdef -o Dpkg::Options::=--force-confold) +LLVM_VERSION="${LLVM_VERSION:-21}" # Scaleway baremetal Debian ships grub-cloud-amd64; its postinst (fired as a # trigger by initramfs-tools / shim-signed / kernel upgrades) runs grub-install @@ -24,11 +25,37 @@ apt-get update -y apt-get upgrade "${APT_OPTS[@]}" # --- 2. apt packages --------------------------------------------------------- -log "apt install base packages + clang/lld/llvm + xz-utils" +log "apt install base packages + xz-utils" apt-get install "${APT_OPTS[@]}" \ ca-certificates curl wget gnupg vim git zip unzip openssl libssl-dev jq \ - build-essential rsyslog htop rsync pkg-config locales ufw \ - clang lld llvm xz-utils + build-essential rsyslog htop rsync pkg-config locales ufw xz-utils + +# Debian's default clang can lag behind RISC-V ISA attribute syntax emitted by +# the checked-in assembly fixtures. Use a pinned apt.llvm.org toolchain. +log "LLVM $LLVM_VERSION toolchain from apt.llvm.org" +. /etc/os-release +LLVM_CODENAME="${VERSION_CODENAME:-}" +if [ -z "$LLVM_CODENAME" ]; then + echo "ERROR: could not determine Debian/Ubuntu codename from /etc/os-release" >&2 + exit 1 +fi +install -d -m 0755 /etc/apt/keyrings +wget -qO /etc/apt/keyrings/apt.llvm.org.asc https://apt.llvm.org/llvm-snapshot.gpg.key +chmod 0644 /etc/apt/keyrings/apt.llvm.org.asc +cat > /etc/apt/sources.list.d/apt.llvm.org.list <&2 + exit 1 + fi + ln -sf "$versioned" "/usr/local/bin/$tool" +done +clang --version | head -n 1 # --- 3. users: admin (sudo) + app (no sudo) ---------------------------------- log "users: admin (sudo) + app (no sudo)" From f6a26f49550b9ba9a742476a9bbe1b4471b95250 Mon Sep 17 00:00:00 2001 From: MauroFab Date: Thu, 11 Jun 2026 15:41:31 -0300 Subject: [PATCH 2/2] address provisioning review feedback --- infra/README.md | 2 +- infra/provision.sh | 10 ++++++++++ infra/provision_server.sh | 12 ++++++++++-- infra/rent_baremetal.sh | 4 +++- 4 files changed, 24 insertions(+), 4 deletions(-) diff --git a/infra/README.md b/infra/README.md index 93ef13702..96fcb98f4 100644 --- a/infra/README.md +++ b/infra/README.md @@ -88,7 +88,7 @@ Everything has a working default; override via env var only when needed. | `READY_TIMEOUT` | `1800` (s) | `rent_baremetal.sh` | How long to wait for `status=ready && install.status=completed`. | | `PROVISION_FILE` | `/provision.sh` | both wrappers | Path to the remote provisioning script. | | `SSH_USER` | `root` | `provision_server.sh` | Switch to `admin` for re-runs after sshd hardening. | -| `LLVM_VERSION` | `21` | `provision.sh` | LLVM major installed from apt.llvm.org for RISC-V assembly builds. | +| `LLVM_VERSION` | `21` | provisioning scripts | LLVM major installed from apt.llvm.org for RISC-V assembly builds. | ### `SCW_TYPE` options diff --git a/infra/provision.sh b/infra/provision.sh index 1896d2526..158c11d35 100755 --- a/infra/provision.sh +++ b/infra/provision.sh @@ -14,6 +14,7 @@ log "apt update + upgrade" export DEBIAN_FRONTEND=noninteractive APT_OPTS=(-y -o Dpkg::Options::=--force-confdef -o Dpkg::Options::=--force-confold) LLVM_VERSION="${LLVM_VERSION:-21}" +LLVM_GPG_FINGERPRINT="6084F3CF814B57C1CF12EFD515CF4D18AF4F7421" # Scaleway baremetal Debian ships grub-cloud-amd64; its postinst (fired as a # trigger by initramfs-tools / shim-signed / kernel upgrades) runs grub-install @@ -41,6 +42,15 @@ if [ -z "$LLVM_CODENAME" ]; then fi install -d -m 0755 /etc/apt/keyrings wget -qO /etc/apt/keyrings/apt.llvm.org.asc https://apt.llvm.org/llvm-snapshot.gpg.key +if ! LLVM_ACTUAL_FINGERPRINT="$(gpg --show-keys --with-colons /etc/apt/keyrings/apt.llvm.org.asc 2>/dev/null \ + | awk -F: '/^fpr:/ { print $10; exit }')"; then + echo "ERROR: could not read apt.llvm.org GPG key fingerprint" >&2 + exit 1 +fi +if [ "$LLVM_ACTUAL_FINGERPRINT" != "$LLVM_GPG_FINGERPRINT" ]; then + echo "ERROR: apt.llvm.org GPG key fingerprint mismatch (got $LLVM_ACTUAL_FINGERPRINT, expected $LLVM_GPG_FINGERPRINT)" >&2 + exit 1 +fi chmod 0644 /etc/apt/keyrings/apt.llvm.org.asc cat > /etc/apt/sources.list.d/apt.llvm.org.list </provision.sh +# LLVM_VERSION default: 21 # # SSH wait is indefinite — Ctrl+C to abort. @@ -25,6 +26,7 @@ NC='\033[0m' SSH_USER="${SSH_USER:-root}" PROVISION_FILE="${PROVISION_FILE:-$SCRIPT_DIR/provision.sh}" +LLVM_VERSION="${LLVM_VERSION:-21}" err() { echo -e "${RED}error:${NC} $*" >&2; } info() { echo -e "${BOLD}$*${NC}"; } @@ -45,6 +47,12 @@ if ! command -v ssh >/dev/null 2>&1; then err "ssh not found on PATH." exit 1 fi +case "$LLVM_VERSION" in + ''|*[!0-9]*) + err "LLVM_VERSION must be a numeric LLVM major version, got '$LLVM_VERSION'" + exit 2 + ;; +esac SSH_OPTS=(-o StrictHostKeyChecking=accept-new -o ConnectTimeout=10 -o BatchMode=yes) @@ -60,9 +68,9 @@ done ok "sshd reachable on $SSH_USER@$IP (attempt $attempt)" if [ "$SSH_USER" = "root" ]; then - REMOTE_CMD="bash -s" + REMOTE_CMD="env LLVM_VERSION=$LLVM_VERSION bash -s" else - REMOTE_CMD="sudo bash -s" + REMOTE_CMD="sudo env LLVM_VERSION=$LLVM_VERSION bash -s" fi info "Running $PROVISION_FILE on $SSH_USER@$IP..." diff --git a/infra/rent_baremetal.sh b/infra/rent_baremetal.sh index fb7e46bcb..ce41877b7 100755 --- a/infra/rent_baremetal.sh +++ b/infra/rent_baremetal.sh @@ -8,6 +8,7 @@ # SCW_TYPE default: EM-I320E-NVME # PROVISION_FILE default: /infra/provision.sh # READY_TIMEOUT default: 1800 (seconds) +# LLVM_VERSION default: 21 # # Requires: scw, jq, ssh. # To delete the server when done: scw baremetal server delete zone= @@ -28,6 +29,7 @@ SCW_OS_ID="${SCW_OS_ID:-83640d93-a0b8-45ad-9c9f-30cae48380a4}" # Debian SCW_PROJECT_ID="${SCW_PROJECT_ID:-946cfb34-d351-48c4-8566-127e7727e15f}" PROVISION_FILE="${PROVISION_FILE:-$SCRIPT_DIR/provision.sh}" READY_TIMEOUT="${READY_TIMEOUT:-1800}" +LLVM_VERSION="${LLVM_VERSION:-21}" err() { echo -e "${RED}error:${NC} $*" >&2; } info() { echo -e "${BOLD}$*${NC}"; } @@ -180,7 +182,7 @@ info "Wiping any stale known_hosts entry for $PUBLIC_IP (Scaleway recycles IPs). ssh-keygen -R "$PUBLIC_IP" >/dev/null 2>&1 || true info "Handing off to provision_server.sh (Ctrl+C to skip and provision later)..." -PROVISION_FILE="$PROVISION_FILE" SSH_USER=root "$SCRIPT_DIR/provision_server.sh" "$PUBLIC_IP" +PROVISION_FILE="$PROVISION_FILE" SSH_USER=root LLVM_VERSION="$LLVM_VERSION" "$SCRIPT_DIR/provision_server.sh" "$PUBLIC_IP" echo echo "To delete the server:"