320 Install and audit packages

Use case

Use the role vbotka.freebsd.packages to install packages in Ansible clients. Audit installed packages.

Tree

shell> tree .
.
├── ansible.cfg
├── group_vars
│   └── all
│       └── ansible-client.yml
├── hosts
│   ├── 02_iocage.yml
│   └── 99_constructed.yml
├── iocage.ini
├── pb-pkg-update.yml
├── pb-test-01.yml
└── pb-test-02.yml

Synopsis

At the managed node iocage_02:

  • playbook pb-pkg-update.yml:

    • upgrade the package ports-mgmt/pkg

    • update FreeBSD repository catalogue (default cached = false).

At all running jails:

  • playbook pb-test-01.yml:

    • display variables

    • install packages

    • audit installed packages.

At the managed node iocage_02:

  • playbook pb-test-02.yml:

    • audit installed packages.

Requirements

  • Running jails at the iocage host.

Notes

  • Jail name doesn’t work in the parameter name of the module community.general.pkgng if the jail was created by iocage. Use JID instead

    pkg_jail: "{{ iocage_jid }}"
    

    The play pb-test-01.yml runs in the jails. The inventory iocage.ini is needed when a task is delegated to an iocage host

    pkg_delegate: "{{ iocage_tags.vmm }}"
    
  • Disable use_globs

    pkg_use_globs: false
    

    to use the packages in the form pkg-origin

    pkg_list:
      - security/sudo
      - lang/python311
      - ports-mgmt/pkg
    
  • The playbook pb-pkg-update.yml updates the repositories. Then, use the cached local package base instead of fetching an updated one

    pkg_cached: true
    

Note

vbotka.freebsd.packages is the role packages in the collection vbotka.freebsd.
vbotka.freebsd_packages is the role freebsd_packages in the namespace vbotka.
Please make sure the versions are the same before you switch between them.

See also

Jails at iocage_02

[iocage_02]# iocage list -l
+------+----------+------+-------+------+-----------------+--------------------+-----+----------------+----------+
| JID  |   NAME   | BOOT | STATE | TYPE |     RELEASE     |        IP4         | IP6 |    TEMPLATE    | BASEJAIL |
+======+==========+======+=======+======+=================+====================+=====+================+==========+
| None | test_2   | off  | down  | jail | 14.2-RELEASE-p3 | -                  | -   | -              | no       |
+------+----------+------+-------+------+-----------------+--------------------+-----+----------------+----------+
| 94   | test_111 | off  | up    | jail | 14.3-RELEASE-p8 | epair0b|10.1.0.174 | -   | ansible_client | no       |
+------+----------+------+-------+------+-----------------+--------------------+-----+----------------+----------+
| 92   | test_112 | off  | up    | jail | 14.3-RELEASE-p8 | epair0b|10.1.0.147 | -   | ansible_client | no       |
+------+----------+------+-------+------+-----------------+--------------------+-----+----------------+----------+
| 93   | test_113 | off  | up    | jail | 14.3-RELEASE-p8 | epair0b|10.1.0.231 | -   | ansible_client | no       |
+------+----------+------+-------+------+-----------------+--------------------+-----+----------------+----------+

ansible.cfg

Do not display skipped hosts. See the option display_skipped_hosts

[defaults]
gathering = explicit
callback_result_format = yaml
display_skipped_hosts = false
host_key_checking = false

[connection]
pipelining = true

Inventory iocage.ini

iocage_01 ansible_host=10.1.0.18
iocage_02 ansible_host=10.1.0.73
iocage_03 ansible_host=10.1.0.17
iocage_04 ansible_host=10.1.0.29

[iocage]
iocage_04

[iocage:vars]
ansible_user=admin
ansible_become=true
ansible_python_interpreter=auto_silent

group_vars

group_vars/all/ansible-client.yml
freebsd_install_method: packages
freebsd_install_retries: 3
freebsd_install_delay: 5

pkg_delegate: "{{ iocage_tags.vmm }}"
pkg_jail: "{{ iocage_jid }}"
pkg_use_globs: false
pkg_cached: true
pkg_list:
  - security/sudo
  - lang/python311
  - ports-mgmt/pkg

Inventory hosts

hosts/02_iocage.yml
plugin: vbotka.freebsd.iocage
host: 10.1.0.73
user: admin
env:
  CRYPTOGRAPHY_OPENSSL_NO_LEGACY: 1
get_properties: True
hooks_results:
  - /var/db/dhclient-hook.address.epair0b
