diff --git a/packages/jumpstarter-driver-ssh/jumpstarter_driver_ssh/driver.py b/packages/jumpstarter-driver-ssh/jumpstarter_driver_ssh/driver.py index ec5597ca9..2a0fda411 100644 --- a/packages/jumpstarter-driver-ssh/jumpstarter_driver_ssh/driver.py +++ b/packages/jumpstarter-driver-ssh/jumpstarter_driver_ssh/driver.py @@ -24,13 +24,6 @@ def __post_init__(self): if self.ssh_identity and self.ssh_identity_file: raise ConfigurationError("Cannot specify both ssh_identity and ssh_identity_file") - # If ssh_identity_file is provided, read it into ssh_identity - if 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 - @classmethod def client(cls) -> str: return "jumpstarter_driver_ssh.client.SSHWrapperClient" @@ -48,4 +41,10 @@ def get_ssh_command(self): @export def get_ssh_identity(self): """Get the SSH identity key content""" + # If ssh_identity_file is provided, read it lazily and cache in ssh_identity + 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 return self.ssh_identity diff --git a/packages/jumpstarter-driver-ssh/jumpstarter_driver_ssh/driver_test.py b/packages/jumpstarter-driver-ssh/jumpstarter_driver_ssh/driver_test.py index 0533c5a65..02ea1ba1a 100644 --- a/packages/jumpstarter-driver-ssh/jumpstarter_driver_ssh/driver_test.py +++ b/packages/jumpstarter-driver-ssh/jumpstarter_driver_ssh/driver_test.py @@ -391,9 +391,17 @@ def test_ssh_identity_file_configuration(): ) # Test that the instance was created correctly - assert instance.ssh_identity == TEST_SSH_KEY + # ssh_identity should be None until first use (lazy loading) + assert instance.ssh_identity is None assert instance.ssh_identity_file == temp_file_path + # Test that get_ssh_identity() reads the file on first use + identity = instance.get_ssh_identity() + assert identity == TEST_SSH_KEY + + # Test that ssh_identity is now cached + assert instance.ssh_identity == TEST_SSH_KEY + # Test that the client class is correct assert instance.client() == "jumpstarter_driver_ssh.client.SSHWrapperClient" finally: @@ -413,13 +421,17 @@ def test_ssh_identity_validation_error(): def test_ssh_identity_file_read_error(): - """Test SSH wrapper raises error when ssh_identity_file cannot be read""" + """Test SSH wrapper raises error when ssh_identity_file cannot be read on first use""" + # Instance creation should succeed (lazy loading) + instance = SSHWrapper( + children={"tcp": TcpNetwork(host="127.0.0.1", port=22)}, + default_username="testuser", + ssh_identity_file="/nonexistent/path/to/key" + ) + + # Error should be raised when get_ssh_identity() is called with pytest.raises(ConfigurationError, match="Failed to read ssh_identity_file"): - SSHWrapper( - children={"tcp": TcpNetwork(host="127.0.0.1", port=22)}, - default_username="testuser", - ssh_identity_file="/nonexistent/path/to/key" - ) + instance.get_ssh_identity() def test_ssh_command_with_identity_string():