lib/packages.cf

Table of Contents

See the packages promises documentation for a comprehensive reference on the body types and attributes used here.

package_module bodies

apk

Prototype: apk

Implementation:

body package_module apk
{
  query_installed_ifelapsed => "$(package_module_knowledge.query_installed_ifelapsed)";
  query_updates_ifelapsed => "$(package_module_knowledge.query_updates_ifelapsed)";
}

apt_get

Prototype: apt_get

Implementation:

body package_module apt_get
{
    query_installed_ifelapsed => "$(package_module_knowledge.query_installed_ifelapsed)";
    query_updates_ifelapsed => "$(package_module_knowledge.query_updates_ifelapsed)";
    #default_options =>  {};
@if minimum_version(3.12.2)
    termux::
      interpreter => "$(paths.bin_path)/python";
    !termux::
      interpreter => "$(sys.bindir)/cfengine-selected-python";
@endif
}

zypper

Prototype: zypper

Implementation:

body package_module zypper
{
      query_installed_ifelapsed => "$(package_module_knowledge.query_installed_ifelapsed)";
      query_updates_ifelapsed => "$(package_module_knowledge.query_updates_ifelapsed)";
      #default_options =>  {};
@if minimum_version(3.12.2)
      interpreter => "$(sys.bindir)/cfengine-selected-python";
@endif
}

nimclient

Prototype: nimclient

Description: Define details used when interfacing with nimclient package module

Example:

bundle agent example_nimclient
{
  packages:
      "expect.base"
        policy => "present",
        options => { "lpp_source=lppaix71034" },
        package_module => nimclient;
}

Implementation:

body package_module nimclient
{
    query_installed_ifelapsed => "$(package_module_knowledge.query_installed_ifelapsed)";
    query_updates_ifelapsed => "$(package_module_knowledge.query_updates_ifelapsed)";
    # This would likey be customized based on your infrastructure specifics
    # you may for example want to default the lpp_source based on something
    # like `oslevel -s` output.
    #default_options =>  {};
}

pkgsrc

Prototype: pkgsrc

Description: Define details used when interfacing with the pkgsrc package module.

Example: cf3 bundle agent main { packages: "vim" policy => "present", package_module => pkgsrc; }

Implementation:

body package_module pkgsrc
{
    query_installed_ifelapsed => "$(package_module_knowledge.query_installed_ifelapsed)";
    query_updates_ifelapsed => "$(package_module_knowledge.query_updates_ifelapsed)";
}

yum

Prototype: yum

Description: Define details used when interfacing with yum

Implementation:

body package_module yum
{
    query_installed_ifelapsed => "$(package_module_knowledge.query_installed_ifelapsed)";
    query_updates_ifelapsed => "$(package_module_knowledge.query_updates_ifelapsed)";
    #default_options => {};
@if minimum_version(3.12.2)
    interpreter => "$(sys.bindir)/cfengine-selected-python";
@endif
}

slackpkg

Prototype: slackpkg

Description: Define details used when interfacing with slackpkg

Implementation:

body package_module slackpkg
{
      query_installed_ifelapsed => "$(package_module_knowledge.query_installed_ifelapsed)";
      query_updates_ifelapsed => "$(package_module_knowledge.query_updates_ifelapsed)";
      #default_options =>  {};
}

pkg

Prototype: pkg

Description: Define details used when interfacing with pkg

Implementation:

body package_module pkg
{
    query_installed_ifelapsed => "$(package_module_knowledge.query_installed_ifelapsed)";
    query_updates_ifelapsed => "$(package_module_knowledge.query_updates_ifelapsed)";
    #default_options => {};
}

snap

Prototype: snap

Description: Define details used when interfacing with snapcraft

Implementation:

body package_module snap
{
    query_installed_ifelapsed => "$(package_module_knowledge.query_installed_ifelapsed)";
    query_updates_ifelapsed => "$(package_module_knowledge.query_updates_ifelapsed)";
    #default_options => {};
}

freebsd_ports

Prototype: freebsd_ports

Description: Define details used when interfacing with the freebsd ports package module.

Note: Ports are expected to be setup prior to trying to use the packages promise. You may need to ensure that portsnap extract has been run, e.g. fileexists("/usr/ports/Mk/bsd.port.mk")

Example: cf3 bundle agent main { packages: freebsd:: "vim" policy => "present", package_module => freebsd_ports; }

Implementation:

body package_module freebsd_ports
{
    query_installed_ifelapsed => "$(package_module_knowledge.query_installed_ifelapsed)";
    query_updates_ifelapsed => "$(package_module_knowledge.query_updates_ifelapsed)";
}

file bodies

control

Prototype: control

Description: include policy needed by this file

Implementation:

body file control
{
      inputs => { @(packages_common.inputs) };
}

package_method bodies

pip

Prototype: pip(flags)

Description: Python `pip' package management

`pip' is a package manager for Python http://www.pip-installer.org/en/latest/

Available commands : add, delete, (add)update, verify

Arguments:

  • flags: The command line parameter passed to pip

Note: "update" command performs recursive upgrade (of dependencies) by default. Set $flags to "--no-deps" to perform non-recursive upgrade. http://www.pip-installer.org/en/latest/cookbook.html#non-recursive-upgrades

Example:

packages:
    "Django"              package_method => pip(""), package_policy => "add";
    "django-registration" package_method => pip(""), package_policy => "delete";
    "requests"            package_method => pip(""), package_policy => "verify";

Note: "Django" with a capital 'D' in the example above. Explicitly match the name of the package, capitalization does count!

    $ pip search django | egrep "^Django\s+-"
    Django - A high-level Python Web framework [..output trimmed..]

Implementation:

body package_method pip(flags)
{
      package_changes => "individual";

      package_noverify_regex => "";

      package_list_update_ifelapsed => "$(common_knowledge.list_update_ifelapsed)";

      package_list_name_regex    => "$(pip_knowledge.pip_list_name_regex)";
      package_list_version_regex => "$(pip_knowledge.pip_list_version_regex)";
      package_installed_regex    => "$(pip_knowledge.pip_installed_regex)";

      package_name_convention   => "$(name)";
      package_delete_convention => "$(name)";

      package_list_command   => "$(paths.path[pip]) list $(flags)";
      package_verify_command => "$(paths.path[pip]) show $(flags)";
      package_add_command    => "$(paths.path[pip]) install $(flags)";
      package_delete_command => "$(paths.path[pip]) uninstall --yes $(flags)";
      package_update_command => "$(paths.path[pip]) install --upgrade $(flags)";
}

npm

Prototype: npm(dir)

Description: Node.js `npm' local-mode package management

`npm' is a package manager for Node.js https://npmjs.org/package/npm

Available commands : add, delete, (add)update, verify

For the difference between local and global install see here: https://npmjs.org/doc/cli/npm-install.html

Arguments:

  • dir: The prefix path to ./node_modules/

Example:

vars:
    "dirs"    slist => { "/root/myproject", "/home/somedev/someproject" };

packages:
    "express"              package_method => npm("$(dirs)"), package_policy => "add";
    "redis"                package_method => npm("$(dirs)"), package_policy => "delete";

Implementation:

body package_method npm(dir)
{
      package_changes => "individual";

      package_noverify_regex => "";

      package_list_update_ifelapsed => "$(common_knowledge.list_update_ifelapsed)";

      package_list_name_regex    => "$(npm_knowledge.npm_list_name_regex)";
      package_list_version_regex => "$(npm_knowledge.npm_list_version_regex)";
      package_installed_regex    => "$(npm_knowledge.npm_installed_regex)";

      package_name_convention   => "$(name)";
      package_delete_convention => "$(name)";

      package_list_command   => "$(npm_knowledge.call_npm) list --prefix $(dir)";
      package_verify_command => "$(npm_knowledge.call_npm) list --prefix $(dir)";
      package_add_command    => "$(npm_knowledge.call_npm) install --prefix $(dir)";
      package_delete_command => "$(npm_knowledge.call_npm) remove --prefix $(dir)";
      package_update_command => "$(npm_knowledge.call_npm) update --prefix $(dir)";
}

npm_g

Prototype: npm_g

Description: Node.js `npm' global-mode package management

`npm' is a package manager for Node.js https://npmjs.org/package/npm

Available commands : add, delete, (add)update, verify

For the difference between global and local install see here: https://npmjs.org/doc/cli/npm-install.html

Example:

packages:
    "express"              package_method => npm_g, package_policy => "add";
    "redis"                package_method => npm_g, package_policy => "delete";

Implementation:

body package_method npm_g
{
      package_changes => "individual";

      package_noverify_regex => "";

      package_list_update_ifelapsed => "$(common_knowledge.list_update_ifelapsed)";

      package_list_name_regex    => "$(npm_knowledge.npm_list_name_regex)";
      package_list_version_regex => "$(npm_knowledge.npm_list_version_regex)";
      package_installed_regex    => "$(npm_knowledge.npm_installed_regex)";

      package_name_convention   => "$(name)";
      package_delete_convention => "$(name)";

      package_list_command   => "$(npm_knowledge.call_npm) list --global";
      package_verify_command => "$(npm_knowledge.call_npm) list --global";
      package_add_command    => "$(npm_knowledge.call_npm) install --global";
      package_delete_command => "$(npm_knowledge.call_npm) remove --global";
      package_update_command => "$(npm_knowledge.call_npm) update --global";
}

brew

Prototype: brew(user)

Description: Darwin/Mac OS X + Homebrew installation method

Homebrew is a package manager for OS X -- http://brew.sh

Available commands : add, delete, (add)update (with package_version).

Arguments:

  • user: The user under which to run the commands

Homebrew expects a regular (non-root) user to install packages. https://github.com/mxcl/homebrew/wiki/FAQ#why-does-homebrew-say-sudo-is-bad As CFEngine doesn't give the possibility to run package_add_command with a different user, this body uses sudo -u.

Example:

packages:
    "mypackage" package_method => brew("adminuser"), package_policy => "add";
    "uppackage" package_method => brew("adminuser"), package_policy => "update", package_version => "3.5.2";

Implementation:

body package_method brew(user)
{

      package_changes               => "bulk";
      package_add_command           => "$(darwin_knowledge.call_sudo) -u $(user) $(darwin_knowledge.call_brew) install";
      package_delete_command        => "$(darwin_knowledge.call_sudo) -u $(user) $(darwin_knowledge.call_brew) uninstall";
      package_delete_convention     => "$(name)";
      package_name_convention       => "$(name)";

      # Homebrew can list only installed packages along versions.
      # for a complete list of packages, we could use `brew search`, but there's no easy
      # way to determine the version or wether it's installed.
      package_installed_regex       => ".*";
      package_list_command          => "$(darwin_knowledge.call_sudo) -u $(user) $(darwin_knowledge.call_brew) list --versions";
      package_list_name_regex       => "$(darwin_knowledge.brew_name_regex)";
      package_list_version_regex    => "$(darwin_knowledge.brew_version_regex)";
      package_list_update_command   => "$(darwin_knowledge.call_sudo) -u $(user) $(darwin_knowledge.call_brew) update";
      package_list_update_ifelapsed => "$(common_knowledge.list_update_ifelapsed)";

      # brew list [package] will print the installed files and return 1 if not found.
      package_verify_command        => "$(darwin_knowledge.call_sudo) -u $(user) $(darwin_knowledge.call_brew) list";
      package_noverify_returncode   => "1";

      # remember to specify the package version
      package_update_command        => "$(darwin_knowledge.call_sudo) -u $(user) $(darwin_knowledge.call_brew) upgrade";

}

