¿Un comando Ansible desde dentro de virtualenv?


Esto parece que debería ser realmente simple:

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

Sin embargo, el comando no tendrá éxito a menos que el script activate de virtualenv se obtenga primero, y no parece haber provisión para hacerlo en el módulo de comando Ansible .

He experimentado con el abastecimiento de la secuencia de comandos activar en varios de .perfil, .bashrc, .bash_login, etc, sin suerte. Alternativamente, está el comando shell, pero parece una especie de truco incómodo:

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

Está allí una mejor manera?

Author: mikepurvis, 2013-11-18

5 answers

La mejor manera es usar la ruta completa al script instalado-se ejecutará en su virtualenv automáticamente:

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"
 20
Author: anatoly techtonik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-08 09:15:12

Esta es una versión genérica del método wrapper.

Venv_exec.j2:

#!/bin/bash
source {{ venv }}/bin/activate
$@

Y luego el libro de jugadas:

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 }}"
 24
Author: mikepurvis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-12-13 17:22:12

Aquí hay una manera de habilitar el virtualenv para una reproducción completa; este ejemplo construye el virtualenv en una reproducción, luego comienza a usarlo en la siguiente.

No estoy seguro de lo limpio que está, pero funciona. Estoy construyendo un poco sobre lo que Mikepurvis mencionó aquí.

---
# 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 == ""

Archivo de envoltura Pyenv:

#!/bin/bash
source "$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )/activate"
python $@
 7
Author: Matt Schlobohm,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-12-14 01:36:24

Como comenté anteriormente, creo un script, digamos que se llama buildbot.sh:

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

Luego ejecútelo en el control remoto con una tarea como esta:

- name: Create buildbot master
  script: buildbot.sh

Para mí esto todavía parece innecesario, pero tal vez más limpio que ejecutarlo en un comando de shell. Su libro de jugadas se ve más limpio a costa de no ver inmediatamente lo que hace el script.

Al menos algunos módulos parecen usar virtualenv, ya que tanto django_manage como rax_clb ya tienen un parámetro virtualenv incorporado. Puede que no sea un gran paso por Ansible para incluir un comando en virtenv tipo de módulo.

 1
Author: glormph,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-18 12:00:58

Simplemente ejecute el pip virtualenvs en un shell:

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

Funciona como un encanto. No tengo idea de lo que hace el módulo pip con virtualenvs, pero parece bastante inútil.

 1
Author: Lennart Regebro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-16 17:14:42