Как автоматизатору побороть SSH

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

images?q=tbn:ANd9GcSIluTpLycP4jpvVo3Y0WeOulr4QuhdBSp4Yg6r1doJY4IEX0wx0Q

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

Приступим ближе к делу: зачем оно автоматизаторам и зачем я вообще затронул эту тему? Все очень просто! Если у вас на проекте есть linux сервера, то вам не избежать работы с ssh. У меня был опыт реализации такой задачи, когда нам нужно было закидывать конфигурационные файлы на сервер и смотреть, как себя поведет система после таких изменений. Делать это руками интересно, но только в первый раз =) Я заавтоматизировал этот процесс.

Тогда я был маленьким джуниором и мое решение свелось к использованию библиотеки Jsch. Штука работала, но пришлось нахвататься проблем и опыта. Не буду вдаваться в подробности, просто посмотрите пример реализации здесь.

Гораздо проще пользоваться библиотеками-обертками, к примеру Jcabi-ssh. Здесь и кода меньше и выглядит он поприятнее:

import com.jcabi.ssh.Shell;
import com.jcabi.ssh.SSH;
Shell shell = new SSH("example.com", 22, "username", "password");
String stdout = new Shell.Plain(shell).exec("echo 'Hello, world!'");

Но все равно как-то выглядит не очень элегантно.

Абсолютным победителем для меня является библиотека - sshoogr. По сути - это Groovy DSL для работы с SSH.

Посмотрите, как легко с ней работать:

@Grab('com.aestasit.infrastructure.sshoogr:sshoogr:0.9.18')
import static com.aestasit.infrastructure.ssh.DefaultSsh.*

remoteSession('user2:654321@localhost:2222') {
  exec 'rm -rf /tmp/*'
  exec 'touch /var/lock/my.pid'
  remoteFile('/var/my.conf').text = "enabled=true"
}

Что стало для меня самым приятным, так это работа с файлами. К примеру:

def file = "/root/home/test.txt"
 def selenium = "selenium-server-standalone-2.48.2.jar"

 //write to file
 remoteFile(file).text = "Hello"

 //read from file
 print remoteFile(file).text

 //copy file to remote host
 scp {
      from { localFile "/root/home/${selenium}"}
      into { remoteFile "/root/remote/${selenium}" }
 }

Вот как можно легко и просто делать вещи. Не нужно париться с тысячей try-catch блоков, просто бери и делай. А самое важное здесь то, что все это является кодом, вы можете писать свои функции и использовать их, вы можете использовать мощь GString для параметризации и многие другие фишки Groovy. Я жалею, что узнал о ней только когда начал разбираться с Groovy.

P.S

В бочке меда не без ложки дегтя: у меня почему-то не сработал вариант конфигурации:

remoteSession {

  host = 'localhost'
  username = 'user2'
  password = '654321'
  port = 2222

  ...
}

Возможно, я что-то недосмотрел, но во всех остальных случаях работает отлично. На этом все! спасибо, что читали. Возможно, эта заметка поможет в будущем решать подобные проблемы проще и эффективнее. Счастливого Рождества всем! Подписывайтесь - в 2016 будем на связи…​