mirror of
https://github.com/andrey271192/Keenetic_SSH.git
synced 2026-09-20 14:41:58 +00:00
55 lines
2.5 KiB
Python
55 lines
2.5 KiB
Python
import asyncio, logging
|
|
from . import config
|
|
logger = logging.getLogger("keenetic_ssh")
|
|
|
|
async def ssh_exec(host: str, command: str, user: str = None, password: str = None, timeout: int = 15) -> str:
|
|
if not user: user = config.SSH_USER
|
|
if not password: password = config.SSH_PASS
|
|
try:
|
|
proc = await asyncio.create_subprocess_exec(
|
|
"sshpass", "-p", password,
|
|
"ssh", "-o", "StrictHostKeyChecking=no", "-o", "ConnectTimeout=10",
|
|
f"{user}@{host}", command,
|
|
stdout=asyncio.subprocess.PIPE,
|
|
stderr=asyncio.subprocess.PIPE,
|
|
)
|
|
stdout, stderr = await asyncio.wait_for(proc.communicate(), timeout=timeout)
|
|
out = stdout.decode("utf-8", errors="replace").strip()
|
|
err = stderr.decode("utf-8", errors="replace").strip()
|
|
if proc.returncode == 0:
|
|
return out or "(пусто)"
|
|
return f"Ошибка (код {proc.returncode}):\n{err or out}"
|
|
except asyncio.TimeoutError:
|
|
return f"⏰ Таймаут SSH ({timeout} сек)"
|
|
except FileNotFoundError:
|
|
return "❌ sshpass не установлен: apt install sshpass"
|
|
except Exception as e:
|
|
return f"❌ SSH: {e}"
|
|
|
|
async def ssh_exec_verbose(host: str, command: str, user: str = None, password: str = None, timeout: int = 120) -> dict:
|
|
if not user: user = config.SSH_USER
|
|
if not password: password = config.SSH_PASS
|
|
wrapped = f"echo \"[$(hostname)] $(date '+%H:%M:%S')\"; ({command}); _ec=$?; echo \"--- exit: $_ec ---\"; exit $_ec"
|
|
try:
|
|
proc = await asyncio.create_subprocess_exec(
|
|
"sshpass", "-p", password,
|
|
"ssh", "-o", "StrictHostKeyChecking=no", "-o", "ConnectTimeout=10",
|
|
f"{user}@{host}", wrapped,
|
|
stdout=asyncio.subprocess.PIPE,
|
|
stderr=asyncio.subprocess.PIPE,
|
|
)
|
|
stdout, stderr = await asyncio.wait_for(proc.communicate(), timeout=timeout)
|
|
code = proc.returncode
|
|
return {
|
|
"exit_code": code,
|
|
"output": stdout.decode("utf-8", errors="replace").strip(),
|
|
"stderr": stderr.decode("utf-8", errors="replace").strip(),
|
|
"ok": code == 0,
|
|
}
|
|
except asyncio.TimeoutError:
|
|
return {"exit_code": -1, "output": "⏰ Таймаут SSH", "stderr": "", "ok": False}
|
|
except FileNotFoundError:
|
|
return {"exit_code": -1, "output": "❌ sshpass не установлен", "stderr": "", "ok": False}
|
|
except Exception as e:
|
|
return {"exit_code": -1, "output": f"❌ {e}", "stderr": "", "ok": False}
|