compose:
  ansible_host: (iocage_hooks.0 == '-') | ternary(iocage_ip4, iocage_hooks.0)
  iocage_tags: dict(iocage_properties.notes | regex_findall('(\w+)=([\w\-]+)'))
hosts/99_constructed.yml
plugin: ansible.builtin.constructed
groups:
    up: iocage_state == 'up'

Display inventory

(env) > ansible-inventory -i hosts -i iocage.ini --graph
@all:
  |--@ungrouped:
  |  |--iocage_01
  |  |--iocage_02
  |  |--iocage_03
  |  |--test_2
  |--@up:
  |  |--test_111
  |  |--test_112
  |  |--test_113
  |--@iocage:
  |  |--iocage_04

Playbook pb-pkg-update.yml

- name: Upgrade package ports-mgmt/pkg
  hosts: iocage
  gather_facts: true
    
  tasks:

    - name: Upgrade package ports-mgmt/pkg
      register: out
      community.general.pkgng:
        name: ports-mgmt/pkg
        state: latest
        use_globs: false

    - name: Debug
      when: debug | d(false) | bool
      ansible.builtin.debug:
        var: out

Playbook output - Update repo

(env) > ansible-playbook pb-pkg-update.yml -i iocage.ini -e debug=true
PLAY [Upgrade package ports-mgmt/pkg] ******************************************

TASK [Gathering Facts] *********************************************************
ok: [iocage_04]

TASK [Upgrade package ports-mgmt/pkg] ******************************************
ok: [iocage_04]

TASK [Debug] *******************************************************************
ok: [iocage_04] => 
    out:
        changed: false
        failed: false
        msg: package(s) already latest
        stderr: ''
        stderr_lines: []
        stdout: |-
            Updating FreeBSD-ports repository catalogue...
            FreeBSD-ports repository is up to date.
            Updating FreeBSD-ports-kmods repository catalogue...
            FreeBSD-ports-kmods repository is up to date.
            Updating FreeBSD-base repository catalogue...
            FreeBSD-base repository is up to date.
            All repositories are up to date.
        stdout_lines:
        - Updating FreeBSD-ports repository catalogue...
        - FreeBSD-ports repository is up to date.
        - Updating FreeBSD-ports-kmods repository catalogue...
        - FreeBSD-ports-kmods repository is up to date.
        - Updating FreeBSD-base repository catalogue...
        - FreeBSD-base repository is up to date.
        - All repositories are up to date.

PLAY RECAP *********************************************************************
iocage_04                  : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

Playbook pb-test-01.yml

- name: Test role vbotka.freebsd.packages
  hosts: up
  gather_facts: true
  remote_user: admin
  become: true

  vars:
    ansible_python_interpreter: auto_silent

  roles:
    - vbotka.freebsd.packages

Playbook output - Display variables

Limit the inventory to one jail test_111

(env) > ansible-playbook pb-test-01.yml -i hosts -l test_111 \
                                        -t pkg_debug \
                                        -e pkg_debug=true
PLAY [Test role vbotka.freebsd.packages] ***************************************

TASK [Gathering Facts] *********************************************************
ok: [test_111]

TASK [vbotka.freebsd.packages : Vars: Set the lists for amd64] *****************
ok: [test_111]

TASK [vbotka.freebsd.packages : Vars: Debug pkg_debug=true] ********************
ok: [test_111] => 
    msg: |-
        ansible_facts.architecture: amd64
        pkg_dict:
          []

        pkg_list:
          - lang/python311
          - ports-mgmt/pkg
          - security/sudo

        pkg_list_deinstall:
          []

        pkg_dict_select:
          []

TASK [vbotka.freebsd.packages : Debug pkg_debug=true] **************************
ok: [test_111] => 
    msg: |-
        pkg_role_version: 2.8.1
        pkg_version_community_general: 9.3.0

        ansible_facts.architecture: amd64
        ansible_facts.os_family: FreeBSD
        ansible_facts.distribution: FreeBSD
        ansible_facts.distribution_major_version: 14
        ansible_facts.distribution_version: 14.2
        ansible_facts.distribution_release: 14.2-RELEASE-p1
        ansible_facts.python_version: 3.11.14

        freebsd_install_method: packages
        freebsd_install_retries: 3
        freebsd_install_delay: 5

        pkg_sanity: True
        pkg_sanity_version_community_general: True
        pkg_stat: False
        pkg_audit_enable: False
        pkg_backup_conf: False
        pkg_dryrun: False
        pkg_install_individually: False
        pkg_delegate: "iocage_02"

        pkg_owner: root
        pkg_group: wheel
        pkg_annotation: UNDEFINED
        pkg_autoremove: UNDEFINED
        pkg_cached: True
        pkg_chroot: UNDEFINED
        pkg_ignore_osver: UNDEFINED
        pkg_jail: 94
        pkg_pkgsite: UNDEFINED
        pkg_rootdir: UNDEFINED
        pkg_state: UNDEFINED
        pkg_use_globs: False

        pkg_default_repo_template: repo.j2
        pkg_default_repo_conf:
          []

        pkg_keys:
          {}

        pkg_repos_template: repos.j2
        pkg_repos_conf_clean: False
        pkg_repos_conf:
          []

        pkg_dict_all: False
        pkg_dict_select:
          []

        pkg_dict:
          []

        pkg_list:
          [security/sudo, lang/python311, ports-mgmt/pkg]

        pkg_list_deinstall:
          []

PLAY RECAP *********************************************************************
test_111                   : ok=4    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

Playbook output - Install packages

The inventory iocage.ini is needed to delegate the tasks Install list pkg_list

(env) > ansible-playbook pb-test-01.yml -i hosts -i iocage.ini
PLAY [Test role vbotka.freebsd.packages] ***************************************

TASK [Gathering Facts] *********************************************************
ok: [test_113]
ok: [test_112]
ok: [test_111]

TASK [vbotka.freebsd.packages : Vars: Set the lists for amd64] *****************
ok: [test_111]
ok: [test_112]
ok: [test_113]

TASK [vbotka.freebsd.packages : Sanity: Test collection community_general minimal version 9.3.0] ***
ok: [test_113]
ok: [test_112]
ok: [test_111]

TASK [vbotka.freebsd.packages : Sanity: Required variable pkg_jail when pkg_delegate] ***
ok: [test_111]
ok: [test_112]
ok: [test_113]

TASK [vbotka.freebsd.packages : Packages_install: Install list pkg_list] *******
ok: [test_112 -> iocage_02(10.1.0.73)]
ok: [test_113 -> iocage_02(10.1.0.73)]
ok: [test_111 -> iocage_02(10.1.0.73)]

PLAY RECAP *********************************************************************
test_111                   : ok=5    changed=0    unreachable=0    failed=0    skipped=39   rescued=0    ignored=0   
test_112                   : ok=5    changed=0    unreachable=0    failed=0    skipped=38   rescued=0    ignored=0   
test_113                   : ok=5    changed=0    unreachable=0    failed=0    skipped=38   rescued=0    ignored=0   

Hint

Optionally, do not display OK hosts. See display_ok_hosts

Playbook output - Install packages

Enable debug and limit the inventory to one jail test_111

(env) > ansible-playbook pb-test-01.yml -i hosts -i iocage.ini -l test_111 \
                                        -e pkg_debug=true
PLAY [Test role vbotka.freebsd.packages] ***************************************

TASK [Gathering Facts] *********************************************************
ok: [test_111]

TASK [vbotka.freebsd.packages : Vars: Set the lists for amd64] *****************
ok: [test_111]

TASK [vbotka.freebsd.packages : Vars: Debug pkg_debug=true] ********************
ok: [test_111] => 
    msg: |-
        ansible_facts.architecture: amd64
        pkg_dict:
          []

        pkg_list:
          - lang/python311
          - ports-mgmt/pkg
          - security/sudo

        pkg_list_deinstall:
          []

        pkg_dict_select:
          []

TASK [vbotka.freebsd.packages : Sanity: Test collection community_general minimal version 9.3.0] ***
ok: [test_111]

TASK [vbotka.freebsd.packages : Sanity: Required variable pkg_jail when pkg_delegate] ***
ok: [test_111]

TASK [vbotka.freebsd.packages : Debug pkg_debug=true] **************************
ok: [test_111] => 
    msg: |-
        pkg_role_version: 2.8.1
        pkg_version_community_general: 9.3.0

        ansible_facts.architecture: amd64
        ansible_facts.os_family: FreeBSD
        ansible_facts.distribution: FreeBSD
        ansible_facts.distribution_major_version: 14
        ansible_facts.distribution_version: 14.2
        ansible_facts.distribution_release: 14.2-RELEASE-p1
        ansible_facts.python_version: 3.11.14

        freebsd_install_method: packages
        freebsd_install_retries: 3
        freebsd_install_delay: 5

        pkg_sanity: True
        pkg_sanity_version_community_general: True
        pkg_stat: False
        pkg_audit_enable: False
        pkg_backup_conf: False
        pkg_dryrun: False
        pkg_install_individually: False
        pkg_delegate: "iocage_02"

        pkg_owner: root
        pkg_group: wheel
        pkg_annotation: UNDEFINED
        pkg_autoremove: UNDEFINED
        pkg_cached: True
        pkg_chroot: UNDEFINED
        pkg_ignore_osver: UNDEFINED
        pkg_jail: 94
        pkg_pkgsite: UNDEFINED
        pkg_rootdir: UNDEFINED
        pkg_state: UNDEFINED
        pkg_use_globs: False

        pkg_default_repo_template: repo.j2
        pkg_default_repo_conf:
          []

        pkg_keys:
          {}

        pkg_repos_template: repos.j2
        pkg_repos_conf_clean: False
        pkg_repos_conf:
          []

        pkg_dict_all: False
        pkg_dict_select:
          []

        pkg_dict:
          []

        pkg_list:
          [security/sudo, lang/python311, ports-mgmt/pkg]

        pkg_list_deinstall:
          []

TASK [vbotka.freebsd.packages : Keys: Debug pkg_debug=true] ********************
ok: [test_111] => 
    msg: |-
        pkg_keys:
          {}

TASK [vbotka.freebsd.packages : Conf: Debug pkg_debug=true] ********************
ok: [test_111] => 
    msg: |-
        pkg_owner: root
        pkg_group: wheel
        pkg_backup_conf: False
        pkg_default_repo_template: repo.j2
        pkg_default_repo_conf:
          []

        pkg_repos_template: repos.j2
        pkg_repos_conf:
          []

TASK [vbotka.freebsd.packages : Packages_install: Debug list pkg_list pkg_debug=true] ***
ok: [test_111] => 
    pkg_list:
    - security/sudo
    - lang/python311
    - ports-mgmt/pkg

TASK [vbotka.freebsd.packages : Packages_install: Install list pkg_list] *******
ok: [test_111 -> iocage_02(10.1.0.73)]

TASK [vbotka.freebsd.packages : Packages_install: Debug result pkg_debug=true] ***
ok: [test_111] => 
    result:
        attempts: 1
        changed: false
        failed: false
        msg: package(s) already present
        stderr: ''
        stderr_lines: []
        stdout: ''
        stdout_lines: []

PLAY RECAP *********************************************************************
test_111                   : ok=11   changed=0    unreachable=0    failed=0    skipped=33   rescued=0    ignored=0   

Playbook output - Audit installed packages

There are no installed packages with known vulnerabilities

(env) > ansible-playbook pb-test-01.yml -i hosts \
                                        -t pkg_stat \
                                        -e pkg_stat=true -e pkg_audit_enable=true \
                                        -e pkg_debug=true
PLAY [Test role vbotka.freebsd.packages] ***************************************

TASK [Gathering Facts] *********************************************************
ok: [test_111]
ok: [test_112]
ok: [test_113]

TASK [vbotka.freebsd.packages : Vars: Set the lists for amd64] *****************
ok: [test_112]
ok: [test_111]
ok: [test_113]

TASK [vbotka.freebsd.packages : Vars: Debug pkg_debug=true] ********************
ok: [test_112] => 
    msg: |-
        ansible_facts.architecture: amd64
        pkg_dict:
          []

        pkg_list:
          - lang/python311
          - ports-mgmt/pkg
          - security/sudo

        pkg_list_deinstall:
          []

        pkg_dict_select:
          []
ok: [test_111] => 
    msg: |-
        ansible_facts.architecture: amd64
        pkg_dict:
          []

        pkg_list:
          - lang/python311
          - ports-mgmt/pkg
          - security/sudo

        pkg_list_deinstall:
          []

        pkg_dict_select:
          []
ok: [test_113] => 
    msg: |-
        ansible_facts.architecture: amd64
        pkg_dict:
          []

        pkg_list:
          - lang/python311
          - ports-mgmt/pkg
          - security/sudo

        pkg_list_deinstall:
          []

        pkg_dict_select:
          []

TASK [vbotka.freebsd.packages : Stat: Get pkg audit] ***************************
ok: [test_113]
ok: [test_111]
ok: [test_112]

TASK [vbotka.freebsd.packages : Stat: Debug pkg audit pkg_debug=true] **********
ok: [test_111] => 
    pkg_audit:
        test_111:
            pkg_count: 0
        test_112:
            pkg_count: 0
        test_113:
            pkg_count: 0

PLAY RECAP *********************************************************************
test_111                   : ok=5    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
test_112                   : ok=4    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
test_113                   : ok=4    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

Playbook pb-test-02.yml

- name: Test role vbotka.freebsd.packages.
  hosts: iocage
  gather_facts: true
    
  roles:
    - vbotka.freebsd.packages

Playbook output - Audit installed packages at iocage_02

There are 9 packages with known vulnerabilities

(env) > ansible-playbook pb-test-02.yml -i iocage.ini \
                                        -t pkg_stat \
                                        -e pkg_stat=true -e pkg_audit_enable=true -e pkg_debug=true
PLAY [Test role vbotka.freebsd.packages.] **************************************

TASK [Gathering Facts] *********************************************************
ok: [iocage_04]

TASK [vbotka.freebsd.packages : Vars: Set the lists for amd64] *****************
ok: [iocage_04]

TASK [vbotka.freebsd.packages : Vars: Debug pkg_debug=true] ********************
ok: [iocage_04] => 
    msg: |-
        ansible_facts.architecture: amd64
        pkg_dict:
          []

        pkg_list:
          - lang/python311
          - ports-mgmt/pkg
          - security/sudo

        pkg_list_deinstall:
          []

        pkg_dict_select:
          []

TASK [vbotka.freebsd.packages : Stat: Get pkg audit] ***************************
ok: [iocage_04]

TASK [vbotka.freebsd.packages : Stat: Debug pkg audit pkg_debug=true] **********
ok: [iocage_04] => 
    pkg_audit:
        iocage_04:
            packages:
                expat:
                    issue_count: 1
                    issues:
                    -   Affected versions:
                        - < 2.7.4
                        cve:
                        - CVE-2026-25210
                        - CVE-2026-24515
                        description: expat -- multiple vulnerabilities
                        url: https://vuxml.FreeBSD.org/freebsd/027c6c07-065b-11f1-baae-589cfc023192.html
                    reverse dependencies:
                    - apache24
                    - mod_php83
                    - apr
                    - avahi-app
                    - samba416
                    - sssd2
                    - sudo-sssd
                    - dbus-glib
                    - dbus
                    - libarchive
                    - git
                    - py311-iocage
                    version: 2.7.3
                python311:
                    issue_count: 1
                    issues:
                    -   Affected versions:
                        - < 3.11.14_2
                        cve:
                        - CVE-2026-0865
                        - CVE-2026-1299
                        description: python -- several security vulnerabilities
                        url: https://vuxml.FreeBSD.org/freebsd/bfe9adc8-0224-11f1-8790-c5fb948922ad.html
                    reverse dependencies:
                    - py311-acme
                    - py311-setuptools
                    - py311-pyrfc3339
                    - py311-pytz
                    - py311-josepy
                    - acme-tiny
                    - py311-iocage
                    - py311-requests
                    - py311-urllib3
                    - py311-texttable
                    - py311-gitpython
                    - py311-gitdb
                    - py311-smmap
                    - py311-six
                    - py311-jsonschema
                    - py311-jsonschema-specifications
                    - py311-referencing
                    - py311-rpds-py
                    - py311-pysocks
                    - py311-netifaces
                    - py311-coloredlogs
                    - py311-humanfriendly
                    - py311-click
                    - py311-charset-normalizer
                    - py311-fail2ban
                    - py311-sqlite3
                    - py311-pyinotify
                    - python
                    - python3
                    - sssd2
                    - sudo-sssd
                    - samba416
                    - tevent
                    - ldb25
                    - tdb
                    - talloc
                    - py311-dnspython
                    - py311-aioquic
                    - py311-pyopenssl
                    - py311-httpx
                    - py311-httpcore
                    - py311-anyio
                    - py311-typing-extensions
                    - py311-truststore
                    - py311-trio
                    - py311-sortedcontainers
                    - py311-socksio
                    - py311-sniffio
                    - py311-service-identity
                    - py311-pylsqpack
                    - py311-cryptography
                    - py311-cffi
                    - py311-pycparser
                    - py311-pyasn1-modules
                    - py311-pyasn1
                    - glib
                    - avahi-app
                    - dbus-glib
                    - gamin
                    - py311-packaging
                    - py311-outcome
                    - py311-markdown
                    - py311-idna
                    - py311-h2
                    - py311-hyperframe
                    - py311-hpack
                    - py311-h11
                    - py311-certifi
                    - py311-attrs
                    - py311-async_generator
                    - git
                    version: 3.11.14_1
            pkg_count: 2

PLAY RECAP *********************************************************************
iocage_04                  : ok=5    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0