共享python虚拟环境

时间:2018-01-26 10:24:26

标签: pip ansible virtualenv ansible-role

我有ansible角色,其任务委托给localhost:

- name: Test role
  hosts: my_hosts
  gather_facts: no

  tasks:
      - name: Register remote hosts
        include_role: name=register_remote_hosts
        delegate_to: localhost

角色register_remote_systems必须适用于my_hosts中的每个主机,但必须从调用Ansible的框中运行,这就是为什么有delegate_to。

role_remote_hosts角色检查localhost上的特定应用程序,如果没有安装,则会创建虚拟环境,然后安装它:

- name: Check if my_app is installed system-wide
  shell: |
    my_app --version >/dev/null 2>&1
  register: my_app_cmd
  failed_when: my_app_cmd.rc not in [0, 127]

- name: Install My App
  block:
    - name: Create temporary directory for my_app
      tempfile:
        state: directory
        suffix: my_app
      register: my_app_temp

    - name: Create virtual environment
      command: virtualenv "{{ my_app_temp.path }}"

    - name: Install my_app
      pip:
        name: my_app
        state: latest
        virtualenv: "{{ my_app_temp.path }}"
        virtualenv_site_packages: yes

    - name: Set Virtual Environment variable
      set_fact:
        venv_activate: "source {{ my_app_temp.path }}/bin/activate"

  when: my_app_cmd.rc != 0

-  name: Use my_app
   shell: |
     {{ venv_activate | default('echo "Using my_app from system path"') }}
     my_app --version

一切都很好,但如果my_hosts中有很多主机,那么就会创建很多venv。

创建角色的最佳方法是什么,重新使用安装了my_app的相同venv。请注意,角色包含在许多不同的剧本中,我不想在每个使用“注册远程主机”角色的剧本中添加其他角色。在使用其他剧本之前,创建venv当然存在并发问题。

以上解决方案有效,我可以忍受它,但也许在Ansible中有更好的设计模式来解决这些问题。

1 个答案:

答案 0 :(得分:1)

解决方案是放置run_once(感谢@ssbarnea):

when: my_app_cmd.rc != 0
run_once: yes