1

There is a probably a better way to do this, but as of now, I am making this work, but having issues. I am attempting to do the following:

  1. Gather package facts using package_facts and register the packages
  2. I debug the registered variable and get the package I want, converting the version to an int
  3. I would then dynmaically set variable of the later package and also pull the version and convert to an int
  4. I attempt to upgrade the package with the set variable of the latest version of the package and only apply it if the set_fact variable's int version is greater than the existing package installed

Here is the playbook:

---
- name: Attempt upgrade package
  hosts: all
  gather_facts: false

  tasks:  
     
        - name: Get Splunk package
      package_facts:
        manager: auto
      register: package_info

    - name: Get SplunkForwarder Package Info
      debug:
        var: package_info.ansible_facts.packages.splunkforwarder[0].version
      register: splunk_current_version

    - name: Include variables for new splunk forwarder
      set_fact:
        splunk_latest_version: "{{ splunkforwarder_latest.split('-')[1] }}"
      vars:
        splunkforwarder_latest: "splunkforwarder-9.1.1-82c987350fde-linux-2.6-x86_64.rpm"
      when: splunk_current_version is defined

    - name: Debug latest
      debug:
        var: splunk_latest_version

    - name: Upgrade when latest package is detected
      yum:
        name: "splunkforwarder-{{ splunk_latest_version }}-linux-2.6-x86_64.rpm"
        state: latest
      when: splunk_current_version is defined and splunk_current_version is version(splunk_latest_version, '<')

Here is the error message I get, stating I am comparing two dicts, which is probably true. I am still fairly new at this.

fatal: [server1]: FAILED! => {"msg": "The conditional check 'splunk_current_version > splunk_current_version' failed. The error was: Unexpected templating type error occurred on ({% if splunk_current_version > splunk_current_version %} True {% else %} False {% endif %}): '>' not supported between instances of 'dict' and 'dict'\n\nThe error appears to be in '/home/admin/python-env/ansible/playbooks/uuid.yml': line 33, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n - name: Upgrade when latest package is detected.\n ^ here\n"}

I can probably simply just past the later version of the package to a variable, by including the variable or set and just yum update with the latest package. I am probably overcomplicating this, but I would appreciate any help or advice.

Debug output below:

    TASK [Get Splunk package] ******************************************************************************************************************************************************************************************
ok: [server1]
[WARNING]: Platform linux on host server1 is using the discovered Python interpreter at /usr/bin/python3.6, but future installation of another Python interpreter could change this. See
https://docs.ansible.com/ansible/2.9/reference_appendices/interpreter_discovery.html for more information.

ok: [server1]

TASK [Get SplunkForwarder Package Info] ****************************************************************************************************************************************************************************
ok: [server1] => {
    "package_info.ansible_facts.packages.splunkforwarder[0].version": "9.0.1"
}
ok: [server1] => {
    "package_info.ansible_facts.packages.splunkforwarder[0].version": "9.0.1"
}

TASK [Include variables for new splunk forwarder] ******************************************************************************************************************************************************************
ok: [server1]
ok: [server1]

TASK [Debug latest] ************************************************************************************************************************************************************************************************
ok: [server1] => {
    "splunk_latest_version": "9.1.1"
}
ok: [server1] => {
    "splunk_latest_version": "9.1.1"
}

TASK [Upgrade when latest package is detected] *********************************************************************************************************************************************************************
fatal: [server1]: FAILED! => {"msg": "The conditional check 'splunk_current_version is defined and splunk_current_version is version(splunk_latest_version, '<')' failed. The error was: Version comparison: '<' not supported between instances of 'str' and 'int'\n\nThe error appears to be in '/home/admin/python-env/ansible/playbooks/uuid.yml': line 36, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n    - name: Upgrade when latest package is detected\n      ^ here\n"}
fatal: [server1]: FAILED! => {"msg": "The conditional check 'splunk_current_version is defined and splunk_current_version is version(splunk_latest_version, '<')' failed. The error was: Version comparison: '<' not supported between instances of 'str' and 'int'\n\nThe error appears to be in '/home/admin/python-env/ansible/playbooks/uuid.yml': line 36, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n    - name: Upgrade when latest package is detected\n      ^ here\n"}

PLAY RECAP *********************************************************************************************************************************************************************************************************
SwiperNo
  • 59
  • 10
  • 2
    It sounds like you have not yet read about [the version comparison test](https://docs.ansible.com/ansible/7/playbook_guide/playbooks_tests.html#comparing-versions), setting aside your typo or tautological test of `when: thing > thing` – mdaniel Mar 15 '23 at 04:53
  • I updated my error. Apologies! I have never heard of this. I will check it out. Thank you for sharing! – SwiperNo Mar 15 '23 at 05:02
  • You could take advantage from [How to compare kernel (or other) version numbers in Ansible](https://stackoverflow.com/questions/39779802/), [Compare version numbers using Jinja2](https://stackoverflow.com/questions/46324330/) and others ... – U880D Mar 15 '23 at 07:12
  • 1
    `I debug the registered variable and get the package I want, converting the version to an int`. 1) make this a [mre] by providing the debug result in an [edit] to your question 2) versions are not int and there's no need to convert as there is a specific filter to compare them as already mentioned in comments above. – Zeitounator Mar 15 '23 at 08:30
  • @Zeitounator I updated the playbook and provided the debug output. I went with the version test and removed the int conversion. Still getting the same error. – SwiperNo Mar 15 '23 at 13:39
  • @U880D I am attempting to use something similar but still having issues. – SwiperNo Mar 15 '23 at 13:40
  • I think I may have found the issue. I needed to add '' - single qoutes {{ 'splunk_current_version' is version('splunk_latest_version', '<') }}. When I tested an assert - it passed. – SwiperNo Mar 15 '23 at 14:58
  • Your situation is made worse by the fact that `- { register: ..., debug: ... }` is wrong 100% of the time, you want `set_fact:` instead – mdaniel Mar 15 '23 at 15:23
  • @mdaniel Thanks I will make that adjustment. Better usage for sure. – SwiperNo Mar 15 '23 at 15:28

1 Answers1

4

The version you want to compare is not the raw one given in package facts. You will need to extract it as you did for your latest version.

Given the following version_compare.yml test playbook:

---
- name: Compare version demo
  hosts: localhost
  gather_facts: false

  vars:
    current_package_version: "{{ ansible_facts.packages[search_package][0].version.split('-') | first }}"

  tasks:
    - name: This test playbook requires variables search_package and compare_version
      ansible.builtin.assert:
        that:
          - search_package is defined
          - compare_version is defined
        msg: please define the search_package and compare_version variables

    - name: Get package facts
      ansible.builtin.package_facts:

    - name: Facts for {{ search_package }} must exist to go on
      ansible.builtin.assert:
        that: ansible_facts.packages[search_package] is defined
        msg: Please use in search_package a package name which exist on the sytem

    - name: Show raw facts about package {{ search_package }}
      ansible.builtin.debug:
        var: ansible_facts.packages[search_package]

    - name: Show version number we actually want to work with
      ansible.builtin.debug:
        var: current_package_version

    - name: Do something if version is lower than compared one
      ansible.builtin.debug:
        msg: >-
          I would do something since version {{ current_package_version }}
          is lower than {{ compare_version }}
      when: current_package_version is version(compare_version, '<')

You can run against any package installed on your system to test. I used the zenity package which is installed on my local machine. 2 example run below for a passing (lower) and failing (greater of equal) case:

$ ansible-playbook version_compare.yml -e search_package=zenity -e compare_version=4.0.0

PLAY [Compare version demo] *******************************************************************************************************************************************************************************

TASK [This test playbook requires variables search_package and compare_version] ***************************************************************************************************************************
ok: [localhost]

TASK [Get package facts] **********************************************************************************************************************************************************************************
ok: [localhost]

TASK [Facts for zenity must exist to go on] ***************************************************************************************************************************************************************
ok: [localhost]

TASK [Show raw facts about package zenity] ****************************************************************************************************************************************************************
ok: [localhost] => {
    "ansible_facts.packages[search_package]": [
        {
            "arch": "amd64",
            "category": "gnome",
            "name": "zenity",
            "origin": "Ubuntu",
            "source": "apt",
            "version": "3.42.1-0ubuntu1"
        }
    ]
}

TASK [Show version number we actually want to work with] **************************************************************************************************************************************************
ok: [localhost] => {
    "current_package_version": "3.42.1"
}

TASK [Do something if version is lower than compared one] *************************************************************************************************************************************************
ok: [localhost] => {
    "msg": "I would do something since version 3.42.1 is lower than 4.0.0"
}

PLAY RECAP ************************************************************************************************************************************************************************************************
localhost                  : ok=6    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

$ ansible-playbook version_compare.yml -e search_package=zenity -e compare_version=3.42.1

PLAY [Compare version demo] *******************************************************************************************************************************************************************************

TASK [This test playbook requires variables search_package and compare_version] ***************************************************************************************************************************
ok: [localhost]

TASK [Get package facts] **********************************************************************************************************************************************************************************
ok: [localhost]

TASK [Facts for zenity must exist to go on] ***************************************************************************************************************************************************************
ok: [localhost]

TASK [Show raw facts about package zenity] ****************************************************************************************************************************************************************
ok: [localhost] => {
    "ansible_facts.packages[search_package]": [
        {
            "arch": "amd64",
            "category": "gnome",
            "name": "zenity",
            "origin": "Ubuntu",
            "source": "apt",
            "version": "3.42.1-0ubuntu1"
        }
    ]
}

TASK [Show version number we actually want to work with] **************************************************************************************************************************************************
ok: [localhost] => {
    "current_package_version": "3.42.1"
}

TASK [Do something if version is lower than compared one] *************************************************************************************************************************************************
skipping: [localhost]

PLAY RECAP ************************************************************************************************************************************************************************************************
localhost                  : ok=5    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0
Zeitounator
  • 38,476
  • 7
  • 53
  • 66