Compare commits
2 Commits
16f1c2f079
...
a057ad5db5
| Author | SHA1 | Date | |
|---|---|---|---|
| a057ad5db5 | |||
| 8e273ec683 |
@@ -34,6 +34,7 @@ env:
|
|||||||
REGISTRY_NAMESPACE: ${{ vars.CONTAINER_REGISTRY_NAMESPACE }}
|
REGISTRY_NAMESPACE: ${{ vars.CONTAINER_REGISTRY_NAMESPACE }}
|
||||||
REGISTRY_PLAIN_HTTP: ${{ vars.CONTAINER_REGISTRY_INSECURE }}
|
REGISTRY_PLAIN_HTTP: ${{ vars.CONTAINER_REGISTRY_INSECURE }}
|
||||||
ARTIFACT_REPOSITORY: attune-build-artifacts
|
ARTIFACT_REPOSITORY: attune-build-artifacts
|
||||||
|
GNU_GLIBC_VERSION: "2.28"
|
||||||
CARGO_TERM_COLOR: always
|
CARGO_TERM_COLOR: always
|
||||||
CARGO_INCREMENTAL: 0
|
CARGO_INCREMENTAL: 0
|
||||||
CARGO_NET_RETRY: 10
|
CARGO_NET_RETRY: 10
|
||||||
@@ -133,9 +134,13 @@ jobs:
|
|||||||
include:
|
include:
|
||||||
- arch: amd64
|
- arch: amd64
|
||||||
runner_label: build-amd64
|
runner_label: build-amd64
|
||||||
|
service_rust_target: x86_64-unknown-linux-gnu
|
||||||
|
service_target: x86_64-unknown-linux-gnu.2.28
|
||||||
musl_target: x86_64-unknown-linux-musl
|
musl_target: x86_64-unknown-linux-musl
|
||||||
- arch: arm64
|
- arch: arm64
|
||||||
runner_label: build-arm64
|
runner_label: build-amd64
|
||||||
|
service_rust_target: aarch64-unknown-linux-gnu
|
||||||
|
service_target: aarch64-unknown-linux-gnu.2.28
|
||||||
musl_target: aarch64-unknown-linux-musl
|
musl_target: aarch64-unknown-linux-musl
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
@@ -156,7 +161,9 @@ jobs:
|
|||||||
- name: Setup Rust
|
- name: Setup Rust
|
||||||
uses: dtolnay/rust-toolchain@stable
|
uses: dtolnay/rust-toolchain@stable
|
||||||
with:
|
with:
|
||||||
targets: ${{ matrix.musl_target }}
|
targets: |
|
||||||
|
${{ matrix.service_rust_target }}
|
||||||
|
${{ matrix.musl_target }}
|
||||||
|
|
||||||
- name: Cache Cargo registry + index
|
- name: Cache Cargo registry + index
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@v4
|
||||||
@@ -184,22 +191,69 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
apt-get update
|
apt-get update
|
||||||
apt-get install -y pkg-config libssl-dev musl-tools file
|
apt-get install -y pkg-config libssl-dev file binutils python3 python3-pip
|
||||||
|
|
||||||
|
- name: Install Zig
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
pip3 install --break-system-packages --no-cache-dir ziglang
|
||||||
|
|
||||||
|
- name: Install cargo-zigbuild
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
if ! command -v cargo-zigbuild >/dev/null 2>&1; then
|
||||||
|
cargo install --locked cargo-zigbuild
|
||||||
|
fi
|
||||||
|
|
||||||
- name: Build release binaries
|
- name: Build release binaries
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
cargo build --release \
|
cargo zigbuild --release \
|
||||||
|
--target "${{ matrix.service_target }}" \
|
||||||
--bin attune-api \
|
--bin attune-api \
|
||||||
--bin attune-executor \
|
--bin attune-executor \
|
||||||
--bin attune-notifier
|
--bin attune-notifier
|
||||||
|
|
||||||
|
- name: Verify minimum glibc requirement
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
output_dir="target/${{ matrix.service_rust_target }}/release"
|
||||||
|
|
||||||
|
get_min_glibc() {
|
||||||
|
local file_path="$1"
|
||||||
|
readelf -W --version-info --dyn-syms "$file_path" \
|
||||||
|
| grep 'Name: GLIBC_' \
|
||||||
|
| sed -E 's/.*GLIBC_(.+) Flags.*/\1/' \
|
||||||
|
| sort -t . -k1,1n -k2,2n \
|
||||||
|
| tail -n 1
|
||||||
|
}
|
||||||
|
|
||||||
|
version_gt() {
|
||||||
|
[ "$(printf '%s\n%s\n' "$1" "$2" | sort -V | tail -n 1)" = "$1" ] && [ "$1" != "$2" ]
|
||||||
|
}
|
||||||
|
|
||||||
|
for binary in attune-api attune-executor attune-notifier; do
|
||||||
|
min_glibc="$(get_min_glibc "${output_dir}/${binary}")"
|
||||||
|
if [ -z "${min_glibc}" ]; then
|
||||||
|
echo "Failed to determine glibc requirement for ${binary}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "${binary} requires glibc ${min_glibc}"
|
||||||
|
if version_gt "${min_glibc}" "${GNU_GLIBC_VERSION}"; then
|
||||||
|
echo "Expected ${binary} to require glibc <= ${GNU_GLIBC_VERSION}, got ${min_glibc}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
- name: Build static agent binaries
|
- name: Build static agent binaries
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
cargo build --release \
|
cargo zigbuild --release \
|
||||||
--target "${{ matrix.musl_target }}" \
|
--target "${{ matrix.musl_target }}" \
|
||||||
--bin attune-agent \
|
--bin attune-agent \
|
||||||
--bin attune-sensor-agent
|
--bin attune-sensor-agent
|
||||||
@@ -210,11 +264,12 @@ jobs:
|
|||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
bundle_root="dist/bundle/${{ matrix.arch }}"
|
bundle_root="dist/bundle/${{ matrix.arch }}"
|
||||||
|
service_output_dir="target/${{ matrix.service_rust_target }}/release"
|
||||||
mkdir -p "$bundle_root/bin" "$bundle_root/agent"
|
mkdir -p "$bundle_root/bin" "$bundle_root/agent"
|
||||||
|
|
||||||
cp target/release/attune-api "$bundle_root/bin/"
|
cp "${service_output_dir}/attune-api" "$bundle_root/bin/"
|
||||||
cp target/release/attune-executor "$bundle_root/bin/"
|
cp "${service_output_dir}/attune-executor" "$bundle_root/bin/"
|
||||||
cp target/release/attune-notifier "$bundle_root/bin/"
|
cp "${service_output_dir}/attune-notifier" "$bundle_root/bin/"
|
||||||
cp target/${{ matrix.musl_target }}/release/attune-agent "$bundle_root/agent/"
|
cp target/${{ matrix.musl_target }}/release/attune-agent "$bundle_root/agent/"
|
||||||
cp target/${{ matrix.musl_target }}/release/attune-sensor-agent "$bundle_root/agent/"
|
cp target/${{ matrix.musl_target }}/release/attune-sensor-agent "$bundle_root/agent/"
|
||||||
|
|
||||||
@@ -263,16 +318,19 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
push_args=()
|
push_args=()
|
||||||
|
artifact_file="attune-binaries-${{ matrix.arch }}.tar.gz"
|
||||||
|
|
||||||
if [ "${{ needs.metadata.outputs.registry_plain_http }}" = "true" ]; then
|
if [ "${{ needs.metadata.outputs.registry_plain_http }}" = "true" ]; then
|
||||||
push_args+=(--plain-http)
|
push_args+=(--plain-http)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
cp "dist/${artifact_file}" "${artifact_file}"
|
||||||
|
|
||||||
oras push \
|
oras push \
|
||||||
"${push_args[@]}" \
|
"${push_args[@]}" \
|
||||||
"${{ needs.metadata.outputs.artifact_ref_base }}:rust-binaries-${{ needs.metadata.outputs.image_tag }}-${{ matrix.arch }}" \
|
"${{ needs.metadata.outputs.artifact_ref_base }}:rust-binaries-${{ needs.metadata.outputs.image_tag }}-${{ matrix.arch }}" \
|
||||||
--artifact-type application/vnd.attune.rust-binaries.v1 \
|
--artifact-type application/vnd.attune.rust-binaries.v1 \
|
||||||
"dist/attune-binaries-${{ matrix.arch }}.tar.gz:application/vnd.attune.rust-binaries.layer.v1.tar+gzip"
|
"${artifact_file}:application/vnd.attune.rust-binaries.layer.v1.tar+gzip"
|
||||||
|
|
||||||
publish-rust-images:
|
publish-rust-images:
|
||||||
name: Publish ${{ matrix.image.name }} (${{ matrix.arch }})
|
name: Publish ${{ matrix.image.name }} (${{ matrix.arch }})
|
||||||
|
|||||||
20
Makefile
20
Makefile
@@ -238,22 +238,24 @@ docker-build-web:
|
|||||||
docker compose build web
|
docker compose build web
|
||||||
|
|
||||||
# Agent binary (statically-linked for injection into any container)
|
# Agent binary (statically-linked for injection into any container)
|
||||||
|
AGENT_RUST_TARGET ?= x86_64-unknown-linux-musl
|
||||||
|
|
||||||
build-agent:
|
build-agent:
|
||||||
@echo "Installing musl target (if not already installed)..."
|
@echo "Installing musl target (if not already installed)..."
|
||||||
rustup target add x86_64-unknown-linux-musl 2>/dev/null || true
|
rustup target add $(AGENT_RUST_TARGET) 2>/dev/null || true
|
||||||
@echo "Building statically-linked worker and sensor agent binaries..."
|
@echo "Building statically-linked worker and sensor agent binaries..."
|
||||||
SQLX_OFFLINE=true cargo build --release --target x86_64-unknown-linux-musl --bin attune-agent --bin attune-sensor-agent
|
SQLX_OFFLINE=true cargo build --release --target $(AGENT_RUST_TARGET) --bin attune-agent --bin attune-sensor-agent
|
||||||
strip target/x86_64-unknown-linux-musl/release/attune-agent
|
strip target/$(AGENT_RUST_TARGET)/release/attune-agent
|
||||||
strip target/x86_64-unknown-linux-musl/release/attune-sensor-agent
|
strip target/$(AGENT_RUST_TARGET)/release/attune-sensor-agent
|
||||||
@echo "✅ Agent binaries built:"
|
@echo "✅ Agent binaries built:"
|
||||||
@echo " - target/x86_64-unknown-linux-musl/release/attune-agent"
|
@echo " - target/$(AGENT_RUST_TARGET)/release/attune-agent"
|
||||||
@echo " - target/x86_64-unknown-linux-musl/release/attune-sensor-agent"
|
@echo " - target/$(AGENT_RUST_TARGET)/release/attune-sensor-agent"
|
||||||
@ls -lh target/x86_64-unknown-linux-musl/release/attune-agent
|
@ls -lh target/$(AGENT_RUST_TARGET)/release/attune-agent
|
||||||
@ls -lh target/x86_64-unknown-linux-musl/release/attune-sensor-agent
|
@ls -lh target/$(AGENT_RUST_TARGET)/release/attune-sensor-agent
|
||||||
|
|
||||||
docker-build-agent:
|
docker-build-agent:
|
||||||
@echo "Building agent Docker image (statically-linked binary)..."
|
@echo "Building agent Docker image (statically-linked binary)..."
|
||||||
DOCKER_BUILDKIT=1 docker buildx build --target agent-init -f docker/Dockerfile.agent -t attune-agent:latest .
|
DOCKER_BUILDKIT=1 docker buildx build --build-arg RUST_TARGET=$(AGENT_RUST_TARGET) --target agent-init -f docker/Dockerfile.agent -t attune-agent:latest .
|
||||||
@echo "✅ Agent image built: attune-agent:latest"
|
@echo "✅ Agent image built: attune-agent:latest"
|
||||||
|
|
||||||
run-agent:
|
run-agent:
|
||||||
|
|||||||
@@ -237,7 +237,7 @@ impl Update for RuntimeRepository {
|
|||||||
|
|
||||||
query.push(", updated = NOW() WHERE id = ");
|
query.push(", updated = NOW() WHERE id = ");
|
||||||
query.push_bind(id);
|
query.push_bind(id);
|
||||||
query.push(&format!(" RETURNING {}", SELECT_COLUMNS));
|
query.push(format!(" RETURNING {}", SELECT_COLUMNS));
|
||||||
|
|
||||||
let runtime = query
|
let runtime = query
|
||||||
.build_query_as::<Runtime>()
|
.build_query_as::<Runtime>()
|
||||||
|
|||||||
@@ -28,12 +28,15 @@
|
|||||||
|
|
||||||
ARG RUST_VERSION=1.92
|
ARG RUST_VERSION=1.92
|
||||||
ARG DEBIAN_VERSION=bookworm
|
ARG DEBIAN_VERSION=bookworm
|
||||||
|
ARG RUST_TARGET=x86_64-unknown-linux-musl
|
||||||
|
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
# Stage 1: Builder - Cross-compile a statically-linked binary with musl
|
# Stage 1: Builder - Cross-compile a statically-linked binary with musl
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
FROM rust:${RUST_VERSION}-${DEBIAN_VERSION} AS builder
|
FROM rust:${RUST_VERSION}-${DEBIAN_VERSION} AS builder
|
||||||
|
|
||||||
|
ARG RUST_TARGET
|
||||||
|
|
||||||
# Install musl toolchain for static linking
|
# Install musl toolchain for static linking
|
||||||
RUN apt-get update && apt-get install -y \
|
RUN apt-get update && apt-get install -y \
|
||||||
musl-tools \
|
musl-tools \
|
||||||
@@ -42,8 +45,8 @@ RUN apt-get update && apt-get install -y \
|
|||||||
ca-certificates \
|
ca-certificates \
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
# Add the musl target for fully static binaries
|
# Add the requested musl target for fully static binaries
|
||||||
RUN rustup target add x86_64-unknown-linux-musl
|
RUN rustup target add ${RUST_TARGET}
|
||||||
|
|
||||||
WORKDIR /build
|
WORKDIR /build
|
||||||
|
|
||||||
@@ -104,9 +107,9 @@ COPY crates/ ./crates/
|
|||||||
RUN --mount=type=cache,target=/usr/local/cargo/registry,sharing=shared \
|
RUN --mount=type=cache,target=/usr/local/cargo/registry,sharing=shared \
|
||||||
--mount=type=cache,target=/usr/local/cargo/git,sharing=shared \
|
--mount=type=cache,target=/usr/local/cargo/git,sharing=shared \
|
||||||
--mount=type=cache,id=agent-target,target=/build/target,sharing=locked \
|
--mount=type=cache,id=agent-target,target=/build/target,sharing=locked \
|
||||||
cargo build --release --target x86_64-unknown-linux-musl --bin attune-agent --bin attune-sensor-agent && \
|
cargo build --release --target ${RUST_TARGET} --bin attune-agent --bin attune-sensor-agent && \
|
||||||
cp /build/target/x86_64-unknown-linux-musl/release/attune-agent /build/attune-agent && \
|
cp /build/target/${RUST_TARGET}/release/attune-agent /build/attune-agent && \
|
||||||
cp /build/target/x86_64-unknown-linux-musl/release/attune-sensor-agent /build/attune-sensor-agent
|
cp /build/target/${RUST_TARGET}/release/attune-sensor-agent /build/attune-sensor-agent
|
||||||
|
|
||||||
# Strip the binaries to minimize size
|
# Strip the binaries to minimize size
|
||||||
RUN strip /build/attune-agent && strip /build/attune-sensor-agent
|
RUN strip /build/attune-agent && strip /build/attune-sensor-agent
|
||||||
|
|||||||
Reference in New Issue
Block a user