Установка Ansistrano на Debian и решение проблем
Не так давно появилась необходимость реализовать CI/CD. Подумав, решил разбить это на две части - сборку и деплой контейнеров и отдельно - на деплой кода. Вторую часть решил реализовать с помощью ansistrano - это аналог capistrano, только выполненный в виде модуля для ansible. Почему не стал делать статические контейнеры с кодом? Хотя бы потому, что в случае использования ansistrano, роллбек проходит практически мгновенно, а это большой плюс. Когда-то я уже поднимал ansistrano, но на этот раз всё оказалось несколько сложнее.
Ansible был установлен в контейнер c debian 9.0 из штатной пакетной базы. Затем были устновлены роли deploy и rollback в соответствии с документацией:
ansible-galaxy install ansistrano.deploy ansistrano.rollback
Первая возникшая проблема заключалась в том, что при попытке запуска деплоя всё падало на конструкции:
- include_tasks: "{{ ansistrano_before_setup_tasks_file | default('empty.yml') }}"
Это самая первая строка main.yml из роли deploy ansistrano. Как оказалось, директива include_tasks появилась только в ansible версии 2.4, а по умолчанию из репозитория дебиана можно поставить только 2.2. Пришлось немного изменить сборку контейнера, добавить в него python-pip3 и установить ansible через pip install ansible. Текущая версия аж 2.8.0! Как быстро летит время. Казалось бы совсем недавно пользовался версией 1.8, это явно говорит о том, какими темпами развивается ansible. На всякий случай проверил - в репозиториях убунты 18.04 лежит версия 2.5.1, так что если у вас контейнер базируется на ubuntu 18.04, у вас этой проблемы возникнуть не должно.
После этого всё начало работать, но упорно пыталось отправить анонимную статистику в ansistrano и на этом падало:
TASK [common/ansistrano/deploy : ANSISTRANO | Send anonymous stats] ***************************************************
[DEPRECATION WARNING]: evaluating ansistrano_allow_anonymous_stats as a bare variable, this behaviour will go away and
you might need to add |bool to the expression in the future. Also see CONDITIONAL_BARE_VARS configuration toggle..
This feature will be removed in version 2.12. Deprecation warnings can be disabled by setting
deprecation_warnings=False in ansible.cfg.
fatal: [utest]: FAILED! => {"changed": false, "msg": "Failed to connect to ansistrano.com at port 443: [Errno 104] Connection reset by peer"}
...ignoring
В документации для отключения отправки статистики рекомендуется задать значение false для переменной ansistrano_allow_anonymous_stats, но как я ни бился, это не помогло. Я пытался добавить это значение в раздел vars плейбука деплоя, задать в роли, подгрузить из внешнего файла с переменными - бесполезно. Даже добавил вывод значения переменной дебагом - переменная была успешно задана, но при деплое всё-равно шла попытка отправить статистику, после чего роль падала. Проблема была решена просто. В директории роли ansistrano.deploy в поддиректории tasks заменяем файл anon-stats.yml на пустой:
mv anon-stats.yml anon-stats.yml_orig
touch anon-stats.yml
Вуаля! Деплой проходит! Но после деплоя получаем пачку ошибок следующего вида:
Exception ignored in: <function WeakValueDictionary.__init__.<locals>.remove at 0xb7099d64>
Traceback (most recent call last):
File "/usr/lib/python3.5/weakref.py", line 117, in remove
TypeError: 'NoneType' object is not callable
Exception ignored in: <function WeakValueDictionary.__init__.<locals>.remove at 0xb7099d64>
Traceback (most recent call last):
File "/usr/lib/python3.5/weakref.py", line 117, in remove
TypeError: 'NoneType' object is not callable
Спустя какое-то время гугла подсказал, как решить эту проблему:
In short open
/usr/lib/python3.5/weakref.py
and change line 109 to:def remove(wr, selfref=ref(self), _atomic_removal=_remove_dead_weakref):
And line 117 to:
_atomic_removal(d, wr.key)
Note you need to do this with spaces, not tabs as this will cause other errors.
Возможно это кому-то будет полезным, как минимум оставлю этот пост в качестве памятки для себя самого.