apt

Prototype: apt

Description: APT installation package method

This package method interacts with the APT package manager through aptitude.

Example:

packages:
    "mypackage" package_method => apt, package_policy => "add";

Implementation:

body package_method apt
{
      package_changes => "bulk";
      package_list_command => "$(debian_knowledge.call_dpkg) -l";
      package_list_name_regex => "$(debian_knowledge.list_name_regex)";
      package_list_version_regex => "$(debian_knowledge.list_version_regex)";
      package_installed_regex => ".i.*"; # packages that have been uninstalled may be listed
      package_name_convention => "$(name)";

      # set it to "0" to avoid caching of list during upgrade
      package_list_update_ifelapsed => "$(common_knowledge.list_update_ifelapsed)";

      # make correct version comparisons
      package_version_less_command => "$(debian_knowledge.dpkg_compare_less)";
      package_version_equal_command => "$(debian_knowledge.dpkg_compare_equal)";

    have_aptitude::
      package_add_command => "$(debian_knowledge.call_aptitude) $(debian_knowledge.dpkg_options) --assume-yes install";
      package_list_update_command => "$(debian_knowledge.call_aptitude) update";
      package_delete_command => "$(debian_knowledge.call_aptitude) $(debian_knowledge.dpkg_options) --assume-yes -q remove";
      package_update_command =>  "$(debian_knowledge.call_aptitude) $(debian_knowledge.dpkg_options) --assume-yes install";
      package_patch_command =>  "$(debian_knowledge.call_aptitude) $(debian_knowledge.dpkg_options) --assume-yes install";
      package_verify_command =>  "$(debian_knowledge.call_aptitude) show";
      package_noverify_regex => "(State: not installed|E: Unable to locate package .*)";

      package_patch_list_command => "$(debian_knowledge.call_aptitude) --assume-yes --simulate --verbose full-upgrade";
      package_patch_name_regex => "$(debian_knowledge.patch_name_regex)";
      package_patch_version_regex => "$(debian_knowledge.patch_version_regex)";

    !have_aptitude::
      package_add_command => "$(debian_knowledge.call_apt_get) $(debian_knowledge.dpkg_options) --yes install";
      package_list_update_command => "$(debian_knowledge.call_apt_get) update";
      package_delete_command => "$(debian_knowledge.call_apt_get) $(debian_knowledge.dpkg_options) --yes -q remove";
      package_update_command =>  "$(debian_knowledge.call_apt_get) $(debian_knowledge.dpkg_options) --yes install";
      package_patch_command =>  "$(debian_knowledge.call_apt_get) $(debian_knowledge.dpkg_options) --yes install";
      package_verify_command => "$(debian_knowledge.call_dpkg) -s";
      package_noverify_returncode => "1";

      package_patch_list_command => "$(debian_knowledge.call_apt_get) --just-print dist-upgrade";
      package_patch_name_regex => "$(debian_knowledge.patch_name_regex)";
      package_patch_version_regex => "$(debian_knowledge.patch_version_regex)";

}

apt_get

Prototype: apt_get

Description: APT installation package method

This package method interacts with the APT package manager through apt-get.

Example:

packages:
    "mypackage" package_method => apt_get, package_policy => "add";

Implementation:

body package_method apt_get
{
      package_changes => "bulk";
      package_list_command => "$(debian_knowledge.call_dpkg) -l";
      package_list_name_regex => "$(debian_knowledge.list_name_regex)";
      package_list_version_regex => "$(debian_knowledge.list_version_regex)";
      package_installed_regex => ".i.*"; # packages that have been uninstalled may be listed
      package_name_convention => "$(name)=$(version)";

      # set it to "0" to avoid caching of list during upgrade
      package_list_update_ifelapsed => "$(common_knowledge.list_update_ifelapsed)";

      # Target a specific release, such as backports
      package_add_command => "$(debian_knowledge.call_apt_get) $(debian_knowledge.dpkg_options) --yes install";
      package_list_update_command => "$(debian_knowledge.call_apt_get) update";
      package_delete_command => "$(debian_knowledge.call_apt_get) $(debian_knowledge.dpkg_options) --yes -q remove";
      package_update_command =>  "$(debian_knowledge.call_apt_get) $(debian_knowledge.dpkg_options) --yes install";
      package_patch_command =>  "$(debian_knowledge.call_apt_get) $(debian_knowledge.dpkg_options) --yes install";
      package_verify_command => "$(debian_knowledge.call_dpkg) -s";
      package_noverify_returncode => "1";

      package_patch_list_command => "$(debian_knowledge.call_apt_get) --just-print dist-upgrade";
      package_patch_name_regex => "$(debian_knowledge.patch_name_regex)";
      package_patch_version_regex => "$(debian_knowledge.patch_version_regex)";

      # make correct version comparisons
      package_version_less_command => "$(debian_knowledge.dpkg_compare_less)";
      package_version_equal_command => "$(debian_knowledge.dpkg_compare_equal)";
}

apt_get_permissive

Prototype: apt_get_permissive

Description: APT permissive (just by name) package method

This package method interacts with the APT package manager through apt-get.

Normally you have to specify the package version, and it defaults to *, which then triggers the bug of installing xyz-abc when you ask for xyz.

This "permissive" body sets

package_name_convention => "$(name)";

which is permissive in the sense of not requiring the version.

Example:

packages:
    "mypackage" package_method => apt_get_permissive, package_policy => "add";

Implementation:

body package_method apt_get_permissive
{
      package_changes => "bulk";
      package_list_command => "$(debian_knowledge.call_dpkg) -l";
      package_list_name_regex => "$(debian_knowledge.list_name_regex)";
      package_list_version_regex => "$(debian_knowledge.list_version_regex)";
      package_installed_regex => ".i.*"; # packages that have been uninstalled may be listed
      package_name_convention => "$(name)";

      # set it to "0" to avoid caching of list during upgrade
      package_list_update_ifelapsed => "$(common_knowledge.list_update_ifelapsed)";

      # Target a specific release, such as backports
      package_add_command => "$(debian_knowledge.call_apt_get) $(debian_knowledge.dpkg_options) --yes install";
      package_list_update_command => "$(debian_knowledge.call_apt_get) update";
      package_delete_command => "$(debian_knowledge.call_apt_get) $(debian_knowledge.dpkg_options) --yes -q remove";
      package_update_command =>  "$(debian_knowledge.call_apt_get) $(debian_knowledge.dpkg_options) --yes install";
      package_patch_command =>  "$(debian_knowledge.call_apt_get) $(debian_knowledge.dpkg_options) --yes install";
      package_verify_command => "$(debian_knowledge.call_dpkg) -s";
      package_noverify_returncode => "1";

      package_patch_list_command => "$(debian_knowledge.call_apt_get) --just-print dist-upgrade";
      package_patch_name_regex => "$(debian_knowledge.patch_name_regex)";
      package_patch_version_regex => "$(debian_knowledge.patch_version_regex)";

      # make correct version comparisons
      package_version_less_command => "$(debian_knowledge.dpkg_compare_less)";
      package_version_equal_command => "$(debian_knowledge.dpkg_compare_equal)";
}

apt_get_release

Prototype: apt_get_release(release)

Description: APT installation package method

Arguments:

  • release: specific release to use

This package method interacts with the APT package manager through apt-get but sets a specific target release.

Example:

packages:
    "mypackage" package_method => apt_get_release("xyz"), package_policy => "add";

Implementation:

body package_method apt_get_release(release)
{
      package_changes => "bulk";
      package_list_command => "$(debian_knowledge.call_dpkg) -l";
      package_list_name_regex => "$(debian_knowledge.list_name_regex)";
      package_list_version_regex => "$(debian_knowledge.list_version_regex)";
      package_installed_regex => ".i.*"; # packages that have been uninstalled may be listed
      package_name_convention => "$(name)";

      # set it to "0" to avoid caching of list during upgrade
      package_list_update_ifelapsed => "$(common_knowledge.list_update_ifelapsed)";

      # Target a specific release, such as backports
      package_add_command => "$(debian_knowledge.call_apt_get) $(debian_knowledge.dpkg_options) --yes --target-release $(release) install";
      package_list_update_command => "$(debian_knowledge.call_apt_get) update";
      package_delete_command => "$(debian_knowledge.call_apt_get) $(debian_knowledge.dpkg_options) --yes -q remove";
      package_update_command =>  "$(debian_knowledge.call_apt_get) $(debian_knowledge.dpkg_options) --yes --target-release $(release) install";
      package_patch_command =>  "$(debian_knowledge.call_apt_get) $(debian_knowledge.dpkg_options) --yes --target-release $(release) install";
      package_verify_command => "$(debian_knowledge.call_dpkg) -s";
      package_noverify_returncode => "1";

      package_patch_list_command => "$(debian_knowledge.call_apt_get) --just-print dist-upgrade";
      package_patch_name_regex => "$(debian_knowledge.patch_name_regex)";
      package_patch_version_regex => "$(debian_knowledge.patch_version_regex)";

      # make correct version comparisons
      package_version_less_command => "$(debian_knowledge.dpkg_compare_less)";
      package_version_equal_command => "$(debian_knowledge.dpkg_compare_equal)";

}

dpkg_version

Prototype: dpkg_version(repo)

Description: dpkg installation package method

Arguments:

  • repo: specific repo to use

This package method interacts with dpkg.

Example:

packages:
    "mypackage" package_method => dpkg_version("xyz"), package_policy => "add";

Implementation:

body package_method dpkg_version(repo)
{
      package_changes => "individual";
      package_list_command => "$(debian_knowledge.call_dpkg) -l";

      # set it to "0" to avoid caching of list during upgrade
      package_list_update_command => "$(debian_knowledge.call_apt_get) update";
      package_list_update_ifelapsed => "$(common_knowledge.list_update_ifelapsed)";

      package_list_name_regex => "$(debian_knowledge.list_name_regex)";
      package_list_version_regex => "$(debian_knowledge.list_version_regex)";

      package_installed_regex => ".i.*"; # packages that have been uninstalled may be listed

      package_file_repositories => { "$(repo)" };

    debian.x86_64::
      package_name_convention => "$(name)_$(version)_amd64.deb";

    debian.i686::
      package_name_convention => "$(name)_$(version)_i386.deb";

    have_aptitude::
      package_patch_list_command => "$(debian_knowledge.call_aptitude) --assume-yes --simulate --verbose full-upgrade";
      package_patch_name_regex => "$(debian_knowledge.patch_name_regex)";
      package_patch_version_regex => "$(debian_knowledge.patch_version_regex)";

    !have_aptitude::
      package_patch_list_command => "$(debian_knowledge.call_apt_get) --just-print dist-upgrade";
      package_patch_name_regex => "$(debian_knowledge.patch_name_regex)";
      package_patch_version_regex => "$(debian_knowledge.patch_version_regex)";

    debian::
      package_add_command => "$(debian_knowledge.call_dpkg) --install";
      package_delete_command => "$(debian_knowledge.call_dpkg) --purge";
      package_update_command =>  "$(debian_knowledge.call_dpkg) --install";
      package_patch_command =>  "$(debian_knowledge.call_dpkg) --install";

      # make correct version comparisons
      package_version_less_command => "$(debian_knowledge.dpkg_compare_less)";
      package_version_equal_command => "$(debian_knowledge.dpkg_compare_equal)";
}

rpm_version

Prototype: rpm_version(repo)

Description: RPM direct installation method

Arguments:

This package method interacts with the RPM package manager for a specific repo.

Example:

packages:
    "mypackage" package_method => rpm_version("myrepo"), package_policy => "add";

Implementation:

body package_method rpm_version(repo)
{
      package_changes => "individual";

      package_list_command => "$(rpm_knowledge.call_rpm) -qa --queryformat \"$(rpm_knowledge.rpm_output_format)\"";

      # set it to "0" to avoid caching of list during upgrade
      package_list_update_command => "$(redhat_knowledge.call_yum) $(redhat_knowledge.yum_options) check-update $(redhat_knowledge.check_update_postproc)";
      package_list_update_ifelapsed => "$(common_knowledge.list_update_ifelapsed)";

      package_list_name_regex    => "$(rpm_knowledge.rpm_name_regex)";
      package_list_version_regex => "$(rpm_knowledge.rpm_version_regex)";
      package_list_arch_regex    => "$(rpm_knowledge.rpm_arch_regex)";

      package_installed_regex => "i.*";

      package_file_repositories => { "$(repo)" };

      package_name_convention => "$(name)-$(version).$(arch).rpm";

      package_add_command => "$(rpm_knowledge.call_rpm) -ivh ";
      package_update_command => "$(rpm_knowledge.call_rpm) -Uvh ";
      package_patch_command => "$(rpm_knowledge.call_rpm) -Uvh ";
      package_delete_command => "$(rpm_knowledge.call_rpm) -e --nodeps";
      package_verify_command => "$(rpm_knowledge.call_rpm) -V";
      package_noverify_regex => ".*[^\s].*";
      package_version_less_command => "$(redhat_knowledge.rpm_compare_less)";
      package_version_equal_command => "$(redhat_knowledge.rpm_compare_equal)";
}

windows_feature

Prototype: windows_feature

Description: Method for managing Windows features

Implementation:

body package_method windows_feature
{
      package_changes => "individual";

      package_name_convention   => "$(name)";
      package_delete_convention => "$(name)";

      package_installed_regex => ".*";
      package_list_name_regex => "(.*)";
      package_list_version_regex => "(.*)";  # FIXME: the listing does not give version, so takes name for version too now

      package_add_command    => "$(sys.winsysdir)\\WindowsPowerShell\\v1.0\\powershell.exe -Command \"Import-Module ServerManager; Add-WindowsFeature -Name\"";
      package_delete_command => "$(sys.winsysdir)\\WindowsPowerShell\\v1.0\\powershell.exe -Command \"Import-Module ServerManager; Remove-WindowsFeature -confirm:$false -Name\"";
      package_list_command   => "$(sys.winsysdir)\\WindowsPowerShell\\v1.0\\powershell.exe -Command \"Import-Module ServerManager; Get-WindowsFeature | where {$_.installed -eq $True} |foreach {$_.Name}\"";
}

msi_implicit

Prototype: msi_implicit(repo)

Description: Windows MSI method

Arguments:

  • repo: The package file repository

Uses the whole file name as promiser, e.g. "7-Zip-4.50-x86_64.msi". The name, version and arch is then deduced from the promiser.

See also: msi_explicit()

Implementation:

body package_method msi_implicit(repo)
{
      package_changes => "individual";
      package_file_repositories => { "$(repo)" };

      package_installed_regex => ".*";

      package_name_convention => "$(name)-$(version)-$(arch).msi";
      package_delete_convention => "$(firstrepo)$(name)-$(version)-$(arch).msi";

      package_name_regex => "^(\S+)-(\d+\.?)+";
      package_version_regex => "^\S+-((\d+\.?)+)";
      package_arch_regex => "^\S+-[\d\.]+-(.*).msi";

      package_add_command => "\"$(sys.winsysdir)\msiexec.exe\" /qn /i";
      package_update_command => "\"$(sys.winsysdir)\msiexec.exe\" /qn /i";
      package_delete_command => "\"$(sys.winsysdir)\msiexec.exe\" /qn /x";
}

msi_explicit

Prototype: msi_explicit(repo)

Description: Windows MSI method

Arguments:

  • repo: The package file repository

Uses software name as promiser, e.g. "7-Zip", and explicitly specify any package_version and package_arch.

See also: msi_implicit()

Implementation:

body package_method msi_explicit(repo)
{
      package_changes => "individual";
      package_file_repositories => { "$(repo)" };

      package_installed_regex => ".*";

      package_name_convention => "$(name)-$(version)-$(arch).msi";
      package_delete_convention => "$(firstrepo)$(name)-$(version)-$(arch).msi";

      package_add_command => "\"$(sys.winsysdir)\msiexec.exe\" /qn /i";
      package_update_command => "\"$(sys.winsysdir)\msiexec.exe\" /qn /i";
      package_delete_command => "\"$(sys.winsysdir)\msiexec.exe\" /qn /x";
}

yum

Prototype: yum

Description: Yum+RPM installation method

This package method interacts with the Yum and RPM package managers. It is a copy of yum_rpm(), which was contributed by Trond Hasle Amundsen. The old yum package method has been removed.

This is an efficient package method for RPM-based systems - uses rpm instead of yum to list installed packages.

It will use rpm -e to remove packages. Please note that if several packages with the same name but varying versions or architectures are installed, rpm -e will return an error and not delete any of them.

Example:

packages:
    "mypackage" package_method => yum, package_policy => "add";

Implementation:

body package_method yum
{
      package_changes => "bulk";
      package_list_command => "$(rpm_knowledge.call_rpm) -qa --qf '$(rpm_knowledge.rpm3_output_format)'";
      package_patch_list_command => "$(redhat_knowledge.call_yum) $(redhat_knowledge.yum_offline_options) check-update $(redhat_knowledge.check_update_postproc)";

      package_list_name_regex    => "$(rpm_knowledge.rpm3_name_regex)";
      package_list_version_regex => "$(rpm_knowledge.rpm3_version_regex)";
      package_list_arch_regex    => "$(rpm_knowledge.rpm3_arch_regex)";

      package_installed_regex => ".*";
      package_name_convention => "$(name)-$(version).$(arch)";

      # just give the package name to rpm to delete, otherwise it gets "name.*" (from package_name_convention above)
      package_delete_convention => "$(name)";

      # set it to "0" to avoid caching of list during upgrade
      package_list_update_command => "$(redhat_knowledge.call_yum) $(redhat_knowledge.yum_options) check-update $(redhat_knowledge.check_update_postproc)";
      package_list_update_ifelapsed => "$(common_knowledge.list_update_ifelapsed)";

      package_patch_name_regex    => "$(redhat_knowledge.patch_name_regex)";
      package_patch_version_regex => "$(redhat_knowledge.patch_version_regex)";
      package_patch_arch_regex    => "$(redhat_knowledge.patch_arch_regex)";

      package_add_command    => "$(redhat_knowledge.call_yum) $(redhat_knowledge.yum_options) -y install";
      package_update_command => "$(redhat_knowledge.call_yum) $(redhat_knowledge.yum_options) -y update";
      package_patch_command  => "$(redhat_knowledge.call_yum) $(redhat_knowledge.yum_options) -y update";
      package_delete_command => "$(rpm_knowledge.call_rpm) -e --nodeps";
      package_verify_command => "$(rpm_knowledge.call_rpm) -V";
      package_noverify_returncode => "1";
      package_version_less_command => "$(redhat_knowledge.rpm_compare_less)";
      package_version_equal_command => "$(redhat_knowledge.rpm_compare_equal)";
}

yum_rpm

Prototype: yum_rpm

Description: Yum+RPM installation method

This package method interacts with the Yum and RPM package managers.

Contributed by Trond Hasle Amundsen

This is an efficient package method for RPM-based systems - uses rpm instead of yum to list installed packages.

It will use rpm -e to remove packages. Please note that if several packages with the same name but varying versions or architectures are installed, rpm -e will return an error and not delete any of them.

Example:

packages:
    "mypackage" package_method => yum_rpm, package_policy => "add";

Implementation:

body package_method yum_rpm
{
      package_changes => "bulk";
      package_list_command => "$(rpm_knowledge.call_rpm) -qa --qf '$(rpm_knowledge.rpm3_output_format)'";
      package_patch_list_command => "$(redhat_knowledge.call_yum) $(redhat_knowledge.yum_offline_options) check-update $(redhat_knowledge.check_update_postproc)";

      package_list_name_regex    => "$(rpm_knowledge.rpm3_name_regex)";
      package_list_version_regex => "$(rpm_knowledge.rpm3_version_regex)";
      package_list_arch_regex    => "$(rpm_knowledge.rpm3_arch_regex)";

      package_installed_regex => ".*";
      package_name_convention => "$(name)-$(version).$(arch)";

      # just give the package name to rpm to delete, otherwise it gets "name.*" (from package_name_convention above)
      package_delete_convention => "$(name)";

      # set it to "0" to avoid caching of list during upgrade
      package_list_update_command => "$(redhat_knowledge.call_yum) $(redhat_knowledge.yum_options) check-update $(redhat_knowledge.check_update_postproc)";
      package_list_update_ifelapsed => "$(common_knowledge.list_update_ifelapsed)";

      package_patch_name_regex    => "$(redhat_knowledge.patch_name_regex)";
      package_patch_version_regex => "$(redhat_knowledge.patch_version_regex)";
      package_patch_arch_regex    => "$(redhat_knowledge.patch_arch_regex)";

      package_add_command    => "$(redhat_knowledge.call_yum) $(redhat_knowledge.yum_options) -y install";
      package_update_command => "$(redhat_knowledge.call_yum) $(redhat_knowledge.yum_options) -y update";
      package_patch_command  => "$(redhat_knowledge.call_yum) $(redhat_knowledge.yum_options) -y update";
      package_delete_command => "$(rpm_knowledge.call_rpm) -e --nodeps";
      package_verify_command => "$(rpm_knowledge.call_rpm) -V";
      package_noverify_returncode => "1";
      package_version_less_command => "$(redhat_knowledge.rpm_compare_less)";
      package_version_equal_command => "$(redhat_knowledge.rpm_compare_equal)";
}

yum_rpm_permissive

Prototype: yum_rpm_permissive

Description: Yum+RPM permissive (just by name) package method

This package method interacts with the Yum and RPM package managers.

Copy of yum_rpm which was contributed by Trond Hasle Amundsen

This is an efficient package method for RPM-based systems - uses rpm instead of yum to list installed packages. It can't delete packages and can't take a target version or architecture, so only the "add" and "addupdate" methods should be used.

Normally you have to specify the package version, and it defaults to *, which then triggers the bug of installing xyz-abc when you ask for xyz.

This "permissive" body sets

package_name_convention => "$(name)";

which is permissive in the sense of not requiring the version.

Example:

packages:
    "mypackage" package_method => yum_rpm_permissive, package_policy => "add";

Implementation:

body package_method yum_rpm_permissive
{
      package_changes => "bulk";
      package_list_command => "$(rpm_knowledge.call_rpm) -qa --qf '$(rpm_knowledge.rpm3_output_format)'";
      package_patch_list_command => "$(redhat_knowledge.call_yum) $(redhat_knowledge.yum_offline_options) check-update $(redhat_knowledge.check_update_postproc)";

      package_list_name_regex    => "$(rpm_knowledge.rpm3_name_regex)";
      package_list_version_regex => "$(rpm_knowledge.rpm3_version_regex)";
      package_list_arch_regex    => "$(rpm_knowledge.rpm3_arch_regex)";

      package_installed_regex => ".*";
      package_name_convention => "$(name)";

      # not needed, same as package_name_convention above
      package_delete_convention => "$(name)";

      # set it to "0" to avoid caching of list during upgrade
      package_list_update_command => "$(redhat_knowledge.call_yum) $(redhat_knowledge.yum_options) check-update $(redhat_knowledge.check_update_postproc)";
      package_list_update_ifelapsed => "$(common_knowledge.list_update_ifelapsed)";

      package_patch_name_regex    => "$(redhat_knowledge.patch_name_regex)";
      package_patch_version_regex => "$(redhat_knowledge.patch_version_regex)";
      package_patch_arch_regex    => "$(redhat_knowledge.patch_arch_regex)";

      package_add_command    => "$(redhat_knowledge.call_yum) $(redhat_knowledge.yum_options) -y install";
      package_update_command => "$(redhat_knowledge.call_yum) $(redhat_knowledge.yum_options) -y update";
      package_patch_command  => "$(redhat_knowledge.call_yum) $(redhat_knowledge.yum_options) -y update";
      package_delete_command => "$(rpm_knowledge.call_rpm) -e --nodeps";
      package_verify_command => "$(rpm_knowledge.call_rpm) -V";
      package_noverify_returncode => "1";
      package_version_less_command => "$(redhat_knowledge.rpm_compare_less)";
      package_version_equal_command => "$(redhat_knowledge.rpm_compare_equal)";
}

yum_rpm_enable_repo

Prototype: yum_rpm_enable_repo(repoid)

Description: Yum+RPM repo-specific installation method

Arguments:

  • repoid: the repository name as in yum --enablerepo=???

This package method interacts with the RPM package manager for a specific repo.

Based on yum_rpm() with addition to enable a repository for the install.

Sometimes repositories are configured but disabled by default. For example this pacakge_method could be used when installing a package that exists in the EPEL, which normally you do not want to install packages from.

Example:

packages:
    "mypackage" package_method => yum_rpm_enable_repo("myrepo"), package_policy => "add";

Implementation:

body package_method yum_rpm_enable_repo(repoid)
{
      package_changes => "bulk";
      package_list_command => "$(rpm_knowledge.call_rpm) -qa --qf '$(rpm_knowledge.rpm2_output_format)'";
      package_patch_list_command => "$(redhat_knowledge.call_yum) $(redhat_knowledge.yum_offline_options) check-update $(redhat_knowledge.check_update_postproc)";

      package_list_name_regex    => "$(rpm_knowledge.rpm2_name_regex)";
      package_list_version_regex => "$(rpm_knowledge.rpm2_version_regex)";
      package_list_arch_regex    => "$(rpm_knowledge.rpm2_arch_regex)";

      package_installed_regex => ".*";
      package_name_convention => "$(name)";

      # set it to "0" to avoid caching of list during upgrade
      package_list_update_command => "$(redhat_knowledge.call_yum) $(redhat_knowledge.yum_options) check-update $(redhat_knowledge.check_update_postproc)";
      package_list_update_ifelapsed => "$(common_knowledge.list_update_ifelapsed)";

      package_patch_name_regex    => "$(redhat_knowledge.patch_name_regex)";
      package_patch_version_regex => "$(redhat_knowledge.patch_version_regex)";
      package_patch_arch_regex    => "$(redhat_knowledge.patch_arch_regex)";

      package_add_command    => "$(redhat_knowledge.call_yum) $(redhat_knowledge.yum_options) --enablerepo=$(repoid) -y install";
      package_update_command => "$(redhat_knowledge.call_yum) $(redhat_knowledge.yum_options) --enablerepo=$(repoid) -y update";
      package_patch_command => "$(redhat_knowledge.call_yum) $(redhat_knowledge.yum_options) -y update";
      package_delete_command => "$(rpm_knowledge.call_rpm) -e --nodeps --allmatches";
      package_verify_command => "$(rpm_knowledge.call_rpm) -V";
      package_noverify_returncode => "1";
      package_version_less_command => "$(redhat_knowledge.rpm_compare_less)";
      package_version_equal_command => "$(redhat_knowledge.rpm_compare_equal)";
}

yum_group

Prototype: yum_group

Description: RPM direct installation method

Makes use of the "groups of packages" feature of Yum possible. (yum groupinstall, yum groupremove)

Groups must be specified by their groupids, available through yum grouplist -v (between parentheses). For example, below network-tools is the groupid.

$ yum grouplist -v|grep Networking|head -n 1
  Networking Tools (network-tools)

Example:

Policies examples:

-Install "web-server" group:
----------------------------

packages:
  "web-server"
    package_policy   =>  "add",
    package_method   =>  yum_group;

-Remove "debugging" and "php" groups:
-------------------------------------

vars:
  "groups"  slist  => { "debugging", "php" };

packages:
  "$(groups)"
     package_policy   =>   "delete",
     package_method   =>   yum_group;

Implementation:

body package_method yum_group
{
      package_add_command             =>  "$(redhat_knowledge.call_yum) $(redhat_knowledge.yum_options) groupinstall -y";
      package_changes                 =>  "bulk";
      package_delete_command          =>  "$(redhat_knowledge.call_yum) $(redhat_knowledge.yum_options) groupremove -y";
      package_delete_convention       =>  "$(name)";
      package_installed_regex         =>  "^i.*";

      # Generate a dpkg -l like listing, "i" means installed, "a" available, and a dummy version 1
      package_list_command            =>
      "$(redhat_knowledge.call_yum) grouplist -v|awk '$0 ~ /^Done$/ {next} {sub(/.*\(/, \"\");sub(/\).*/, \"\")} /Available/ {h=\"a\";next} /Installed/ {h=\"i\";next} h==\"i\" || h==\"a\" {print h\" \"$0\" 1\"}'";

      package_list_name_regex         =>  "a|i ([^\s]+) 1";
      package_list_update_command     =>  "$(redhat_knowledge.call_yum) $(redhat_knowledge.yum_options) check-update $(redhat_knowledge.check_update_postproc)";
      package_list_update_ifelapsed   =>  "$(common_knowledge.list_update_ifelapsed)";
      package_list_version_regex      =>  "(1)";
      package_name_convention         =>  "$(name)";
      package_name_regex              =>  "(.*)";
      package_noverify_returncode     =>  "0";
      package_update_command          =>  "$(redhat_knowledge.call_yum) $(redhat_knowledge.yum_options) groupupdate";

      # grep -x to only get full line matching
      package_verify_command          => "$(redhat_knowledge.call_yum) grouplist -v|awk '$0 ~ /^Done$/ {next} {sub(/.*\(/, \"\");sub(/\).*/, \"\")} /Available/ {h=\"a\";next} /Installed/ {h=\"i\";next} h==\"i\"|grep -qx";
}

rpm_filebased

Prototype: rpm_filebased(path)

Description: install packages from local filesystem-based RPM repository.

Arguments:

  • path: the path to the local package repository

Contributed by Aleksey Tsalolikhin. Written on 29-Feb-2012. Based on yum_rpm() body by Trond Hasle Amundsen.

Example:

packages:
    "epel-release"
    package_policy => "add",
    package_version => "5-4",
    package_architectures => { "noarch" },
    package_method => rpm_filebased("/repo/RPMs");

Implementation:

body package_method rpm_filebased(path)
{
      package_file_repositories => { "$(path)" };
      # the above is an addition to Trond's yum_rpm body

      package_add_command => "$(rpm_knowledge.call_rpm) -ihv ";
      # The above is a change from Trond's yum_rpm body, this makes the commands rpm only.
      # The reason I changed the install command from yum to rpm is yum will be default
      # refuse to install the epel-release RPM as it does not have the EPEL GPG key,
      # but rpm goes ahead and installs the epel-release RPM and the EPEL GPG key.

      package_name_convention => "$(name)-$(version).$(arch).rpm";
      # The above is a change from Tron's yum_rpm body. When package_file_repositories is in play,
      # package_name_convention has to match the file name, not the package name, per the
      # CFEngine 3 Reference Manual

      # set it to "0" to avoid caching of list during upgrade
      package_list_update_command => "$(redhat_knowledge.call_yum) $(redhat_knowledge.yum_options) check-update $(redhat_knowledge.check_update_postproc)";
      package_list_update_ifelapsed => "$(common_knowledge.list_update_ifelapsed)";

      # The rest is unchanged from Trond's yum_rpm body
      package_changes => "bulk";
      package_list_command => "$(rpm_knowledge.call_rpm) -qa --qf '$(rpm_knowledge.rpm2_output_format)'";

      package_list_name_regex    => "$(rpm_knowledge.rpm2_name_regex)";
      package_list_version_regex => "$(rpm_knowledge.rpm2_version_regex)";
      package_list_arch_regex    => "$(rpm_knowledge.rpm2_arch_regex)";

      package_installed_regex => ".*";

      package_delete_command => "$(rpm_knowledge.call_rpm) -e --allmatches";
      package_verify_command => "$(rpm_knowledge.call_rpm) -V";
      package_noverify_returncode => "1";
      package_version_less_command => "$(redhat_knowledge.rpm_compare_less)";
      package_version_equal_command => "$(redhat_knowledge.rpm_compare_equal)";
}

ips

Prototype: ips

Description: Image Package System method, used by OpenSolaris based systems (Solaris 11, Illumos, etc)

A note about Solaris 11.1 versioning format:

$ pkg list -v --no-refresh zsh
FMRI                                                                         IFO
pkg://solaris/shell/zsh@4.3.17,5.11-0.175.1.0.0.24.0:20120904T174236Z        i--
name--------- |<----->| |/________________________\|
version---------------- |\                        /|

Notice that the publisher and timestamp aren't used. And that the package version then must have the commas replaced by underscores.

Thus, 4.3.17,5.11-0.175.1.0.0.24.0 Becomes: 4.3.17_5.11-0.175.1.0.0.24.0

Therefore, a properly formatted package promise looks like this:

   "shell/zsh"
     package_policy  => "addupdate",
     package_method  => ips,
     package_select  => ">=",
     package_version => "4.3.17_5.11-0.175.1.0.0.24.0";

Implementation:

body package_method ips
{
      package_changes => "bulk";
      package_list_command => "$(paths.path[pkg]) list -v --no-refresh";
      package_list_name_regex    => "pkg://.+?(?<=/)([^\s]+)@.*$";
      package_list_version_regex => "[^\s]+@([^\s]+):.*";
      package_installed_regex => ".*(i..)"; # all reported are installed

      # set it to "0" to avoid caching of list during upgrade
      package_list_update_command => "$(paths.path[pkg]) refresh --full";
      package_list_update_ifelapsed => "$(common_knowledge.list_update_ifelapsed)";

      package_add_command => "$(paths.path[pkg]) install --accept ";
      package_delete_command => "$(paths.path[pkg]) uninstall";
      package_update_command =>  "$(paths.path[pkg]) install --accept";
      package_patch_command =>  "$(paths.path[pkg]) install --accept";
      package_verify_command =>  "$(paths.path[pkg]) list -a -v --no-refresh";
      package_noverify_regex => "(.*---|pkg list: no packages matching .* installed)";
}

smartos

Prototype: smartos

Description: pkgin method for SmartOS (solaris 10 fork by Joyent)

Implementation:

body package_method smartos
{
      package_changes => "bulk";
      package_list_command => "/opt/local/bin/pkgin list";
      package_list_name_regex    => "([^\s]+)\-[0-9][^\s;]+.*[\s;]";
      package_list_version_regex => "[^\s]+\-([0-9][^\s;]+).*[\s;]";

      package_installed_regex => ".*"; # all reported are installed

      package_list_update_command => "/opt/local/bin/pkgin -y update";
      package_list_update_ifelapsed => "$(common_knowledge.list_update_ifelapsed)";

      package_add_command => "/opt/local/bin/pkgin -y install";

      package_delete_command => "/opt/local/bin/pkgin -y remove";

      # pkgin update doesn't do what you think it does. pkgin install against and
      # already installed package will upgrade it however.

      package_update_command =>  "/opt/local/bin/pkgin -y install";
}

smartos_pkg_add

Prototype: smartos_pkg_add(repo)

Description: SmartOS pkg_add installation package method

This package method interacts with SmartOS pkg_add to install from local or remote repositories. It is slightly different than the FreeBSD pkg_add.

This example installs "perl5" from a remote repository:

----------------------------
packages:
  "perl5"
    package_policy   =>  "add",
    package_method   =>  smartos_pkg_add("http://pkg.example.com/packages/");

Arguments:

Implementation:

body package_method smartos_pkg_add(repo)
{
      package_changes => "individual";
      package_list_command => "/opt/local/sbin/pkg_info";
      package_list_name_regex    => "([^\s]+)\-[0-9]+.*\s";
      package_list_version_regex => "[^\s]+\-([0-9][^\s]+)\s";

      package_installed_regex => ".*"; # all reported are installed

      package_add_command => "/usr/bin/env PKG_PATH=$(repo) /opt/local/sbin/pkg_add";

      package_delete_command => "/opt/local/sbin/pkg_delete";
      package_update_command => "/usr/bin/env PKG_PATH=$(repo) /opt/local/sbin/pkg_add";
}

opencsw

Prototype: opencsw

Description: OpenCSW (Solaris software packages) method

Implementation:

body package_method opencsw
{
      package_changes => "bulk";
      package_list_command => "/opt/csw/bin/pkgutil -c";
      package_list_name_regex    => "CSW(.*?)\s.*";
      package_list_version_regex => ".*?\s+(.*),.*";

      package_installed_regex => ".*"; # all reported are installed

      package_list_update_command => "/opt/csw/bin/pkgutil -U";
      package_list_update_ifelapsed => "$(common_knowledge.list_update_ifelapsed)";

      package_add_command => "/opt/csw/bin/pkgutil -yi";

      package_delete_command => "/opt/csw/bin/pkgutil -yr";
      package_update_command =>  "/opt/csw/bin/pkgutil -yu";
}

solaris

Prototype: solaris(pkgname, spoolfile, adminfile)

Description: Package method for old Solaris package system

Arguments:

  • pkgname: Not used
  • spoolfile: The spool file, located in /tmp
  • adminfile: The admin file, located in /tmp

The older solaris package system is poorly designed, with too many different names to track. See the example in tests/units/unit_package_solaris.cf to see how to use this.

Implementation:

body package_method solaris(pkgname, spoolfile, adminfile)
{
      package_changes => "individual";
      package_list_command => "$(solaris_knowledge.call_pkginfo) -l";
      package_multiline_start    =>  "\s*PKGINST:\s+[^\s]+.*";
      package_list_name_regex    => "\s*PKGINST:\s+([^\s]+).*";
      package_list_version_regex => "\s*VERSION:\s+([^\s]+).*";
      package_list_arch_regex    => "\s*ARCH:\s+([^\s]+)";
      package_installed_regex => "\s*STATUS:\s*(completely|partially)\s+installed.*";
      package_name_convention => "$(name)";
      package_add_command => "$(solaris_knowledge.call_pkgadd) -n -a /tmp/$(adminfile) -d /tmp/$(spoolfile)";
      package_delete_command => "$(solaris_knowledge.call_pkgrm) -n -a /tmp/$(adminfile)";
}

solaris_install

Prototype: solaris_install(adminfile)

Description: Package method for old Solaris package system

Arguments:

  • adminfile: The admin file created by create_solaris_admin_file

Implementation:

body package_method solaris_install(adminfile)
{
      package_changes => "individual";
      package_list_command => "$(solaris_knowledge.call_pkginfo) -l";
      package_multiline_start    =>  "\s*PKGINST:\s+[^\s]+.*";
      package_list_name_regex    => "\s*PKGINST:\s+([^\s]+).*";
      package_list_version_regex => "\s*VERSION:\s+([^\s]+).*";
      package_list_arch_regex    => "\s*ARCH:\s+([^\s]+)";
      package_installed_regex => "\s*STATUS:\s*(completely|partially)\s+installed.*";
      package_name_convention => "$(name)";
      package_add_command => "$(solaris_knowledge.call_pkgadd) -n -a $(adminfile)";
      package_delete_command => "$(solaris_knowledge.call_pkgrm) -n -a $(adminfile)";
}

freebsd

Prototype: freebsd

Description: FreeBSD pkg_add installation package method

This package method interacts with FreeBSD pkg_add to install from remote repositories.

Example: NOTE: Do not use this method on pkgng systems! It will appear to operate normally but is highly likely to break your package system.

This example installs "perl5" from a non-default repository:

----------------------------

vars:
  environment => { "PACKAGESITE=http://repo.example.com/private/8_STABLE/" };
packages:
  "perl5"
    package_policy   =>  "add",
    package_method   =>  freebsd;

Implementation:

body package_method freebsd
{
      package_changes => "individual";

      # Could use rpm for this
      package_list_command => "/usr/sbin/pkg info";

      # Remember to escape special characters like |

      package_list_name_regex    => "([^\s]+)-.*";
      package_list_version_regex => "[^\s]+-([^\s]+).*";

      package_name_regex    => "([^\s]+)-.*";
      package_version_regex => "[^\s]+-([^\s]+).*";

      package_installed_regex => ".*";

      package_name_convention => "$(name)-$(version)";

      package_add_command => "/usr/sbin/pkg install -y";
      package_delete_command => "/usr/sbin/pkg delete -y";
}

freebsd_portmaster

Prototype: freebsd_portmaster

Description: FreeBSD portmaster package installation method

This package method interacts with portmaster to build and install packages.

Note that you must use the complete package name as it appears in /usr/ports/*/name, such as 'perl5.14' rather than 'perl5'. Repositories are hard-coded to /usr/ports; alternate locations are unsupported at this time. This method supports both pkg_* and pkgng systems.

Example:

packages:
  "perl5.14"
    package_policy   =>  "add",
    package_method   =>  freebsd_portmaster;

Implementation:

body package_method freebsd_portmaster
{
      package_changes => "individual";

      package_list_command => "/usr/sbin/pkg info";

      package_list_name_regex    => "([^\s]+)-.*";
      package_list_version_regex => "[^\s]+-([^\s]+).*";

      package_installed_regex => ".*";

      package_name_convention => "$(name)";
      package_delete_convention => "$(name)-$(version)";

      package_file_repositories => {
                                     "/usr/ports/accessibility/",
                                     "/usr/port/arabic/",
                                     "/usr/ports/archivers/",
                                     "/usr/ports/astro/",
                                     "/usr/ports/audio/",
                                     "/usr/ports/benchmarks/",
                                     "/usr/ports/biology/",
                                     "/usr/ports/cad/",
                                     "/usr/ports/chinese/",
                                     "/usr/ports/comms/",
                                     "/usr/ports/converters/",
                                     "/usr/ports/databases/",
                                     "/usr/ports/deskutils/",
                                     "/usr/ports/devel/",
                                     "/usr/ports/dns/",
                                     "/usr/ports/editors/",
                                     "/usr/ports/emulators/",
                                     "/usr/ports/finance/",
                                     "/usr/ports/french/",
                                     "/usr/ports/ftp/",
                                     "/usr/ports/games/",
                                     "/usr/ports/german/",
                                     "/usr/ports/graphics/",
                                     "/usr/ports/hebrew/",
                                     "/usr/ports/hungarian/",
                                     "/usr/ports/irc/",
                                     "/usr/ports/japanese/",
                                     "/usr/ports/java/",
                                     "/usr/ports/korean/",
                                     "/usr/ports/lang/",
                                     "/usr/ports/mail/",
                                     "/usr/ports/math/",
                                     "/usr/ports/mbone/",
                                     "/usr/ports/misc/",
                                     "/usr/ports/multimedia/",
                                     "/usr/ports/net/",
                                     "/usr/ports/net-im/",
                                     "/usr/ports/net-mgmt/",
                                     "/usr/ports/net-p2p/",
                                     "/usr/ports/news/",
                                     "/usr/ports/packages/",
                                     "/usr/ports/palm/",
                                     "/usr/ports/polish/",
                                     "/usr/ports/ports-mgmt/",
                                     "/usr/ports/portuguese/",
                                     "/usr/ports/print/",
                                     "/usr/ports/russian/",
                                     "/usr/ports/science/",
                                     "/usr/ports/security/",
                                     "/usr/ports/shells/",
                                     "/usr/ports/sysutils/",
                                     "/usr/ports/textproc/",
                                     "/usr/ports/ukrainian/",
                                     "/usr/ports/vietnamese/",
                                     "/usr/ports/www/",
                                     "/usr/ports/x11/",
                                     "/usr/ports/x11-clocks/",
                                     "/usr/ports/x11-drivers/",
                                     "/usr/ports/x11-fm/",
                                     "/usr/ports/x11-fonts/",
                                     "/usr/ports/x11-servers/",
                                     "/usr/ports/x11-themes/",
                                     "/usr/ports/x11-toolkits/",
                                     "/usr/ports/x11-wm/",
      };

      package_add_command => "/usr/local/sbin/portmaster -D -G --no-confirm";
      package_update_command => "/usr/local/sbin/portmaster -D -G --no-confirm";
      package_delete_command => "/usr/local/sbin/portmaster --no-confirm -e";
}

alpinelinux

Prototype: alpinelinux

Description: Alpine Linux apk package installation method

This package method interacts with apk to manage packages.

Example:

packages:
  "vim"
    package_policy   =>  "add",
    package_method   =>  alpinelinux;

Implementation:

body package_method alpinelinux
{
      package_changes => "bulk";
      package_list_command => "/sbin/apk info -v";
      package_list_name_regex    => "([^\s]+)-.*";
      package_list_version_regex => "[^\s]+-([^\s]+).*";
      package_name_regex    => ".*";
      package_installed_regex => ".*";
      package_name_convention => "$(name)";
      package_add_command => "/sbin/apk add";
      package_delete_command => "/sbin/apk del";
}

emerge

Prototype: emerge

Description: Gentoo emerge package installation method

This package method interacts with emerge to build and install packages.

Example:

packages:
  "zsh"
    package_policy   =>  "add",
    package_method   =>  emerge;

Implementation:

body package_method emerge
{
      package_changes => "individual";
      package_list_command => "/bin/sh -c '/bin/ls -d /var/db/pkg/*/* | cut -c 13-'";
      package_list_name_regex => ".*/([^\s]+)-\d.*";
      package_list_version_regex => ".*/[^\s]+-(\d.*)";
      package_installed_regex => ".*";                          # all reported are installed
      package_name_convention => "$(name)";
      package_list_update_command => "/bin/true";               # I prefer manual syncing
      #package_list_update_command => "/usr/bin/emerge --sync"; # if you like automatic
      package_list_update_ifelapsed => "$(common_knowledge.list_update_ifelapsed)";

      package_add_command => "/usr/bin/emerge -q --quiet-build";
      package_delete_command => "/usr/bin/emerge --depclean";
      package_update_command => "/usr/bin/emerge --update";
      package_patch_command => "/usr/bin/emerge --update";
      package_verify_command => "/usr/bin/emerge -s";
      package_noverify_regex => ".*(Not Installed|Applications found : 0).*";
}

pacman

