Skip to content

fix: route reports by booted image - #1010

Closed
kubestellar-hive[bot] wants to merge 4 commits into
mainfrom
scanner/fix-bonedigger-live-image
Closed

kubestellar-hive[bot] wants to merge 4 commits into
mainfrom
scanner/fix-bonedigger-live-image

Conversation

@kubestellar-hive

Copy link
Copy Markdown
Contributor

Fix

Use the booted image reference from bootc status --json when generating ujust report metadata and repository routing. Keep build-time image-info.json as fallback when no booted reference is available, and add regression coverage for stale metadata.

Refs #1009


Filed by scanner agent (ACMM L5 — hold-gated mode). Hold-gated: human review required.

— hive: agent=scanner backend=copilot model=gpt-5.6-luna

Signed-off-by: Copilot <223556219+Copilot@users.noreply.github.com>

@hanthor hanthor left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

CI is genuinely red on this head commit: the PR's own new regression test test_bonedigger_report.bats #4 ("image info prefers booted image reference over stale build metadata") fails in CI with an output mismatch — a real failure, not an infra flake (build/E2E jobs otherwise pass). Root cause looks like a shell-quoting bug in the test itself (a single-quoted JSON literal embedded inside an outer single-quoted bash -c '...' string), which needs fixing before merge regardless of whether the underlying read_boot_status/read_image_info reordering fix (which does look correct on inspection) is sound.


Generated by Claude Code

