LINUX.ORG.RU

Параллельное выполнение скрипта по ssh

 , ,


1

1

В целях изучения питона и спортивного интереса делаю нечто вроде системы мониторинга с веб-интерфейсом
Python 2.6, сервер не имеет доступа в интернет, доустановка пакетов со сложными зависимостями (типа Paramiko) слишком геморройна, поэтому в идеале хотелось бы обойтись стандартной библиотекой
Пока что просто вывожу аптайм интересующих меня процессов.
Для единичного сервера это делается так

cat proc_uptime.sh | ssh server /bin/bash
Результат выглядит примерно так: 1324634 343245 546456 657567

Непосредственно в скрипте:

import commands
serverlist = [[] for i in range(SERVERS_NUM)]
for n in range(SERVERS_NUM):
    cmd = 'cat test.sh | ssh server' + str(n+1) + ' /bin/bash'
    serverlist[n] = commands.getoutput(cmd).split()

Т.е. получаем список списков, где для каждого сервера будет список аптаймов его процессов
Это всё даже работает и даже с приемлемой скоростью, но это пока все сервера в строю и нет ошибок.
При каких-то затыках с одним сервером в цикле у меня всё встанет колом.
Что я думаю нужно в идеале:
все запросы к серверам выполняются параллельно и отстреливаются на всякий случай после Х секунд неответа
Гугл подсказал мне для моего случая вполне подойдёт вариант с Popen
Но ман плохо раскуриваются и я так и не понял как мне с помощью Popen получить вывод скрипта в список (т.е. упорядоченно)
Лорогуру питона, посоветуйте мне полезных советов

UPDATE:
Что у меня пока получилось (Бог его знает насколько это канонично, феншуйно и надёжно, но ускорение почти линейное получилось)

    serverlist = ['server01','server02','server03','fake_test_server','server04','server05']
    running_procs = [Popen(['./wrapper.sh',server],stdout=PIPE, stderr=PIPE) for server in serverlist]
    d = defaultdict((lambda:['N/A','N/A','N/A','N/A','N/A']))
    while running_procs:
        for proc in running_procs:
            retcode = proc.poll()
            if retcode is not None: # процесс отработал
                res = proc.communicate()[0]
                if res:
                    d[res.partition(' ')[0]] = res.partition(' ')[2].split(' ')
                running_procs.remove(proc)
                break
            else: # процесс ещё работает, будем подождать
                time.sleep(.1)
                continue 

★★★★★

Ответ на: комментарий от dvrts

Зачём ездить на жигулях если в мире выпускаются феррари?
Смирись с уловиями задачи: на сервере есть только 2.6

zolden ★★★★★ ()
Ответ на: комментарий от dvrts

Почему же не корректное.
Я могу там поставить 2.7 при определённых усилиях.
Так и ты можешь начать ездить на феррари, если приложишь определённые усилия.

На самом деле я не вижу особой разницы между 2.6 и 2.7
Что-то поправили, добавили сахара для словарей и прочее.
Но у меня тут довольно таки базовая задача, особо не привязанная к версиям библиотек или каким-то синтаксическим конструкциям.

zolden ★★★★★ ()
Ответ на: комментарий от dvrts

Paramiko

Это то, которое автор забросил, а тот, кто поддерживает, не знает как оно работает? Ненужно. Да и не получится заставить это стабильно работать в параллельном режиме с питоном 2.6 или 2.7

feofan ★★★★★ ()
Последнее исправление: feofan (всего исправлений: 1)

*цокот костылей приближается* xargs --max-procs *цокот костылей удаляется*

Tark ★★ ()
Ответ на: комментарий от anonymous

судя по описанию выглядит неплохо, жаль только искаропки на SLES его нет и сходу пакет не нашёл

zolden ★★★★★ ()
Ответ на: комментарий от feofan

Это то, которое автор забросил, а тот, кто поддерживает, не знает как оно работает? Ненужно. Да и не получится заставить это стабильно работать в параллельном режиме с питоном 2.6 или 2.7

Как же оно тогда у меня в fabric работает?

AnDoR ★★★★★ ()

сервер не имеет доступа в интернет

выполнение скрипта по ssh

Это как?) сервер без интернета - и ты на нём по ssh запускаешь скрипт?)

menangen ★★★★★ ()
Ответ на: комментарий от zolden

Вам на уроках обещал дяденька информатик? Тогда потерпим.

menangen ★★★★★ ()
Ответ на: комментарий от stevejobs

В чём проблема прокинуть инет на сервер для установки парамико? На крайняк вкатить докер контейнер из .tar, в котором будет всё питон-окружение. После настройки можно отрубить инет на сервере. Либо вообще не использовать инет, а ставить докер контейнер с парамико и не писать свои чудные велосипеды.

menangen ★★★★★ ()
Ответ на: комментарий от AnDoR

Любят же в этих ваших центосях устаревший софт :) та же дебиан стабильная имеет 2.7.3, вроде. Ветке 2.7 уже 1.5 года. А 3-я ветка, небось python 3.1 в лучшем случае.

menangen ★★★★★ ()
Ответ на: комментарий от menangen

Каждый нашёл то, что искал

Я нашёл способ сделать, а ты нашёл миллион оправданий не делать.

zolden ★★★★★ ()
Ответ на: комментарий от AnDoR

4 коннекта это несерьезно. Вот если бы 4 десятка... А этих fabric, paramico и питона я наелся, больше не хочу. Там есть баг в классе threading, когда тред не создается, а родительский процесс ждет его завершения. Бесконечно. Мы перестали использовать параллельный режим.

feofan ★★★★★ ()
Ответ на: комментарий от menangen

Если сильно надо, то можно и 2.7 поставить и 3, но ни разу не было такой нужды. Ну и CentOS 6 нынче типа oldstable, есть же 7 версия теперь. Но переезжать нам смысла нет, ключевые пакеты актуальных версий.

AnDoR ★★★★★ ()
Ответ на: комментарий от feofan

Не представляю, для чего может понадобиться 40 параллельных подключений по ssh. Но не сильно удивлён подобным багам.

AnDoR ★★★★★ ()
Ответ на: комментарий от AnDoR

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

feofan ★★★★★ ()
Ответ на: комментарий от feofan

Кажется, в архитектуре где-то просчёт, если надо делать одновременно 40 подключений по ssh. Нельзя было сделать иначе?

AnDoR ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.