Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 17 additions & 22 deletions dvc_ssh/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@
from asyncssh.public_key import KeyPairListArg


async def _getpass(*args, **kwargs) -> str:
return await asyncio.to_thread(getpass, *args, **kwargs)


class InteractiveSSHClient(SSHClient):
def __init__(self, *args, **kwargs) -> None:
super().__init__(*args, **kwargs)
Expand Down Expand Up @@ -79,11 +83,8 @@ async def _read_private_key_interactive(self, path: "FilePath") -> "SSHKey":
if passphrase:
return read_private_key(path, passphrase=passphrase)

loop = asyncio.get_running_loop()
for _ in range(3):
passphrase = await loop.run_in_executor(
None, getpass, f"Enter passphrase for key '{path}': "
)
passphrase = await _getpass(f"Enter passphrase for key {path!r}: ")
if passphrase:
try:
key = read_private_key(path, passphrase=passphrase)
Expand All @@ -105,27 +106,21 @@ async def kbdint_challenge_received(
) -> Optional["KbdIntResponse"]:
assert self._conn is not None
options = self._conn._options
username = f"{options.username}" if options.username else ""
if options.host:
prompt_prefix = f"({username}@{options.host}) "
elif username:
prompt_prefix = f"({username}) "
else:
prompt_prefix = ""

def _getpass(prompt: str) -> str:
prompt = f"{prompt_prefix}{prompt}"
return getpass(prompt=prompt).rstrip()
prompt_prefix = ""
addr = "@".join(filter(None, (options.username, options.host)))
if addr:
prompt_prefix = f"({addr}) "
if name:
prompt_prefix += f"({name}) "

# NOTE: we write an extra line otherwise the prompt will be written on
# the same line as any active tqdm progress bars
sys.stderr.write(os.linesep)
if instructions:
sys.stderr.write(f"{instructions}{os.linesep}")
loop = asyncio.get_running_loop()
return [
await loop.run_in_executor(
None, _getpass, f"({name}) {prompt}" if name else prompt
)
for prompt, _ in prompts
]

response: list[str] = []
for prompt, _echo in prompts:
p = await _getpass(f"{prompt_prefix}{prompt}")
response.append(p.rstrip())
return response
Loading