Ansible: установка нескольких пакетов Python за один сеанс

В одном из моих плейбуков есть задача, которая устанавливает базовые пакеты Python:

---
  -
    name: "Install Python packages: {{ python_packages_to_install }}"
    sudo: true
    pip: name={{ item }}
    with_items: python_packages_to_install

Со следующим списком пакетов:

-
  include: python_basics.yaml
  vars:
     python_packages_to_install:
       - virtualenv
       - pss
       - requests
       - comment-builder
       - boto
       - ansible
       - uwsgitop
       - gitpull
       - ipython

Задача работает корректно и устанавливает пакеты:

TASK: [common | Install Python packages: ['virtualenv', 'pss', 'requests', 'comment-builder', 'boto', 'ansible', 'uwsgitop', 'gitpull', 'ipython']] ***
ok: [push-prod-01] => (item=virtualenv)
ok: [push-prod-01] => (item=pss)
ok: [push-prod-01] => (item=requests)
ok: [push-prod-01] => (item=comment-builder)
ok: [push-prod-01] => (item=boto)
ok: [push-prod-01] => (item=ansible)
ok: [push-prod-01] => (item=uwsgitop)
ok: [push-prod-01] => (item=gitpull)
changed: [push-prod-01] => (item=ipython)

Проблема в том, что каждая строка выполняется последовательной SSH-командой, а не установкой всех пакетов за один вызов.

Есть ли способ установить несколько пакетов Python с помощью команды Ansible pip?


person Adam Matan    schedule 14.07.2015    source источник


Ответы (2)


Расширяя ответ Бена, вы также можете продолжать сохранять список пакетов в виде списка yaml, как он у вас есть, и делать проекцию на одно значение, когда вы передаете его модулю pip, например:

pip: name="{{ python_packages_to_install | join(' ') }}"

Сохраняет ваш playbook немного более удобным в сопровождении...

person nitzmahone    schedule 14.07.2015
comment
Я получаю msg: this module requires key=value arguments (['name=virtualenv', 'pss', 'requests', 'comment-builder', 'boto', 'ansible', 'uwsgitop', 'gitpull', 'ipython']). Вероятно, что-то не так со строковым списком. - person Adam Matan; 14.07.2015
comment
Нужна пара цитат - обновление вашего ответа. - person Adam Matan; 14.07.2015
comment
О да, я на самом деле протестировал его с синтаксисом многострочного словаря, но сократил его до синтаксиса ярлыка для ответа (который обычно не требует кавычек, если нет пробелов, в зависимости от версии Ansible). Спасибо за исправление. ;) - person nitzmahone; 14.07.2015
comment
@MattDavis Лучше использовать синтаксис YAML, синтаксис ключ = значение Ansible довольно хакерский и хрупкий. - person augurar; 08.09.2016
comment
@augurar, так что я слышал (я работаю в основной инженерной группе Ansible;)) - person nitzmahone; 08.09.2016
comment
Похоже, это не работает с Ansible 2.7 — я получаю сообщение об ошибке fatal: [localhost]: FAILED! => { "changed": false, "cmd": [ "/usr/local/bin/pip2", "install", "openshift==0.8.4 boto3==1.5.20 botocore==1.8.50" ]. Проблема в том, что pip получает один аргумент со всеми тремя пакетами, а не один аргумент на пакет. Вместо этого использование цикла может быть немного медленнее, но с большей вероятностью будет работать. - person RichVel; 06.02.2019

В отличие от модуля Ansible apt, модуль pip не принимает список пакетов, разделенных запятыми. Вместо этого вы можете указать все имена пакетов в виде строки, разделенной пробелами, используя синтаксис == для указания версий:

python_packages_to_install: "virtualenv==1.11.6 pss requests comment-builder boto ansible uwsgitop gitpull ipython"

Если вы похожи на меня, это может показаться вам уродливым и непрактичным в управлении. Альтернативой является использование параметра requirements в модуле pip для указания файла требований. Конечно, вам нужно сначала создать файл требований, возможно, используя шаблон.

person Ben Whaley    schedule 14.07.2015