не может установить sh соединение после перезагрузки - PullRequest
0 голосов
/ 28 апреля 2020

люди,

Я столкнулся с проблемой, пытаясь переподключиться к серверу после перезагрузки .. Я видел другие статьи о похожих проблемах, но все, что я пытаюсь, происходит с той же ошибкой.

Цель

Автоматически переподключаться к серверу после перезагрузки

Script

ssh_client = SSHClient()
ssh_client.set_missing_host_key_policy(AutoAddPolicy())
ssh_client.connect(hostname=host,port=port, username=user, password=psw)
s = ssh_client.get_transport().open_session()
agent.AgentRequestHandler(s)

         try:
            stdin, stdout, stderr = ssh_client.exec_command(command, get_pty= True)
            get_output(stdout)
            channel = stdout.channel
            stdin.close()
            channel.shutdown_write()
            stdout_chunks = []
            stdout_chunks.append(channel.recv(len(channel.in_buffer)))
            while not channel.closed or channel.recv_ready() or channel.recv_stderr_ready():
                got_chunk = False
                readq, _, _ = select.select([stdout.channel], [], [])
                for c in readq:
                    if c.recv_ready():
                        stdout_chunks.append(channel.recv(len(c.in_buffer)))
                        got_chunk = True
                    if c.recv_stderr_ready():
                        stderr.channel.recv_stderr(len(c.in_stderr_buffer))
                        got_chunk = True
                    if not got_chunk \
                            and channel.exit_status_ready() \
                            and not channel.recv_stderr_ready() \
                            and not channel.recv_ready():
                        channel.shutdown_read()
                        channel.close()
                        break
            stdout.close()
            stderr.close()

        except (ConnectionResetError, SSHException):
            print('Connection died')

Ошибка кэшируется блоком try catch:

Connection died
Connection died
Connection died
Connection died
Connection died
Connection died
Connection died
Connection died
Connection died
Connection died
Connection died
Connection died
Connection died
Connection died
Connection died

Скрипт, который я запускаю в удаленный сервер завершается командой перезагрузки:

/sbin/shutdown -r now

1 Ответ

1 голос
/ 29 апреля 2020

Я опубликую это как ответ, так как это слишком долго, чтобы быть объясненным в комментарии.

В вашем коде по-прежнему отсутствуют части, так как мы не знаем, как вы называете структуру try / исключением и что происходит при обнаружении исключения. Тем не менее, если я могу сделать вывод из вашего отступа, что в случае обнаружения исключения вы будете повторять попытку / исключение каким-либо образом.

Вы, кажется, полагаетесь на статус закрытого канала в вашей логике c, но есть нижележащий уровень в виде сокета TCP. Когда вы перезагружаете сервер, ваш канал умирает, но также и уровень TCP. При обработке исключений вам нужно будет воссоздать это.

Я бы попробовал что-то вроде этого:

try:
    ...
    ...
    ...
    stdout.close()
    stderr.close()
except (...):
    sleep(2)  # to prevent a busyloop when your server is rebooting      
    try:
        ssh_client.close()  # Close the connection just in case it is alive
    except:
        pass    # We do not care if it succeeds or fails
    counter = 0     # optional
    while True:
        sleep(2)    # to prevent a busyloop when your server is rebooting
        counter += 1
        if counter > X:
            print("server permanently down, exiting")
            exit (1)
        try:
            ssh_client.connect(hostname=host,port=port, username=user, password=psw)
            s = ssh_client.get_transport().open_session()
            break    # We have a liftoff
        except:
            pass     # Server not responding yet. Try again. 

(я не тестировал приведенный выше код, просто написал его здесь, чтобы дать идею. Там могут быть опечатки)

Вы можете игнорировать встречную часть. Я обычно использую счетчик, чтобы предотвратить попытки программ, пока коровы не вернутся домой, если сервер не работает в течение длительного времени. Если вы хотите продолжать попытки, удалите их. Если вы используете их, просто установите X достаточно высоко, чтобы у сервера было достаточно времени для перезагрузки, а затем еще немного.

Ключевая часть - воссоздание TCP-соединения после ошибки и выход из обработчика ошибок только при наличии снова работающего соединения.

Мы пытаемся закрыть существующее соединение на тот случай, если оно все еще существует, чтобы избежать исчерпания ресурсов сервера, если проблема не в сбое соединения, но нам все равно, будет ли оно успешным или нет. Затем мы воссоздаем соединение с нуля.

Это может или не может работать в вашем случае, так как мы не знаем из вашего кода, как вы вводите это заново после исключения - и вы, похоже, тоже не уверены основываясь на ваших комментариях.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...