Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 4 additions & 21 deletions system_files/bluefin/usr/libexec/bonedigger-report
Original file line number Diff line number Diff line change
Expand Up @@ -117,27 +117,10 @@ read_boot_status() {
}

route_issue_repo() {
case "$IMAGE_NAME" in
bluefin-lts*)
BUG_REPO="projectbluefin/bluefin-lts"
;;
bluefin)
if [[ "$IMAGE_TAG" == lts* ]]; then
BUG_REPO="projectbluefin/bluefin-lts"
else
BUG_REPO="projectbluefin/bluefin"
fi
;;
bluefin*)
BUG_REPO="projectbluefin/bluefin"
;;
dakota*)
BUG_REPO="projectbluefin/dakota"
;;
*)
BUG_REPO="projectbluefin/common"
;;
esac
# Routing grammar lives in one place only — see
# system_files/shared/usr/libexec/ublue-image-repo.
BUG_REPO="$("${UBLUE_IMAGE_REPO_BIN:-/usr/libexec/ublue-image-repo}" \
--default "projectbluefin/common" "$IMAGE_NAME" "$IMAGE_TAG")"
}

scrub_kernel_log() {
Expand Down
12 changes: 4 additions & 8 deletions system_files/bluefin/usr/share/ublue-os/just/changelog.just
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,11 @@ changelogs:
IMAGE_INFO_FILE="${IMAGE_INFO_FILE:-/usr/share/ublue-os/image-info.json}"
TAG="$(jq -r '.["image-tag"]' < "${IMAGE_INFO_FILE}")"

# Select the correct upstream repo based on image stream
# Select the correct upstream repo based on image stream. The name/tag ->
# repo grammar is owned by /usr/libexec/ublue-image-repo; do not restate it.
IMAGE_NAME="$(jq -r '.["image-name"] // empty' < "${IMAGE_INFO_FILE}")"
if [[ "$IMAGE_NAME" == "dakota" ]]; then
REPO="projectbluefin/dakota"
elif [[ "$IMAGE_NAME" =~ ^bluefin-lts ]] || [[ "$TAG" =~ ^lts ]]; then
REPO="projectbluefin/bluefin-lts"
else
REPO="projectbluefin/bluefin"
fi
REPO="$("${UBLUE_IMAGE_REPO_BIN:-/usr/libexec/ublue-image-repo}" \
--default "projectbluefin/bluefin" "$IMAGE_NAME" "$TAG")"

# If stable, gts, or lts, fetch from GitHub Releases
if [[ "$TAG" =~ gts$|stable$|^lts ]]; then
Expand Down
70 changes: 70 additions & 0 deletions system_files/shared/usr/libexec/ublue-image-repo
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#!/usr/bin/bash
# ublue-image-repo — canonical image-name/tag -> upstream GitHub repo resolver.
#
# Single source of truth for "which repository owns this booted image".
# Every consumer (bonedigger-report, ujust changelogs, ...) must route through
# here so the grammar cannot drift per call site.
#
# Usage:
# ublue-image-repo [--default REPO] [IMAGE_NAME] [IMAGE_TAG]
#
# IMAGE_NAME/IMAGE_TAG may also be supplied via the environment variables of
# the same name. --default sets the repo returned when nothing matches
# (callers differ: issue reporting falls back to common, changelogs to
# bluefin), and defaults to projectbluefin/common.

set -euo pipefail

UBLUE_IMAGE_REPO_DEFAULT="projectbluefin/common"

while [[ $# -gt 0 ]]; do
case "$1" in
--default)
UBLUE_IMAGE_REPO_DEFAULT="${2:-$UBLUE_IMAGE_REPO_DEFAULT}"
shift 2
;;
--default=*)
UBLUE_IMAGE_REPO_DEFAULT="${1#--default=}"
shift
;;
--)
shift
break
;;
*)
break
;;
esac
done

IMAGE_NAME="${1-${IMAGE_NAME-}}"
IMAGE_TAG="${2-${IMAGE_TAG-}}"

case "$IMAGE_NAME" in
bluefin-lts*)
printf '%s\n' "projectbluefin/bluefin-lts"
;;
bluefin)
# The plain bluefin image publishes the LTS stream under lts* tags.
if [[ "$IMAGE_TAG" == lts* ]]; then
printf '%s\n' "projectbluefin/bluefin-lts"
else
printf '%s\n' "projectbluefin/bluefin"
fi
;;
bluefin*)
printf '%s\n' "projectbluefin/bluefin"
;;
dakota*)
printf '%s\n' "projectbluefin/dakota"
;;
*)
# No name (or an unrecognised fork): an lts* tag still identifies the
# LTS stream, otherwise defer to the caller-supplied default.
if [[ "$IMAGE_TAG" == lts* ]]; then
printf '%s\n' "projectbluefin/bluefin-lts"
else
printf '%s\n' "$UBLUE_IMAGE_REPO_DEFAULT"
fi
;;
esac
1 change: 1 addition & 0 deletions tests/test_bonedigger_report.bats
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

