Skip to content

fix(image): use synchronous containerd exports - #7643

Merged
devantler merged 4 commits into
mainfrom
codex/synchronous-image-export-7642
Oct 10, 2026
Merged

devantler merged 4 commits into
mainfrom
codex/synchronous-image-export-7642

Conversation

@devantler

@devantler devantler commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

🤖 Generated by the Agentic Engineer

Why

An image export can report success before its archive has finished writing, leaving the next import with an incomplete file. A K3s trial exposed an unreadable archive; its original contents were not retained, so that individual failure still needs confirmation.

What

Use the runtime's synchronous export path and preserve compatibility with older supported runtimes. Repairs and retries use the same selection, and incomplete capability information stops the operation instead of guessing.

Fixes #7642.

@devantler

Copy link
Copy Markdown
Contributor Author

🤖 Generated by the Agentic Engineer

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Oct 9, 2026 •

Copy link
Copy Markdown
✅ Action performed

Full review finished.

@devantler

Copy link
Copy Markdown
Contributor Author

🤖 Generated by the Agentic Engineer

Validation at 652b452090676f4b01929d6b6fdacc0a71a5ac5a: the public K3s export regression was RED before the source change and GREEN afterward. The image service passes race tests, including containerd 1.6/1.7/2.x compatibility, repair and fallback paths, unrelated option names, discovery errors, and incomplete help output. The full root Go suite, affected lint (zero findings), final CLI build, and outgoing signature verification pass. Independent static review found no actionable defect.

The matching K3s containerd source starts the transfer output copy separately from its request: archive exporter, transfer proxy, ctr file lifetime. This supports the timing hypothesis; the original failing archive was not retained and is not claimed as reproduced. Actual native K3s and Vanilla export/import/restart trials remain required before merge, along with the current-head normal review and CI gates.

@github-actions

github-actions Bot commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

@coderabbitai

coderabbitai Bot commented Oct 9, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository YAML (base), Organization UI (inherited)
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: 49781fb0-fd86-447c-8e73-2b30503c13e3
📥 Commits

Reviewing files that changed from the base of the PR and between 15322e4 and 652b452.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (9)
  • go.mod
  • images/ksail-analysis-runner/Dockerfile
  • images/ksail-analysis-runner/smoke.sh
  • images/ksail-analysis-runner/smoke_test.go
  • pkg/svc/image/export_mode_test.go
  • pkg/svc/image/exporter.go
  • pkg/svc/image/exporter_test.go
  • pkg/svc/image/repair.go
  • pkg/svc/image/repair_retry_test.go

Included review availability: This review used your included allowance. Your plan provides up to 2 included reviews per hour; 0 remain after this review.

📜 Recent review details
⏰ Context from checks skipped due to timeout. (8)
  • GitHub Check: ⏳ Rate Limit Gate
  • GitHub Check: 🔍 Detect Changes
  • GitHub Check: Analyze (go)
  • GitHub Check: 🏗️ Build + test (Linux)
  • GitHub Check: 🏗️ Build + cask (macOS)
  • GitHub Check: Verify restricted analysis toolchain
  • GitHub Check: 🏗️ Build + test (Windows)
  • GitHub Check: Analyze (go)
