Skip to content

Reject CreateContainer on a non-ready sandbox#13614

Open
yugstar wants to merge 1 commit into
containerd:mainfrom
yugstar:fix-13599-reject-create-on-stopped-sandbox
Open

Reject CreateContainer on a non-ready sandbox#13614
yugstar wants to merge 1 commit into
containerd:mainfrom
yugstar:fix-13599-reject-create-on-stopped-sandbox

Conversation

@yugstar

@yugstar yugstar commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Fixes #13599

Description

CreateContainer loads the sandbox (c.sandboxStore.Get) but never checks that the sandbox is in the ready state before proceeding. As a result a container can be created against a stopped sandbox, which violates the CRI spec — RunPodSandbox/CreateContainer require the sandbox to be running — and is what blocks the cri-tools conformance test referenced in #13599.

StartContainer already guards against this:

if sandbox.Status.Get().State != sandboxstore.StateReady {
    return nil, fmt.Errorf("sandbox container %q is not running", sandboxID)
}

This applies the same guard in CreateContainer, right after the sandbox is loaded.

Note: container_create.go imported the sandbox store package as sandbox, which is shadowed by the local sandbox variable inside CreateContainer. I aliased the import to sandboxstore (matching container_start.go) so the StateReady constant can be referenced; the only other use of the package alias in the file (a struct field type) was updated accordingly.

Test

Added TestCreateContainerNotReadySandbox, which adds a StateNotReady sandbox to the store and asserts CreateContainer fails with is not running.

--- PASS: TestCreateContainerNotReadySandbox (0.00s)

go vet and the existing internal/cri/server container/sandbox tests pass.

CreateContainer loaded the sandbox but never verified it was in the
ready state, so a container could be created against a stopped sandbox,
which violates the CRI spec (CreateContainer must fail if the sandbox is
not running). Add the same guard that StartContainer already applies,
returning "sandbox container %q is not running".

The sandbox store package was imported as `sandbox`, which is shadowed
by the local `sandbox` variable inside CreateContainer; alias it to
`sandboxstore` (matching container_start.go) so the state constant can
be referenced.

Fixes containerd#13599

Signed-off-by: Aman Raj <[email protected]>
Copilot AI review requested due to automatic review settings June 17, 2026 19:59
@github-project-automation github-project-automation Bot moved this to Needs Triage in Pull Request Review Jun 17, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds a CRI-spec guard to prevent creating containers in non-ready sandboxes, and introduces a unit test to verify the behavior.

Changes:

  • Reject CreateContainer requests when the target sandbox is not in StateReady.
  • Align sandbox store import usage via sandboxstore alias and update related types.
  • Add a unit test ensuring non-ready sandboxes cause CreateContainer to fail.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
internal/cri/server/container_create.go Adds a readiness-state check for the sandbox before allowing container creation; updates sandbox store import/type references.
internal/cri/server/container_create_test.go Adds a regression test that verifies CreateContainer is rejected for a non-ready sandbox.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

// The CRI spec requires that containers are only created in a running
// sandbox. Reject the request otherwise, matching StartContainer.
if sandbox.Status.Get().State != sandboxstore.StateReady {
return nil, fmt.Errorf("sandbox container %q is not running", sandbox.ID)
Comment on lines +70 to +74
// The CRI spec requires that containers are only created in a running
// sandbox. Reject the request otherwise, matching StartContainer.
if sandbox.Status.Get().State != sandboxstore.StateReady {
return nil, fmt.Errorf("sandbox container %q is not running", sandbox.ID)
}
SandboxConfig: sandboxConfig,
})
require.Error(t, err)
assert.Contains(t, err.Error(), "is not running")
@yugstar

yugstar commented Jun 18, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the review. All three points come down to staying consistent with the existing sandbox-not-ready guard in container_start.go, which this mirrors:

  1. Error wording: container_start.go uses the same "sandbox container %q is not running" text for the same check (line 94), so I kept it identical rather than introduce a second phrasing for the same condition.
  2. gRPC status code: the guard in container_start.go also returns a plain fmt.Errorf and the CRI layer wraps it, so matching it keeps the two paths uniform.
  3. Test assertion: the existing tests in this package assert on the error substring and there is no typed error to match on here, so I followed the same approach.

Happy to switch to a typed error with a FailedPrecondition status if preferred, but it would be better done for both create and start together in a separate change so the two stay in sync.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

Status: Needs Triage

Development

Successfully merging this pull request may close these issues.

CreateContainer CRI API should be rejected on stopped sandbox

3 participants