This seems like it should be really simple:
tasks:
- name: install python packages
pip: name=${item} virtualenv=~/buildbot-env
with_items: [ buildbot ]
- nam
The better way is to use the full path to installed script - it will run in its virtualenv automatically:
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"
Here's a way to enable the virtualenv for an entire play; this example builds the virtualenv in one play, then starts using it the next.
Not sure how clean it is, but it works. I'm just building a bit on what mikepurvis mentioned here.
---
# 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 wrapper file:
#!/bin/bash
source "$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )/activate"
python $@
Just run the virtualenvs pip in a shell:
shell: ~/buildbot-env/pip install ${item}
Works like a charm. I have no idea what the pip module does with virtualenvs, but it seems pretty useless.
This is a genericized version of the wrapper method.
venv_exec.j2:
#!/bin/bash
source {{ venv }}/bin/activate
$@
And then the playbook:
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 }}"
As I commented above, I create a script, say it is called buildbot.sh
:
source ~/buildbot-env/bin/activate
buildbot create-master [and more stuff]
Then run it on the remote with a task like this:
- name: Create buildbot master
script: buildbot.sh
To me this still seems unneccessary, but it maybe cleaner than running it in a shell command. Your playbook looks cleaner at the cost of not seeing immediately what the script does.
At least some modules do seem to use virtualenv, as both django_manage
and rax_clb
already have an inbuilt virtualenv parameter. It may not be such a big step for Ansible to include a command-in-virtenv sort of module.