Канал paramiko не может получить данные, если он создан вне маршрута flask - PullRequest
0 голосов
/ 31 марта 2020

Я работаю над API для автоматизации задач в проприетарной системе. Я использую paramiko S SH для доступа к указанной системе и обмена данными в приложении Flask, обслуживаемом nginx и uwsgi.

Процесс входа в систему медленный, поэтому я хочу создать свой канал снаружи из различных маршрутов оформлены функции. Я надеюсь, что запуск uwsgi приведет к созданию экземпляра paramiko.SSHClient () и канала, который будет готов обмениваться данными для фактических HTTP-запросов.

Когда я это сделаю, я могу отправлять данные в @route оформленные функции, и данные поступают в систему, но я не могу получить данные, поскольку chan.recv_ready () всегда внутри функции False.

Вот базовый c пример, показывающий s sh на локальный хост и пытается вернуть данные из команды.

Работает с сервером flask dev, но не работает с помощью nginx + uwsgi. Я уверен, что это связано с несколькими процессами uwsgi.

Создание экземпляра paramiko в функциях @route работает, но так как вход в систему в этой проприетарной системе, с которой я работаю, очень медленный (10 секунд), он просто делает каждый HTTP-запрос намного медленнее.

Почему это не работает?

import paramiko
import re
import time
from flask import Flask
app = Flask(__name__)

host = 'localhost'
username = 'test_user'
password = 'password123'
port = 22

client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(host, username=username, password=password, port=port, timeout=10, look_for_keys=False, allow_agent=False)
chan = client.invoke_shell()

data = ''
slept = 0
while True:
        # if chan has data to receive, do it, otherwise wait
    if chan.recv_ready():
        buf = chan.recv(1024)
        if buf:
            data += buf.decode()
    else:
        time.sleep(.1)
        slept += .1
        # if received data has prompt, break
    if re.search(']\$ $', data):
        break
        # if 5 seconds with no received data, give up.
    if slept > 5:
        break

@app.route('/uname')
def uname():
    chan.send('uname -a\n')
    data = ''
    slept = 0
    while True:
        # if chan has data to receive, do it, otherwise wait
        if chan.recv_ready():
            buf = chan.recv(1024)
            if buf:
                data += buf.decode()
        else:
            time.sleep(.1)
            slept += .1
        # if received data has prompt, we're done.
        if re.search(']\$ $', data):
            return repr(data)
        # if 5 seconds with no received data, give up.
        if slept > 5:
           return "cannot receive data\n"
...