This commit is contained in:
yumoqing 2025-07-15 16:55:33 +08:00
parent 14c9bb02fe
commit 563f7218ec
2 changed files with 103 additions and 1 deletions

View File

@ -12,7 +12,11 @@ import asyncio, asyncssh, sys
class SSHServer:
def __init__(self, server, jumpservers=[]):
self.server = server
self.jumpservers = jumpservers
if not jumpservers:
if server['jumpservers']:
self.jumpservers = server['jumpservers']
else:
self.jumpservers = jumpservers
async def _connect_server(self, server, refconn=None):
f = asyncssh.connect

98
test/sshnode.py Normal file
View File

@ -0,0 +1,98 @@
import asyncio
import asyncssh
import sys
import termios
import tty
import signal
from appPublic.sshx import SSHServer
class InteractiveSSHClient(asyncssh.SSHClientSession):
def __init__(self):
self._chan = None
self._stdin_task = None
def connection_made(self, chan):
self._chan = chan
self._stdin_task = asyncio.create_task(self._forward_stdin())
async def _forward_stdin(self):
old_attrs = termios.tcgetattr(sys.stdin)
try:
tty.setraw(sys.stdin.fileno())
while True:
data = await asyncio.get_event_loop().run_in_executor(None, sys.stdin.read, 1)
if not data:
break
self._chan.write(data)
except asyncio.CancelledError:
pass
finally:
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old_attrs)
def data_received(self, data, datatype):
print(data, end='', flush=True)
def connection_lost(self, exc):
if self._stdin_task:
self._stdin_task.cancel()
def get_terminal_size():
try:
import fcntl, struct
h, w, hp, wp = struct.unpack('HHHH',
fcntl.ioctl(sys.stdin, termios.TIOCGWINSZ,
struct.pack('HHHH', 0, 0, 0, 0)))
return (h, w)
except:
return (24, 80) # fallback
async def run_interactive_bash():
term_size = get_terminal_size()
node = {
"host":"192.168.16.8",
"username":"root",
"password":"Kyy@123456",
"jumpservers" : [
{
"host":"git.opencomputing.cn",
"username":"ymq",
"password":"Ymq@651018"
}
]
}
jumpservers = [
{
"host":"git.opencomputing.cn",
"username":"ymq",
"password":"Ymq@651018"
}
]
node = SSHServer(node)
async with node.get_connector() as conn:
A, B = await conn.create_session(
InteractiveSSHClient,
term_type='xterm',
term_size=term_size
)
print(f'{A=}, {B=}')
# 监听窗口 resize 信号,更新远端窗口大小
def resize_handler(signum, frame):
nonlocal A
if A:
rows, cols = get_terminal_size()
chan.change_pty('xterm', term_size=(rows, cols))
signal.signal(signal.SIGWINCH, resize_handler)
await A.wait_closed()
if __name__ == '__main__':
try:
asyncio.run(run_interactive_bash())
except (OSError, asyncssh.Error) as e:
print(f'SSH session failed: {e}')
except KeyboardInterrupt:
pass