davidsteg
davidsteg

Reputation: 11

How to Print the Version of an updated Package?

I'm just trying to get a notification from my weekly Update Ansible Task. The Idea is to get a notification when a specific repository got an update, e.g. "Jellyfin got the update 10.8.7-1". So far the Playbook look like this:

- name: Manages Packages
  hosts: ubuntu
  become: true
  tasks:
  - name: Cache Update and Upgrade
    apt:
      update_cache: yes
      cache_valid_time: 86400
      upgrade: full

  - name: Create Register
    shell: grep -E "^$(date +%Y-%m-%d).+ (install|upgrade) " /var/log/dpkg.log |cut -d " " -f 3-5
    register: result

  - name: Show Output Register
    debug: msg="{{ result.stdout_lines }}"
    when: result.stdout_lines is defined

  - name: Send notify to Telegram
    telegram:
      token: '###'
      chat_id: '###'
      msg: '{{ansible_hostname}} updated {{ result.stdout_lines | length }} Packages : {{ result.stdout_lines }}'
    when: result.stdout_lines | length > 0

As workaroud I Print all upgraded Packages. But I hope on a elegant solution.

the interessting result.stdout_lines could be:

"upgrade jellyfin-server:amd64 10.8.7-1", "upgrade jellyfin-web:all 10.8.7-1", "upgrade jellyfin:all 10.8.7-1",

I tried:

  - name: Check Jellyfin Upgrade
    telegram:
      token: '###'
      chat_id: '###'
      msg: 'Jellyfin got an New Update !'
    when: '"upgrade jellyfin:all 10.8.7-1" in result.stdout_lines'

but this need the whole String to work, that's not the point and I have no idea how to extract just the Version into a notification.

Have someone an idea?

Thanks in advance!

Upvotes: 1

Views: 622

Answers (1)

Vladimir Botka
Vladimir Botka

Reputation: 68004

Create a dictionary of installed and upgraded packages.

  1. Use module community.general.read_csv to parse the log
    - name: Parse dpkg.log
      community.general.read_csv:
        path: /var/log/dpkg.log
        delimiter: ' '
        fieldnames: [date, time, p1, p2, p3, p4]
      register: dpkg_log

See the registered variable. The list of the dictionaries will be in the attribute dpkg_log.list

    - debug:
        var: dpkg_log
      when: debug1|d(false)|bool
  1. Group the items by date, select today's items, select install/upgrade items, and create the dictionary of packages and their versions. Declare the variables
  dpkg_log_dict: "{{ dict(dpkg_log.list|groupby('date')) }}"
  today: "{{ '%Y-%m-%d'|strftime }}"
  pkg_arch_ver: "{{ dpkg_log_dict[today]|
                    selectattr('p1', 'in', ['install', 'upgrade'])|
                    items2dict(key_name='p2', value_name='p3') }}"

gives

  pkg_arch_ver:
    ansible-core:all: 2.12.9-1ppa~focal
    containerd.io:amd64: 1.6.8-1
    docker-ce-cli:amd64: 5:20.10.18~3-0~ubuntu-focal
    docker-ce-rootless-extras:amd64: 5:20.10.18~3-0~ubuntu-focal
    docker-ce:amd64: 5:20.10.18~3-0~ubuntu-focal
    docker-scan-plugin:amd64: 0.17.0~ubuntu-focal

Remove the architecture from the keys

  pkg_ver: "{{ dict(pkg_arch_ver.keys()|map('split', ':')|map('first')|list|
                    zip(pkg_arch_ver.values())) }}"

gives

  pkg_ver:
    ansible-core: 2.12.9-1ppa~focal
    containerd.io: 1.6.8-1
    docker-ce: 5:20.10.18~3-0~ubuntu-focal
    docker-ce-cli: 5:20.10.18~3-0~ubuntu-focal
    docker-ce-rootless-extras: 5:20.10.18~3-0~ubuntu-focal
    docker-scan-plugin: 0.17.0~ubuntu-focal
  1. Reporting should be trivial now
    - community.general.mail:
        to: admin
        subject: Ansible Upgrade
        body: |
          ansible-core updated to version: {{ pkg_ver['ansible-core'] }}
      when: pkg_ver.keys() is contains 'ansible-core'

gives

From: [email protected]
To: [email protected]
Cc: 
Subject: Ansible Upgrade
Date: Sat, 31 Dec 2022 04:15:21 +0100
X-Mailer: Ansible mail module

ansible-core updated to version: 2.12.9-1ppa~focal

Example of a complete playbook for testing

- hosts: localhost
  become: true

  vars:

    dpkg_log_dict: "{{ dict(dpkg_log.list|groupby('date')) }}"
    today: "{{ '%Y-%m-%d'|strftime }}"
    pkg_arch_ver: "{{ dpkg_log_dict[today]|
                      selectattr('p1', 'in', ['install', 'upgrade'])|
                      items2dict(key_name='p2', value_name='p3') }}"
    pkg_ver: "{{ dict(pkg_arch_ver.keys()|map('split', ':')|map('first')|list|
                      zip(pkg_arch_ver.values())) }}"

  tasks:

    - name: Cache Update and Upgrade
      apt:
        update_cache: yes
        cache_valid_time: 86400
        upgrade: full
      when: upgrade|d(false)|bool

    - name: Parse dpkg.log
      community.general.read_csv:
        path: /var/log/dpkg.log
        delimiter: ' '
        fieldnames: [date, time, p1, p2, p3, p4]
      register: dpkg_log
    - debug:
        var: dpkg_log
      when: debug1|d(false)|bool

    - debug:
        var: pkg_arch_ver
    - debug:
        var: pkg_ver

    - community.general.mail:
        to: admin
        subject: Ansible Upgrade
        body: |
          ansible-core updated to version: {{ pkg_ver['ansible-core'] }}
      when: pkg_ver.keys() is contains 'ansible-core'

Upvotes: 2

Related Questions