Skip to content

Commit

Permalink
Fixes #8952: Add generic methods using new package promises
Browse files Browse the repository at this point in the history
  • Loading branch information
amousset committed Sep 9, 2016
1 parent 6b3fe1e commit d6dc5a2
Show file tree
Hide file tree
Showing 7 changed files with 1,357 additions and 0 deletions.
38 changes: 38 additions & 0 deletions tree/20_cfe_basics/package_lib.cf
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#####################################################################################
# Copyright 2016 Normation SAS
#####################################################################################
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#####################################################################################

# @agent_version >=3.7
#
# This collection of bodies configure the package modules
# As it require the new package modules introduced in 3.7, we need to load it only on CFEngine 3.7.

body package_module apt_get
{
# Query package updates only every 24 hours.
query_updates_ifelapsed => "1440";
# Query installed packages every 2 hours.
query_installed_ifelapsed => "240";
}

body package_module yum
{
# Query package updates only every 24 hours.
query_updates_ifelapsed => "1440";
# Query installed packages every 2 hours.
query_installed_ifelapsed => "240";
}
196 changes: 196 additions & 0 deletions tree/30_generic_methods/_package_state.cf
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
#####################################################################################
# Copyright 2016 Normation SAS
#####################################################################################
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#####################################################################################

# @name Package state
# @agent_version >=3.7
# @description Enforce the state of a package
# @documentation See package_present and package_absent for documentation.
# @parameter name Name of the package, or path to a local package if state is present
# @parameter version Version of the package, can be "latest" for latest version or "any" for any version (defaults to "any")
# @parameter architecture Architecture of the package, can be an architecture name or "default" (defaults to "default")
# @parameter provider Package provider to use, can be "yum", "apt", "pkg" or "default" for system default package manager (defaults to "default")
#
# @class_prefix package_${state}
# @class_parameter name

bundle agent package_state(name, version, architecture, provider, state)
{

vars:
"canonified_name" string => canonify("${name}");
"old_class_prefix" string => "package_${state}_${canonified_name}";
"promisers" slist => { @{this.callers_promisers}, cf_null }, policy => "ifdefined";
"class_prefix" string => canonify(join("_", "promisers"));
"args" slist => { "${name}", "${version}", "${architecture}", "${provider}", "${state}" };

# Build string vars used for reporting

# State
state_present::
"state_descritpion" string => "Presence";
!state_present::
"state_descritpion" string => "Absence";

# Architecture
architecture_specified::
"architecture_description" string => " for ${architecture} architecture ";
!architecture_specified::
"architecture_description" string => " ";

# Version
version_latest::
"version_description" string => "in latest available version";
!version_specified::
"version_description" string => "in any version";
version_specified.!version_latest::
"version_description" string => "in version ${version}";

defaults:
"version" string => "any", if_match_regex => "";
"architecture" string => "default", if_match_regex => "";
"provider" string => "default", if_match_regex => "";

classes:
"version_latest" expression => strcmp("latest", "${version}");
# As "latest" is understood by package promises,
# the only special case is "any", which maps to
# no specified version in the promise
"version_specified" not => strcmp("any", "${version}");

"state_present" expression => strcmp("present", "${state}");

# If architecture is not specified, do not add it to the promise.
# The package module will pick the default one for the local platform
"architecture_specified" not => strcmp("default", "${architecture}");

# Select the right package manager
# Always use the specified one, and select a default based on the OS
"default_provider_specified" expression => strcmp("default", "${provider}");
"use_apt_provider" expression => strcmp("apt", "${provider}");
"use_yum_provider" expression => strcmp("yum", "${provider}");
"use_pkg_provider" expression => strcmp("pkg", "${provider}");
default_provider_specified.debian::
"use_apt_provider" expression => "any";
default_provider_specified.redhat::
"use_yum_provider" expression => "any";
default_provider_specified.freebsd::
"use_pkg_provider" expression => "any";

packages:

#### apt ####

use_apt_provider.architecure_specified.version_specified::
"${name}"
policy => "${state}",
package_module => apt_get,
architecture => "${architecture}",
version => "${version}",
classes => classes_generic_two("${old_class_prefix}", "${class_prefix}");

use_apt_provider.architecure_specified.!version_specified::
"${name}"
policy => "${state}",
package_module => apt_get,
architecture => "${architecture}",
classes => classes_generic_two("${old_class_prefix}", "${class_prefix}");

use_apt_provider.!architecure_specified.version_specified::
"${name}"
policy => "${state}",
package_module => apt_get,
version => "${version}",
classes => classes_generic_two("${old_class_prefix}", "${class_prefix}");

use_apt_provider.!architecure_specified.!version_specified::
"${name}"
policy => "${state}",
package_module => apt_get,
classes => classes_generic_two("${old_class_prefix}", "${class_prefix}");

#### yum ####

use_yum_provider.architecure_specified.version_specified::
"${name}"
policy => "${state}",
package_module => yum,
architecture => "${architecture}",
version => "${version}",
classes => classes_generic_two("${old_class_prefix}", "${class_prefix}");

use_yum_provider.architecure_specified.!version_specified::
"${name}"
policy => "${state}",
package_module => yum,
architecture => "${architecture}",
classes => classes_generic_two("${old_class_prefix}", "${class_prefix}");

use_yum_provider.!architecure_specified.version_specified::
"${name}"
policy => "${state}",
package_module => yum,
version => "${version}",
classes => classes_generic_two("${old_class_prefix}", "${class_prefix}");

use_yum_provider.!architecure_specified.!version_specified::
"${name}"
policy => "${state}",
package_module => yum,
classes => classes_generic_two("${old_class_prefix}", "${class_prefix}");

#### pkg ####

use_pkg_provider.architecure_specified.version_specified::
"${name}"
policy => "${state}",
package_module => pkg,
architecture => "${architecture}",
version => "${version}",
classes => classes_generic_two("${old_class_prefix}", "${class_prefix}");

use_pkg_provider.architecure_specified.!version_specified::
"${name}"
policy => "${state}",
package_module => pkg,
architecture => "${architecture}",
classes => classes_generic_two("${old_class_prefix}", "${class_prefix}");

use_pkg_provider.!architecure_specified.version_specified::
"${name}"
policy => "${state}",
package_module => pkg,
version => "${version}",
classes => classes_generic_two("${old_class_prefix}", "${class_prefix}");

use_pkg_provider.!architecure_specified.!version_specified::
"${name}"
policy => "${state}",
package_module => pkg,
classes => classes_generic_two("${old_class_prefix}", "${class_prefix}");

methods:

(use_apt_provider|use_yum_provider|use_pkg_provider)::
"reports" usebundle => _log("${state_descritpion} of package ${name}${architecture_description}${version_description}", "${old_class_prefix}", "${class_prefix}", @{args});

!(use_apt_provider|use_yum_provider|use_pkg_provider)::
"force failure class" usebundle => _classes_failure("${class_prefix}");
"force failure class" usebundle => _classes_failure("${old_class_prefix}");
"report failure" usebundle => _log("Presence of package ${name} - package managers other than yum and apt are not currently supported", "${old_class_prefix}", "${class_prefix}", @{args});

}
46 changes: 46 additions & 0 deletions tree/30_generic_methods/package_absent.cf
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#####################################################################################
# Copyright 2016 Normation SAS
#####################################################################################
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#####################################################################################

