Сильная команда изнутри virtualenv?

Кажется, что это должно быть очень просто:

tasks:
- name: install python packages
  pip: name=${item} virtualenv=~/buildbot-env
  with_items: [ buildbot ]
- name: create buildbot master
  command: buildbot create-master ~/buildbot creates=~/buildbot/buildbot.tac

Однако команда не будет выполнена, если инициатор virtualenv script не будет найден первым, и, похоже, нет необходимости делать это в Ansible command module.

Я экспериментировал с поиском активировать script в различных файлах .profile,.bashrc,.bash_login и т.д., без везения. В качестве альтернативы, есть команда оболочки, но это выглядит как неудобный хак:

- name: create buildbot master
  shell: source ~/buildbot-env/bin/activate && \
         buildbot create-master ~/buildbot \
         creates=~/buildbot/buildbot.tac executable=/bin/bash

Есть ли лучший способ?

Ответ 1

Лучше всего использовать полный путь к установленному script - он будет запускаться в своем виртуальном каталоге автоматически:

tasks:
- name: install python packages
  pip: name={{ item }} virtualenv={{ venv }}
  with_items: [ buildbot ]
- name: create buildbot master
  command: "{{ venv }}/bin/buildbot create-master ~/buildbot
            creates=~/buildbot/buildbot.tac"

Ответ 2

Это обобщенная версия метода обертки.

venv_exec.j2:

#!/bin/bash
source {{ venv }}/bin/activate
[email protected]

А затем плейер:

tasks:
  - pip: name={{ item }} virtualenv={{ venv }}
    with_items:
      - buildbot
  - template: src=venv_exec.j2 dest={{ venv }}/exec mode=755
  - command: "{{ venv }}/exec buildbot create-master {{ buildbot_master }}"

Ответ 3

Здесь вы можете включить виртуальную игру для целой игры; в этом примере создается виртуальный файл в одном воспроизведении, затем он начинает его использовать.

Не уверен, насколько он чист, но он работает. Я просто немного поразмышляю над тем, что здесь упоминается mikepurvis.

---
# Build virtualenv
- hosts: all
vars:
  PROJECT_HOME: "/tmp/my_test_home"
  ansible_python_interpreter: "/usr/local/bin/python"
tasks:
  - name: "Create virtualenv"
    shell: virtualenv "{{ PROJECT_HOME }}/venv"
           creates="{{ PROJECT_HOME }}/venv/bin/activate"

  - name: "Copy virtualenv wrapper file"
    synchronize: src=pyvenv
                 dest="{{ PROJECT_HOME }}/venv/bin/pyvenv"

# Use virtualenv
- hosts: all
vars:
  PROJECT_HOME: "/tmp/my_test_home"
  ansible_python_interpreter: "/tmp/my_test_home/venv/bin/pyvenv"
tasks:
  - name: "Guard code, so we are more certain we are in a virtualenv"
    shell: echo $VIRTUAL_ENV
    register: command_result
    failed_when: command_result.stdout == ""

файл оболочки pyenv:

#!/bin/bash
source "$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )/activate"
python [email protected]

Ответ 4

Как я уже отмечал выше, я создаю script, скажем, он называется buildbot.sh:

source ~/buildbot-env/bin/activate
buildbot create-master [and more stuff]

Затем запустите его на пульте дистанционного управления с помощью следующей задачи:

- name: Create buildbot master
  script: buildbot.sh

Мне это все еще кажется ненужным, но, возможно, он чище, чем запуск его в команде оболочки. Ваш плейер выглядит более чистым, если не увидеть, что делает script.

По крайней мере некоторые модули, похоже, используют virtualenv, поскольку как django_manage, так и rax_clb уже имеют встроенный параметр virtualenv. Возможно, это не такой большой шаг, чтобы Ansible мог включать в себя модуль типа command-in-virtenv.

Ответ 5

Просто запустите виртуальный пип в оболочке:

shell: ~/buildbot-env/pip install ${item}

Работает как шарм. Я понятия не имею, что делает модуль pip с virtualenvs, но он кажется довольно бесполезным.