Docker builds report unknown version, and profiling output is truncated on error #75

Open
opened 2026-08-09 03:44:22 +02:00 by clawbot · 0 comments
Collaborator

Two independent defects in build metadata and developer tooling.

1. Docker images cannot report their version or commit

.dockerignore excludes .git, but the Dockerfile build stage embeds
the commit with:

-X '...Commit=$(git rev-parse HEAD 2>/dev/null || echo unknown)'

Inside the container there is no .git, so this always evaluates to
unknown. Every Docker-built image reports commit: unknown, build date: unknown. Separately, ARG VERSION=dev is never passed by
script/docker, so the version is dev too.

The result: a container image that cannot identify which source it was
built from. For a backup tool, being unable to answer "which build
produced this archive?" is a real operational problem, not cosmetic.

2. os.Exit(1) discards pprof output

cli.Entry() (internal/cli/entry.go:34-36) calls os.Exit(1) on any
command error. That skips main's defer pprof.StopCPUProfile()
(cmd/vaultik/main.go:26) and the entire deferred heap-profile writer
(main.go:31-44).

So profiling a failing command — often exactly the command you want to
profile — silently yields a truncated or empty profile, with no warning
that the data is unusable.

Definition of done

  1. Version, commit, and build date are passed into the Docker build as
    ARGs from script/docker (computed on the host, where .git
    exists), rather than being computed inside the container. Do not solve
    this by un-ignoring .git — that bloats the build context and busts
    the layer cache on every commit.
  2. docker run … vaultik version prints a real version, commit sha, and
    build date matching the host checkout it was built from.
  3. A dirty working tree is reflected in the embedded version (e.g. a
    -dirty suffix) so an image built from uncommitted changes cannot
    masquerade as a clean build.
  4. Item 2 fixed so profiles are complete regardless of exit status:
    restructure Entry/main so cleanup runs before exit — have Entry
    return a status code that main turns into os.Exit after its
    defers, rather than exiting from within. Do not paper over it by
    duplicating the profile-flush logic at each exit site.
  5. Manual verification recorded on this issue: run a deliberately failing
    command with VAULTIK_CPUPROFILE set and confirm the resulting profile
    is readable and non-empty.
  6. Coordinate with #65, which reworks version derivation — if #65 lands
    first, build on its mechanism rather than adding a second one.
  7. make check green.
Two independent defects in build metadata and developer tooling. ## 1. Docker images cannot report their version or commit `.dockerignore` excludes `.git`, but the Dockerfile build stage embeds the commit with: ``` -X '...Commit=$(git rev-parse HEAD 2>/dev/null || echo unknown)' ``` Inside the container there is no `.git`, so this **always** evaluates to `unknown`. Every Docker-built image reports `commit: unknown, build date: unknown`. Separately, `ARG VERSION=dev` is never passed by `script/docker`, so the version is `dev` too. The result: a container image that cannot identify which source it was built from. For a backup tool, being unable to answer "which build produced this archive?" is a real operational problem, not cosmetic. ## 2. `os.Exit(1)` discards pprof output `cli.Entry()` (`internal/cli/entry.go:34-36`) calls `os.Exit(1)` on any command error. That skips `main`'s `defer pprof.StopCPUProfile()` (`cmd/vaultik/main.go:26`) and the entire deferred heap-profile writer (`main.go:31-44`). So profiling a **failing** command — often exactly the command you want to profile — silently yields a truncated or empty profile, with no warning that the data is unusable. ## Definition of done 1. Version, commit, and build date are passed **into** the Docker build as `ARG`s from `script/docker` (computed on the host, where `.git` exists), rather than being computed inside the container. Do not solve this by un-ignoring `.git` — that bloats the build context and busts the layer cache on every commit. 2. `docker run … vaultik version` prints a real version, commit sha, and build date matching the host checkout it was built from. 3. A dirty working tree is reflected in the embedded version (e.g. a `-dirty` suffix) so an image built from uncommitted changes cannot masquerade as a clean build. 4. Item 2 fixed so profiles are complete regardless of exit status: restructure `Entry`/`main` so cleanup runs before exit — have `Entry` return a status code that `main` turns into `os.Exit` after its defers, rather than exiting from within. Do not paper over it by duplicating the profile-flush logic at each exit site. 5. Manual verification recorded on this issue: run a deliberately failing command with `VAULTIK_CPUPROFILE` set and confirm the resulting profile is readable and non-empty. 6. Coordinate with #65, which reworks version derivation — if #65 lands first, build on its mechanism rather than adding a second one. 7. `make check` green.
clawbot added this to the 1.0.0 milestone 2026-08-09 03:44:22 +02:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/vaultik#75