# @name Package absent
# @agent_version >=3.7
# @description Enforce the absence of a package
# @documentation *Example*:
# ```
# methods:
# "any" usebundle => package_absent("postgresql", "9.1", "x86_64", "");
# "any" usebundle => package_absent("postgresql", "any", "", "");
# "any" usebundle => package_absent("postgresql", "", "", "");
# ```
#
# @parameter name Name of the package
# @parameter version Version of the package or "any" for any version (defaults to "any")
# @parameter_constraint version "allow_empty_string" : true
# @parameter architecture Architecture of the package, can be an architecture name or "default" (defaults to "default")
# @parameter_constraint architecture "allow_empty_string" : true
# @parameter provider Package provider to use, can be "yum", "apt", "pkg" or "default" for system default package manager (defaults to "default")
# @parameter_constraint provider "allow_empty_string" : true
# @parameter_constraint provider "select" : [ "", "default", "yum", "apt", "pkg" ]
#
# @class_prefix package_absent
# @class_parameter name

bundle agent package_absent(name, version, architecture, provider)
{
methods:
"enforce absence" usebundle => package_state("${name}", "${version}", "${architecture}", "${provider}", "absent");
}
82 changes: 82 additions & 0 deletions tree/30_generic_methods/package_present.cf
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
#####################################################################################
# Copyright 2016 Normation SAS
#####################################################################################
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#####################################################################################

# @name Package present
# @agent_version >=3.7
# /!\ Please be careful to maintain this documentation in sync with package_absent
# @description Enforce the presence of a package
# @documentation This method manages packages using a package manager
#
# #### Package options
#
# There is only one mandatory parameter, which is the package name to install.
# When it should be installed from a local package, you need to specify the full path to the package as name.
#
# The version parameter allows specifying a version you want installed.
# It should be the complete versions string as used by the used package manager.
# This parameter allows two special values:
#
# * *any* which is the default value, and is satisfied by any version of the given package
# * *latest* which will ensure, at each run, that the package is at the latest available version.
#
# #### Package providers
#
# This method supports several package managers. You can specify the package manager
# you want to use or let the method choose the default for the local system.
#
# The package providers include a caching systems for package information.
# The package lists (installed, available and available updates) are only updated
# when the cache expires, or when an operation is made by the agent on packages.
#
# ##### apt
#
# This package provider uses apt/dpkg to manage packages on the system.
#
# ##### rpm
#
# This package provider uses yum/rpm to manage packages on the system. It
# is able to downgrade packages when specifying an older version.
#
# ##### Name
#
# plop
#
# ```
# methods:
# "any" usebundle => package_present("postgresql", "9.1", "x86_64", "");
# "any" usebundle => package_present("postgresql", "latest", "", "");
# "any" usebundle => package_present("postgresql", "", "", "");
# ```
#
# @parameter name Name of the package, or path to a local package
# @parameter version Version of the package, can be "latest" for latest version or "any" for any version (defaults to "any")
# @parameter_constraint version "allow_empty_string" : true
# @parameter architecture Architecture of the package, can be an architecture name or "default" (defaults to "default")
# @parameter_constraint architecture "allow_empty_string" : true
# @parameter provider Package provider to use, can be "yum", "apt", "pkg" or "default" for system default package manager (defaults to "default")
# @parameter_constraint provider "allow_empty_string" : true
# @parameter_constraint provider "select" : [ "", "default", "yum", "apt", "pkg" ]
#
# @class_prefix package_present
# @class_parameter name

bundle agent package_present(name, version, architecture, provider)
{
methods:
"enforce presence" usebundle => package_state("${name}", "${version}", "${architecture}", "${provider}", "present");
}
Loading

0 comments on commit d6dc5a2

Please sign in to comment.