Prototype: pacman

Description: Arch Linux pacman package management method

Implementation:

body package_method pacman
{
      package_changes => "bulk";

      package_list_command => "/usr/bin/pacman -Q";
      package_verify_command  => "/usr/bin/pacman -Q";
      package_noverify_regex  => "error:\b.*\bwas not found";

      # set it to "0" to avoid caching of list during upgrade
      package_list_update_ifelapsed => "$(common_knowledge.list_update_ifelapsed)";

      package_list_name_regex    => "(.*)\s+.*";
      package_list_version_regex => ".*\s+(.*)";
      package_installed_regex => ".*";

      package_name_convention => "$(name)";
      package_add_command => "/usr/bin/pacman -S --noconfirm --noprogressbar --needed";
      package_delete_command => "/usr/bin/pacman -Rs --noconfirm";
      package_update_command => "/usr/bin/pacman -S --noconfirm --noprogressbar --needed";
}

zypper

Prototype: zypper

Description: SUSE installation method

This package method interacts with the SUSE Zypper package manager

Example:

packages:
    "mypackage" package_method => zypper, package_policy => "add";

Implementation:

body package_method zypper
{
      package_changes => "bulk";

      package_list_command => "$(paths.path[rpm]) -qa --queryformat \"$(rpm_knowledge.rpm_output_format)\"";

      # set it to "0" to avoid caching of list during upgrade
      package_list_update_command => "$(suse_knowledge.call_zypper) list-updates";
      package_list_update_ifelapsed => "$(common_knowledge.list_update_ifelapsed)";

      package_patch_list_command => "$(suse_knowledge.call_zypper) patches";
      package_installed_regex => "i.*";
      package_list_name_regex    => "$(rpm_knowledge.rpm_name_regex)";
      package_list_version_regex => "$(rpm_knowledge.rpm_version_regex)";
      package_list_arch_regex    => "$(rpm_knowledge.rpm_arch_regex)";

      package_patch_installed_regex => ".*Installed.*|.*Not Applicable.*";
      package_patch_name_regex    => "[^|]+\|\s+([^\s]+).*";
      package_patch_version_regex => "[^|]+\|[^|]+\|\s+([^\s]+).*";

      package_name_convention => "$(name)";
      package_add_command => "$(suse_knowledge.call_zypper) --non-interactive install";
      package_delete_command => "$(suse_knowledge.call_zypper) --non-interactive remove --force-resolution";
      package_update_command => "$(suse_knowledge.call_zypper) --non-interactive update";
      package_patch_command => "$(suse_knowledge.call_zypper) --non-interactive patch$"; # $ means no args
      package_verify_command => "$(suse_knowledge.call_zypper) --non-interactive verify$";
}

generic

Prototype: generic

Description: Generic installation package method

This package method attempts to handle all platforms.

The Redhat section is a verbatim insertion of yum_rpm(), which was contributed by Trond Hasle Amundsen.

Example:

packages:
    "mypackage" package_method => generic, package_policy => "add";

Implementation:

body package_method generic
{
    suse|sles|opensuse::
      package_changes => "bulk";
      package_list_command => "$(rpm_knowledge.call_rpm) -qa --queryformat \"$(rpm_knowledge.rpm_output_format)\"";
      # set it to "0" to avoid caching of list during upgrade
      package_list_update_command => "$(suse_knowledge.call_zypper) list-updates";
      package_list_update_ifelapsed => "$(common_knowledge.list_update_ifelapsed)";
      package_patch_list_command => "$(suse_knowledge.call_zypper) patches";
      package_installed_regex => "i.*";
      package_list_name_regex    => "$(rpm_knowledge.rpm_name_regex)";
      package_list_version_regex => "$(rpm_knowledge.rpm_version_regex)";
      package_list_arch_regex    => "$(rpm_knowledge.rpm_arch_regex)";
      package_patch_installed_regex => ".*Installed.*|.*Not Applicable.*";
      package_patch_name_regex    => "[^|]+\|\s+([^\s]+).*";
      package_patch_version_regex => "[^|]+\|[^|]+\|\s+([^\s]+).*";
      package_name_convention => "$(name)";
      package_add_command => "$(suse_knowledge.call_zypper) --non-interactive install";
      package_delete_command => "$(suse_knowledge.call_zypper) --non-interactive remove --force-resolution";
      package_update_command => "$(suse_knowledge.call_zypper) --non-interactive update";
      package_patch_command => "$(suse_knowledge.call_zypper) --non-interactive patch$"; # $ means no args
      package_verify_command => "$(suse_knowledge.call_zypper) --non-interactive verify$";

    redhat::
      package_changes => "bulk";
      package_list_command => "$(rpm_knowledge.call_rpm) -qa --qf '$(rpm_knowledge.rpm3_output_format)'";
      package_patch_list_command => "$(redhat_knowledge.call_yum) $(redhat_knowledge.yum_offline_options) check-update $(redhat_knowledge.check_update_postproc)";

      package_list_name_regex    => "$(rpm_knowledge.rpm3_name_regex)";
      package_list_version_regex => "$(rpm_knowledge.rpm3_version_regex)";
      package_list_arch_regex    => "$(rpm_knowledge.rpm3_arch_regex)";

      package_installed_regex => ".*";
      package_name_convention => "$(name)-$(version).$(arch)";

      # just give the package name to rpm to delete, otherwise it gets "name.*" (from package_name_convention above)
      package_delete_convention => "$(name)";

      # set it to "0" to avoid caching of list during upgrade
      package_list_update_command => "$(redhat_knowledge.call_yum) $(redhat_knowledge.yum_options) check-update $(redhat_knowledge.check_update_postproc)";
      package_list_update_ifelapsed => "$(common_knowledge.list_update_ifelapsed)";

      package_patch_name_regex    => "$(redhat_knowledge.patch_name_regex)";
      package_patch_version_regex => "$(redhat_knowledge.patch_version_regex)";
      package_patch_arch_regex    => "$(redhat_knowledge.patch_arch_regex)";

      package_add_command    => "$(redhat_knowledge.call_yum) $(redhat_knowledge.yum_options) -y install";
      package_update_command => "$(redhat_knowledge.call_yum) $(redhat_knowledge.yum_options) -y update";
      package_patch_command  => "$(redhat_knowledge.call_yum) $(redhat_knowledge.yum_options) -y update";
      package_delete_command => "$(rpm_knowledge.call_rpm) -e --nodeps";
      package_verify_command => "$(rpm_knowledge.call_rpm) -V";
      package_noverify_returncode => "1";
      package_version_less_command => "$(redhat_knowledge.rpm_compare_less)";
      package_version_equal_command => "$(redhat_knowledge.rpm_compare_equal)";

    debian::
      package_changes => "bulk";
      package_list_command => "$(debian_knowledge.call_dpkg) -l";
      package_list_name_regex => "$(debian_knowledge.list_name_regex)";
      package_list_version_regex => "$(debian_knowledge.list_version_regex)";
      package_installed_regex => ".i.*"; # packages that have been uninstalled may be listed
      package_name_convention => "$(name)";
      package_list_update_ifelapsed => "$(common_knowledge.list_update_ifelapsed)";

      # make correct version comparisons
      package_version_less_command => "$(debian_knowledge.dpkg_compare_less)";
      package_version_equal_command => "$(debian_knowledge.dpkg_compare_equal)";

    debian.have_aptitude::
      package_add_command => "$(debian_knowledge.call_aptitude) $(debian_knowledge.dpkg_options) --assume-yes install";
      package_list_update_command => "$(debian_knowledge.call_aptitude) update";
      package_delete_command => "$(debian_knowledge.call_aptitude) $(debian_knowledge.dpkg_options) --assume-yes remove";
      package_update_command =>  "$(debian_knowledge.call_aptitude) $(debian_knowledge.dpkg_options) --assume-yes install";
      package_patch_command =>  "$(debian_knowledge.call_aptitude) $(debian_knowledge.dpkg_options) --assume-yes install";
      package_verify_command =>  "$(debian_knowledge.call_aptitude) show";
      package_noverify_regex => "(State: not installed|E: Unable to locate package .*)";

      package_patch_list_command => "$(debian_knowledge.call_aptitude) --assume-yes --simulate --verbose full-upgrade";
      package_patch_name_regex => "$(debian_knowledge.patch_name_regex)";
      package_patch_version_regex => "$(debian_knowledge.patch_version_regex)";

    debian.!have_aptitude::
      package_add_command => "$(debian_knowledge.call_apt_get) $(debian_knowledge.dpkg_options) --yes install";
      package_list_update_command => "$(debian_knowledge.call_apt_get) update";
      package_delete_command => "$(debian_knowledge.call_apt_get) $(debian_knowledge.dpkg_options) --yes remove";
      package_update_command =>  "$(debian_knowledge.call_apt_get) $(debian_knowledge.dpkg_options) --yes install";
      package_patch_command =>  "$(debian_knowledge.call_apt_get) $(debian_knowledge.dpkg_options) --yes install";
      package_verify_command => "$(debian_knowledge.call_dpkg) -s";
      package_noverify_returncode => "1";

      package_patch_list_command => "$(debian_knowledge.call_apt_get) --just-print dist-upgrade";
      package_patch_name_regex => "$(debian_knowledge.patch_name_regex)";
      package_patch_version_regex => "$(debian_knowledge.patch_version_regex)";

    freebsd::
      package_changes => "individual";
      package_list_command => "/usr/sbin/pkg info";
      package_list_name_regex    => "([^\s]+)-.*";
      package_list_version_regex => "[^\s]+-([^\s]+).*";
      package_name_regex    => "([^\s]+)-.*";
      package_version_regex => "[^\s]+-([^\s]+).*";
      package_installed_regex => ".*";
      package_name_convention => "$(name)-$(version)";
      package_add_command => "/usr/sbin/pkg install -y";
      package_delete_command => "/usr/sbin/pkg delete";

    alpinelinux::
      package_changes => "bulk";
      package_list_command => "/sbin/apk info -v";
      package_list_name_regex    => "([^\s]+)-.*";
      package_list_version_regex => "[^\s]+-([^\s]+).*";
      package_name_regex    => ".*";
      package_installed_regex => ".*";
      package_name_convention => "$(name)";
      package_add_command => "/sbin/apk add";
      package_delete_command => "/sbin/apk del";

    gentoo::
      package_changes => "individual";
      package_list_command => "/bin/sh -c '/bin/ls -d /var/db/pkg/*/* | cut -c 13-'";
      package_list_name_regex => "([^/]+/(?:(?!-\d).)+)-\d.*";
      package_list_version_regex => "[^/]+/(?:(?!-\d).)+-(\d.*)";
      package_installed_regex => ".*";                          # all reported are installed
      package_name_convention => "$(name)";
      package_list_update_command => "/bin/true";               # I prefer manual syncing
      #package_list_update_command => "/usr/bin/emerge --sync"; # if you like automatic
      package_list_update_ifelapsed => "$(common_knowledge.list_update_ifelapsed)";

      package_add_command => "/usr/bin/emerge -q --quiet-build";
      package_delete_command => "/usr/bin/emerge --depclean";
      package_update_command => "/usr/bin/emerge --update";
      package_patch_command => "/usr/bin/emerge --update";
      package_verify_command => "/usr/bin/emerge -s";
      package_noverify_regex => ".*(Not Installed|Applications found : 0).*";

    archlinux::
      package_changes => "bulk";
      package_list_command => "/usr/bin/pacman -Q";
      package_verify_command  => "/usr/bin/pacman -Q";
      package_noverify_regex  => "error:\b.*\bwas not found";
      package_list_name_regex    => "(.*)\s+.*";
      package_list_version_regex => ".*\s+(.*)";
      package_installed_regex => ".*";
      package_name_convention => "$(name)";
      package_list_update_ifelapsed => "$(common_knowledge.list_update_ifelapsed)";
      package_add_command => "/usr/bin/pacman -S --noconfirm --noprogressbar --needed";
      package_delete_command => "/usr/bin/pacman -Rs --noconfirm";
      package_update_command => "/usr/bin/pacman -S --noconfirm --noprogressbar --needed";
}

common bodies

package_module_knowledge

Prototype: package_module_knowledge

Description: common package_module_knowledge bundle

This common bundle defines which package modules are the defaults on different platforms.

Implementation:

bundle common package_module_knowledge
{
  vars:

    # First we set the default package manager based on the platform:
    # TODO Refactor to use ifelse()?

    debian::
      "platform_default" string => "apt_get";

    freebsd::
      "platform_default" string => "pkg";

    redhat|amazon_linux::
      "platform_default" string => "yum";

    suse|sles|opensuse::
      "platform_default" string => "zypper";

    aix::
      "platform_default" string => "nimclient";

    slackware::
      "platform_default" string => "slackpkg";

      # CFEngine 3.12.2+ and 3.14+ have new package module on Windows
    windows.cfengine_3_12.!(cfengine_3_12_0|cfengine_3_12_1)::
      "platform_default" string => "msiexec";
@if minimum_version(3.14)
    windows::
      "platform_default" string => "msiexec";
@endif

    alpinelinux::
      "platform_default" string => "apk";

    termux::
      "platform_default" string => "apt_get";

    any::

      # By default, we don't want additional package managers inventoried, but
      # we need the variable to be defined, so we initialize it to an empty
      # list.

      "additional_inventory" slist => {};

      # We look to see if additional package inventory modules should be used.
      # `default:def.additional_package_inventory_modules` is expected to be a data
      # structure keyed with values expected to match the value of `sys.flavor`.

      # For example: { "aix_7": [ "yum"], "ubuntu_20: [ "snap" ] }

      # If there is additional inventory defined for the platform we want to use them
      "additional_inventory" -> { "CFE-3612" }
        slist => getvalues( "default:def.additional_package_inventory_modules[$(sys.flavor)]" ),
        if => isvariable( "default:def.additional_package_inventory_modules[$(sys.flavor)]" );

      # Package inventory refresh
      "query_installed_ifelapsed" -> { "CFE-2771", "CFE-3504" }
        string => ifelse( isvariable( "def.package_module_$(this.promiser)" ),
                          "$(def.package_module_$(this.promiser))",
                          "0"); # Always refresh local package inventory

      "query_updates_ifelapsed" -> { "CFE-2771", "CFE-3504" }
        string => ifelse( isvariable( "def.package_module_$(this.promiser)" ),
                          "$(def.package_module_$(this.promiser))",
                          "1440"); # Refresh software updates available once a day

      # It's possible that a user wants to use a different default package
      # manager. To support that we look at
      # `default:def.default_package_module`, a data structure keyed
      # with values expected to match the value of `sys.flavor`

      "platform_default" -> { "CFE-3612" }
        string => "$(default:def.default_package_module[$(sys.flavor)])",
        if => isvariable( "default:def.default_package_module[$(sys.flavor)]"),
        comment => concat( "default:def.default_package_module[$(sys.flavor)] has been defined.",
                           "This overrides the default package manager.");

}

packages_common

Prototype: packages_common

Description: Define inputs required for this policy file

Implementation:

bundle common packages_common
{
  vars:
      "inputs" slist => {
                          "$(this.promise_dirname)/paths.cf",
                          "$(this.promise_dirname)/files.cf",
                          "$(this.promise_dirname)/common.cf"
      };
}

common_knowledge

Prototype: common_knowledge

Description: common packages knowledge bundle

This common bundle defines general things about platforms.

Implementation:

bundle common common_knowledge
{
  vars:

      # This variable can be customized via augments:
      # { "variables": { "default:common_knowledge.list_update_ifelapsed": { "value": "0" } } }
      "list_update_ifelapsed"
        string => "240",
        if => not( isvariable( "list_update_ifelapsed" )),
        comment => concat( "The number of minutes to wait before updating the",
                           " package cache. Note this controls both the software",
                           " installed and the software updates available.");
}

debian_knowledge

Prototype: debian_knowledge

Description: common Debian knowledge bundle

This common bundle has useful information about Debian.

Implementation:

bundle common debian_knowledge
{
  vars:
      # Debian default package architecture, see https://wiki.debian.org/Multiarch/Tuples
      "default_arch" string => ifelse("x86_64", "amd64",
                                      "i386", "i386",
                                      $(sys.arch));

      "apt_prefix" string => "/usr/bin/env DEBIAN_FRONTEND=noninteractive LC_ALL=C PATH=/bin:/sbin/:/usr/bin:/usr/sbin";
      "call_dpkg" string => "$(apt_prefix) $(paths.path[dpkg])";
      "call_apt_get" string => "$(apt_prefix) $(paths.path[apt_get])";
      "call_aptitude" string => "$(apt_prefix) $(paths.path[aptitude])";
      "dpkg_options" string => "-o Dpkg::Options::=--force-confold -o Dpkg::Options::=--force-confdef";

      "dpkg_compare_equal" string => "$(call_dpkg) --compare-versions '$(v1)' eq '$(v2)'";
      "dpkg_compare_less" string => "$(call_dpkg) --compare-versions '$(v1)' lt '$(v2)'";

      "list_name_regex" string => "^.i\s+([^\s:]+).*";
      "list_version_regex" string => "^.i\s+[^\s]+\s+([^\s]+).*";

      "patch_name_regex" string => "^Inst\s+(\S+)\s+.*";
      "patch_version_regex" string => "^Inst\s+\S+\s+\[\S+\]\s+\((\S+)\s+.*";
}

rpm_knowledge

Prototype: rpm_knowledge

Description: common RPM knowledge bundle

This common bundle has useful information about platforms using RPM

Implementation:

bundle common rpm_knowledge
{
  vars:
      "call_rpm" string => "$(paths.rpm)";

      "rpm_output_format" string => "i | repos | %{name} | %{version}-%{release} | %{arch}\n";
      "rpm_name_regex" string => "[^|]+\|[^|]+\|\s+([^\s|]+).*";
      "rpm_version_regex" string => "[^|]+\|[^|]+\|[^|]+\|\s+([^\s|]+).*";
      "rpm_arch_regex" string => "[^|]+\|[^|]+\|[^|]+\|[^|]+\|\s+([^\s]+).*";

      "rpm2_output_format" string => "%{name} %{version}-%{release} %{arch}\n";
      "rpm2_name_regex" string => "^(\S+?)\s\S+?\s\S+$";
      "rpm2_version_regex" string => "^\S+?\s(\S+?)\s\S+$";
      "rpm2_arch_regex" string => "^\S+?\s\S+?\s(\S+)$";

      "rpm3_output_format" string => "%{name} %{arch} %{version}-%{release}\n";
      "rpm3_name_regex" string => "(\S+).*";
      "rpm3_version_regex" string => "\S+\s+\S+\s+(\S+).*";
      "rpm3_arch_regex" string => "\S+\s+(\S+).*";
}

redhat_no_locking_knowledge

Prototype: redhat_no_locking_knowledge

Description: common Red Hat knowledge bundle

This common bundle has useful information about Red Hat and its derivatives

Implementation:

bundle common redhat_no_locking_knowledge {
{
  vars:
      # Red Hat default package architecture
      "default_arch" string => $(sys.arch);

      "call_yum" string => "$(paths.path[yum])";
      "call_rpmvercmp" string => "$(sys.bindir)/rpmvercmp";

      # on RHEL 3/4, Yum doesn't know how to be --quiet
      "yum_options" string => ifelse("centos_4|redhat_4|centos_3|redhat_3", "",
                                     "--quiet ${redhat_no_locking_knowledge.no_locking_option}");
      "yum_offline_options" string => "$(yum_options) -C";

      "rpm_compare_equal" string => "$(call_rpmvercmp) '$(v1)' eq '$(v2)'";
      "rpm_compare_less" string => "$(call_rpmvercmp)  '$(v1)' lt '$(v2)'";
      # yum check-update prints a lot of extra useless lines, but the format of
      # the actual package lines is:
      #
      #   <name>.<arch>    <version>    <repo>
      #
      # We try to match that format as closely as possible, so we reject
      # possibly interspersed error messages.
      "patch_name_regex" string    => "^(\S+)\.[^\s.]+\s+\S+\s+\S+\s*$";
      "patch_version_regex" string => "^\S+\.[^\s.]+\s+(\S+)\s+\S+\s*$";
      "patch_arch_regex" string    => "^\S+\.([^\s.]+)\s+\S+\s+\S+\s*$";

      # Combine multiline entries into one line. A line without at least three
      # fields gets combined with the next line, if that line starts with a
      # space.
      "check_update_postproc" string => "| $(paths.sed) -r -n -e '
        :begin;
        /\S+\s+\S+\s+\S+/!{    # Check for valid line.
            N;                 # If not, read in the next line and append it.
            /\n /!{            # Check whether that line started with a space.
                h;             # If not, copy buffer to clipboard.
                s/\n[^\n]*$//; # Erase last line.
                p;             # Print current buffer.
                x;             # Restore from clipboard.
                s/^.*\n//;     # Erase everything but last line.
            };
            s/\n / /;          # Combine lines by removing newline.
            bbegin;            # Jump back to begin.
        };
        p;                     # Print current buffer.'";
}

redhat_knowledge

Prototype: redhat_knowledge

Description: common Red Hat knowledge bundle

This common bundle has useful information about Red Hat and its derivatives

Implementation:

bundle common redhat_knowledge
{
  vars:
      # Red Hat default package architecture
      "default_arch" string => $(sys.arch);

      "call_yum" string => "$(paths.path[yum])";
      "call_rpmvercmp" string => "$(sys.bindir)/rpmvercmp";

      # on RHEL 3/4, Yum doesn't know how to be --quiet
      "yum_options" string => ifelse("centos_4|redhat_4|centos_3|redhat_3", "",
                                     "--quiet ${redhat_no_locking_knowledge.no_locking_option}");
      "yum_offline_options" string => "$(yum_options) -C";

      "rpm_compare_equal" string => "$(call_rpmvercmp) '$(v1)' eq '$(v2)'";
      "rpm_compare_less" string => "$(call_rpmvercmp)  '$(v1)' lt '$(v2)'";
      # yum check-update prints a lot of extra useless lines, but the format of
      # the actual package lines is:
      #
      #   <name>.<arch>    <version>    <repo>
      #
      # We try to match that format as closely as possible, so we reject
      # possibly interspersed error messages.
      "patch_name_regex" string    => "^(\S+)\.[^\s.]+\s+\S+\s+\S+\s*$";
      "patch_version_regex" string => "^\S+\.[^\s.]+\s+(\S+)\s+\S+\s*$";
      "patch_arch_regex" string    => "^\S+\.([^\s.]+)\s+\S+\s+\S+\s*$";

      # Combine multiline entries into one line. A line without at least three
      # fields gets combined with the next line, if that line starts with a
      # space.
      "check_update_postproc" string => "| $(paths.sed) -r -n -e '
        :begin;
        /\S+\s+\S+\s+\S+/!{    # Check for valid line.
            N;                 # If not, read in the next line and append it.
            /\n /!{            # Check whether that line started with a space.
                h;             # If not, copy buffer to clipboard.
                s/\n[^\n]*$//; # Erase last line.
                p;             # Print current buffer.
                x;             # Restore from clipboard.
                s/^.*\n//;     # Erase everything but last line.
            };
            s/\n / /;          # Combine lines by removing newline.
            bbegin;            # Jump back to begin.
        };
        p;                     # Print current buffer.'";
}

suse_knowledge

Prototype: suse_knowledge

Description: common SUSE knowledge bundle

Implementation:

bundle common suse_knowledge
{
  vars:
      # SUSE default package architecture
      "default_arch" string => $(sys.arch);

      "call_zypper" string => "$(paths.zypper)";
}

darwin_knowledge

Prototype: darwin_knowledge

Description: common Darwin / Mac OS X knowledge bundle

This common bundle has useful information about Darwin / Mac OS X.

Implementation:

bundle common darwin_knowledge
{
  vars:
      "call_brew" string => "$(paths.path[brew])";
      "call_sudo" string => "$(paths.path[sudo])";

      # used with brew list --versions format '%{name} %{version}\n'

      "brew_name_regex" string => "([\S]+)\s[\S]+";
      "brew_version_regex" string => "[\S]+\s([\S]+)";
}

npm_knowledge

Prototype: npm_knowledge

Description: Node.js `npm' knowledge bundle

This common bundle has useful information about the Node.js `npm' package manager.

Implementation:

bundle common npm_knowledge
{
  vars:
      "call_npm" string => "$(paths.path[npm])";

      "npm_list_name_regex"    string => "^[^ /]+ ([\w\d-._~]+)@[\d.]+";
      "npm_list_version_regex" string => "^[^ /]+ [\w\d-._~]+@([\d.]+)";
      "npm_installed_regex"    string => "^[^ /]+ ([\w\d-._~]+@[\d.]+)";
}

pip_knowledge

Prototype: pip_knowledge

Description: Python `pip' knowledge bundle

This common bundle has useful information about the Python `pip' package manager.

Implementation:

bundle common pip_knowledge
{
  vars:
      "call_pip" string => "$(paths.path[pip])";

      "pip_list_name_regex"    string => "^([[:alnum:]-_]+)\s\([\d.]+\)";
      "pip_list_version_regex" string => "^[[:alnum:]-_]+\s\(([\d.]+)\)";
      "pip_installed_regex"    string => "^([[:alnum:]-_]+\s\([\d.]+\))";
}

solaris_knowledge

Prototype: solaris_knowledge

Description: Solaris knowledge bundle

This common bundle has useful information about the Solaris packages.

Implementation:

bundle common solaris_knowledge
{
  vars:
      "call_pkgadd" string => "$(paths.path[pkgadd])";
      "call_pkgrm" string => "$(paths.path[pkgrm])";
      "call_pkginfo" string => "$(paths.path[pkginfo])";

      "admin_nocheck" string => "mail=
instance=unique
partial=nocheck
runlevel=nocheck
idepend=nocheck
rdepend=nocheck
space=nocheck
setuid=nocheck
conflict=nocheck
action=nocheck
networktimeout=60
networkretries=3
authentication=quit
keystore=/var/sadm/security
proxy=
basedir=default";

}

edit_line bundles

create_solaris_admin_file

Prototype: create_solaris_admin_file

Description: The following bundle is part of a package setup for solaris

See unit examples.

Implementation:

bundle edit_line create_solaris_admin_file
{
  insert_lines:

      "$(solaris_knowledge.admin_nocheck)"
      comment => "Insert contents of Solaris admin file (automatically install packages)";
}

agent bundles

package_absent

Prototype: package_absent(package)

Description: Ensure package is absent

Arguments:

  • package: the packages to remove

This package method will remove package, using package_ensure.

Example:

methods:
    "nozip" usebundle => package_absent("zip");

Implementation:

bundle agent package_absent(package)
{
  packages:
    debian::
      "$(package)"
      package_policy => "delete",
      package_method => apt_get_permissive;

    redhat::
      "$(package)"
      package_policy => "delete",
      package_method => yum_rpm_permissive;

    suse|sles|opensuse::
      "$(package)"
      package_policy => "delete",
      package_method => zypper;

    !debian.!redhat.!(suse|sles|opensuse)::
      "$(package)"
      package_policy => "delete",
      package_method => generic;
}

package_present

Prototype: package_present(package)

Description: Ensure package is present

Arguments:

  • package: the packages to install

This package method will install package. On Debian, it will use apt_get_permissive. On Red Hat, yum_rpm_permissive. Otherwise, generic.

Example:

methods:
    "pleasezip" usebundle => package_present("zip");

Implementation:

bundle agent package_present(package)
{
  packages:
    debian::
      "$(package)"
      package_policy => "add",
      package_method => apt_get_permissive;

    redhat::
      "$(package)"
      package_policy => "add",
      package_method => yum_rpm_permissive;

    suse|sles|opensuse::
      "$(package)"
      package_policy => "add",
      package_method => zypper;

    !debian.!redhat.!(suse|sles|opensuse)::
      "$(package)"
      package_policy => "add",
      package_method => generic;
}

package_latest

Prototype: package_latest(package)

Description: Ensure package is present and updated

Arguments:

  • package: the package to add/update

This package method will install package or update it to the latest version. On Debian, it will use apt_get_permissive. On Red Hat, yum_rpm_permissive. Otherwise, generic.

Example:

methods:
    "latestzip" usebundle => package_latest("zip");

Implementation:

bundle agent package_latest(package)
{
  packages:
    debian::
      "$(package)"
      package_policy => "addupdate",
      package_version => "999999999:9999999999",
      package_method => apt_get_permissive;

    redhat::
      "$(package)"
      package_policy => "addupdate",
      package_version => "999999999",
      package_method => yum_rpm_permissive;

    suse|sles|opensuse::
      "$(package)"
      package_policy => "addupdate",
      package_version => "999999999",
      package_method => zypper;

    !debian.!redhat.!(suse|sles|opensuse)::
      "$(package)"
      package_policy => "addupdate",
      package_method => generic;
}

package_specific_present

Prototype: package_specific_present(packageorfile, package_version, package_arch)

Description: Ensure package is present

Arguments:

This package method will add packageorfile as a package or file, using package_specific.

Example:

methods:
     "addfilezip"
     usebundle => package_specific_present("/mydir/zip",
                                           "3.0-7",
                                           $(debian_knowledge.default_arch));

Implementation:

bundle agent package_specific_present(packageorfile, package_version, package_arch)
{
  methods:
      "ensure" usebundle => package_specific($(packageorfile),
                                             "add",
                                             $(package_version),
                                             $(package_arch));
}

package_specific_absent

Prototype: package_specific_absent(packageorfile, package_version, package_arch)

Description: Ensure package is absent

Arguments:

This package method will remove packageorfile as a package or file, using package_specific.

Example:

methods:
     "addfilezip"
     usebundle => package_specific_absent("/mydir/zip",
                                          "3.0-7",
                                          $(debian_knowledge.default_arch));

Implementation:

bundle agent package_specific_absent(packageorfile, package_version, package_arch)
{
  methods:
      "ensure" usebundle => package_specific($(packageorfile),
                                             "delete",
                                             $(package_version),
                                             $(package_arch));
}

package_specific_latest

Prototype: package_specific_latest(packageorfile, package_version, package_arch)

Description: Ensure package is added or updated

Arguments:

This package method will add or update packageorfile as a package or file, using package_specific.

Example:

methods:
     "latestfilezip"
     usebundle => package_specific_latest("/mydir/zip",
                                          "3.0-7",
                                          $(debian_knowledge.default_arch));
     "latestzip"
     usebundle => package_specific_latest("/mydir/zip",
                                          "3.0-7",
                                          $(debian_knowledge.default_arch));

Implementation:

bundle agent package_specific_latest(packageorfile, package_version, package_arch)
{
  methods:
      "ensure" usebundle => package_specific($(packageorfile),
                                             "addupdate",
                                             $(package_version),
                                             $(package_arch));
}

package_specific

Prototype: package_specific(package_name, desired, package_version, package_arch)

Description: Ensure package_name has the desired state

Arguments:

  • package_name: the packages to ensure (can be files)
  • desired: the desired package_policy, add or delete or addupdate
  • package_version: the desired package_version
  • package_arch: the desired package architecture

This package method will manage packages with package_policy set to desired, using package_version, and package_arch.

If package_name is not a file name: on Debian, it will use apt_get. On Red Hat, yum_rpm. Otherwise, generic.

If package_name is a file name, it will use dpkg_version or rpm_version from the file's directory.

For convenience on systems where sys.arch is not correct, you can use debian_knowledge.default_arch and redhat_knowledge.default_arch.

Solaris is only supported with pkgadd. Patches welcome.

Example:

methods:
     "ensure" usebundle => package_specific("zsh", "add", "1.2.3", "amd64");
     "ensure" usebundle => package_specific("/mydir/package.deb", "add", "9.8.7", "amd64");
     "ensure" usebundle => package_specific("tcsh", "delete", "2.3.4", "x86_64");

Implementation:

bundle agent package_specific(package_name, desired, package_version, package_arch)
{
  classes:
      "filebased" expression => fileexists($(package_name));
      "solaris_pkgadd" and => { "solaris", "_stdlib_path_exists_pkgadd" };

  vars:
      "solaris_adminfile" string => "/tmp/cfe-adminfile";

    filebased::
      "package_basename" string => lastnode($(package_name), "/");
      "dir" string => dirname($(package_name));

  methods:
    solaris_pkgadd.filebased::
      "" usebundle => file_make($(solaris_adminfile),
                                $(solaris_knowledge.admin_nocheck)),
      classes => scoped_classes_generic("bundle", "solaris_adminfile");

  packages:

    debian.!filebased::

      "$(package_name)"
      package_policy => $(desired),
      package_select => '>=', # see verify_packages.c
      package_version => $(package_version),
      package_architectures => { $(package_arch) },
      package_method => apt_get;

    debian.filebased::

      "$(package_basename)"
      package_policy => $(desired),
      package_select => '>=',
      package_version => $(package_version),
      package_architectures => { $(package_arch) },
      package_method => dpkg_version($(dir));

    redhat.!filebased::

      "$(package_name)"
      package_policy => $(desired),
      package_select => '>=', # see verify_packages.c
      package_version => $(package_version),
      package_architectures => { $(package_arch) },
      package_method => yum_rpm;

    suse|sles|opensuse::

      "$(package_name)"
      package_policy => $(desired),
      package_select => '>=', # see verify_packages.c
      package_version => $(package_version),
      package_architectures => { $(package_arch) },
      package_method => zypper;

    (redhat|aix).filebased::

      "$(package_basename)"
      package_policy => $(desired),
      package_select => '>=',
      package_version => $(package_version),
      package_architectures => { $(package_arch) },
      package_method => rpm_version($(dir));

    solaris_adminfile_ok::

      "$(package_name)"
      package_policy => $(desired),
      package_select => '>=',
      package_version => $(package_version),
      package_method => solaris_install($(solaris_admin_file));

    !filebased.!debian.!redhat.!(suse|sles|opensuse)::

      "$(package_name)"
      package_policy => $(desired),
      package_method => generic;

  reports:
    "(DEBUG|DEBUG_$(this.bundle)).filebased.!(suse|sles|opensuse).!debian.!redhat.!aix.!solaris_pkgadd"::
      "DEBUG $(this.bundle): sorry, can't do file-based installs on $(sys.os)";
}