diff --git a/roles/custom/matrix-bridge-rustpush/defaults/main.yml b/roles/custom/matrix-bridge-rustpush/defaults/main.yml index ebc292793..8d6a31952 100644 --- a/roles/custom/matrix-bridge-rustpush/defaults/main.yml +++ b/roles/custom/matrix-bridge-rustpush/defaults/main.yml @@ -4,17 +4,17 @@ --- # matrix-bridge-rustpush is a Matrix <-> iMessage bridge using RustPush -# Project source code URL: https://github.com/lrhodin/imessage +# Project source code URL: https://github.com/jasonlaguidice/imessage matrix_rustpush_bridge_enabled: true # No upstream Docker image exists; self-build is always required. matrix_rustpush_bridge_container_image_self_build: true -matrix_rustpush_bridge_container_image_self_build_repo: "https://github.com/lrhodin/imessage.git" -matrix_rustpush_bridge_container_image_self_build_repo_version: "{{ 'main' if matrix_rustpush_bridge_version == 'latest' else matrix_rustpush_bridge_version }}" +matrix_rustpush_bridge_container_image_self_build_repo: "https://github.com/jasonlaguidice/imessage.git" +matrix_rustpush_bridge_container_image_self_build_repo_version: "{{ 'master' if matrix_rustpush_bridge_version == 'latest' else matrix_rustpush_bridge_version }}" matrix_rustpush_bridge_version: latest -matrix_rustpush_bridge_docker_image: "{{ matrix_rustpush_bridge_docker_image_registry_prefix }}lrhodin/imessage:{{ matrix_rustpush_bridge_version }}" +matrix_rustpush_bridge_docker_image: "{{ matrix_rustpush_bridge_docker_image_registry_prefix }}jasonlaguidice/imessage:{{ matrix_rustpush_bridge_version }}" matrix_rustpush_bridge_docker_image_registry_prefix: "localhost/" matrix_rustpush_bridge_docker_image_force_pull: "{{ matrix_rustpush_bridge_docker_image.endswith(':latest') }}" diff --git a/roles/custom/matrix-bridge-rustpush/templates/Dockerfile.j2 b/roles/custom/matrix-bridge-rustpush/templates/Dockerfile.j2 index 58baef06b..a46a432fc 100644 --- a/roles/custom/matrix-bridge-rustpush/templates/Dockerfile.j2 +++ b/roles/custom/matrix-bridge-rustpush/templates/Dockerfile.j2 @@ -4,42 +4,105 @@ SPDX-FileCopyrightText: 2025 MDAD project contributors SPDX-License-Identifier: AGPL-3.0-or-later #} -# Multi-stage build for mautrix-imessage with RustPush support -# Stage 1: Rust + Go builder -FROM docker.io/golang:1.24-bookworm AS builder +# ── Stage 1: builder ───────────────────────────────────────────────────────── +FROM ubuntu:24.04 AS builder -# Install Rust toolchain -RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y -ENV PATH="/root/.cargo/bin:${PATH}" +ENV DEBIAN_FRONTEND=noninteractive -# Install build dependencies RUN apt-get update && apt-get install -y --no-install-recommends \ - build-essential \ - clang \ - libclang-dev \ - protobuf-compiler \ - git \ - ca-certificates \ + cmake protobuf-compiler build-essential pkg-config \ + git curl ca-certificates \ + libolm-dev libclang-dev libssl-dev libunicorn-dev libheif-dev zlib1g-dev \ && rm -rf /var/lib/apt/lists/* +# Rust — install to default ~/.cargo so the Makefile's $(HOME)/.cargo/bin path resolves +RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs \ + | sh -s -- -y --default-toolchain stable +ENV PATH=/root/.cargo/bin:$PATH + +# Go — arch-aware, fetches latest stable with fallback +ARG TARGETARCH +RUN set -e; \ + GOARCH="${TARGETARCH:-amd64}"; \ + GO_VERSION=$(curl -fsSL 'https://go.dev/dl/?mode=json' \ + | grep -o '"version":"go[0-9.]*"' | head -1 \ + | sed 's/"version":"//;s/"//'); \ + : "${GO_VERSION:=go1.25.0}"; \ + curl -fsSL "https://go.dev/dl/${GO_VERSION}.linux-${GOARCH}.tar.gz" \ + | tar -C /usr/local -xz +ENV PATH=/usr/local/go/bin:$PATH \ + GOTOOLCHAIN=local + WORKDIR /build -# Copy the source code -COPY . /build/ +# ── Rust build layers ───────────────────────────────────────────────────────── +# Copy files that determine whether the clone+patch layer is valid. +# Changing the SHA pin, Makefile, or open-absinthe overlay invalidates this layer. +COPY third_party/rustpush-upstream.sha third_party/ +COPY rustpush/ rustpush/ +COPY Makefile . + +# Clone upstream rustpush at the pinned SHA, apply all patches, overlay open-absinthe. +RUN make ensure-rustpush-source + +# Copy Rust crate sources. Changing these invalidates only the Rust build layer, +# not the clone layer above. +COPY pkg/rustpushgo/ pkg/rustpushgo/ +COPY nac-validation/ nac-validation/ + +# Build the Rust static library (~3 min; cached when Rust source is unchanged). +# hardware-key enables the unicorn-based x86 NAC emulator required on Linux +# (both amd64 and arm64 — unicorn supports cross-arch x86 emulation). +RUN cd pkg/rustpushgo && \ + cargo build --release --features hardware-key && \ + cp target/release/librustpushgo.a /build/librustpushgo.a + +# ── Go build layers ─────────────────────────────────────────────────────────── +# Download modules first so this layer is cached by go.mod/go.sum. +COPY go.mod go.sum ./ +RUN go mod download + +# Copy Go source. +COPY cmd/ cmd/ +COPY pkg/connector/ pkg/connector/ +COPY imessage/ imessage/ +COPY ipc/ ipc/ + +# Build the bridge binary. +ARG BUILD_VERSION=dev +ARG BUILD_COMMIT=unknown +RUN BUILD_TIME=$(date -u +%Y-%m-%dT%H:%M:%SZ) && \ + CGO_LDFLAGS="-L/build" \ + go build \ + -ldflags "-X main.Tag=${BUILD_VERSION} -X main.Commit=${BUILD_COMMIT} -X main.BuildTime=${BUILD_TIME}" \ + -o /build/mautrix-imessage-v2 \ + ./cmd/mautrix-imessage/ -# Build the Go binary with CGO enabled (required for Rust FFI) -RUN cd /build && make build +# ── Stage 2: runtime ───────────────────────────────────────────────────────── +FROM ubuntu:24.04 -# Stage 2: Runtime -FROM docker.io/debian:bookworm-slim +ENV DEBIAN_FRONTEND=noninteractive +# Runtime shared libraries the bridge binary needs at startup. +# libunicorn2 — unicorn-engine x86 NAC emulator (hardware-key feature) +# libheif1 — HEIC/HEIF conversion (linked at compile time even when disabled) +# libolm3 — Matrix OLM encryption (mautrix bridgev2 framework) +# libssl3 — OpenSSL (rustpush openssl crate dynamic link) RUN apt-get update && apt-get install -y --no-install-recommends \ - ca-certificates \ + libunicorn2 libheif1 libolm3 libssl3 \ + ca-certificates openssl curl \ + && curl -fsSL 'https://www.apple.com/appleca/AppleIncRootCertificate.cer' \ + -o /tmp/AppleRootCA.cer \ + && openssl x509 -inform DER -in /tmp/AppleRootCA.cer \ + -out /usr/local/share/ca-certificates/AppleRootCA.crt \ + && update-ca-certificates \ + && rm /tmp/AppleRootCA.cer \ && rm -rf /var/lib/apt/lists/* -COPY --from=builder /build/mautrix-imessage-v2 /usr/bin/mautrix-imessage-v2 +COPY --from=builder /build/mautrix-imessage-v2 /usr/local/bin/mautrix-imessage-v2 +WORKDIR /data VOLUME /data -VOLUME /config +EXPOSE 29332 -CMD ["/usr/bin/mautrix-imessage-v2", "-c", "/config/config.yaml", "-r", "/config/registration.yaml", "--no-update"] +ENTRYPOINT ["mautrix-imessage-v2", "-c", "/data/config.yaml"] diff --git a/roles/custom/matrix-bridge-rustpush/templates/systemd/matrix-rustpush-bridge.service.j2 b/roles/custom/matrix-bridge-rustpush/templates/systemd/matrix-rustpush-bridge.service.j2 index 3a38291ec..f72f05066 100644 --- a/roles/custom/matrix-bridge-rustpush/templates/systemd/matrix-rustpush-bridge.service.j2 +++ b/roles/custom/matrix-bridge-rustpush/templates/systemd/matrix-rustpush-bridge.service.j2 @@ -26,11 +26,12 @@ ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \ --mount type=bind,src={{ matrix_rustpush_bridge_config_path }},dst=/config,ro \ --mount type=bind,src={{ matrix_rustpush_bridge_data_path }},dst=/data \ --label-file={{ matrix_rustpush_bridge_base_path }}/labels \ + --entrypoint /usr/local/bin/mautrix-imessage-v2 \ {% for arg in matrix_rustpush_bridge_container_extra_arguments %} {{ arg }} \ {% endfor %} {{ matrix_rustpush_bridge_docker_image }} \ - /usr/bin/mautrix-imessage-v2 -c /config/config.yaml -r /config/registration.yaml --no-update + -c /config/config.yaml -r /config/registration.yaml {% for network in matrix_rustpush_bridge_container_additional_networks %} ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-rustpush-bridge