Скриптовая команда s sh иногда зависает на неопределенный срок, сервер активен и принимает соединения - PullRequest
1 голос
/ 28 марта 2020

Я автоматизирую некоторые тесты, которые выполняются в облаке ( GCE , если быть точным c).

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

Иногда s sh просто зависает на неопределенное время, и я не могу понять, почему.

Сначала я использовал paramiko.exec_command, но я обнаружил эту проблему от 2015 года, которая остается нерешенной, поэтому я решил вместо этого попробовать команды vanilla s sh с помощью subprocess.run

После виртуальной машины Создается, требуется время для загрузки и sshd для начала прослушивания. Поэтому я сначала запускаю команду true над s sh в al oop до тех пор, пока она не будет выполнена успешно:

retries = 6
while True:
    # just run 'true' on the remove server so if it executes successfully we know 
    # sshd is alive and accepting connections
    cmd = ('ssh -o ConnectTimeout=10 -o StrictHostKeyChecking=no '
           '-o UserKnownHostsFile=/dev/null {user}@{host} true').format(
           user=user, host=host)
    r = subprocess.run(cmd,
                       stdout=subprocess.PIPE,
                       stderr=subprocess.PIPE,
                       shell=True)
    if r.returncode == 0:
        break
    retries -= 1
    if retries == 0:
        raise UnableToConnect()
    time.sleep(10)

После успешного запуска true я знаю, что сервер активен и принимает s sh подключений, поэтому я могу продолжить свои шаги по настройке.

def run_cmd(user, host, cmd):
    cmd = ('ssh -o ConnectTimeout=10 -o StrictHostKeyChecking=no '
           '-o UserKnownHostsFile=/dev/null {user}@{host} {cmd}').format(
           user=user, host=host, cmd=shlex.quote(cmd))
    r = subprocess.run(cmd,
                       stdout=subprocess.PIPE,
                       stderr=subprocess.PIPE,
                       shell=True)
    return {
        'returncode': p.returncode,
        'stdout'    : p.stdout.decode("utf-8").rstrip(),
        'stderr'    : p.stderr.decode("utf-8").rstrip(),
    }

В большинстве случаев все работает как положено, но иногда команда s sh никогда не возвращается, зависая бесконечно.

Одним из таких примеров является то, что мне нужно установить binutils:

run_cmd(user, vm_ip_addr, 'dpkg -s binutils || sudo apt-get install -y binutils')

Команда никогда не возвращается.

$ ps -ef | grep ssh
steve 31855 ... 00:00:00 /bin/sh -c ssh -o ConnectTimeout=10 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null fred@123.123.123.123 'dpkg -s binutils || sudo apt-get install -y binutils'
steve 31856 ... 00:00:00 ssh -o ConnectTimeout=10 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null fred@123.123.123.123 dpkg -s binutils || sudo apt-get install -y binutils

Я подключен к команде ssh, используя strace и он застрял в чтении:

$ sudo strace -p 31856
strace: Process 31856 attached
read(5, 

(я не очень разбираюсь в strace, поэтому я не уверен, есть ли что-то еще, что я мог бы сделать, чтобы получить больше информации в этом точка)

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

Вопросы:

  • Почему эта команда зависает?
...