mirror of
ssh://git.janware.com/janware/proj/jw-pkg
synced 2026-04-24 17:23:36 +02:00
lib.SSHClient.run_cmd(): Accept cmd: list[str]
Make SSHClient accept a list of strings for the cmd argument to align with the other run_cmd() functions in jw-pkg. Signed-off-by: Jan Lindemann <jan@janware.com>
This commit is contained in:
parent
5a48143064
commit
d0776db01f
2 changed files with 40 additions and 16 deletions
|
|
@ -38,9 +38,9 @@ class CmdListRepos(Cmd): # export
|
||||||
ssh.set_username(username)
|
ssh.set_username(username)
|
||||||
if password is not None:
|
if password is not None:
|
||||||
ssh.set_password(password)
|
ssh.set_password(password)
|
||||||
cmd = f'/opt/jw-pkg/bin/git-srv-admin.sh -u {args.from_owner} -j list-personal-projects'
|
cmd = ['/opt/jw-pkg/bin/git-srv-admin.sh', '-u', args.from_owner, '-j', 'list-personal-projects']
|
||||||
out = await ssh.run_cmd(cmd)
|
stdout, stderr, code = await ssh.run_cmd(cmd)
|
||||||
print(out)
|
print(stdout)
|
||||||
return
|
return
|
||||||
case 'https':
|
case 'https':
|
||||||
cmd_input = None
|
cmd_input = None
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,11 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
import os, abc
|
from typing import Any
|
||||||
|
|
||||||
|
import os, abc, shlex, sys
|
||||||
|
|
||||||
from .util import run_cmd
|
from .util import run_cmd
|
||||||
|
from .ExecContext import Result
|
||||||
|
|
||||||
class SSHClient(abc.ABC):
|
class SSHClient(abc.ABC):
|
||||||
|
|
||||||
|
|
@ -16,12 +19,10 @@ class SSHClient(abc.ABC):
|
||||||
return self.__hostname
|
return self.__hostname
|
||||||
|
|
||||||
def set_password(self, password: str) -> None:
|
def set_password(self, password: str) -> None:
|
||||||
assert password != 'jan'
|
|
||||||
self.__password = password
|
self.__password = password
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def password(self) -> str:
|
def password(self) -> str:
|
||||||
assert self.__password != 'jan'
|
|
||||||
return self.__password
|
return self.__password
|
||||||
|
|
||||||
def set_username(self, username: str) -> None:
|
def set_username(self, username: str) -> None:
|
||||||
|
|
@ -32,20 +33,37 @@ class SSHClient(abc.ABC):
|
||||||
return self.__username
|
return self.__username
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
async def run_cmd(self, cmd: str):
|
async def _run_cmd(self, cmd: list[str]) -> Result:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
async def run_cmd(
|
||||||
|
self,
|
||||||
|
cmd: list[str],
|
||||||
|
output_encoding: str|None = None,
|
||||||
|
) -> Result:
|
||||||
|
stdout_b, stderr_b, status = await self._run_cmd(cmd)
|
||||||
|
if output_encoding == 'bytes':
|
||||||
|
return stdout_b, stderr_b, status
|
||||||
|
|
||||||
|
if output_encoding is None:
|
||||||
|
output_encoding = sys.stdout.encoding or "utf-8"
|
||||||
|
stdout_s = stdout_b.decode(output_encoding, errors="replace") if stdout_b is not None else None
|
||||||
|
stderr_s = stderr_b.decode(output_encoding, errors="replace") if stderr_b is not None else None
|
||||||
|
return stdout_s, stderr_s, status
|
||||||
|
|
||||||
class SSHClientInternal(SSHClient): # export
|
class SSHClientInternal(SSHClient): # export
|
||||||
|
|
||||||
def __init__(self, hostname: str) -> None:
|
def __init__(self, hostname: str) -> None:
|
||||||
super().__init__(hostname=hostname)
|
super().__init__(hostname=hostname)
|
||||||
|
self.__timeout: float|None = None # Untested
|
||||||
|
self.___ssh: Any|None = None
|
||||||
|
|
||||||
def __ssh_connect(self):
|
def __ssh_connect(self):
|
||||||
import paramiko # type: ignore # error: Library stubs not installed for "paramiko"
|
import paramiko # type: ignore # error: Library stubs not installed for "paramiko"
|
||||||
ret = paramiko.SSHClient()
|
ret = paramiko.SSHClient()
|
||||||
ret.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
ret.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||||
path_to_key=os.path.join(os.environ['HOME'], '.ssh', 'id_rsa')
|
path_to_key=os.path.join(os.environ['HOME'], '.ssh', 'id_rsa')
|
||||||
ret.connect(self.__hostname, key_filename=path_to_key, allow_agent=True)
|
ret.connect(self.hostname, key_filename=path_to_key, allow_agent=True)
|
||||||
s = ret.get_transport().open_session()
|
s = ret.get_transport().open_session()
|
||||||
# set up the agent request handler to handle agent requests from the server
|
# set up the agent request handler to handle agent requests from the server
|
||||||
paramiko.agent.AgentRequestHandler(s)
|
paramiko.agent.AgentRequestHandler(s)
|
||||||
|
|
@ -54,15 +72,17 @@ class SSHClientInternal(SSHClient): # export
|
||||||
@property
|
@property
|
||||||
def __ssh(self):
|
def __ssh(self):
|
||||||
if self.___ssh is None:
|
if self.___ssh is None:
|
||||||
self.___ssh = self.__ssh_connect(self.__server)
|
self.___ssh = self.__ssh_connect()
|
||||||
return self.___ssh
|
return self.___ssh
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def __scp(self):
|
def __scp(self):
|
||||||
return SCPClient(self.__ssh.get_transport())
|
return SCPClient(self.__ssh.get_transport())
|
||||||
|
|
||||||
async def run_cmd(self, cmd: str):
|
async def _run_cmd(self, cmd: list[str]) -> Result:
|
||||||
return self.__ssh.exec_command(find_cmd)
|
stdin, stdout, stderr = self.__ssh.exec_command(shlex.join(cmd), timeout=self.__timeout)
|
||||||
|
exit_status = stdout.channel.recv_exit_status()
|
||||||
|
return stdout.read(), stderr.read(), exit_status
|
||||||
|
|
||||||
class SSHClientCmd(SSHClient): # export
|
class SSHClientCmd(SSHClient): # export
|
||||||
|
|
||||||
|
|
@ -93,9 +113,13 @@ class SSHClientCmd(SSHClient): # export
|
||||||
self.__askpass_orig[key] = os.getenv(key)
|
self.__askpass_orig[key] = os.getenv(key)
|
||||||
os.environ[key] = val
|
os.environ[key] = val
|
||||||
|
|
||||||
async def run_cmd(self, cmd: str):
|
async def _run_cmd(self, cmd: list[str]) -> Result:
|
||||||
self.__init_askpass()
|
self.__init_askpass()
|
||||||
cmd_arr = ['ssh']
|
return await run_cmd(['ssh', self.hostname, shlex.join(cmd)], output_encoding='bytes')
|
||||||
cmd_arr.append(self.hostname)
|
|
||||||
stdout, stderr, status = await run_cmd(['ssh', self.hostname, cmd])
|
def ssh_client(*args, **kwargs) -> SSHClient: # export
|
||||||
return stdout
|
try:
|
||||||
|
return SSHClientInternal(*args, **kwargs)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
return SSHClientCmd(*args, **kwargs)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue