Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Андрей Усов (Kaspersky Lab) - Работаем с Bash на распределенных системах

Андрей Усов (Kaspersky Lab) - Работаем с Bash на распределенных системах

Доклад с конференции Moscow Python Conf 2016 (http://conf.python.ru)
Видео: https://conf.python.ru/rabotaem-s-bash-na-raspredelennyh-sistemah/

В процессе автоматизации с использованием Python в Linux-среде очень часто возникает необходимость использовать Bash.
Если мы вызываем простые команды без потребности ввода данных, то проблем не возникает. Но в более сложных сценариях, например при автоматизации тестирования собственного интерактивного консольного приложения, требуется уметь вводить данные в зависимости от вывода. Задача усложняется, если система распределенная и используется доступ по SSH к удаленным хостам.
В докладе я хочу рассказать на реальных примерах о тех проблемах, с которыми мы столкнулись при работе с Bash, и о том, как мы эти проблемы решали. В интернете достаточно много информации о работе с Bash, но она разбросана и не систематизирована. Я же попытался собрать все это воедино и надеюсь, что это упростит жизнь тем, кто столкнется с похожими задачами.
Доклад будет интересен в основном тем, кто использует Python для внутренних целей, например для автоматизации тестирования или других процессов разработки.

Moscow Python Meetup

October 12, 2016
Tweet

More Decks by Moscow Python Meetup

Other Decks in Programming

Transcript

  1. О себе • Тестирую • Пишу автотесты на Python •

    Разрабатываю утилиты для автоматизации 3
  2. Локально - subprocess import shlex from subprocess import Popen, PIPE

    p = Popen(shlex.split( 'ls -1 /home/user' ), stdout=PIPE, stderr=PIPE) stdout, stderr = p.communicate() 01. 02. 03. 04. 8
  3. Удаленно - paramiko from paramiko import SSHClient, AutoAddPolicy client =

    SSHClient() client.set_missing_host_key_policy(AutoAddPolicy()) client.connect(hostname='192.168.0.2', username='user', password='password') 01. 02. 03. 04. 10
  4. Удаленно - paramiko from paramiko import SSHClient, AutoAddPolicy client =

    SSHClient() client.set_missing_host_key_policy(AutoAddPolicy()) client.connect(hostname='192.168.0.2', username='user', password='password') 01. 02. 03. 04. 11
  5. Удаленно - paramiko stdin, stdout, stderr = client.exec_command( 'ls -1

    /home/user' ) print stdout.read() > file1 > file2 > ... 01. 02. 12
  6. Пример 1 ./my_script > Принять лицензионное соглашение (yes/no)?: да >

    Вы ввели чушь > Принять лицензионное соглашение (yes/no)?: yes > ... 15
  7. Чего мы хотим? • Работать под пользователем (локально, удаленно) •

    Использовать sudo для простых команд (без интерактивности) 18
  8. Локально - subprocess import shlex from subprocess import Popen, PIPE

    p = Popen(shlex.split( 'sudo -S ls -l /root' ), stdout=PIPE, stderr=PIPE, stdin=PIPE) stdout, stderr = p.communicate('password\n') 01. 02. 03. 04. 20
  9. Локально - subprocess import shlex from subprocess import Popen, PIPE

    p = Popen(shlex.split(' sudo -S ls -l /root'), stdout=PIPE, stderr=PIPE, stdin=PIPE ) stdout, stderr = p.communicate( 'password\n' ) 01. 02. 03. 04. 21
  10. Удаленно - paramiko (подключаемся) from paramiko import SSHClient, AutoAddPolicy client

    = SSHClient() client.set_missing_host_key_policy(AutoAddPolicy()) client.connect(hostname='192.168.0.2', username='user', password='password') 01. 02. 03. 04. 23
  11. Ждем буфер in_buffer = channel.in_buffer # тут возможно придется подождать

    if in_buffer.read_ready(): print in_buffer.empty() > [sudo] password for user: 01. 02. 03. 04. 25
  12. Чего мы хотим? • Получать данные и вводить данные •

    Пример: выполнение под sudo с вводом неправильного пароля 29
  13. Локально - pexpect from pexpect import spawn, EOF child =

    spawn( 'sudo ls -1 /root' ) child.expect('.*password*') print child.before + child.after + child.buffer > [sudo] password for user: 01. 02. 03. 04. 30
  14. Удаленно - paramiko (подключаемся) from paramiko import SSHClient, AutoAddPolicy client

    = SSHClient() client.set_missing_host_key_policy(AutoAddPolicy()) client.connect(hostname='192.168.0.2', username='user', password='password') 01. 02. 03. 04. 34
  15. Ждем буфер in_buffer = channel.in_buffer # тут возможно придется подождать

    if in_buffer.read_ready(): print in_buffer.empty() > [sudo] password for user: 01. 02. 03. 04. 36
  16. Отправляем правильный пароль channel.send('good_password\n') # получаем код выхода exit_status =

    channel.recv_exit_status() if in_buffer.read_ready(): result = in_buffer.empty() 01. 02. 03. 04. 05. 38
  17. В итоге • Научились выполнять команды под sudo локально и

    удаленно • Освоили интерактивность 40