# Runlayer AI Watch scanner — container image (Detect only).
#
# Multi-stage: a manylinux_2_28 build stage produces the PyInstaller `aiwatch`
# onedir bundle with a glibc 2.28 floor (same approach as the .deb/.rpm build);
# a debian:12-slim runtime stage (glibc 2.36 ≥ 2.28) runs it. The entrypoint
# scan-host-users.sh fans out one privilege-dropped scan per bind-mounted host
# home (see that script's header).
#
# BUILD CONTEXT: the monorepo ROOT. `cli/` has an editable path dependency on
# the sibling `packages/python` (runlayer-hooks-sdk, `../packages/python` in
# cli/pyproject.toml), so both trees must be in the context. Build with:
#
#     docker build -f cli/packaging/container/Dockerfile -t runlayer-aiwatch .
#
# (All COPY paths below are relative to the repo root.) The manylinux build stage is
# amd64-only; the full image build is exercised in CI/release (chunk 4). The
# entrypoint logic is validated independently by the stub smoke test in
# packaging/container/tests/ (no manylinux/PyInstaller build required).
#
# RUN (standalone) — scan every host user's home, looping every 15 min:
#
#     docker run --rm \
#       -e RUNLAYER_API_KEY=rl_org_... \
#       -e RUNLAYER_HOST=https://api.runlayer.com \
#       -e RUNLAYER_HOST_HOME_PREFIX=/host \
#       -e RUNLAYER_MACHINE_ID_PATH=/host/etc/machine-id \
#       -v /:/host:ro \
#       runlayer-aiwatch
#
# SELinux caveat (RHEL/Fedora hosts): bind mounts are unreadable to the
# container without an opt-out. With the whole-root mount NEVER use `:z`/`:Z`
# — that relabels the bind SOURCE, i.e. the entire host filesystem, which can
# break host services (Docker's own docs warn against relabeling system dirs).
# Use `--security-opt label=disable` (per-container, leaves host labels
# untouched) or a custom SELinux policy. `:z` is only reasonable on narrow
# per-directory mounts you own.
#
# Read-only mounts also mean the scanner's per-user ~/.runlayer state (stored
# device-id fallback, logs) cannot persist — deliberate and tolerated: the
# device id comes from the mounted machine-id (RUNLAYER_MACHINE_ID_PATH) and
# container logs go to stdout, so nothing load-bearing is lost.

# ---- Build stage: glibc 2.28 floor onedir bundle -----------------------------
FROM quay.io/pypa/manylinux_2_28_x86_64 AS build

ARG UV_VERSION=0.9.18
ENV UV_INSTALL_DIR=/usr/local/bin \
    UV_UNMANAGED_INSTALL=1 \
    PATH=/usr/local/bin:$PATH

# Pinned uv installer (matches .tool-versions).
RUN curl -LsSf "https://astral.sh/uv/${UV_VERSION}/install.sh" | sh

# Preserve the cli/ ↔ packages/python sibling layout so cli's editable
# `../packages/python` path dependency resolves inside the image.
COPY cli/ /src/cli/
COPY packages/python/ /src/packages/python/
WORKDIR /src/cli

# Build the aiwatch onedir bundle exactly as the Linux package build does
# (cwd = cli/, spec resolves ../runlayer_cli/... relative to packaging/). uv
# provisions its own CPython, so no system python is required.
RUN uv sync --frozen \
    && uv pip install pyinstaller \
    && uv run pyinstaller packaging/aiwatch.spec \
    && test -x /src/cli/dist/aiwatch/aiwatch

# ---- Runtime stage -----------------------------------------------------------
# Pinned linux/amd64: the aiwatch bundle is x86_64-only (manylinux_2_28_x86_64,
# same as the .deb/.rpm), so the whole image is amd64. Pinning keeps the runtime
# arch coherent with the build stage even when building on an arm64 host (the
# binary then runs under emulation, e.g. Rosetta/qemu).
FROM --platform=linux/amd64 debian:12-slim AS runtime

LABEL org.opencontainers.image.title="Runlayer AI Watch scanner" \
      org.opencontainers.image.vendor="Runlayer Inc." \
      org.opencontainers.image.licenses="Apache-2.0" \
      org.opencontainers.image.source="https://github.com/Runlayer"

# util-linux -> setpriv + flock (numeric-uid privilege drop + overlap guard);
# coreutils -> timeout/readlink/date/mktemp; procps for operator debugging;
# ca-certificates for the HTTPS submission to the gateway.
RUN apt-get update \
    && apt-get install -y --no-install-recommends \
        util-linux \
        coreutils \
        procps \
        ca-certificates \
    && rm -rf /var/lib/apt/lists/*

# Install the onedir bundle and put the binary on PATH.
COPY --from=build /src/cli/dist/aiwatch/ /usr/lib/runlayer/aiwatch/
RUN ln -sf /usr/lib/runlayer/aiwatch/aiwatch /usr/bin/aiwatch

# Fan-out entrypoint.
COPY cli/packaging/container/scan-host-users.sh /usr/lib/runlayer/scan-host-users.sh
RUN chmod 0755 /usr/lib/runlayer/scan-host-users.sh

ENTRYPOINT ["/usr/lib/runlayer/scan-host-users.sh"]
