Как автоматизатору побороть SSH
Хоу-хоу, надеюсь все отлично встретили Новый год и теперь ждут Рождества. Я решил не тратить время попусту и в этот короткий промежуток между праздниками написать небольшую заметку. В этот раз напишу о возможных вариантах работы с SSH.
Я думаю, что люди, работающие с 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 будем на связи…