Details
-
Type:
Story
-
Status: Open
-
Priority:
Low
-
Resolution: Unresolved
-
Affects Version/s: None
-
Fix Version/s: None
-
Component/s: None
-
Labels:
Description
Currently we can use `packagesmatching()` to find packages that are currently installed based on name, version, architecture, and the `package_module` or `package_method` used to collect the data.
In order to define a class that indicates a package is installed we can check the length of the returned data container and see if its greater than 0.
bundle agent main { vars: "pkg" string => "vim"; "p" data => packagesmatching( $(pkg), ".*", ".*", ".*" ); "l" int => length(p); classes: "have_vim_installed" expression => isgreaterthan( $(l), 0); reports: "I $(l) packages matching $(pkg) installed which is more than 0." if => "have_vim_installed"; "I have $(l) packages matching $(pkg) installed." unless => isgreaterthan( $(l), 0 ); }
It would be convenient to not have to step through these intermediary variables when I am only concerned with a class.
Syntax suggestions:
bundle agent example { classes: "at_least_one_package_installed_matching" expression => package_installed_matching( name_reg, version_reg, arch_reg, method_reg); "at_least_one_package_update_matching" expression => package_update_available( name_reg, version_reg, arch_reg, method_reg) }
Policy Examples
Class for each package found via packagesmatching()
This example defines classes for each package found by packagesmatching(). You don't have to worry about explicitly canonifying the names, cfengine will do it for you automatically (only when you are defining a class, not when you are checking a class).
bundle agent main { vars: "pkgs_installed_d" data => packagesmatching( "e.*", ".*", ".*", ".*" ); "i" slist => getindices( pkgs_installed_d ); classes: "pkg_installed_$(pkgs_installed_d[$(i)][name])" expression => isvariable( "pkgs_installed_d[$(i)][name]" ); vars: "c" slist => classesmatching("pkg_installed_.*"); reports: "$(c)"; }
On my workstation all of these packages starting with e are installed:
R: pkg_installed_evolution_data_server_online_accounts R: pkg_installed_exo_utils R: pkg_installed_enfuse R: pkg_installed_enblend R: pkg_installed_evolution_data_server R: pkg_installed_empathy_common R: pkg_installed_emacs24 R: pkg_installed_e2fslibs R: pkg_installed_enigmail R: pkg_installed_e2fsprogs R: pkg_installed_eog R: pkg_installed_enchant R: pkg_installed_emacsen_common R: pkg_installed_emacs R: pkg_installed_example_content R: pkg_installed_evince R: pkg_installed_emacs24_common R: pkg_installed_elinks R: pkg_installed_efibootmgr R: pkg_installed_evolution_data_server_common R: pkg_installed_espeak_data R: pkg_installed_ethtool R: pkg_installed_ed R: pkg_installed_emacs24_bin_common R: pkg_installed_evince_common R: pkg_installed_elinks_data R: pkg_installed_eject R: pkg_installed_emacs24_common_non_dfsg
Class for each package name and version found by packagesmatching()
bundle agent main { vars: "pkgs_installed_d" data => packagesmatching( "e.*", ".*", ".*", ".*" ); "i" slist => getindices( pkgs_installed_d ); classes: "pkg_installed_$(pkgs_installed_d[$(i)][name])" expression => isvariable( "pkgs_installed_d[$(i)][name]" ), meta => { "identifies=package_name_present" }; "pkg_installed_$(pkgs_installed_d[$(i)][name])_$(pkgs_installed_d[$(i)][version])" expression => isvariable( "pkgs_installed_d[$(i)][version]" ), meta => { "identifies=package_version_present" }; vars: "c_pkg_name_installed" slist => classesmatching(".*", "identifies=package_name_present"); "c_pkg_name_version_installed" slist => classesmatching(".*", "identifies=package_version_present"); reports: "Classes for package names that are installed:"; " $(c_pkg_name_installed)"; "Classes for package names and versions that are installed:"; " $(c_pkg_name_version_installed)"; }
Here you can see the classes that were defined by the package name, followed by the classes defined for the package name and version.
R: Classes for package names that are installed: R: pkg_installed_evolution_data_server_online_accounts R: pkg_installed_exo_utils R: pkg_installed_enfuse R: pkg_installed_enblend R: pkg_installed_evolution_data_server R: pkg_installed_empathy_common R: pkg_installed_emacs24 R: pkg_installed_e2fslibs R: pkg_installed_enigmail R: pkg_installed_e2fsprogs R: pkg_installed_eog R: pkg_installed_enchant R: pkg_installed_emacsen_common R: pkg_installed_emacs R: pkg_installed_example_content R: pkg_installed_evince R: pkg_installed_emacs24_common R: pkg_installed_elinks R: pkg_installed_efibootmgr R: pkg_installed_evolution_data_server_common R: pkg_installed_espeak_data R: pkg_installed_ethtool R: pkg_installed_ed R: pkg_installed_emacs24_bin_common R: pkg_installed_evince_common R: pkg_installed_elinks_data R: pkg_installed_eject R: pkg_installed_emacs24_common_non_dfsg R: Classes for package names and versions that are installed: R: pkg_installed_eog_3_16_3_1ubuntu2_1 R: pkg_installed_emacs24_bin_common_24_5_1_1ubuntu2 R: pkg_installed_efibootmgr_0_12_4 R: pkg_installed_emacs_46_1 R: pkg_installed_eject_2_1_5_deb1_cvs20081104_13_1 R: pkg_installed_elinks_data_0_12_pre6_10 R: pkg_installed_enigmail_2_1_8_2_0ubuntu1 R: pkg_installed_evince_common_3_16_1_0ubuntu1 R: pkg_installed_emacs24_common_24_5_1_1ubuntu2 R: pkg_installed_elinks_0_12_pre6_10 R: pkg_installed_evince_3_16_1_0ubuntu1 R: pkg_installed_evolution_data_server_3_16_5_1ubuntu3 R: pkg_installed_enfuse_4_1_3_dfsg_2build1 R: pkg_installed_emacs24_24_5_1_1ubuntu2 R: pkg_installed_emacsen_common_2_0_8 R: pkg_installed_emacs24_common_non_dfsg_24_4_1_2 R: pkg_installed_ethtool_1_3_16_1 R: pkg_installed_evolution_data_server_common_3_16_5_1ubuntu3 R: pkg_installed_empathy_common_3_12_10_0ubuntu2 R: pkg_installed_exo_utils_0_10_7_1 R: pkg_installed_espeak_data_1_48_04_dfsg_1 R: pkg_installed_enblend_4_1_3_dfsg_2build1 R: pkg_installed_enchant_1_6_0_10_1build1 R: pkg_installed_e2fsprogs_1_42_12_1ubuntu2 R: pkg_installed_evolution_data_server_online_accounts_3_16_5_1ubuntu3 R: pkg_installed_ed_1_10_2 R: pkg_installed_e2fslibs_1_42_12_1ubuntu2 R: pkg_installed_example_content_48
Parameterized bundle to deifne namespace scoped class if packagesmatching() finds matches on package name.
Here is a parameterized bundle that can be used to define a class if any package on the system is found by packagesmatching():
bundle agent main { methods: "Define class if any packages installed matching emacs" usebundle => package_exists( "emacs" ); vars: "p" slist => classesmatching( ".*", "package_exists" ); reports: "Found class $(p)"; } bundle agent package_exists(pkg) # This code is based on the example code in https://tracker.mender.io/browse/CFE-2346 { vars: "p" data => packagesmatching( $(pkg), ".*", ".*", ".*" ); "l" int => length(p); classes: "package_exists_$(pkg)" expression => isgreaterthan( $(l), 0), meta => { "package_exists" }, scope => "namespace"; }
R: Found class package_exists_emacs
Beware your search may match more than you want.
bundle agent main { methods: "Define class if any packages installed starting with e" usebundle => package_exists( "e.*" ); vars: "p" slist => classesmatching( ".*", "package_exists" ); reports: "Found class $(p)"; } bundle agent package_exists(pkg) # This code is based on the example code in https://tracker.mender.io/browse/CFE-2346 { vars: "p" data => packagesmatching( $(pkg), ".*", ".*", ".*" ); "l" int => length(p); classes: "package_exists_$(pkg)" expression => isgreaterthan( $(l), 0), meta => { "package_exists" }, scope => "namespace"; }
Because I have at least one package installed that starts with e I get the class package_exists_e__.
R: Found class package_exists_e__
Attachments
Issue Links
- relates to
-
CFE-1963 Request for a way to check if a package is installed
-
- Rejected
-