setup() {
export BONEDIGGER_SCRIPT="$BATS_TEST_DIRNAME/../system_files/bluefin/usr/libexec/bonedigger-report"
export UBLUE_IMAGE_REPO_BIN="$BATS_TEST_DIRNAME/../system_files/shared/usr/libexec/ublue-image-repo"
export WORKDIR="$BATS_TEST_DIRNAME/.bonedigger-report-test-${BATS_TEST_NUMBER}-${$}"
export HOME="$WORKDIR/home"
export XDG_STATE_HOME="$WORKDIR/state"
Expand Down
3 changes: 3 additions & 0 deletions tests/test_changelog.bats
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ setup() {
MOCKDIR="${WORKDIR}/bin"
mkdir -p "${MOCKDIR}"

# Canonical repo-routing resolver used by the recipe under test.
export UBLUE_IMAGE_REPO_BIN="$BATS_TEST_DIRNAME/../system_files/shared/usr/libexec/ublue-image-repo"

# Capture file — curl writes each URL it receives here
CURL_CALLS="${WORKDIR}/curl_calls"
touch "${CURL_CALLS}"
Expand Down
93 changes: 93 additions & 0 deletions tests/test_image_repo.bats
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
#!/usr/bin/env bats
# Tests for /usr/libexec/ublue-image-repo — the single source of truth for
# image-name/tag -> upstream GitHub repository routing.

setup() {
RESOLVER="$BATS_TEST_DIRNAME/../system_files/shared/usr/libexec/ublue-image-repo"
export RESOLVER
}

@test "image-repo: bluefin latest routes to projectbluefin/bluefin" {
run "$RESOLVER" bluefin latest
[ "$status" -eq 0 ]
[ "$output" = "projectbluefin/bluefin" ]
}

@test "image-repo: bluefin with lts tag routes to bluefin-lts" {
run "$RESOLVER" bluefin lts-20260601
[ "$status" -eq 0 ]
[ "$output" = "projectbluefin/bluefin-lts" ]
}

@test "image-repo: bluefin-lts-hwe routes to bluefin-lts" {
run "$RESOLVER" bluefin-lts-hwe stable
[ "$status" -eq 0 ]
[ "$output" = "projectbluefin/bluefin-lts" ]
}

@test "image-repo: bluefin-nvidia routes to bluefin" {
run "$RESOLVER" bluefin-nvidia stable
[ "$status" -eq 0 ]
[ "$output" = "projectbluefin/bluefin" ]
}

@test "image-repo: dakota routes to projectbluefin/dakota" {
run "$RESOLVER" dakota latest
[ "$status" -eq 0 ]
[ "$output" = "projectbluefin/dakota" ]
}

# Regression: dakota-nvidia is a published image (docs/skills/image-registry.md).
# The changelog call site used an exact `== dakota` match and sent it to
# projectbluefin/bluefin; the resolver must treat every dakota* variant alike.
@test "image-repo: dakota-nvidia routes to projectbluefin/dakota" {
run "$RESOLVER" dakota-nvidia stable
[ "$status" -eq 0 ]
[ "$output" = "projectbluefin/dakota" ]
}

@test "image-repo: unknown image falls back to caller default" {
run "$RESOLVER" --default projectbluefin/common knuckle latest
[ "$status" -eq 0 ]
[ "$output" = "projectbluefin/common" ]

run "$RESOLVER" --default projectbluefin/bluefin knuckle latest
[ "$status" -eq 0 ]
[ "$output" = "projectbluefin/bluefin" ]
}

@test "image-repo: default fallback is projectbluefin/common" {
run "$RESOLVER" knuckle latest
[ "$status" -eq 0 ]
[ "$output" = "projectbluefin/common" ]
}

@test "image-repo: empty image name with lts tag still routes to bluefin-lts" {
run "$RESOLVER" --default projectbluefin/bluefin "" lts-hwe
[ "$status" -eq 0 ]
[ "$output" = "projectbluefin/bluefin-lts" ]
}

@test "image-repo: --default= form is accepted" {
run "$RESOLVER" --default=projectbluefin/bluefin "" latest
[ "$status" -eq 0 ]
[ "$output" = "projectbluefin/bluefin" ]
}

@test "image-repo: reads IMAGE_NAME/IMAGE_TAG from the environment" {
IMAGE_NAME=dakota-nvidia IMAGE_TAG=stable run "$RESOLVER"
[ "$status" -eq 0 ]
[ "$output" = "projectbluefin/dakota" ]
}

# Structural invariant: no consumer may restate the routing grammar inline.
@test "image-repo: consumers do not hardcode upstream repo routing" {
local root="$BATS_TEST_DIRNAME/.."
for consumer in \
"system_files/bluefin/usr/libexec/bonedigger-report" \
"system_files/bluefin/usr/share/ublue-os/just/changelog.just"
do
run grep -c 'projectbluefin/\(bluefin-lts\|dakota\)"' "$root/$consumer"
[ "$output" = "0" ]
done
}
Loading