[PR #150] [MERGED] fix(images): stop reporting doubled image IDs and tag-strings as container IDs #149

Closed
opened 2026-10-15 12:52:22 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/games-on-whales/LXC2Docker/pull/150
Author: @JBailes
Created: 8/1/2026
Status: ✅ Merged
Merged: 8/1/2026
Merged by: @JBailes

Base: main ← Head: fix/image-id-double-prefix


📝 Commits (1)

  • b34d540 fix(images): stop reporting doubled image IDs and tag-strings as container IDs

📊 Changes

4 files changed (+139 additions, -4 deletions)

View changed files

📝 internal/api/containers.go (+26 -1)
➕ internal/api/image_id_prefix_test.go (+93 -0)
📝 internal/api/images.go (+14 -1)
📝 internal/lxc/manager.go (+6 -2)

📄 Description

Two defects that between them make Docker's standard deploy-verification check impossible to pass against this daemon:

WANT=$(docker image inspect $TAG      --format '{{.Id}}')
GOT=$( docker inspect      $CONTAINER --format '{{.Image}}')
[ "$WANT" = "$GOT" ] || abort

1. Doubled sha256: on every pulled image

store.ImageRecord.ConfigDigest is documented as "the 64-hex value; callers prefix sha256:", and all five readers do exactly that. Build and commit honour it via hex.EncodeToString. Pull, added in f2785c3, stores manifest.Config.Digest straight from the OCI manifest — which already carries the prefix.

Observed on a live SmoothNAS host:

docker image inspect ghcr.io/ggml-org/llama.cpp:server-rocm
  Id = "sha256:sha256:a40ffec0460df2942bc4da5dbc5d7ba1b89bafed0aafec4615ac99bb9a96ebeb"

Fixed at both ends. Pull now stores bare hex per the contract, and imageDisplayID trims a prefix defensively so records already persisted in the wrong format heal without a store migration — existing installs have bad values on disk, so the read-side fix is the one that actually repairs them.

2. Container .Image returned a reference, not an ID

Docker keeps the reference in .Config.Image and the content-addressed ID in .Image. This daemon returned rec.Image, the original image:tag string, in both. ImageID on the record is no better — containers.go:420 sets it to the ref as well.

inspectContainer now resolves the image record and reports "sha256:"+imageDisplayID, falling back to the reference when no record exists (legacy container, or the image has since been removed) rather than inventing a digest or returning empty. .Config.Image is unchanged and still carries the reference, which is correct.

Why it matters

Found while verifying a container deploy, where the assertion reported MISMATCH for a correctly deployed container. That is the worst failure mode for a safety check: one that can only ever fail gets deleted or ignored, and then a genuine stale-image deploy goes through unnoticed.

Testing

Both tests were written failing first and reproduce the exact strings observed on the host, plus the legacy fallback paths.

TestCheckCreateDiskPressure in internal/lxc fails identically on unmodified c76098e — verified against a clean baseline worktree, unrelated to this change.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/games-on-whales/LXC2Docker/pull/150 **Author:** [@JBailes](https://github.com/JBailes) **Created:** 8/1/2026 **Status:** ✅ Merged **Merged:** 8/1/2026 **Merged by:** [@JBailes](https://github.com/JBailes) **Base:** `main` ← **Head:** `fix/image-id-double-prefix` --- ### 📝 Commits (1) - [`b34d540`](https://github.com/games-on-whales/LXC2Docker/commit/b34d540d1125848a40445a2b9d47f7f45c5dae35) fix(images): stop reporting doubled image IDs and tag-strings as container IDs ### 📊 Changes **4 files changed** (+139 additions, -4 deletions) <details> <summary>View changed files</summary> 📝 `internal/api/containers.go` (+26 -1) ➕ `internal/api/image_id_prefix_test.go` (+93 -0) 📝 `internal/api/images.go` (+14 -1) 📝 `internal/lxc/manager.go` (+6 -2) </details> ### 📄 Description Two defects that between them make Docker's standard deploy-verification check impossible to pass against this daemon: ```bash WANT=$(docker image inspect $TAG --format '{{.Id}}') GOT=$( docker inspect $CONTAINER --format '{{.Image}}') [ "$WANT" = "$GOT" ] || abort ``` ## 1. Doubled `sha256:` on every pulled image `store.ImageRecord.ConfigDigest` is documented as *"the 64-hex value; callers prefix `sha256:`"*, and all five readers do exactly that. Build and commit honour it via `hex.EncodeToString`. Pull, added in f2785c3, stores `manifest.Config.Digest` straight from the OCI manifest — which already carries the prefix. Observed on a live SmoothNAS host: ``` docker image inspect ghcr.io/ggml-org/llama.cpp:server-rocm Id = "sha256:sha256:a40ffec0460df2942bc4da5dbc5d7ba1b89bafed0aafec4615ac99bb9a96ebeb" ``` Fixed at both ends. Pull now stores bare hex per the contract, and `imageDisplayID` trims a prefix defensively so records **already persisted** in the wrong format heal without a store migration — existing installs have bad values on disk, so the read-side fix is the one that actually repairs them. ## 2. Container `.Image` returned a reference, not an ID Docker keeps the reference in `.Config.Image` and the content-addressed ID in `.Image`. This daemon returned `rec.Image`, the original `image:tag` string, in both. `ImageID` on the record is no better — `containers.go:420` sets it to the ref as well. `inspectContainer` now resolves the image record and reports `"sha256:"+imageDisplayID`, falling back to the reference when no record exists (legacy container, or the image has since been removed) rather than inventing a digest or returning empty. `.Config.Image` is unchanged and still carries the reference, which is correct. ## Why it matters Found while verifying a container deploy, where the assertion reported `MISMATCH` for a **correctly deployed** container. That is the worst failure mode for a safety check: one that can only ever fail gets deleted or ignored, and then a genuine stale-image deploy goes through unnoticed. ## Testing Both tests were written failing first and reproduce the exact strings observed on the host, plus the legacy fallback paths. `TestCheckCreateDiskPressure` in `internal/lxc` fails identically on unmodified `c76098e` — verified against a clean baseline worktree, unrelated to this change. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
Sign in to join this conversation.
No labels
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
games-on-whales/LXC2Docker#149
No description provided.