From e6116adc6b94020d8c90b06d943404400e974dc2 Mon Sep 17 00:00:00 2001 From: Pavel Kirilin <win10@list.ru> Date: Thu, 30 Jan 2020 01:26:40 +0400 Subject: [PATCH] Fixed ssh known-hosts bug and more. Description: - Unknown hosts now will be added automatically; - In docker removed known-hosts file mounting as volume; - Fixed stdout and stderr handling. - Fixed stdout message formatting. Signed-off-by: Pavel Kirilin <win10@list.ru> --- docker-compose.yml | 3 ++- src/utils/ssh.py | 33 +++++++++++++++++++++------------ 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 55189d5..6e44265 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -20,7 +20,8 @@ services: APP_MODE: 'dev' TELEGRAM_BOT_TOKEN: 'your dev token here' volumes: - - ~/.ssh:/root/.ssh + - ~/.ssh/id_rsa:/root/.ssh/id_rsa + - ~/.ssh/id_rsa.pub:/root/.ssh/id_rsa.pub - ./:/app working_dir: '/app' networks: diff --git a/src/utils/ssh.py b/src/utils/ssh.py index ff8a2c9..7452cbc 100644 --- a/src/utils/ssh.py +++ b/src/utils/ssh.py @@ -10,26 +10,35 @@ logger = logging.getLogger() async def open_ssh_session(server: Server) -> asyncssh.SSHClientProcess: - connection = await asyncssh.connect(server.server_address, server.server_port) + connection = await asyncssh.connect(server.server_address, server.server_port, known_hosts=None) process = await connection.create_process('/bin/bash') return process -async def run_interactive_command(command: str, - process: asyncssh.SSHClientProcess, - timeout=0.5) -> str: - process.stdin.write(command + '\n') +async def collect_output(out_pipe, timeout): res = [] try: - line = await asyncio.wait_for(process.stdout.readline(), timeout) + line = await asyncio.wait_for(out_pipe.readline(), timeout) res.append(line) while line: - logger.debug(line) - res.append(await asyncio.wait_for(process.stdout.readline(), timeout)) - except asyncio.exceptions.TimeoutError as e: - logger.exception(e) - return '\n'.join(res).strip() - return '\n'.join(res).strip() + logger.info(line) + res.append(await asyncio.wait_for(out_pipe.readline(), timeout)) + except asyncio.exceptions.TimeoutError: + return ''.join(res).strip() + return ''.join(res).strip() + + +async def run_interactive_command(command: str, + process: asyncssh.SSHClientProcess, + timeout=0.5) -> str: + process.stdin.write(command + '\n') + stdout = await collect_output(process.stdout, timeout) + stderr = await collect_output(process.stderr, timeout) + logger.debug(f"STDOUT: {stdout}") + logger.debug(f"STDERR: {stderr}") + if stderr: + raise Exception(stderr) + return stdout async def run_ssh_command(server: Server, command: str) -> str: -- GitLab