Prototype: packagesmatching(package_regex, version_regex, arch_regex, method_regex)

Return type: data

Description: Return a data container with the list of installed packages matching the parameters.

This function searches for the anchored regular expressions in the list of currently installed packages.

The return is a data container with a list of package descriptions, looking like this:

code
[
   {
      "arch":"default",
      "method":"dpkg",
      "name":"zsh-common",
      "version":"5.0.7-5ubuntu1"
   }
]

Arguments:

  • package_regex: string - Regular expression (unanchored) to match package name - in the range: .*
  • version_regex: string - Regular expression (unanchored) to match package version - in the range: .*
  • arch_regex: string - Regular expression (unanchored) to match package architecture - in the range: .*
  • method_regex: string - Regular expression (unanchored) to match package method - in the range: .*

IMPORTANT: The data source used when querying depends on policy configuration. When package_inventory in body common control is configured, CFEngine will record the packages installed and the package updates available for the configured package modules. In the Masterfiles Policy Framework package_inventory will be configured to the default for the hosts platform. Since only one body common control can be present in a policy set any bundles which use these functions will typically need to execute in the context of a full policy run. However, the packagesmatching and packageupdatesmatching policy functions will look for and use the existing software inventory databases (available in $(sys.statedir)), even if the default package inventory is not configured. This enables the usage of these policy functions in standalone policy files. But please note that you still need the default package inventory attribute specified in the policy framework for the software inventory databases to exist in the first place and for them to be maintained/updated. If there is no package_inventory attribute (such as on package module unsupported platforms) and there are no software inventory databases available in $(sys.statedir) then the legacy package methods data will be used instead. At no time will both the standard and the legacy data be available to these functions simultaneously.

Example:

The following code extracts just the package names, then looks for some desired packages, and finally reports if they are installed.

code
body common control

{
      bundlesequence => { "missing_packages" };
}


bundle agent missing_packages
{
  vars:
    # List of desired packages
    "desired" slist => { "mypackage1", "mypackage2" };

    # Get info on all installed packages
    "installed" data => packagesmatching(".*",".*",".*",".*");
    "installed_indices" slist => getindices(installed);

    # Build a simple array of the package names so that we can use
    # getvalues to pull a unified list of package names that are installed.
    "installed_name[$(installed_indices)]"
      string => "$(installed[$(installed_indices)][name])";

    # Get unified list of installed packages
    "installed_names" slist => getvalues("installed_name");

    # Determine packages that are missing my differencing the list of
    # desired packages, against the list of installed packages
    "missing_list" slist => difference(desired,installed_names);

  reports:
    # Report on packages that are missing, installed
    # and what we were looking for
    "Missing packages = $(missing_list)";
    "Installed packages = $(installed_names)";
    "Desired packages = $(desired)";
}

This policy can be found in /var/cfengine/share/doc/examples/packagesmatching.cf and downloaded directly from github.

Refresh rules: * installed packages cache used by packagesmatching() is refreshed at the end of each agent run in accordance with constraints defined in the relevant package module body. * installed packages cache is refreshed after installing or removing a package. * installed packages cache is refreshed if no local cache exists. This means a reliable way to force a refresh of CFEngine's internal package cache is to simply delete the local cache:

code
$(sys.statedir)/packages_installed_<package_module>.lmdb*

Or in the case of legacy package methods:

code
$(sys.statedir)/software_packages.csv

History:

  • Introduced in CFEngine 3.6

  • Function started using package_module based data sources by default, even if there is no package_inventory attribute defined in body common control if available in 3.23.0, 3.21.3

See also: packageupdatesmatching(), Package information cache tunables in the MPF