Files
firmware/tools/replica/printer/Dockerfile.full
Oleksandr ShyshatskyiandClaude Opus 5 9b5b562a22 Comments: keep the contract and the trap, drop the narration
A sweep over every commented file in the tree. What is kept is what a
reader needs to change the code safely: what a thing is, its signature,
the invariants other files depend on, and the traps that fail silently
(find's non-zero exit under set -e, s6's baked-in libexecdir, the -lm
that decides whether _sqlite3 exists, opkg's compile-time prefix).

What goes is the narration around it: incident histories, arguments
against alternatives already rejected, restatements of the code below,
and paragraphs re-explaining a rule three files already state. One
paragraph in pkgs/3rdparty/opkg/build.sh was duplicated outright.

Comment lines 7971 -> 6158. Every change is comment-only: no
non-comment line differs anywhere in the 86 files, checked
mechanically. Commented-out config directives (#fast_feed: 30000 and
friends) are documentation of defaults and are kept.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NMMpQTajN7RDJySrhQ2cTE
2026-08-30 14:54:50 +03:00

95 lines
4.0 KiB
Docker

# A Creator 5 / Creator 5 Pro you can `docker run`.
#
# It fetches the firmware itself, so the build context is just the harness
# scripts and nothing proprietary has to be staged on disk first:
#
# * the stock OTA package -> decrypt -> kernel component -> rootfs.squashfs,
# the printer's real root filesystem
# * the factory image -> /usr/prog and /usr/data, the real partitions
#
# Everything executed inside is the printer's own MIPS userland under
# qemu-mipsel. See docs/printer-replica.md. Built by
# tools/replica/build-printer-image.sh, which supplies the URLs per model.
#
# CONTAINS PROPRIETARY FLASHFORGE FIRMWARE.
# ----------------------------------------------------------------- fetch ----
# A throwaway stage: the ~93MB package and the 182MB factory image never reach
# a layer of the final image, and the ~60 seconds of unpack and install
# happens once, here.
FROM debian:bookworm-slim AS fetch
RUN apt-get update -qq \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y -qq --no-install-recommends \
curl ca-certificates xz-utils openssl squashfs-tools \
&& rm -rf /var/lib/apt/lists/*
ARG STOCK_URL
ARG FACTORY_URL
# The package key, hardcoded in /usr/prog/bin/unTar on the printer.
ARG FF_KEY='FFP0331&*%root'
# The root filesystem. Three things about the stock package matter: it is DES3
# with -md md5 (the printer's OpenSSL is 1.0.2d, which derived keys with MD5),
# the components inside are plain tar despite the .tar.xz names, and the
# kernel one carries rootfs.squashfs.
RUN set -eu; \
curl -fsSL "$STOCK_URL" -o /stock.tgz; \
mkdir -p /outer; \
openssl des3 -d -k "$FF_KEY" -salt -md md5 -in /stock.tgz | tar -xf - -C /outer; \
mkdir -p /kern; \
tar -xf /outer/kernel-*.tar.xz -C /kern; \
SQ="$(find /kern -name 'rootfs.squashfs*' | head -n1)"; \
test -n "$SQ"; \
unsquashfs -q -d /rootfs "$SQ"; \
test -x /rootfs/bin/busybox; \
rm -rf /stock.tgz /outer /kern
# The two writable partitions, named the way assemble.sh bind-mounts them:
# /parts/prog -> /usr/prog ("usershare")
# /parts/data -> /usr/data ("userdata")
# A factory image is rooted at usr/, so strip that level off. The last two
# tests are the point: a real python3 and a real OpenSSL 1.0.2d mean a real
# /usr/prog rather than an approximation of one.
RUN set -eu; \
mkdir -p /parts; \
curl -fsSL "$FACTORY_URL" -o /factory.tar.xz; \
tar -xJf /factory.tar.xz -C /parts --strip-components=1 usr/prog usr/data; \
rm -f /factory.tar.xz; \
test -x /parts/prog/Python-3.8.2/bin/python3; \
test -x /parts/prog/openssl-1.0.2d/bin/openssl
# ----------------------------------------------------------------- image ----
FROM debian:bookworm-slim
RUN apt-get update -qq \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y -qq --no-install-recommends \
qemu-user-static rsync xz-utils openssl ca-certificates \
dosfstools mount \
&& rm -rf /var/lib/apt/lists/*
COPY --from=fetch /rootfs/ /rootfs/
COPY --from=fetch /parts/ /parts/
# The harness: binfmt registration, mount layout, prog checks, entrypoint.
# Build context is tools/replica/printer.
COPY . /opt/printer/
RUN chmod +x /opt/printer/*.sh
ENV ROOTFS=/rootfs
# One image serves both models: rootfs.squashfs is identical in both packages,
# and /usr/prog comes from the Pro factory image because that is the only one
# published. Which model the replica IS is decided by the stock package a test
# installs into it.
ARG FW_VERSION=unknown
LABEL org.opencontainers.image.title="FlashForge Creator 5 printer replica" \
org.opencontainers.image.description="The printer's real userland (MIPS32r2 o32 nan2008, busybox 1.31.1, glibc 2.33) under qemu-mipsel, for testing firmware packages without a printer" \
com.flashforge.model="Creator5,Creator5Pro" \
com.flashforge.prog-partition="Creator5Pro factory image" \
com.flashforge.firmware="$FW_VERSION"
# --privileged is required: the entrypoint registers a binfmt_misc handler for
# the printer's MIPS binaries and builds the machine's mount layout.
ENTRYPOINT ["/opt/printer/entrypoint.sh"]