Skip to content

feat: register and activate a container image in one call - #869

Open
drake-nominal wants to merge 1 commit into
mainfrom
dteid/register-image-activate
Open

feat: register and activate a container image in one call#869
drake-nominal wants to merge 1 commit into
mainfrom
dteid/register-image-activate

Conversation

@drake-nominal

Copy link
Copy Markdown
Collaborator

Adds an opt-in one-step register-and-deploy flow, keeping registration side-effect-free by default. Builds on #865's corrected register_image semantics.

SDK

ContainerizedExtractor.register_image(..., activate: bool = False) — when true, the freshly registered image is activated on the extractor via set_active_image, which polls the image to readiness first: current backends push synchronously and return READY, but the poll keeps the flow correct if a backend ever processes asynchronously (and for any legacy non-READY rows). The extractor instance refreshes in place; failure modes are documented in Raises: (NominalAlreadyExistsError for immutable-tag collisions, NominalContainerImageError if the image can't become READY).

The default stays False — registration remains the staging state, preserving gated-rollout and rollback workflows (many registered images, one active).

CLI

nom container extractor register-image --activate — one-step deploy for continuous-deployment pipelines:

nom container extractor register-image -r "$EXTRACTOR_RID"     -f image.tar -t $(git rev-parse --short HEAD) -c extractor-config.json --activate

stdout stays RID-only (activation status goes to stderr), so $(...) capture is unaffected. Release-gated pipelines keep the two-step register / set-active-image flow.

Testing note

The activate path is a two-line composition over set_active_image, whose poll-then-activate behavior is already covered by tests/core/test_containerized_extractor.py. A direct happy-path test of register_image would require intercepting the multipart upload's raw HTTP PUTs (not reachable via MagicMock clients), which is why no such test exists for the method today.

🤖 Generated with Claude Code

Adds activate=False to ContainerizedExtractor.register_image and
--activate to `nom container extractor register-image`. When set, the
freshly registered image is activated on the extractor via
set_active_image, which still polls the image to readiness first —
current backends return images READY synchronously, but the poll keeps
the flow correct against async processing. The default remains
register-only (the staging state for release-gated rollouts).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit c3607d9. Configure here.

Comment thread nominal/cli/container.py
if wait:
if activate:
click.secho(f"Activated image {image.rid} ({image.tag}) on {extractor.name}", fg="green", err=True)
elif wait:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Register activate ignores wait flag

Medium Severity

With --activate, register-image never honors --no-wait: activation always blocks in register_image via set_active_image(..., poll_until_ready=True), while the sibling set-active-image command maps --wait/--no-wait to poll_until_ready. Pipelines using --activate --no-wait still wait until READY despite the flag.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit c3607d9. Configure here.

@claude

claude Bot commented Jul 2, 2026

Copy link
Copy Markdown

Claude finished @drake-nominal's task in 1m 51s —— View job


Review

  • Read changed files and repo conventions
  • Run structural lens (thermo-nuclear)
  • Assess API ergonomics, tests, docstrings, breaking changes
  • Post review

Overview

Well-considered change. The activate kwarg is keyword-only and defaults False, keeping registration side-effect-free — consistent with the rest of the public surface and preserving the staged register-then-activate workflow as the default. The SDK side is a genuinely thin two-line composition over the already-tested set_active_image, so skipping a dedicated test here is the right call (the plumbing is trivially correct). Docstrings are thorough google-style with accurate Args/Returns/Raises. No breaking changes — purely additive optional params on both the method and the CLI.

I verified one thing worth calling out as not a bug: register_image discards the return value of set_active_image, but _refresh_from_api mutates the frozen dataclass in place via update_dataclass(self, ...) and returns self, so the docstring's "refreshing this instance in place" claim holds.

Defects

The only real issue — --activate making --wait/--no-wait a dead flag (activation hardcodes poll_until_ready=True at both the CLI and core layers, unlike the sibling set-active-image which threads the flag through) — was already flagged by Cursor Bugbot on nominal/cli/container.py:245. I've endorsed that comment (👍) rather than restate it; the clean fix is to thread wait into the activate path so there's a single poll decision instead of a silently-ignored flag.

No other structural or maintainability concerns: the diff is small, no file approaches a size boundary, and no spaghetti was bolted onto existing flows.
· dteid/register-image-activate

@devin-ai-integration devin-ai-integration Bot 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.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 1 additional finding.

Open in Devin Review

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant