Skip to content

Commit 627b42c

Browse files
genednaclaude
andcommitted
v0.41.17: BB-20 OCI reject manifest with unknown blob case
Register `OCI reject manifest with unknown blob` (plan-20261001 BB-20): with the config blob present but a layer never uploaded, the manifest PUT returns 400 MANIFEST_BLOB_UNKNOWN and the tag stays absent (HEAD 404). Marks BB-19 done. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018bJDjze83ToyPysYzmxxWS Signed-off-by: Eli Ma <eli@patch.sh>
1 parent 46db388 commit 627b42c

5 files changed

Lines changed: 32 additions & 5 deletions

File tree

‎Cargo.lock‎

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎Cargo.toml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "mega2"
3-
version = "0.41.16"
3+
version = "0.41.17"
44
edition = "2024"
55
license = "MIT OR Apache-2.0"
66
description = "Monorepo engine and Git hosting server for AI agents: trunk-based storage, Git Smart HTTP, Git LFS, OCI registry, and Agent Session Capture"

‎docs/deploy-trunk.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,7 @@ CASE='OCI ping' # 换成要跑的 case 名
395395
docker compose -p mega2-trunk -f docker/docker-compose-storage-only.yml --profile interop exec -T -e MEGA2_SMOKE_CASE="$CASE" interop-smoke bash /repo/scripts/oci_client_smoke_storage_only.sh 2>&1 | tee target/tmp/bb-oci-case.log
396396
```
397397

398-
已登记 case:`OCI ping`、`OCI oras push and pull`、`OCI reject unauthenticated push`、`OCI chunked blob upload`、`OCI cross-repo blob mount`、`OCI manifest HEAD and conditional GET`、`OCI blob range`、`OCI tags list pagination`、`OCI image index manifest`。
398+
已登记 case:`OCI ping`、`OCI oras push and pull`、`OCI reject unauthenticated push`、`OCI chunked blob upload`、`OCI cross-repo blob mount`、`OCI manifest HEAD and conditional GET`、`OCI blob range`、`OCI tags list pagination`、`OCI image index manifest`、`OCI reject manifest with unknown blob`。
399399

400400
不设 `MEGA2_SMOKE_CASE` 时整跑全部默认栈 case;opt-in case(auth-none)只经 `scripts/bb_optin_run.sh none oci_client_smoke_storage_only.sh '<case>' <log>` 运行。
401401

‎docs/plan/plan-20261001.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1420,7 +1420,7 @@
14201420
### Task BB-19: OCI image index manifest
14211421

14221422
**Task type:** `implementation`
1423-
**Lifecycle / Acceptance:** `in-progress` / `remote-pending`(v0.41.16;Codex R2 PASS;C 组 2023 测试通过;待 D 组 `docker` job)
1423+
**Lifecycle / Acceptance:** `done` / `complete`(v0.41.16;C 组 2023 测试通过;D 组 docker run 36958427982 success)
14241424
**Description:** 在 `scripts/oci_client_smoke_storage_only.sh` 注册 case `OCI image index manifest`。推送两个单平台 manifest 后 PUT 引用二者的 OCI index。 唯一行为轴:OCI index 推送。
14251425
**Out of scope:** 其它 case(各自成卡);改 `src/**`(产品缺陷按 ADR-BB-08 立 `FIX-BB-*`);改既有 smoke 脚本(GC-BB-06);以 cargo IT 作 VER(GC-BB-04)。
14261426
**Current evidence:**
@@ -1469,7 +1469,7 @@
14691469
### Task BB-20: OCI reject manifest with unknown blob
14701470

14711471
**Task type:** `implementation`
1472-
**Lifecycle / Acceptance:** `pending` / (空)
1472+
**Lifecycle / Acceptance:** `in-progress` / `remote-pending`(v0.41.17;Codex R1 PASS;C 组 2023 测试通过;待 D 组 `docker` job)
14731473
**Description:** 在 `scripts/oci_client_smoke_storage_only.sh` 注册 case `OCI reject manifest with unknown blob`。PUT 一个 layer 从未上传的 image manifest。 唯一行为轴:manifest 引用缺失 blob。
14741474
**Out of scope:** 其它 case(各自成卡);改 `src/**`(产品缺陷按 ADR-BB-08 立 `FIX-BB-*`);改既有 smoke 脚本(GC-BB-06);以 cargo IT 作 VER(GC-BB-04)。
14751475
**Current evidence:**

‎scripts/oci_client_smoke_storage_only.sh‎

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,32 @@ case_oci_image_index() {
311311
|| { echo "index platforms are not linux/amd64 and linux/arm64" >&2; return 1; }
312312
}
313313

314+
# --- BB-20 OCI reject manifest with unknown blob ------------------------
315+
case_oci_manifest_unknown_blob() {
316+
local d="$WORK/unknown" repo="bb-$RUN_ID/unknown" cfg_dg cfg_size missing code
317+
oci_case_begin
318+
mkdir -p "$d"
319+
printf '{}' > "$d/config.json"
320+
code=$(oci_put_blob "$repo" "$d/config.json")
321+
[ "$code" = 201 ] || { echo "config blob upload returned $code" >&2; return 1; }
322+
cfg_dg=$(oci_digest "$d/config.json")
323+
cfg_size=$(wc -c < "$d/config.json" | tr -d ' ')
324+
head -c 64 /dev/urandom > "$d/never-uploaded"
325+
missing=$(oci_digest "$d/never-uploaded")
326+
jq -n --arg c "$cfg_dg" --argjson cs "$cfg_size" --arg l "$missing" '{
327+
schemaVersion: 2,
328+
mediaType: "application/vnd.oci.image.manifest.v1+json",
329+
config: {mediaType: "application/vnd.oci.image.config.v1+json", digest: $c, size: $cs},
330+
layers: [{mediaType: "application/vnd.oci.image.layer.v1.tar", digest: $l, size: 64}]}' > "$d/manifest.json"
331+
code=$(oci_curl -u "bb:$TOKEN" -X PUT -o "$d/put.json" -w '%{http_code}' \
332+
-H 'Content-Type: application/vnd.oci.image.manifest.v1+json' --data-binary @"$d/manifest.json" \
333+
"$MEGA2_BASE_URL/v2/$repo/manifests/v1")
334+
[ "$code" = 400 ] || { echo "manifest PUT returned $code" >&2; return 1; }
335+
[ "$(jq -r '.errors[0].code' "$d/put.json")" = MANIFEST_BLOB_UNKNOWN ] || { echo "error code is not MANIFEST_BLOB_UNKNOWN" >&2; return 1; }
336+
code=$(oci_curl -I -H 'Accept: application/vnd.oci.image.manifest.v1+json' -o /dev/null -w '%{http_code}' "$MEGA2_BASE_URL/v2/$repo/manifests/v1")
337+
[ "$code" = 404 ] || { echo "HEAD of the rejected tag returned $code" >&2; return 1; }
338+
}
339+
314340
run_case "OCI ping" case_oci_ping
315341
run_case "OCI oras push and pull" case_oci_oras_push_pull
316342
run_case "OCI reject unauthenticated push" case_oci_reject_unauth_push
@@ -320,5 +346,6 @@ run_case "OCI manifest HEAD and conditional GET" case_oci_manifest_head_304
320346
run_case "OCI blob range" case_oci_blob_range
321347
run_case "OCI tags list pagination" case_oci_tags_pagination
322348
run_case "OCI image index manifest" case_oci_image_index
349+
run_case "OCI reject manifest with unknown blob" case_oci_manifest_unknown_blob
323350

324351
finish

0 commit comments

Comments
 (0)