Packages (packages)

Install and upgrade packages or ports from the packages lists described below. This way you can create packages lists as needed for a particular purpose and install them automatically when enabled. The details are described in the section Installation frameworks below. For general management of FreeBSD packages and ports use Ansible roles vbotka.freebsd_packages and vbotka.freebsd_ports

See also

defaults

See defaults/main/packages.yml. By default, the installation is disabled

fp_install: false

If enabled, the binary packages will be installed. If failed, the installation will be retried ten times delayed by five seconds.

freebsd_install_method: packages
freebsd_install_retries: 10
freebsd_install_delay: 5

You can change the defaults to install from ports

freebsd_install_method: ports

and optionally, use the already created binaries.

freebsd_use_packages: true

Packages lists pkg-orig

The mandatory structure is a list of dictionaries comprising attributes pkglist and packages. The items of the list packages can be of any form accepted by the FreeBSD utilities pkg, pkg-upgrade and portinstall. In the below example, the items are in the form pkg-orig aka category/port

shell> cat host_vars/foo.example.com/pkg_dict.yml
---
pkg_dict_amd64:
  - pkglist: ansible
    packages:
      - sysutils/ansible
      - sysutils/py-ansible-lint
      - sysutils/py-ansible-runner
  - pkglist: minimal
    packages:
      - shells/bash
      - devel/git@default
      - archivers/gtar
      - ports-mgmt/pkg
      - ports-mgmt/portmaster
      - ports-mgmt/portupgrade
      - net/rsync
      - ftp/wget
  - pkglist: smart
    packages:
      - sysutils/smartmontools
      - sysutils/smart

You can use this form also to:

See also

The default lists of dictionaries pkg_dict_* in defaults/main. Fit the lists to you needs and put them, for example, into the group_vars/all

Note

The list of dictionaries is selected automatically by the variable ansible_architecture

lookup('vars', 'pkg_dict_' ~ ansible_architecture)

See packages-install.yml

Enable lists

In the variable fp_packages enable packages lists that shall be installed

shell> cat host_vars/foo.example.com/fp-packages.yml
---
fp_install: true
fp_packages:
  - {list: ansible, enabled: true}
  - {list: minimal, enabled: true}

Install packages

shell> ANSIBLE_DISPLAY_SKIPPED_HOSTS=false ansible-playbook pb.yml -t fp_packages
...

TASK [vbotka.freebsd_postinstall : packages: Install packages] ****************************************************************************************
included: /home/admin/.ansible/roles/vbotka.freebsd_postinstall/tasks/packages-install.yml for foo.example.com => (item=ansible)
included: /home/admin/.ansible/roles/vbotka.freebsd_postinstall/tasks/packages-install.yml for foo.example.com => (item=minimal)

TASK [vbotka.freebsd_postinstall : packages-install: Get list of packages for ansible] ****************************************************************
ok: [foo.example.com]

TASK [vbotka.freebsd_postinstall : packages-install: Install packages ansible] ************************************************************************
ok: [foo.example.com] => (item=['sysutils/ansible', 'sysutils/py-ansible-lint', 'sysutils/py-ansible-runner'])

TASK [vbotka.freebsd_postinstall : packages-install: Get list of packages for minimal] ****************************************************************
ok: [foo.example.com]

TASK [vbotka.freebsd_postinstall : packages-install: Install packages minimal] ************************************************************************
ok: [foo.example.com] => (item=['shells/bash', 'devel/git@default', 'archivers/gtar', 'ports-mgmt/pkg', 'ports-mgmt/portmaster', 'ports-mgmt/portupgrade', 'net/rsync', 'ftp/wget'])

...

Upgrade packages

Set fp_pkg_state=latest if you want to upgrade packages. The module community.general.pkgng by default set the parameter use_globs=true. This means the module, quote: “Treat the package names as shell glob patterns”. Disable this parameter and set fp_pkg_use_globs=false if you use the form pkg-orig

shell> ansible-playbook pb.yml -t fp_packages -e fp_pkg_state=latest -e fp_pkg_use_globs=false

Packages lists pkg-name

You can use the form pkg-name to simplify the packages lists. You might want to create a dictionary first and convert it to the list to simplify the structure

shell>  cat host_vars/foo.example.com/pkg_dict.yml
---
pkg_dict_amd64: "{{ pkg_dict_amd64_dict |
                    dict2items(key_name='pkglist', value_name='packages') }}"
pkg_dict_amd64_dict:
  ansible: [py311-ansible, py311-ansible-lint, py311-ansible-runner]
  minimal: [bash, git, gtar, pkg, portmaster, portupgrade, rsync, wget]
  smart: [smartmontools, smart]

You’ll have to explicitly include the flavors (py311).

See also

FreeBSD Handbook Chapter 7. Flavors

Note

The form pkg-orig takes the version from the default Python.

Installation frameworks

You can put the list of enabled package lists into the host_vars. For example,

fp_packages:
  - {list: ansible, enabled: true}
  - {list: minimal, enabled: true}
  - {list: postinstall, enabled: true}
  - {list: smart, enabled: true}

Optionally, you can keep the list fp_packages together with the packages lists pkg_dict_* in group_vars/all. In this case, enable lists that shall be installed always and use variables to selectively enable other packages lists as needed. For example,

fp_packages:
  - {list: ansible, enabled: true}
  - {list: minimal, enabled: true}
  - {list: postinstall, enabled: true}
  - {list: apcups, enabled: "{{ fp_apcupsd_install }}"}
  - {list: hostap, enabled: "{{ fp_hostapd_install }}"}
  - {list: linux, enabled: "{{ fp_linux_install }}"}
  - {list: procmail, enabled: "{{ fp_procmail_install }}"}
  - {list: smart, enabled: "{{ fp_smartd_install }}"}
  - {list: snmpd, enabled: "{{ fp_snmpd_install }}"}
  - {list: wpa_supplicant, enabled: "{{ fp_wpasupplicant_install }}"}

All tasks are disabled in the role by default. See main.yml. For example, if you want to configure smartd enable fp_smartd to import smartd.yml. Enable fp_smartd_install if you also want to install packages list smart

fp_apcupsd: true
fp_apcupsd_install: true
fp_procmail: true
fp_procmail_install: true
fp_smartd: true
fp_smartd_install: true

Note

  • Some variables of the form fp_*_install are predefined in defaults. Take a look at the result of the command

    shell> egrep -r fp_.*_install ansible-freebsd-postinstall/defaults/
    
  • Take a look at the values of the variables

    shell> ansible-playbook pb.yml -t fp_debug -e fp_debug=true
    

The simple option is to use the “enablement” variables also in the list fp_packages. For example,

fp_packages:
  - {list: ansible, enabled: true}
  - {list: minimal, enabled: true}
  - {list: postinstall, enabled: true}
  - {list: apcups, enabled: "{{ fp_apcupsd }}"}
  - {list: hostap, enabled: "{{ fp_hostapd }}"}
  - {list: linux, enabled: "{{ fp_linux }}"}
  - {list: procmail, enabled: "{{ fp_procmail }}"}
  - {list: smart, enabled: "{{ fp_smartd }}"}
  - {list: snmpd, enabled: "{{ fp_snmpd }}"}
  - {list: wpa_supplicant, enabled: "{{ fp_wpasupplicant }}"}

In this case, if you enable the tasks the packages list installation will be also enabled. For example,

fp_apcupsd: true
fp_procmail: true
fp_smartd: true

The best practice is to install the packages as a first step

shell> ansible-playbook pb.yml -t fp_packages

Then disable the installation to speedup the play

fp_install: false

Install packages in jail

The module community.general.pkgng is jail-aware. The option jail says:

Pkg will execute in the given jail name or ID.

For example, given the inventory

(env) > ansible-inventory -i iocage-hosts.ini -i hosts --graph
@all:
  |--@ungrouped:
  |--@iocage:
  |  |--iocage_01
  |  |--iocage_02
  |--@up:
  |  |--afa9e515
  |  |--c1670497
  |  |--test_111

The below configuration file keeps the hosts the jails are running on

(env) > cat iocage-hosts.ini
iocage_01 ansible_host=10.1.0.18
iocage_02 ansible_host=10.1.0.73

[iocage]
iocage_01
iocage_02

[iocage:vars]
ansible_user=admin
ansible_become=true

The below configuration files provide dynamic inventory comprising the jails

(env) > cat 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 | split | map('split', '='))
(env) > cat hosts/99_constructed.yml
plugin: ansible.builtin.constructed
groups:
    up: iocage_state == 'up'

See also

The examples in Ansible collection vbotka.freebsd.

The below playbook installs packages on the running jails. The jails are identified by the jail ID (JID) stored in the variable iocage_jid. A jail is running on the host iocage_tags.vmm

- name: Install packages in jails.
  hosts: up
  gather_facts: true
  remote_user: admin
  become: true

  vars:

    ansible_python_interpreter: auto_silent
    act_pkg:
      - security/sudo
      - lang/python39

  tasks:

    - name: Install packages
      delegate_to: "{{ iocage_tags.vmm }}"
      community.general.pkgng:
        name: "{{ act_pkg }}"
        jail: "{{ iocage_jid }}"
        use_globs: false
        cached: true

Note

By default, the module community.general.pkgng treats the name as a shell glob pattern. This works fine with the form <pkg-name>. For example,

act_pkg:
  - sudo
  - python39

But, this doesn’t work with the form <pkg-origin>. For example,

act_pkg:
  - security/sudo
  - lang/python39

Disable parameter use_globs if you want to use the form <pkg-origin>

use_globs: false

For details see the issue FreeBSD. Add option use_globs to the module pkgng. #8632

Hint

The advantage of the delegation to the iocage host is that the repositories don’t have to be updated each time pkg (inside the module community.general.pkgng) is running. The best practice is to update the repositories on the iocage hosts and then set

cached: true

Quoting parameter cached:

cached:  Use local package base instead of fetching an updated one.
default: false

The below playbook does the same by importing this role and task packages.yml

- name: Install packages in jails.
  hosts: up
  gather_facts: true
  remote_user: admin
  become: true

  vars:

    ansible_python_interpreter: auto_silent
    fp_packages:
      - {list: custom, enabled: true}
    pkg_dict_amd64:
      - {pkglist: custom, packages: [security/sudo, lang/python39]}

  tasks:

    - name: Install packages
      vars:
        fp_install_delegate: "{{ iocage_tags.vmm }}"
        fp_pkg_jail: "{{ iocage_jid }}"
        fp_pkg_use_globs: false
        fp_pkg_cached: true
      ansible.builtin.import_role:
        name: vbotka.freebsd_postinstall
        tasks_from: packages.yml