@castrojo castrojo changed the title [scanner] fix: route reports by booted image fix: route reports by booted image Sep 6, 2026
pull Bot pushed a commit to joshyorko/common that referenced this pull request Sep 7, 2026
…ng (projectbluefin#1045)

## Refactor

**Cluster:** image-name/tag → upstream GitHub repository routing.
**Files:** `system_files/shared/usr/libexec/ublue-image-repo` (new),
`system_files/bluefin/usr/libexec/bonedigger-report`
(`route_issue_repo`),
`system_files/bluefin/usr/share/ublue-os/just/changelog.just`
(`changelogs`), `tests/test_image_repo.bats` (new),
`tests/test_bonedigger_report.bats`, `tests/test_changelog.bats`.

`common` decided "which upstream repo owns this image" in two places
with two different grammars:

| site | dakota match | unknown image |
|---|---|---|
| `bonedigger-report:route_issue_repo` | `dakota*` glob |
`projectbluefin/common` |
| `changelog.just:changelogs` | `== "dakota"` exact |
`projectbluefin/bluefin` |

They had already drifted. `dakota-nvidia` is a published image
(`docs/skills/image-registry.md`), matched by the glob but not by the
exact comparison — so `ujust changelogs` on `dakota-nvidia` fetched
release notes from `projectbluefin/bluefin`.

This extracts the grammar into `/usr/libexec/ublue-image-repo` in the
**`shared/`** overlay layer (the decision is variant-agnostic; both
copies previously sat in the GNOME-desktop-only `bluefin/` layer). The
one legitimate per-caller difference — the fallback repo for
unrecognised images — is passed in as `--default`, so each call site
keeps its existing fallback and no unrelated behaviour changes.

Both consumers become one-line delegations. `tests/test_image_repo.bats`
covers the grammar directly, including a `dakota-nvidia` regression test
and a structural invariant asserting no consumer restates
`projectbluefin/bluefin-lts` / `projectbluefin/dakota` inline.

**Verification:** `bats tests/test_image_repo.bats
tests/test_bonedigger_report.bats tests/test_changelog.bats` — 46/46
pass.

**Overlap check:** projectbluefin#1010 also touches `bonedigger-report`, but only
`read_boot_status` (how `IMAGE_NAME`/`IMAGE_REF` are *sourced*); this PR
touches only `route_issue_repo` (how they are *routed*) — disjoint
hunks, complementary. projectbluefin#1042 moves `00-entry.just` into `shared/` and
does not touch `changelog.just`.

Refs projectbluefin#1044

---
*Filed by architect agent (ACMM L5 — hold-gated mode). Hold-gated: human
review required.*

— hive: agent=architect backend=copilot model=claude-opus-5

Signed-off-by: sec-check[bot] <sec-check[bot]@users.noreply.github.com>
Co-authored-by: sec-check[bot] <sec-check[bot]@users.noreply.github.com>
pull Bot pushed a commit to joshyorko/common that referenced this pull request Sep 10, 2026
…luefin#1034)

## Test Improvement

Adds `tests/test_shared_just.bats` — 14 BATS cases covering
`system_files/shared/usr/share/ublue-os/just/shared.just`, which had
**zero**
test coverage.

### Why this file

`powerwash` is the most destructive recipe in the repo: it ends in
`sudo bootc install reset --experimental`, an irreversible factory
reset. It is
guarded by two `gum choose` confirmations plus a `bctl powerwash` fast
path.
None of that gating was verified by any test.

### How

The `powerwash` body is a `#!/usr/bin/bash` shebang recipe with no
`just`
interpolation, so the test extracts it verbatim and **executes** it
against
stubbed `bctl`/`gum`/`sudo` binaries. This exercises real control flow
rather
than grepping recipe text, and requires no `just` binary in CI.

Asserted behavior:
- `bctl` present → delegates to `bctl powerwash`, and `gum`/`sudo` are
never invoked
- declining the first confirmation → cancels, only one prompt, no `sudo`
- declining the second confirmation → cancels, no `sudo`
- non-affirmative (`maybe`) and empty answers → treated as declines
- two prompts are always required; a single "yes" never wipes
- both confirmations → `sudo bootc install reset --experimental`,
exactly once
- both prompts carry their warning text
- `toggle-tpm2` uses the absolute `/usr/bin/luks-tpm2-autounlock` path

All 14 pass locally (bats 1.14.0). Mutation-checked: deleting the second
confirmation from `shared.just` fails 3 of the tests.

### Scope / disjointness

Claimed ground: **`tests/test_shared_just.bats` only** — one new test
file, no
production code touched.

Deliberately does **not** touch `.github/workflows/unit-tests.yml`
(claimed by
open PRs projectbluefin#942 and projectbluefin#961) and does **not** touch `system.just` (projectbluefin#942),
`apps.just` (projectbluefin#1007), `default.just` (projectbluefin#1003), `bonedigger-report`
(projectbluefin#1010),
`hooks.py` (projectbluefin#1011), or `ublue-fastfetch` (projectbluefin#1005). CI registration of
this and
the other test files not yet wired into `unit-tests.yml` is tracked
separately
by projectbluefin#968.

---
*Filed by quality agent (hold-gated mode). Human review required. Do not
merge on my behalf.*

— hive: agent=quality backend=copilot model=claude-opus-5

Signed-off-by: kubestellar-hive[bot] <kubestellar-hive[bot]@users.noreply.github.com>
Co-authored-by: kubestellar-hive[bot] <kubestellar-hive[bot]@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
sec-check[bot] added 2 commits September 17, 2026 19:56
…th invalid JSON

The two image-info tests embedded their BOOTC_JSON fixture inside the
single-quoted 'bash -c' body:

    run bash -c '
        ...
        BOOTC_JSON='{"status":{"booted":...}}'
        ...
    ' _ "$BONEDIGGER_SCRIPT" "$WORKDIR/stale-image-info.json"

The inner quotes close the outer single-quoted string, so the JSON was
left unquoted and the outer shell stripped every double quote from it:

    {status:{booted:{image:{image:{image:ghcr.io/projectbluefin/dakota:stable}}}}}

jq could not parse that, returned empty, and read_image_info silently
fell back to the stale image-info.json. That made
'image info prefers booted image reference over stale build metadata'
fail, and made 'image info falls back when no booted image is reported'
pass for the wrong reason — it exercised the fallback because the
fixture was corrupt, not because booted was null.

Pass the fixture as a positional argument instead so it reaches the
script intact. Both tests now exercise the branch they name; mutating
the jq query in read_image_info turns the first one red, which it did
not before.

Signed-off-by: sec-check[bot] <sec-check[bot]@users.noreply.github.com>
@kubestellar-hive

Copy link
Copy Markdown
Contributor Author

Status after pushing the test fix.

The original red check on this PR was test, failing on one bats case:

not ok 4 image info prefers booted image reference over stale build metadata
#   `[ "$output" = "dakota|stable|ghcr.io/projectbluefin/dakota:stable" ]' failed

Root cause was in the test, not in bonedigger-report. The fixture was embedded inside the single-quoted bash -c body:

BOOTC_JSON='{"status":{"booted":...}}'

The inner quotes closed the outer single-quoted string, so the outer shell stripped every double quote and BOOTC_JSON reached the script as {status:{booted:{image:{image:{image:ghcr.io/projectbluefin/dakota:stable}}}}}. jq could not parse it, returned empty, and read_image_info fell back to the stale image-info.json — which is exactly what the assertion was written to catch.

Fixed by passing the fixture as a positional argument. test is now green. The companion case ("falls back when no booted image is reported") had the same defect and was passing for the wrong reason; it is fixed too. Both were mutation-checked: breaking the jq query in read_image_info turns case 4 red, which it did not do before.

Remaining red check is unrelated to this diff — Build and push image (x86_64) hit a transient Go module proxy error (job 105427795404):

internal/locale.go:8:2: golang.org/x/text@v0.39.0: read "https://proxy.golang.org/...": stream error: stream ID 1; INTERNAL_ERROR; received from peer
Error: building at STEP "RUN go build -ldflags="-s -w" -o /umotd ."

Build and push image (aarch64) succeeded on the same commit. This needs a re-run of that job; gh run rerun is not available to this agent, so it needs a maintainer click or the next push.

🐝 Hive Agent: scanner | Instance: hosted-projectbluefin-knuckle-gjvq | SHA: unknown

— hive: agent=scanner backend=copilot model=claude-opus-5 copilot=1.0.78

@Danathar

Copy link
Copy Markdown

Closing: the fix this PR implements already landed on main through #1020 (read the booted tag from bootc, not baked image-info) and #1030 (fall back to the boot-time snapshot when bootc status fails). The tracking issue #1009 is closed as completed. Thanks for the investigation — it matched what was merged.

@Danathar Danathar closed this Sep 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

hold Work is intentionally paused.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants