Skip to content
This repository was archived by the owner on Jan 23, 2026. It is now read-only.

load ssh identity lazily#715

Merged
mangelajo merged 2 commits intojumpstarter-dev:mainfrom
michalskrivanek:lazy-ssh
Oct 21, 2025
Merged

load ssh identity lazily#715
mangelajo merged 2 commits intojumpstarter-dev:mainfrom
michalskrivanek:lazy-ssh

Conversation

@michalskrivanek
Copy link
Copy Markdown
Contributor

@michalskrivanek michalskrivanek commented Oct 20, 2025

on first use, to prevent a failure on startup if the file doesn't exist yet

Summary by CodeRabbit

  • Refactor
    • SSH identity is now loaded on first use rather than during object initialization; error handling occurs at access time and the identity is cached after first read.
  • Tests
    • Tests updated to expect deferred loading, verify caching after first access, and validate error behavior on first retrieval.

@netlify
Copy link
Copy Markdown

netlify bot commented Oct 20, 2025

Deploy Preview for jumpstarter-docs ready!

Name Link
🔨 Latest commit 1577cc2
🔍 Latest deploy log https://app.netlify.com/projects/jumpstarter-docs/deploys/68f7430611dd3b0008ebad50
😎 Deploy Preview https://deploy-preview-715--jumpstarter-docs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Oct 20, 2025

Walkthrough

The SSH driver's identity file read was moved from eager initialization to lazy, on-first-use loading: __post_init__ no longer reads the identity file; get_ssh_identity() reads, caches, and raises on read errors when first called.

Changes

Cohort / File(s) Summary
SSH Identity Lazy Loading
packages/jumpstarter-driver-ssh/jumpstarter_driver_ssh/driver.py
Removed eager reading of ssh_identity_file in __post_init__; implemented lazy read-and-cache in get_ssh_identity() and surface ConfigurationError on read failure during access.
Tests Updated for Lazy Load
packages/jumpstarter-driver-ssh/jumpstarter_driver_ssh/driver_test.py
Updated tests to expect ssh_identity to be None at construction, verify first-use loading and caching via get_ssh_identity(), and ensure errors occur on first access rather than instantiation.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Caller
  participant SSHWrapper
  participant FS as FileSystem

  Caller->>SSHWrapper: call get_ssh_identity()
  alt ssh_identity cached
    SSHWrapper-->>Caller: return cached ssh_identity
  else ssh_identity missing & ssh_identity_file set
    SSHWrapper->>FS: read `ssh_identity_file`
    alt file read success
      FS-->>SSHWrapper: file contents
      SSHWrapper-->>Caller: return and cache ssh_identity
    else read error
      FS-->>SSHWrapper: read error
      SSHWrapper--x Caller: raise ConfigurationError
    end
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • jumpstarter-dev/jumpstarter#687 — Introduced SSH identity attributes and initial get_ssh_identity behavior; directly related to identity-loading logic.
  • jumpstarter-dev/jumpstarter#689 — Related tests and adjustments around ssh_identity / ssh_identity_file behavior and error handling.

Suggested reviewers

  • mangelajo
  • kirkbrauer

Poem

🐰
I waited on a shelf so still,
The key unread until the will,
A whisper fetches, cached and bright,
I keep it warm for next invite —
Hoppity, lazy (and polite)! 🥕

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The pull request title "load ssh identity lazily" directly and clearly describes the main change in the changeset. The primary modification is transitioning SSH identity loading from eager initialization to lazy loading on first use via get_ssh_identity(). The title is specific and unambiguous—it accurately summarizes the technical change without misleading information. A teammate scanning the commit history would immediately understand that this change implements lazy-loading behavior for SSH identity.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
packages/jumpstarter-driver-ssh/jumpstarter_driver_ssh/driver.py (1)

46-49: Prefer specific exception types over broad Exception catch.

Catching all exceptions can mask unexpected errors. File operations typically raise OSError or its subclasses.

-            except Exception as e:
-                raise ConfigurationError(f"Failed to read ssh_identity_file '{self.ssh_identity_file}': {e}") from None
+            except OSError as e:
+                raise ConfigurationError(f"Failed to read ssh_identity_file '{self.ssh_identity_file}': {e}") from e

Note: Also removed from None to preserve the exception chain for better debugging.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2863bcd and 2f775e3.

📒 Files selected for processing (1)
  • packages/jumpstarter-driver-ssh/jumpstarter_driver_ssh/driver.py (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: e2e
  • GitHub Check: pytest-matrix (ubuntu-24.04, 3.13)
  • GitHub Check: pytest-matrix (macos-15, 3.12)
  • GitHub Check: pytest-matrix (macos-15, 3.11)
  • GitHub Check: pytest-matrix (ubuntu-24.04, 3.12)

Comment thread packages/jumpstarter-driver-ssh/jumpstarter_driver_ssh/driver.py
@mangelajo
Copy link
Copy Markdown
Member

@michalskrivanek there is a test that needs fixing: FAILED jumpstarter_driver_ssh/driver_test.py::test_ssh_identity_file_read_error - Failed: DID NOT RAISE <class 'jumpstarter.common.exceptions.ConfigurationError'>

Copy link
Copy Markdown
Member

@mangelajo mangelajo left a comment

Choose a reason for hiding this comment

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

FAILED jumpstarter_driver_ssh/driver_test.py::test_ssh_identity_file_read_error - Failed: DID NOT RAISE <class 'jumpstarter.common.exceptions.ConfigurationError'>

This one needs fixing

on first use, to prevent a failure on startup if the file doesn't exist yet
auto-merge was automatically disabled October 21, 2025 08:14

Head branch was pushed to by a user without write access

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
packages/jumpstarter-driver-ssh/jumpstarter_driver_ssh/driver.py (1)

44-49: Lazy load looks good; consider path expansion + explicit UTF-8 read.

This preserves the new behavior. Two small hardening tweaks:

  • Expand env vars and ~ in ssh_identity_file.
  • Read with explicit UTF-8 to avoid platform-default surprises.

Apply within this block:

-        if self.ssh_identity is None and self.ssh_identity_file:
-            try:
-                self.ssh_identity = Path(self.ssh_identity_file).read_text()
-            except Exception as e:
-                raise ConfigurationError(f"Failed to read ssh_identity_file '{self.ssh_identity_file}': {e}") from None
+        if self.ssh_identity is None and self.ssh_identity_file:
+            try:
+                path = Path(os.path.expandvars(self.ssh_identity_file)).expanduser()
+                self.ssh_identity = path.read_text(encoding="utf-8")
+            except Exception as e:
+                raise ConfigurationError(f"Failed to read ssh_identity_file '{self.ssh_identity_file}': {e}") from None

Add import at top:

-from dataclasses import dataclass
-from pathlib import Path
+from dataclasses import dataclass
+import os
+from pathlib import Path
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2f775e3 and af48116.

📒 Files selected for processing (2)
  • packages/jumpstarter-driver-ssh/jumpstarter_driver_ssh/driver.py (1 hunks)
  • packages/jumpstarter-driver-ssh/jumpstarter_driver_ssh/driver_test.py (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
packages/jumpstarter-driver-ssh/jumpstarter_driver_ssh/driver_test.py (2)
packages/jumpstarter-driver-ssh/jumpstarter_driver_ssh/driver.py (2)
  • get_ssh_identity (42-50)
  • SSHWrapper (9-50)
packages/jumpstarter-driver-network/jumpstarter_driver_network/driver.py (1)
  • TcpNetwork (88-121)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (11)
  • GitHub Check: Redirect rules - jumpstarter-docs
  • GitHub Check: Header rules - jumpstarter-docs
  • GitHub Check: Pages changed - jumpstarter-docs
  • GitHub Check: build
  • GitHub Check: e2e
  • GitHub Check: pytest-matrix (macos-15, 3.13)
  • GitHub Check: pytest-matrix (macos-15, 3.11)
  • GitHub Check: pytest-matrix (ubuntu-24.04, 3.13)
  • GitHub Check: pytest-matrix (macos-15, 3.12)
  • GitHub Check: pytest-matrix (ubuntu-24.04, 3.12)
  • GitHub Check: pytest-matrix (ubuntu-24.04, 3.11)
🔇 Additional comments (2)
packages/jumpstarter-driver-ssh/jumpstarter_driver_ssh/driver_test.py (2)

394-405: LGTM: validates lazy load and caching semantics.

Asserts None before first use, then value cached after first read. Clear and aligned with new behavior.


424-431: LGTM: fixes the previously failing expectation (error on first use).

Instance creation succeeds; ConfigurationError is raised on get_ssh_identity(). Matches the lazy-load design and resolves the earlier test failure.

Also applies to: 434-434

@mangelajo mangelajo enabled auto-merge October 21, 2025 08:23
@mangelajo mangelajo merged commit 31d0d8f into jumpstarter-dev:main Oct 21, 2025
18 checks passed
@jumpstarter-backport-bot
Copy link
Copy Markdown

Backport failed for release-0.7, because it was unable to cherry-pick the commit(s).

Please cherry-pick the changes locally and resolve any conflicts.

git fetch origin release-0.7
git worktree add -d .worktree/backport-715-to-release-0.7 origin/release-0.7
cd .worktree/backport-715-to-release-0.7
git switch --create backport-715-to-release-0.7
git cherry-pick -x af481163563459b69089b230a27a59de93847df0

@jumpstarter-backport-bot
Copy link
Copy Markdown

Backport failed for release-0.7, because it was unable to cherry-pick the commit(s).

Please cherry-pick the changes locally and resolve any conflicts.

git fetch origin release-0.7
git worktree add -d .worktree/backport-715-to-release-0.7 origin/release-0.7
cd .worktree/backport-715-to-release-0.7
git switch --create backport-715-to-release-0.7
git cherry-pick -x af481163563459b69089b230a27a59de93847df0

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants