воскресенье, 19 июля 2015 г.

Ansible - плагины

В предыдущей статье я показал как можно написать для ansible свой модуль, на примере установки пакетов из AUR. Это делает меня на один шаг ближе к цели - создать решение для максимально полного сохранения конфигурации своего домашнего компьютера, однако остаются нерешенные задачи. В частности хотелось бы список пакетов, которые нужно устанавливать - хранить в отдельном конфигурационном файле, а не прописывать их в playbook. Это позволит н-р в одном случае прочитать конфиг и вернуть из него только неустановленные пакеты, подав их на вход модуля yaourt, в другом случае - можно будет сравнить список явно установленных пакетов в системе и выдать те, которые ещё не прописаны в конфиге и т.д.


В этой нелёгкой задаче могут помочь плагины. Как обычно, заглядываем в документацию, узнаем, что типов плагинов может быть великое множество. Наиболее подходящими мне показались lookup плагины, на сайте о них написано весьма скудно, но в их официальном github, примеров, что бы разобраться - достаточно. Прежде чем приступить к разработке нужно сказать ansible, где искать пользовательские плагины, для этого создаём файл "~/.config/ansible/ansible.cfg":
[defaults]
lookup_plugins = ~/.config/ansible/plugins/lookup_plugins:/usr/share/ansible_plugins/lookup_plugins
Тут мы указали как умолчательный, так и пользовательский путь к плагинам. Теперь в указанной директории добавляем код плагина (файл "~/.config/ansible/plugins/lookup_plugins/cfg_file.py"):
class LookupModule:
    def __init__(self, **kwargs):
        pass

    def run(self, terms, variables=None, **kwargs):
        return ["python2-idna", "python2-notify"]
Объяснить как он работает проще всего на примере playbook, который использовался в предыдущих статьях, немного модифицировав его:
- hosts: all

  tasks:
    - name: Refresh package list
      yaourt: update_cache=yes

    - name: Install python packages
      yaourt: name={{ item }} state=present
      with_cfg_file: ~/projects/git/config.py filter=all
Нас интересует строчка "with_cfg_file: ~/projects/git/config.py filter=all". Она означает, что ansible найдёт плагин "cfg_file" и вызовет его примерно вот так:
import cfg_file

items = cfg_file.LookupModule().run(terms="path=~/projects/git/config.py filter=all")
Метод "run" обязан возвратить список. Затем для каждого элемента которого будет вызван соответствующий модуль, в данном случае - "yaourt". Если запустить все это, то результат опять будет таким же как в предыдущих статьях:
$ cd ~/.config/ansible/
$ ansible-playbook ~/.config/ansible/test.yml -i ~/.config/ansible/hosts

PLAY [all] ******************************************************************** 

GATHERING FACTS *************************************************************** 
ok: [home]

TASK: [Refresh package list] ************************************************** 
changed: [home]

TASK: [Install python packages] *********************************************** 
changed: [home] => (item=python2-idna)
changed: [home] => (item=python2-notify)

PLAY RECAP ******************************************************************** 
home                       : ok=3    changed=2    unreachable=0    failed=0
Обращу внимание, что запускать все нужно из директории "~/.config/ansible/", что бы написанный выше "ansible.cfg" был найден и использован вместо основного. Естественно это всего лишь демонстрация, в реальном плагине входящие параметры следует разобрать и прочитать нужные данные. Но поскольку напрямую к ansible это отношения не имеет и занимает порядка 200 строк тривиального кода, я публиковать его не буду.

Итоги: казалось бы уже третья статья мусолит один и тот же простейший playbook, но обратите внимание, как фактически без переделки playbook удалось перейти с официального "pacman" на более общий "yaourt", а потом ещё разнести данные и управляющие конструкции по разным файлам. Чувствуется, что авторы основательно подумали над архитектурой, хотя конфигурация на yaml на мой взгляд выглядит излишней. Понятно, что таким решением пытались добавить декларативности, максимально отвязаться от python, но складывается впечатление, что без знаний python хотя бы на уровне - почитать исходники модулей и плагинов, обойтись невозможно.

Посмотрим, что будет дальше.

Комментариев нет:

Отправить комментарий