🧰 Additional context used
📚 Code guidelines (1)
CONTRIBUTING.md — auto-discovered
📓 Path-based instructions (1)
Source excerpt: Follow standard Go conventions in this repository: Source excerpt: Follow standard Go conventions in this repository: **Formatting:** Format code with `gofmt` and keep imports organized with `goimports` (or run `golangci-lin...

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Files:

  • pkg/svc/image/repair_retry_test.go
  • images/ksail-analysis-runner/smoke_test.go
  • pkg/svc/image/exporter_test.go
  • pkg/svc/image/repair.go
  • pkg/svc/image/exporter.go
  • pkg/svc/image/export_mode_test.go
🪛 Checkov (3.3.19)
images/ksail-analysis-runner/Dockerfile

[low] 1-39: Ensure that HEALTHCHECK instructions have been added to container images

(CKV_DOCKER_2)

🔇 Additional comments (9)
pkg/svc/image/exporter.go (1)

178-181: LGTM!

Also applies to: 225-251

pkg/svc/image/export_mode_test.go (1)

14-121: LGTM!

pkg/svc/image/exporter_test.go (1)

313-313: LGTM!

Also applies to: 435-435, 502-502, 561-561, 910-910, 1014-1014, 1144-1146, 1382-1382

pkg/svc/image/repair.go (1)

321-336: LGTM!

pkg/svc/image/repair_retry_test.go (1)

143-146: LGTM!

Also applies to: 156-163

go.mod (1)

3-3: LGTM!

Also applies to: 987-987

images/ksail-analysis-runner/Dockerfile (1)

17-17: LGTM!

Also applies to: 19-19, 24-24

images/ksail-analysis-runner/smoke.sh (1)

35-35: LGTM!

images/ksail-analysis-runner/smoke_test.go (1)

97-97: LGTM!


📝 Walkthrough

Walkthrough

The module and analysis-runner image now use Go 1.26.9, and the indirect golang.org/x/net dependency is updated. The image exporter checks ctr images export --help and selects --local when the option is advertised. Export returns an error if capability discovery fails or the help output is incomplete. Export tests cover supported and unsupported options, discovery failures, and updated command expectations.

Priority: ➖ Normal

Severity of issue fixed: Medium

Merge Risk: ⚪ Minimal · up to 652b4

This change selects synchronous containerd exports when the node supports them and updates the Go toolchain. No concrete merge-blocking risk was found in the supplied context. Native cluster export trials remain to be run, as the PR notes.


Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 error, 1 warning)

Check name Status Explanation Resolution
Linked Issues check Error The implementation addresses synchronous exports and related fallback behavior, but the stated acceptance criteria still include outstanding native K3s and Vanilla export/import trials or a bounded ar… Complete the required native K3s and Vanilla trials, or provide the bounded public-test archive receipt requested by issue #7642 if a native trial still fails. Confirm the results before merging.
Docstring Coverage Warning Docstring coverage is 13.33% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 15 functions across 7 files. (2 skipped: … Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Out of Scope Changes check Passed The Go version and dependency updates are additional changes, but the objectives explicitly identify them as the security patch from #7641 and document the required merge order. No other unrelated cha…
Title check Passed The title clearly and concisely describes the primary change: using synchronous containerd exports for image operations.
Description check Passed The description directly explains the export timing problem, the synchronous export solution, compatibility handling, capability discovery behavior, and validation scope.
Full details: Docstring Coverage

Explanation

Docstring coverage is 13.33% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 15 functions across 7 files. (2 skipped: 2 unsupported.)

Full details: Linked Issues check

Explanation

The implementation addresses synchronous exports and related fallback behavior, but the stated acceptance criteria still include outstanding native K3s and Vanilla export/import trials or a bounded archive receipt if those trials fail.

  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@devantler devantler left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

🤖 Generated by the Agentic Engineer

Self-review (fallback — CodeRabbit, Codex and Cursor Bugbot unavailable)

Reviewed commit: 96d6c81

  • CodeRabbit: the freshly read authenticated repository included-review refusal, updated 2026-10-09T01:35:46Z, states a 36-minute retry window that remains active. No usage-based billing is authorized. The new head's direct review surfaces contain no current provider verdict; another request is not sent before that reset.
  • Codex: freshly read authenticated account usage-limit notice has no stated reset; the completed fresh lane-health receipt reports a newer 2026-10-09T01:18:08Z refusal and no serving recovery. No credits are authorized.
  • Cursor Bugbot: freshly read authenticated public user/team usage-limit notice has no stated reset; the completed fresh lane-health receipt reports a newer 2026-10-08T22:47:52Z refusal and no serving recovery. No limit increase is authorized.

I reviewed the final five-file export diff against landed main 4dfe77d. Capability discovery occurs once per operation and preserves the selected mode through bulk export, repair and individual fallbacks. A per-operation copy avoids shared mode mutation. Exact flag tokens preserve older containerd compatibility, and discovery failures or missing final help flags stop export. No error, unsupported flag or asynchronous transfer fallback is silently accepted.

This signed integration absorbs the merged security dependency, leaving the full source tree byte-identical to parent 652b452, which received a finding-free CodeRabbit full review and independent static review. That identical tree passes the full root Go suite, image race tests, affected lint and CLI build; the public K3s regression was RED before the repair and GREEN afterward. Compatibility, incomplete-output and repair/fallback negative controls remain active. Signature verification and source comparison pass, and current main is an ancestor.

Complete direct comments, reviews, check-runs and threads at the new head contain no current provider verdict or reported unresolved finding; there are zero unresolved threads. The original failing archive was not retained, so its individual cause remains a timing hypothesis. Native K3s and Vanilla export/import/restart trials and current-head CI remain required before merge. No check or review setting changes.

Verdict: no P0/P1 findings

@github-code-quality

github-code-quality Bot commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

Code Coverage Overview

Languages: Go

Go / code-coverage/go

The overall line coverage in commit d7898d1 in the codex/synchronous-im... branch remains at 71%, unchanged from commit 5d6163a in the main branch.

Show a line coverage summary of the most impacted files.
File main 5d6163a codex/synchronous-im... d7898d1 +/-
pkg/svc/image/repair.go 94% 94% 0%
pkg/svc/image/exporter.go 86% 87% +1%
pkg/svc/provisi...pgrader_wait.go 94% 95% +1%

Updated October 10, 2026 12:36 UTC

@devantler

Copy link
Copy Markdown
Contributor Author

🤖 Generated by the Agentic Engineer

Blocker: #7131 | upstream | last-verified 2026-10-09: Open; current head 96d6c81 fails managed Go Code Quality in run 37871381265/job 113630034853 with a runner shutdown at 02:07:31 UTC. Its log also records dependency acquisition/import defects; the shutdown trigger remains unknown. Owned Go analysis and local validation pass; native cluster trials remain pending. Complete managed extraction and root ARC acceptance remain required.

@devantler devantler removed the blocked label Oct 10, 2026
@devantler

Copy link
Copy Markdown
Contributor Author

🤖 Generated by the Agentic Engineer

No longer parked on #7131. With the default branch merged in (head d7898d1e), the managed Go analysis passed: job 114209866486. I removed the blocked label. The head changed, so this needs its remaining checks green and a fresh review at this head before it can merge.

@devantler devantler left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

🤖 Generated by the Agentic Engineer

Self-review (fallback — CodeRabbit, Codex and Cursor Bugbot unavailable)

Reviewed commit: d7898d1ee1166e7e1980c8ad471d51ff46f6feb3

  • CodeRabbit: the lane-health read at 2026-10-10T14:21Z reports it rate limited until 14:51:51Z (newest refusal: monorepo#4103, updated 14:01:54Z). No paid overage is requested.
  • Codex: the same read reports the account usage limit in force since 2026-10-09T18:11:46Z, with no review served since. Recovery needs account action.
  • Cursor Bugbot: the same read reports no serving evidence; its last known state is the user/team usage-limit notice.

This round is incremental on the round at 96d6c813; the only commit since is a merge of the default branch, and the change against it is still five files in pkg/svc/image (+187 −4). I re-read the whole change.

  • The premise holds against the released containerd sources (read from the Go module proxy): in v2.1.4 ctr images export declares --local as an ordinary flag that is off by default and takes the transfer path when it is not set; in v1.7.27 the flag exists and is on by default, so passing it changes nothing; v1.6.38 has no such flag. That is exactly the three-row table the new test encodes, so the flag is only ever passed where it exists.
  • Probe safety: the mode is chosen from export --help by whole-word match, so --localization cannot be mistaken for it (tested). Empty or cut-off help is refused by requiring the trailing help entry, instead of silently choosing the asynchronous mode (tested), and a failed probe stops the export with the underlying error (tested).
  • Scope of the selection: the choice lives on a per-operation copy of the exporter, so the bulk export, per-image fallback and repair retries all use the same mode and concurrent exports cannot change each other's. The command builder inserts the flag before the archive path, which is where ctr expects options.
  • Cost: one extra ctr call per export on the node. It can turn a previously working export into a failure only if ctr cannot print its own help, in which case the export command itself would not run either.
  • Evidence at this head: all 28 Docker system-test jobs (Vanilla, K3s, Talos, VCluster, KWOK), code coverage and CI - Required Checks are success. Review threads: 0 of 0. The PR merges cleanly.

One thing this does not prove, as the PR body already says: the original unreadable K3s archive was not kept, so whether this was its cause stays unconfirmed. That is a statement about the incident, not a defect in the change.

Verdict: no P0/P1 findings

@devantler
devantler marked this pull request as ready for review October 10, 2026 14:15
@devantler
devantler merged commit 675db03 into main Oct 10, 2026
88 checks passed
@devantler
devantler deleted the codex/synchronous-image-export-7642 branch October 10, 2026 14:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: ✅ Done

Development

Successfully merging this pull request may close these issues.

Make container image exports finish before returning success

1 participant