Skip to content

installer: build the builder image on Linux and on release installs - #393

Open
mpuig wants to merge 7 commits into
kernel:mainfrom
mpuig:fix/installer-builder-image
Open

installer: build the builder image on Linux and on release installs#393
mpuig wants to merge 7 commits into
kernel:mainfrom
mpuig:fix/installer-builder-image

Conversation

@mpuig

@mpuig mpuig commented Aug 11, 2026

Copy link
Copy Markdown

Problem

Source-to-image builds boot builder VMs from hypeman/builder:latest, and the API's fallback for installed (non-source) services is to find that image in the local Docker daemon — lib/builds/manager.go's own comment says "the installer builds this image before loading the service". But the installer only does that in its darwin branch, and only for source (BRANCH) installs.

A Linux release install therefore has no builder image and no way to grow one: ensureBuilderImage finds no source checkout (go.mod absent) and no local hypeman/builder:latest, preparation retries forever, and every hypeman build fails. On v0.3.0 the failure is especially opaque — the ready flag is set in a defer even on failure, so builds proceed and die with create builder instance: image is required.

Reproduced on a GitHub-hosted ubuntu runner installing v0.3.0 via get.hypeman.sh.

Fix

The builder-image step now runs on every platform where Docker is present:

  • source installs keep using the existing checkout in TMP_DIR;
  • release installs fetch the source tarball for the exact installed $VERSION and build from it — the builder Dockerfile is part of the same tree the binaries were released from;
  • skipped when hypeman/builder:latest already exists; warn-and-continue when it cannot be built (matching the existing style).

On Linux the service is already running by this point; the startup preparation loop picks the image up on its next retry. On macOS the ordering (build before service load) is unchanged.

Testing

  • bash -n clean.
  • The equivalent sequence (fetch pinned source → docker build -t hypeman/builder:latest -f lib/builds/images/generic/Dockerfile) is what we run in barista's CI as a workaround, and it takes a fresh ubuntu runner from "every build fails" to green source-to-image builds.

Found while building barista on hypeman. An alternative worth considering: publish a pinnable pre-built builder image and default build.builder_image to it, which would remove the Docker dependency from installs entirely.


Note

Medium Risk
Changes install-time Docker builds and network fetches on production Linux paths; failures are non-fatal but misconfiguration can still leave builds broken until the image is built manually.

Overview
The installer now builds hypeman/builder:latest on every platform where Docker is available, not only on macOS source installs. That aligns install behavior with what source-to-image builds expect (lib/builds/manager.go looks for the image in the local Docker daemon when there is no source tree), so Linux release installs can run hypeman build instead of failing preparation forever.

For release installs, the script downloads the GitHub source tarball for the installed $VERSION and uses it as the Docker build context when there is no BRANCH checkout. It skips the build if hypeman/builder:latest already exists.

Docker handling is tightened: try the user’s docker, fall back to $SUDO docker when the daemon is not reachable, and warn and skip (rather than failing late) if Docker is missing or the daemon is inaccessible. Failed docker build output is captured and printed (indented) before TMP_DIR is removed.

Reviewed by Cursor Bugbot for commit 03212df. Bugbot is set up for automated code reviews on this repo. Configure here.

Source-to-image builds boot builder VMs from hypeman/builder:latest, and
the API's fallback for installed (non-source) services is to find that
image in the local Docker daemon -- lib/builds/manager.go's own comment
says "the installer builds this image before loading the service". The
installer only did so in its darwin branch, and only for source (BRANCH)
installs. A Linux release install therefore had no builder image and no
way to grow one: builder preparation retried forever, and every
`hypeman build` failed.

The builder-image step now runs on every platform where Docker is present,
and release installs fetch the source tarball for the exact installed
version to build from -- the builder Dockerfile is part of the same tree
the binaries were released from. Skipped when the image already exists,
warn-and-continue (matching the existing style) when it cannot be built.
Comment thread scripts/install.sh
Bugbot's review finding, and it is right: the script's documented Linux
invocation elevates privileged operations through $SUDO, but the new
builder-image step ran docker as the invoking user -- who may not be in the
docker group -- so the step would warn-and-skip and leave exactly the gap
this PR fixes. Docker access is now probed and escalated through the same
$SUDO the rest of the script uses.

Also stop discarding the docker build output: it goes to a log file whose
path the failure warning names, instead of 2>/dev/null-ing the only
evidence of why a build failed.
@mpuig

mpuig commented Aug 11, 2026

Copy link
Copy Markdown
Author

Good catch from Bugbot — fixed in b651481: docker access is now probed and escalated through the same $SUDO the rest of the script uses for privileged operations, so a non-docker-group invoking user on Linux still gets the image built. Also stopped discarding the docker build output — it now lands in a log file whose path the failure warning names, instead of 2>/dev/null-ing the only evidence of why a build failed.

Comment thread scripts/install.sh Outdated
@chruffins
chruffins self-requested a review August 11, 2026 21:17

@chruffins chruffins left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hey, thanks for submitting a PR for this! besides the bugbot finding which should be fixed, everything else looks good to me.

Comment thread scripts/install.sh Outdated
…log path

The builder-image build log lives under TMP_DIR, which the EXIT trap
removes when the script finishes, so the path named in the warning was
gone by the time anyone read it. Print the captured docker build output
to stderr on failure, before cleanup runs (per review feedback).
Comment thread scripts/install.sh Outdated

@chruffins chruffins left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for putting this in!

@chruffins

Copy link
Copy Markdown
Contributor

/test

Comment thread scripts/install.sh
Puig, Marc and others added 2 commits August 17, 2026 18:32
…log to stdout

Addresses the two remaining Bugbot findings on this PR:

- Daemon reachability is now acted on, not just used to pick sudo. If neither
  `docker info` nor `$SUDO docker info` succeeds, warn clearly and skip the
  builder build — the same early skip the "docker not installed" branch already
  does. Previously a release install with an unreachable daemon fetched the
  source tarball and only then failed on `docker build`, wasting work and
  surfacing a confusing error.

- The captured build log prints to stdout, matching every other log dump in
  this script (the source-build path's `cat "$BUILD_LOG"`) and the warn line
  directly above it. It was going to stderr while its own warning went to
  stdout, so the two could detach or the log could vanish under `2>/dev/null`.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want fixes drafted automatically? Bugbot Autofix can create code changes for findings. A team admin can enable Autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 03212df. Configure here.

Comment thread scripts/install.sh
info "Builder image built successfully"
fi
else
elif [ -z "$BUILD_CONTEXT" ]; then

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Misleading second fetch warning

Low Severity

When the release source tarball fetch fails, the script warns that it is skipping the builder build and clears BUILD_CONTEXT, then still hits the empty-context branch and warns that the Dockerfile is not available. The second message points at the wrong cause after a curl or tar failure.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 03212df. Configure here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants