sbo-testbuild image builder
===========================

Builds the docker images that test-build consumes:
  docker.noland.dnx:5000/sbo-testbuild:current
  docker.noland.dnx:5000/sbo-testbuild:15.0

Three scripts, chained (see docs/specs/2026-07-13-image-builder-design.md):
  bootstrap.sh           sbo-base:{ver}       FROM scratch, base pkgs from NAS
  build-full-image.sh    sbo-full:{ver}       FROM base, all series
  build-sbo-testbuild.sh sbo-testbuild:{ver}  FROM full, + sbopkg + tools

All settings live in ./config.

VM setup (docker.noland.dnx, Slackware x86_64, 4 vCPU / 4 GB / 80 GB)
--------------------------------------------------------------------
1. Install docker; enable the daemon.

2. NFS-mount the two NAS trees read-only, named to match:
     /mnt/nas/slackware64-current   -> -current mirror tree
     /mnt/nas/slackware64-15.0      -> 15.0 mirror tree
   Each is a full mirror (PACKAGES.TXT, ChangeLog.txt, slackware64/, patches/,
   extra/). Root must be able to read them (bootstrap runs installpkg as root).

3. Run a LAN registry:
     docker run -d --restart=always -p 5000:5000 \
       -v /opt/registry/data:/var/lib/registry --name registry registry:2

4. Mark the registry insecure (plain HTTP) on the VM AND every pulling client
   (this dev box, the buildsystem VM). In /etc/docker/daemon.json:
     { "insecure-registries": ["docker.noland.dnx:5000"] }
   then restart docker.

5. Drop the two prebuilt packages (built once, re-drop on upstream bumps):
     /opt/sbo-testbuild/pkgs/sbopkg-*.txz
     /opt/sbo-testbuild/pkgs/sbo-maintainer-tools-*.txz

6. Install the nightly cron (root). The NAS repos sync at 01:00 and 02:00, so
   the chain runs after and both variants are ready well before the ~09:00 work
   start. No --force: each script self-gates (bootstrap on the ChangeLog hash,
   full-image on the base-image digest, build-sbo-testbuild on the full-image
   digest + tools .txz hash), so an unchanged night is a cheap no-op. -current
   moves daily and rebuilds most nights; 15.0 is frozen stable and rebuilds only
   on a real repo update. Deployed schedule on docker.noland.dnx:
      # -current (ready ~04:35)
      0  3 * * *  /path/to/sbo-dockerbuild/image-builder/bootstrap.sh           --version current >> /var/log/sbo-testbuild.log 2>&1
     20  3 * * *  /path/to/sbo-dockerbuild/image-builder/build-full-image.sh    --version current >> /var/log/sbo-testbuild.log 2>&1
     30  4 * * *  /path/to/sbo-dockerbuild/image-builder/build-sbo-testbuild.sh --version current >> /var/log/sbo-testbuild.log 2>&1
      # 15.0 (ready ~06:35)
      0  5 * * *  /path/to/sbo-dockerbuild/image-builder/bootstrap.sh           --version 15.0 >> /var/log/sbo-testbuild.log 2>&1
     20  5 * * *  /path/to/sbo-dockerbuild/image-builder/build-full-image.sh    --version 15.0 >> /var/log/sbo-testbuild.log 2>&1
     30  6 * * *  /path/to/sbo-dockerbuild/image-builder/build-sbo-testbuild.sh --version 15.0 >> /var/log/sbo-testbuild.log 2>&1

7. Ensure docker.noland.dnx resolves on the LAN (static IP or DNS).

Manual first run
----------------
   ./bootstrap.sh --version current --force
   ./build-full-image.sh --version current --force
   ./build-sbo-testbuild.sh --version current --force
Then confirm:
   docker pull docker.noland.dnx:5000/sbo-testbuild:current
   docker run --rm docker.noland.dnx:5000/sbo-testbuild:current sbopkg -V

Flags: --force (rebuild unconditionally), --version <current|15.0> (one variant).

Tests
-----
   bash test-image-builder.sh     # pure-logic self-check, no docker
