
Чем меньше рутины мы привносим в свою работу, тем больше она может приносить удовольствия.
Сегодня я расскажу про автоматизированный деплойтинг в python. Это значит одной командой я могу залить на все продакшен сервера файлы, обновить на нем необходимые компоненты и перегрузить веб сервер, и наблюдать за этим откинувшись на кресле и попивать кофеек.
Я Вам расскажу про Fabric(На момент написания статьи 0.9.1 — бала последняя стабильная версия), наиболее подходящий для этого инструмент, который делает все описанное и даже больше через ssh.
Про установку рассказывать особо нечего, pip отлично справляется с этим.
В корень своего проекта я кладу fabfile.py, в этом файле и будут храниться все процедуры для работы с Fabric. Ниже приведу небольшой пример скрипта, который будет архивировать наш проект, заливать его на сервер и там разархивировать.
-
from fabric.api import *
-
env.hosts = ['oduvan@lyabah.com']
-
-
def deploy():
-
local('tar czf /tmp/my_project.tgz .')
-
put('/tmp/my_project.tgz', '/tmp/')
-
with cd('/home/oduvan/www/test_fab/'):
-
run('tar xzf /tmp/my_project.tgz')
Если у Вас все получилось, а я очень надеюсь, что с этим хостом и именем пользователя не у кого кроме меня получиться ничего не может (так что поменяйте свою строку конекта во второй строке), то вы можете увидеть что-то сильно напоминающее вот это:
-
$ fab deploy
-
[localhost] run: tar czf /tmp/my_project.tgz .
-
Password for oduvan@lyabah.com:
-
[oduvan@lyabah.com] put: /tmp/my_project.tgz -> /tmp/my_project.tgz
-
[oduvan@lyabah.com] run: tar xzf /tmp/my_project.tgz
-
[oduvan@lyabah.com] err: tar: ./fabfile.pyc: time stamp 2010-06-21 10:03:41 is 4.461083597 s in the future
-
[oduvan@lyabah.com] err: tar: .: time stamp 2010-06-21 10:03:41 is 4.460804762 s in the future
-
-
Done.
-
Disconnecting from lyabah.com… done.
Само собой, пароль у вас спросят и его необходимо будет ввести, в конце статьи я выложу свой пароль к ссш, чтоб вы могли протестить работу.
Кому лень вводить пароли могу добавить после второй сроки
env.password = ‘oh_its_my_real_password’
либо сгенерить себе файл с ссш ключом и путь к нему положить в
env.key_filename — в отличие и пароля тут может быть передан массив ключей
Но и этот код можно сократить. У Fabric есть contrib libs, одна из них project. Тут подробно каждую я описывать не буду, просто покажу пример с одной из них, дабы просто показать, что они есть
-
from fabric.api import *
-
from fabric.contrib.project import rsync_project
-
env.hosts = ['oduvan@lyabah.com']
-
-
def deploy():
-
local('python manage.py test', capture=False)
-
rsync_project('/home/oduvan/www/test_fab/','.')
как видите наш код сократился до одной команды, не считая команду для тестирования Django проекта, ведь если какая-то команда возвратит ошибочный статус, то выполнения прекратится, а значит если тесты не проходят загрузка не начинается. Дополнительный параметр capture говорит о том, что необходимо скрывать выходные данные команды, мы эту опцию отключаем.
Вот основные команды, которые Вам необходимо знать, чтоб свободно пользоваться Fabric
put — копировать файл с локальной машины на удаленную. Доп параметр mode — устанавливает права на файл, см chmod
get — копировать файл с удаленной на локальную
local — выполнить команду на локальной машине. Доп параметр capture — скрывать выходные данные, по умолчанию False
run — выполнить команду на удаленной машине
sudo — выполнить команду на удаленной машине через судо. Доп параметр user — указываем имя пользователя, под которым необходимо запустить команду
Обратите внимание, что у нас есть команда sudo, а значит при необходимости, мы можем и сервак зарелоадить и вообще сделать любые админ вещи, главное, чтоб пользователь был в судоерсах.
Для деплойтинга на несколько серверов, причем различной конфигурации, и роли – у Fabric тоже кое-что припасено.
-
from fabric.api import *
-
from fabric.contrib.project import rsync_project
-
env.roledefs = {'web':['oduvan@lyabah.com','oduvan@dev.lyabah.com'],
-
'db':['oduvan@db1.lyabah.com','oduvan@db2.lyabah.com'],
-
'media':['oduvan@media@lyabah.com'],
-
}
-
-
@roles('web')
-
def deploy():
-
rsync_project('/home/oduvan/www/test_fab/','.')
в этом примере заливка файлов будет идти сразу на 2 вебовых сервака. Как видите вы можете запланировать у себя роли отдельных серверов под БД, под медиа файл и т.д.
кроме как декоратаром роль можно указывать и при запуске процедуры
Иногда в момент или во время запуска необходимо передать данные скрипту.
В момент запуска это делается через аргументы самой функции
к примеру если у вас
то эти 2 аргумента можно передать как
-
$fab deploy:'HI','HO'
-
$ fab deploy:'HI',arg2='HO'
-
$ fab deploy:arg1='HI',arg2='HO'
Либо спросить что-то во время работы функции у пользователя функцией
prompt(text, key=None, default='', validate=None)
Задает вопрос пользователю с текстом text, если пользователь не вводит данные, то возвращает значение из default, предварительно отчищая его функцией validate, и возвращает как результат этой функции, если не передан key, иначе кладет значение в env[key]
А теперь примеры функций деплойтинга из реальной жизни, которые вы можете написать и у себя в проекте:
bounce_wsgi_procs — зарелоадить wsgi через touch в него
deploy_media — загружаем только медиа файлы
migrate — запускаем скрипт миграции через South
update_repositories - обновляем репозитарии
update_dependencies — устанавливаем зависимости
reload_nginx — перегружаем nginx
deploy — полная установка, последовательный запуск всех этих функций.
Подводя итоги могу сказать, что Fabric должна стать musthave tool в разработке.