2

I need to be able to install a MySQL library. Python has 1 package for v2 and another for v3. I need to be able to tell Ansible which package to install.

- name: Ensure MySQL-python is installed
  pip:
    name: MySQL-python
    state: present
  become: true
  when: python_version is regex("^2.*")

- name: Ensure mysqlclient is installed
  pip:
    name: mysqlclient
    state: present
  become: true
  when: python_version is regex("^3.*")

The regular expression is valid but Ansible is skipping them both even though this:

- debug:
    var: python_version

returns this:

TASK [debug] ****************************************************************************************************************************************************************
ok: [localhost] => {
    "python_version": "2.7.10"
}
Ken Jenney
  • 422
  • 7
  • 15
  • 1
    Are you totally positively sure your `python_version` variable is set correctly in your playbook ? On my side (ansible 2.8.1) I cannot reproduce your problem and your regex match correctly. And why use a custom variable when you can get this automatically in your facts with `ansible_python_version` ? It would be much better to use version comparison (as proposed by @Vladimir Botka below). But this won't work either if your data is not correct in first place – Zeitounator Aug 09 '19 at 18:19

2 Answers2

5

regex works for me with ansible 2.7.9. The example below

      vars:
        python_version: "2.7.10"
      tasks:
        - debug:
            msg: Python version 2
          when: python_version is regex('^2.*')

gives

    "msg": "Python version 2"

Version Comparison is more convenient for complex tests. The example below gives the same result.

        - debug:
            msg: Python version 2
          when:
            - python_version is version('2', '>=')
            - python_version is version('3', '<')

The test regex is documented in Ansible 2.8 for the first time. In earlier versions, only the tests search and match are documented. In the current source the tests search and match are implemented on top of regex

    def match(value, pattern='', ignorecase=False, multiline=False):
        return regex(value, pattern, ignorecase, multiline, 'match')

    def search(value, pattern='', ignorecase=False, multiline=False):
        return regex(value, pattern, ignorecase, multiline, 'search')
Vladimir Botka
  • 58,131
  • 4
  • 32
  • 63
  • 2
    The regex in OPs example match correctly for me and are doing the job (ansible 2.8.1). So I suspect the problem is somewhere else. Meanwhile, I totally agree version comparison is the good practice solution in this case. – Zeitounator Aug 09 '19 at 18:21
1

Like Vladimir said.
Another improvement might be the source of python_version. When using gather_facts you can do it without regexp.

---
- hosts: localhost
  gather_facts: True

  tasks:

    - name: do some stuff
      debug:
        msg: do something because it is python 3
      when: ansible_facts.python.version.major is version('3', '=')

    - name: do other stuff
      debug:
        msg: I don't support legacy software
      when: ansible_facts.python.version.major is version('2', '=')
Markus
  • 2,998
  • 1
  • 21
  • 28
  • This doesn't work when you are in a virtualenv. ansible_facts.python.version reports the system python version rather than the version that's actually running ansible. – Ken Jenney Aug 09 '19 at 21:06