Read ~/.ssh/config in the SSH pre-check

The paramiko pre-check ignored HostName, Port and IdentityFile, so hosts that rsync's ssh reached through ~/.ssh/config failed before the backup started.
This commit is contained in:
Fuxino
2026-10-21 22:31:01 +02:00
parent fa3ba2a6bd
commit dc50ef1b07
2 changed files with 65 additions and 7 deletions
+28 -1
View File
@@ -365,7 +365,7 @@ class FakeClient:
self.policies.append(type(policy).__name__)
def connect(self, hostname: str, **kwargs: Any) -> None:
self.connects.append(kwargs)
self.connects.append({'hostname': hostname, **kwargs})
outcome = self.outcomes.pop(0)
if isinstance(outcome, UserWarning):
@@ -404,8 +404,35 @@ class TestLogin:
assert remote_backup()._ssh_connect(str(tmp_path)) is client
assert client.known_hosts == f'{tmp_path}/.ssh/known_hosts'
assert client.connects[0]['timeout'] == sb.SSH_TIMEOUT
assert client.connects[0]['hostname'] == 'server'
assert 'port' not in client.connects[0]
assert not client.closed
def test_ssh_config(self, client: FakeClient, tmp_path: Path) -> None:
(tmp_path / '.ssh').mkdir()
key = tmp_path / '.ssh' / 'id_backup'
key.touch()
(tmp_path / '.ssh' / 'config').write_text(
f'Host server\n HostName backup.example.org\n Port 2222\n'
f' IdentityFile {key}\n IdentityFile {tmp_path}/.ssh/missing\n')
client.outcomes = [ssh_error(), None]
assert remote_backup()._ssh_connect(str(tmp_path)) is client
for params in client.connects:
assert (params['hostname'], params['port']) == ('backup.example.org', 2222)
assert params['key_filename'] == [str(key)]
def test_bad_ssh_config(self, client: FakeClient, tmp_path: Path, caplog: pytest.LogCaptureFixture) -> None:
(tmp_path / '.ssh').mkdir()
(tmp_path / '.ssh' / 'config').write_text('Host server\n Port abc\n')
client.outcomes = [None]
assert remote_backup()._ssh_connect(str(tmp_path)) is client
assert client.connects[0]['hostname'] == 'server'
assert 'port' not in client.connects[0]
assert 'Cannot read' in caplog.text
@pytest.mark.parametrize('answer, connected', [('y', True), (' Yes', True), ('n', False), ('', False)])
def test_unknown_host_key(self, client: FakeClient, monkeypatch: pytest.MonkeyPatch,
answer: str, connected: bool) -> None: