Skip to content

feat: use generateName for leases to allow alias reuse after deletion#727

Open
bennyz wants to merge 2 commits into
jumpstarter-dev:mainfrom
bennyz:worktree-lease-generate-name
Open

feat: use generateName for leases to allow alias reuse after deletion#727
bennyz wants to merge 2 commits into
jumpstarter-dev:mainfrom
bennyz:worktree-lease-generate-name

Conversation

@bennyz

@bennyz bennyz commented Jun 1, 2026

Copy link
Copy Markdown
Member

Leases created with --lease-id now use K8s generateName instead of a fixed Name. The user-provided alias is stored as a label and resolved transparently in Get/Delete/Update via a name-or-alias lookup. This prevents the "already exists" error when re-creating a lease with the same --lease-id after deletion (since deletion is a soft-delete that leaves the K8s object in etcd).

@coderabbitai

coderabbitai Bot commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds lease alias support across API contract (label key + proto field), controller ToProtobuf propagation and tests, alias-aware ClientService create/get/update/delete with per-alias creation locks, regenerated protobuf/Python stubs, Python client/CLI/MCP surfaces, and related tests and docstring updates.

Changes

Lease alias support

Layer / File(s) Summary
Lease label and proto contract
controller/api/v1alpha1/lease_types.go, protocol/proto/jumpstarter/client/v1/client.proto, python/packages/jumpstarter-protocol/.../client_pb2.py, python/packages/jumpstarter-protocol/.../client_pb2.pyi
Adds LeaseLabelName label key and Lease.alias OUTPUT_ONLY proto field; regenerated Python descriptors/stubs updated with alias metadata and typing/docstrings.
Controller ToProtobuf and tests
controller/api/v1alpha1/lease_helpers.go, controller/api/v1alpha1/lease_helpers_test.go
Controller populates protobuf Lease.alias from the LeaseLabelName label when present; adds tests for present and absent label cases.
Alias-aware ClientService operations
controller/internal/service/client/v1/client_service.go
ClientService gains alias resolution helpers (exact name then label-based active lookup), per-alias mutexes to guard Create when lease_id is provided, and updates Get/Update/Delete/Create flows to operate on resolved lease namespace/name or generated names with labels.
Python client model, CLI and MCP surfaces + tests
python/packages/jumpstarter/jumpstarter/client/grpc.py, python/packages/jumpstarter-cli/jumpstarter_cli/shell.py, python/packages/jumpstarter-mcp/jumpstarter_mcp/tools/leases.py, tests
Python Lease model adds optional alias populated from protobuf; CLI display and MCP listing include alias only when present; unit tests added for formatting and listing behavior.
Generated stubs/docstring updates & e2e test tweak
python/packages/jumpstarter-protocol/... (multiple *_pb2.py, *_pb2.pyi, *_pb2_grpc.py, *_pb2_grpc.pyi), e2e/test/hooks_test.go
Autogenerated Python gRPC/protobuf stubs updated docstrings and type stubs across modules; e2e hook test regex for lease token loosened to include lowercase alphanumerics and hyphen.

Sequence Diagram

sequenceDiagram
  participant Client
  participant ClientService
  participant Resolver as resolveLeaseByNameOrAlias
  participant KubeAPI as Kubernetes API
  Client->>ClientService: Create/Get/Update/Delete (name or lease_id)
  ClientService->>Resolver: resolve name or alias
  Resolver->>KubeAPI: Get(name)
  alt not found
    Resolver->>KubeAPI: List(labelSelector=jumpstarter.dev/lease-name, limit=2)
  end
  KubeAPI-->>Resolver: lease(s) or none
  Resolver-->>ClientService: resolved lease or error
  ClientService-->>Client: result
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Suggested labels

enhancement, go, protocol, python

Suggested reviewers

  • mangelajo
  • raballew
  • evakhoni

Poem

🐰 I hopped through labels, soft and fleet,
An alias found where name and metadata meet.
From proto to CLI the little name gleams,
Tests and servers now share the same dreams.
🥕

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 56.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The PR title clearly describes the main change: using generateName for leases to enable alias reuse after deletion, which is the core feature being implemented.
Description check ✅ Passed The PR description is directly related to the changeset, explaining the Kubernetes generateName approach, label-based alias storage, transparent resolution, and the problem it solves.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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 and usage tips.

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/client/v1/client_pb2.py`:
- Around line 33-34: The generated protobufs in client_pb2.py import nonexistent
top-level package 'jumpstarter.v1' (see the import lines that map to
jumpstarter_dot_v1_dot_kubernetes__pb2 and jumpstarter_dot_v1_dot_common__pb2);
fix by regenerating the jumpstarter-protocol protos with the repo protobuf-gen
target so the Makefile's relative-import rewrite is applied, or manually replace
the absolute imports with the correct relative imports used elsewhere (e.g.,
change the import that produces jumpstarter_dot_v1_dot_kubernetes__pb2 to use
the relative package path like ...v1.kubernetes_pb2 and adjust the common_pb2
import to a relative import) so client_pb2.py no longer tries to import
jumpstarter.v1.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 455a9c3c-dabb-4175-81e0-a064f673c020

📥 Commits

Reviewing files that changed from the base of the PR and between ad6f91b and f16cd14.

⛔ Files ignored due to path filters (9)
  • controller/internal/protocol/jumpstarter/client/v1/client.pb.go is excluded by !**/*.pb.go
  • controller/internal/protocol/jumpstarter/client/v1/client_grpc.pb.go is excluded by !**/*.pb.go
  • controller/internal/protocol/jumpstarter/v1/common.pb.go is excluded by !**/*.pb.go
  • controller/internal/protocol/jumpstarter/v1/jumpstarter.pb.go is excluded by !**/*.pb.go
  • controller/internal/protocol/jumpstarter/v1/jumpstarter_grpc.pb.go is excluded by !**/*.pb.go
  • controller/internal/protocol/jumpstarter/v1/kubernetes.pb.go is excluded by !**/*.pb.go
  • controller/internal/protocol/jumpstarter/v1/router.pb.go is excluded by !**/*.pb.go
  • controller/internal/protocol/jumpstarter/v1/router_grpc.pb.go is excluded by !**/*.pb.go
  • python/uv.lock is excluded by !**/*.lock
📒 Files selected for processing (21)
  • controller/api/v1alpha1/lease_helpers.go
  • controller/api/v1alpha1/lease_helpers_test.go
  • controller/api/v1alpha1/lease_types.go
  • controller/internal/service/client/v1/client_service.go
  • protocol/proto/jumpstarter/client/v1/client.proto
  • python/packages/jumpstarter-cli/jumpstarter_cli/shell.py
  • python/packages/jumpstarter-mcp/jumpstarter_mcp/tools/leases.py
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/client/v1/client_pb2.py
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/client/v1/client_pb2.pyi
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/client/v1/client_pb2_grpc.py
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/client/v1/client_pb2_grpc.pyi
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/v1/common_pb2.pyi
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/v1/jumpstarter_pb2.py
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/v1/jumpstarter_pb2.pyi
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/v1/jumpstarter_pb2_grpc.py
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/v1/jumpstarter_pb2_grpc.pyi
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/v1/kubernetes_pb2.pyi
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/v1/router_pb2.pyi
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/v1/router_pb2_grpc.py
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/v1/router_pb2_grpc.pyi
  • python/packages/jumpstarter/jumpstarter/client/grpc.py

@bennyz bennyz force-pushed the worktree-lease-generate-name branch from f16cd14 to 4088449 Compare June 2, 2026 05:28

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/client/v1/client_pb2_grpc.py`:
- Around line 79-81: Update the RPC doc comments in the source .proto for the
lease service to state that GetLease and DeleteLease resolve leases by name or
alias (not name-only), then re-run the protobuf/grpc codegen to regenerate the
Python stubs so client_pb2_grpc.py reflects the new docs; specifically edit the
proto comments for the RPCs corresponding to the GetLease and DeleteLease
methods and regenerate to update the docstrings in the GetLease and DeleteLease
functions.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 88a8252c-f456-4f34-98c1-189bc967cd18

📥 Commits

Reviewing files that changed from the base of the PR and between f16cd14 and 4088449.

⛔ Files ignored due to path filters (9)
  • controller/internal/protocol/jumpstarter/client/v1/client.pb.go is excluded by !**/*.pb.go
  • controller/internal/protocol/jumpstarter/client/v1/client_grpc.pb.go is excluded by !**/*.pb.go
  • controller/internal/protocol/jumpstarter/v1/common.pb.go is excluded by !**/*.pb.go
  • controller/internal/protocol/jumpstarter/v1/jumpstarter.pb.go is excluded by !**/*.pb.go
  • controller/internal/protocol/jumpstarter/v1/jumpstarter_grpc.pb.go is excluded by !**/*.pb.go
  • controller/internal/protocol/jumpstarter/v1/kubernetes.pb.go is excluded by !**/*.pb.go
  • controller/internal/protocol/jumpstarter/v1/router.pb.go is excluded by !**/*.pb.go
  • controller/internal/protocol/jumpstarter/v1/router_grpc.pb.go is excluded by !**/*.pb.go
  • python/uv.lock is excluded by !**/*.lock
📒 Files selected for processing (20)
  • controller/api/v1alpha1/lease_helpers.go
  • controller/api/v1alpha1/lease_helpers_test.go
  • controller/api/v1alpha1/lease_types.go
  • controller/internal/service/client/v1/client_service.go
  • protocol/proto/jumpstarter/client/v1/client.proto
  • python/packages/jumpstarter-cli/jumpstarter_cli/shell.py
  • python/packages/jumpstarter-mcp/jumpstarter_mcp/tools/leases.py
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/client/v1/client_pb2.py
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/client/v1/client_pb2.pyi
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/client/v1/client_pb2_grpc.py
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/client/v1/client_pb2_grpc.pyi
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/v1/common_pb2.pyi
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/v1/jumpstarter_pb2.pyi
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/v1/jumpstarter_pb2_grpc.py
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/v1/jumpstarter_pb2_grpc.pyi
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/v1/kubernetes_pb2.pyi
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/v1/router_pb2.pyi
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/v1/router_pb2_grpc.py
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/v1/router_pb2_grpc.pyi
  • python/packages/jumpstarter/jumpstarter/client/grpc.py
✅ Files skipped from review due to trivial changes (7)
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/v1/router_pb2_grpc.pyi
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/v1/kubernetes_pb2.pyi
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/client/v1/client_pb2.py
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/v1/jumpstarter_pb2_grpc.pyi
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/v1/common_pb2.pyi
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/client/v1/client_pb2_grpc.pyi
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/v1/router_pb2.pyi
🚧 Files skipped from review as they are similar to previous changes (9)
  • controller/api/v1alpha1/lease_helpers_test.go
  • protocol/proto/jumpstarter/client/v1/client.proto
  • controller/api/v1alpha1/lease_helpers.go
  • python/packages/jumpstarter/jumpstarter/client/grpc.py
  • python/packages/jumpstarter-mcp/jumpstarter_mcp/tools/leases.py
  • python/packages/jumpstarter-cli/jumpstarter_cli/shell.py
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/v1/router_pb2_grpc.py
  • controller/internal/service/client/v1/client_service.go
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/client/v1/client_pb2.pyi

Comment on lines 79 to +81
def GetLease(self, request, context):
"""Missing associated documentation comment in .proto file."""
"""Retrieve a single lease by resource name.
"""

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.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Update the generated RPC docs to mention alias lookup.

These docstrings still describe name-only lookup, but this PR’s contract says GetLease and DeleteLease resolve a lease by name or alias. Please fix the source .proto comments and regenerate so the Python stubs do not advertise narrower behavior than the service actually supports.

Also applies to: 107-109

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/client/v1/client_pb2_grpc.py`
around lines 79 - 81, Update the RPC doc comments in the source .proto for the
lease service to state that GetLease and DeleteLease resolve leases by name or
alias (not name-only), then re-run the protobuf/grpc codegen to regenerate the
Python stubs so client_pb2_grpc.py reflects the new docs; specifically edit the
proto comments for the RPCs corresponding to the GetLease and DeleteLease
methods and regenerate to update the docstrings in the GetLease and DeleteLease
functions.

@bennyz bennyz force-pushed the worktree-lease-generate-name branch 3 times, most recently from d33a6bd to cddd7dd Compare June 2, 2026 06:28

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@python/packages/jumpstarter-mcp/jumpstarter_mcp/server_test.py`:
- Line 287: The test defines duration with the wrong type annotation—change the
field declaration in server_test.py from `duration: None = None` to an optional
timedelta type to match the Lease model (e.g., `duration: datetime.timedelta |
None = None`) and ensure `datetime.timedelta` (or `timedelta`) is imported;
alternatively remove the unused `duration` field if tests don't need it. Refer
to the Lease-related test variables where `duration` is used to update the
annotation or remove the field accordingly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: a59445c5-0568-46e4-b8d6-3ba6db0d5a95

📥 Commits

Reviewing files that changed from the base of the PR and between 4088449 and cddd7dd.

⛔ Files ignored due to path filters (9)
  • controller/internal/protocol/jumpstarter/client/v1/client.pb.go is excluded by !**/*.pb.go
  • controller/internal/protocol/jumpstarter/client/v1/client_grpc.pb.go is excluded by !**/*.pb.go
  • controller/internal/protocol/jumpstarter/v1/common.pb.go is excluded by !**/*.pb.go
  • controller/internal/protocol/jumpstarter/v1/jumpstarter.pb.go is excluded by !**/*.pb.go
  • controller/internal/protocol/jumpstarter/v1/jumpstarter_grpc.pb.go is excluded by !**/*.pb.go
  • controller/internal/protocol/jumpstarter/v1/kubernetes.pb.go is excluded by !**/*.pb.go
  • controller/internal/protocol/jumpstarter/v1/router.pb.go is excluded by !**/*.pb.go
  • controller/internal/protocol/jumpstarter/v1/router_grpc.pb.go is excluded by !**/*.pb.go
  • python/uv.lock is excluded by !**/*.lock
📒 Files selected for processing (22)
  • controller/api/v1alpha1/lease_helpers.go
  • controller/api/v1alpha1/lease_helpers_test.go
  • controller/api/v1alpha1/lease_types.go
  • controller/internal/service/client/v1/client_service.go
  • protocol/proto/jumpstarter/client/v1/client.proto
  • python/packages/jumpstarter-cli/jumpstarter_cli/shell.py
  • python/packages/jumpstarter-cli/jumpstarter_cli/shell_test.py
  • python/packages/jumpstarter-mcp/jumpstarter_mcp/server_test.py
  • python/packages/jumpstarter-mcp/jumpstarter_mcp/tools/leases.py
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/client/v1/client_pb2.py
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/client/v1/client_pb2.pyi
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/client/v1/client_pb2_grpc.py
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/client/v1/client_pb2_grpc.pyi
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/v1/common_pb2.pyi
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/v1/jumpstarter_pb2.pyi
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/v1/jumpstarter_pb2_grpc.py
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/v1/jumpstarter_pb2_grpc.pyi
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/v1/kubernetes_pb2.pyi
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/v1/router_pb2.pyi
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/v1/router_pb2_grpc.py
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/v1/router_pb2_grpc.pyi
  • python/packages/jumpstarter/jumpstarter/client/grpc.py
✅ Files skipped from review due to trivial changes (10)
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/v1/router_pb2_grpc.pyi
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/v1/jumpstarter_pb2_grpc.py
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/client/v1/client_pb2_grpc.pyi
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/v1/router_pb2_grpc.py
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/client/v1/client_pb2.py
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/v1/kubernetes_pb2.pyi
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/v1/common_pb2.pyi
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/v1/jumpstarter_pb2.pyi
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/v1/router_pb2.pyi
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/client/v1/client_pb2_grpc.py
🚧 Files skipped from review as they are similar to previous changes (7)
  • controller/api/v1alpha1/lease_types.go
  • protocol/proto/jumpstarter/client/v1/client.proto
  • controller/api/v1alpha1/lease_helpers.go
  • python/packages/jumpstarter-mcp/jumpstarter_mcp/tools/leases.py
  • controller/api/v1alpha1/lease_helpers_test.go
  • controller/internal/service/client/v1/client_service.go
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/client/v1/client_pb2.pyi

conditions: list
effective_begin_time: datetime | None = None
effective_end_time: datetime | None = None
duration: None = None

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.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Incorrect type annotation for duration field.

The type annotation duration: None = None declares the field type as None itself, not as an optional value. This should likely be duration: timedelta | None = None to match the actual Lease model, or the field could be omitted if it's unused in these tests.

📝 Proposed fix
-    duration: None = None
+    duration: timedelta | None = None
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
duration: None = None
duration: timedelta | None = None
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@python/packages/jumpstarter-mcp/jumpstarter_mcp/server_test.py` at line 287,
The test defines duration with the wrong type annotation—change the field
declaration in server_test.py from `duration: None = None` to an optional
timedelta type to match the Lease model (e.g., `duration: datetime.timedelta |
None = None`) and ensure `datetime.timedelta` (or `timedelta`) is imported;
alternatively remove the unused `duration` field if tests don't need it. Refer
to the Lease-related test variables where `duration` is used to update the
annotation or remove the field accordingly.

@bennyz bennyz force-pushed the worktree-lease-generate-name branch from cddd7dd to 876af2e Compare June 2, 2026 08:56

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@controller/internal/service/client/v1/client_service.go`:
- Around line 291-303: The duplicate-alias check calls
s.resolveLeaseByAlias(ctx, namespace, req.LeaseId) but only handles err == nil
and ignores other errors, allowing duplicate aliases on transient failures;
update the block in CreateLease (or wherever jlease is prepared) so that after
calling resolveLeaseByAlias you treat a NotFound error as the only acceptable
error and for any other non-nil error return that error (wrap it with an
appropriate gRPC code, e.g., status.Errorf(codes.Internal, "failed to resolve
lease by alias %q: %v", req.LeaseId, err)); keep the existing AlreadyExists
return when err == nil and still set jlease.GenerateName and jlease.Labels when
the alias is acceptable.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: dfdae748-8c96-4b32-ab14-5d5a5f5faf87

📥 Commits

Reviewing files that changed from the base of the PR and between cddd7dd and 876af2e.

⛔ Files ignored due to path filters (9)
  • controller/internal/protocol/jumpstarter/client/v1/client.pb.go is excluded by !**/*.pb.go
  • controller/internal/protocol/jumpstarter/client/v1/client_grpc.pb.go is excluded by !**/*.pb.go
  • controller/internal/protocol/jumpstarter/v1/common.pb.go is excluded by !**/*.pb.go
  • controller/internal/protocol/jumpstarter/v1/jumpstarter.pb.go is excluded by !**/*.pb.go
  • controller/internal/protocol/jumpstarter/v1/jumpstarter_grpc.pb.go is excluded by !**/*.pb.go
  • controller/internal/protocol/jumpstarter/v1/kubernetes.pb.go is excluded by !**/*.pb.go
  • controller/internal/protocol/jumpstarter/v1/router.pb.go is excluded by !**/*.pb.go
  • controller/internal/protocol/jumpstarter/v1/router_grpc.pb.go is excluded by !**/*.pb.go
  • python/uv.lock is excluded by !**/*.lock
📒 Files selected for processing (23)
  • controller/api/v1alpha1/lease_helpers.go
  • controller/api/v1alpha1/lease_helpers_test.go
  • controller/api/v1alpha1/lease_types.go
  • controller/internal/service/client/v1/client_service.go
  • e2e/test/hooks_test.go
  • protocol/proto/jumpstarter/client/v1/client.proto
  • python/packages/jumpstarter-cli/jumpstarter_cli/shell.py
  • python/packages/jumpstarter-cli/jumpstarter_cli/shell_test.py
  • python/packages/jumpstarter-mcp/jumpstarter_mcp/server_test.py
  • python/packages/jumpstarter-mcp/jumpstarter_mcp/tools/leases.py
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/client/v1/client_pb2.py
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/client/v1/client_pb2.pyi
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/client/v1/client_pb2_grpc.py
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/client/v1/client_pb2_grpc.pyi
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/v1/common_pb2.pyi
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/v1/jumpstarter_pb2.pyi
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/v1/jumpstarter_pb2_grpc.py
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/v1/jumpstarter_pb2_grpc.pyi
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/v1/kubernetes_pb2.pyi
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/v1/router_pb2.pyi
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/v1/router_pb2_grpc.py
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/v1/router_pb2_grpc.pyi
  • python/packages/jumpstarter/jumpstarter/client/grpc.py
✅ Files skipped from review due to trivial changes (10)
  • e2e/test/hooks_test.go
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/v1/router_pb2.pyi
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/client/v1/client_pb2.py
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/v1/jumpstarter_pb2_grpc.pyi
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/v1/jumpstarter_pb2_grpc.py
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/client/v1/client_pb2_grpc.pyi
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/v1/common_pb2.pyi
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/v1/router_pb2_grpc.pyi
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/client/v1/client_pb2_grpc.py
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/v1/jumpstarter_pb2.pyi
🚧 Files skipped from review as they are similar to previous changes (11)
  • controller/api/v1alpha1/lease_types.go
  • controller/api/v1alpha1/lease_helpers.go
  • controller/api/v1alpha1/lease_helpers_test.go
  • python/packages/jumpstarter-cli/jumpstarter_cli/shell_test.py
  • python/packages/jumpstarter/jumpstarter/client/grpc.py
  • python/packages/jumpstarter-cli/jumpstarter_cli/shell.py
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/v1/router_pb2_grpc.py
  • python/packages/jumpstarter-mcp/jumpstarter_mcp/tools/leases.py
  • protocol/proto/jumpstarter/client/v1/client.proto
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/v1/kubernetes_pb2.pyi
  • python/packages/jumpstarter-protocol/jumpstarter_protocol/jumpstarter/client/v1/client_pb2.pyi

Comment thread controller/internal/service/client/v1/client_service.go Outdated
@mangelajo

Copy link
Copy Markdown
Member

I am not sure about the extra layer of complexity, what if we just trigger a generate name on the lease name if there is a conflict?

The current implementation has some level of race condition (2 leases could end up with the same label) ...

@raballew

raballew commented Jun 3, 2026

Copy link
Copy Markdown
Member

I am not sure about the extra layer of complexity, what if we just trigger a generate name on the lease name if there is a conflict?

The current implementation has some level of race condition (2 leases could end up with the same label) ...

I was about to comment the same thing. I think this just moves the problem one layer of complexity up. maybe we run generated name with the prefix of the user provided input if it conflicts, or we could also simply raise an error and clean up leases properly - the latter is what i prefer @mangelajo

Regenerated Go and Python protobuf stubs pick up doc comments
from proto definitions that the previous generator version omitted.
No functional changes.

Assited-by: claude-opus-4.6
Signed-off-by: Benny Zlotnik <bzlotnik@redhat.com>
@bennyz bennyz force-pushed the worktree-lease-generate-name branch from 876af2e to aac6e20 Compare June 10, 2026 07:14
@bennyz

bennyz commented Jun 10, 2026

Copy link
Copy Markdown
Member Author

I am not sure about the extra layer of complexity, what if we just trigger a generate name on the lease name if there is a conflict?

The current implementation has some level of race condition (2 leases could end up with the same label) ...

the problem with this is that it's essentially the same behavior we already have and the user won't get the name they request

Lease names now use K8s generateName instead of fixed names, allowing
custom lease IDs (aliases) to be reused after deletion. The user-provided
alias is stored as a label and resolved transparently in Get/Delete/Update.

Assisted-by: claude-opus-4.6
Signed-off-by: Benny Zlotnik <bzlotnik@redhat.com>
@bennyz bennyz force-pushed the worktree-lease-generate-name branch from aac6e20 to d93af9d Compare June 10, 2026 07:21
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.

3 participants