mirror of
ssh://git.janware.com/janware/proj/jw-pkg
synced 2026-04-25 17:45:55 +02:00
lib.ec.SSHClientInternal|SSHClientCmd: Own .py
Move the code of SSHClientInternal and SSCClientCmd into lib.ec.ssh, as "Paramiko" and "Exec", respectively. This makes the class layout a little more modular, and along the way fixes a bug where SSHClientInternal could be instantiated but was unusable (if the Paramiko is not installed). Signed-off-by: Jan Lindemann <jan@janware.com>
This commit is contained in:
parent
f37f025b17
commit
f4c76ebab9
4 changed files with 122 additions and 87 deletions
57
src/python/jw/pkg/lib/ec/ssh/Paramiko.py
Normal file
57
src/python/jw/pkg/lib/ec/ssh/Paramiko.py
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import paramiko # type: ignore # error: Library stubs not installed for "paramiko"
|
||||
import shlex
|
||||
|
||||
from ...log import *
|
||||
from ...ExecContext import Result
|
||||
from ..SSHClient import SSHClient as Base
|
||||
|
||||
class Paramiko(Base): # export
|
||||
|
||||
def __init__(self, *args, **kwargs) -> None:
|
||||
super().__init__(*args, **kwargs)
|
||||
self.__timeout: float|None = None # Untested
|
||||
self.___ssh: Any|None = None
|
||||
|
||||
def __ssh_connect(self):
|
||||
ret = paramiko.SSHClient()
|
||||
ret.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||
try:
|
||||
ret.connect(
|
||||
hostname=self.hostname,
|
||||
username=self.username,
|
||||
allow_agent=True
|
||||
)
|
||||
except Exception as e:
|
||||
log(ERR, f'Failed to connect to {self.hostname} with key file {path_to_key} ({str(e)})')
|
||||
raise
|
||||
s = ret.get_transport().open_session()
|
||||
# set up the agent request handler to handle agent requests from the server
|
||||
paramiko.agent.AgentRequestHandler(s)
|
||||
return ret
|
||||
|
||||
@property
|
||||
def __ssh(self):
|
||||
if self.___ssh is None:
|
||||
self.___ssh = self.__ssh_connect()
|
||||
return self.___ssh
|
||||
|
||||
@property
|
||||
def __scp(self):
|
||||
return SCPClient(self.__ssh.get_transport())
|
||||
|
||||
async def _run_ssh(self, cmd: list[str], cmd_input: str|None) -> Result:
|
||||
try:
|
||||
stdin, stdout, stderr = self.__ssh.exec_command(shlex.join(cmd), timeout=self.__timeout)
|
||||
except Exception as e:
|
||||
log(ERR, f'Command failed for {self.uri}: "{shlex.join(cmd)}"')
|
||||
raise
|
||||
if cmd_input is not None:
|
||||
stdin.write(cmd_input)
|
||||
exit_status = stdout.channel.recv_exit_status()
|
||||
return Result(stdout.read(), stderr.read(), exit_status)
|
||||
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue