Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: master
1100 lines (833 sloc) 35.678 kb
################################################################################
#
# Yale Cfengine3 promise body library
#
# Defines bodies and bundles for reuse in Yale Cfengine policy.
#
# Use tremendous care in editing this file, as it is responsible for the inner
# workings of all Cfengine operations at Yale. Any candidates for addition/
# modification to this file should first be very well-vetted on test clients.
#
# Wherever it was reasonable to do so, sets of body types were created as
# follows:
#
# - one full-featured, parameterized body, intended to be as flexible as
# possible without imposing function. For example, if inclusion of a
# particular attribute as a parameter did not have a sane allowed no-op
# value, it was omitted.
# - additional bodies that match known Yale production use cases. Where there
# is a single body intended for general_purpose use, we have named it
# "<foo>_std".
#
# -JG, 20101008
#
################################################################################
################################################################################
#
# process_count bodies
#
################################################################################
# Count the number of processes in the process table matching regex "name". If
# the number lies between the values "lower" and "upper", enable class
# "<name>_in_range"; otherwise "<name>_out_of_range".
#
# Useful for restarting dead and spawning-out-of-control processes.
body process_count check_range( name, lower, upper ) {
match_range => irange("$(lower)","$(upper)");
in_range_define => { "$(name)_in_range" };
out_of_range_define => { "$(name)_out_of_range" };
}
################################################################################
#
# process_select bodies
#
# These act as filters for processes to which to send signals.
#
################################################################################
# Filter-type bodies have no sensible defaults nor full-featured versions; they
# are inherently special-purpose. So, we don't apply our usual strategy of
# creating a full-featured and standard version in this case.
# Find processes that match the regex "command". The "process_result" attribute
# is an boolean expression that otherwise might be more complicated; in this
# case, just this single selection.
body process_select processes_named ( command ) {
command => "$(command)";
process_result => "command";
}
# 20101008 JG removed commented-out body
# "process_select processes_older_than_x_sec_named ( seconds, command )"
# Requires use of the ago() function, which we were unable to get
# working reliably; investigate later and file bugs if necessary.
################################################################################
#
# delete bodies
#
# The bodies formerly known as "tidy"
#
################################################################################
# Full-featured body
body delete deletesettings ( dirlinks, rmdirs ) {
# Preserve or delete symlinks?
dirlinks => "$(dirlinks)";
# Preserve or delete directories?
rmdirs => "$(rmdirs)";
}
# Std body
body delete deletesettings_std {
dirlinks => "delete";
rmdirs => "false";
}
################################################################################
#
# edit_defaults bodies
#
# Address handling of files manipulated by edit_line (formerly
# editfiles) bundles.
#
################################################################################
body edit_defaults editsettings( edit_backup, empty_file_before_editing,
max_file_size ) {
# Make a backup of the file before editing?
edit_backup => "$(edit_backup)";
# Clear it before editing?
empty_file_before_editing => "$(empty_file_before_editing)";
# Decline to edit, if size exceeds this, in bytes
# Note: Supports orders-of-magnitude shorthand (i.e. "100K")
max_file_size => "$(max_file_size)";
}
body edit_defaults editsettings_std( edit_backup ) {
edit_backup => "$(edit_backup)";
empty_file_before_editing => "false";
max_file_size => "100K";
}
################################################################################
#
# edit_fields bodies
#
# Bodies for manipulation of tabulated files.
#
################################################################################
body edit_field editfield_settings(allow_blank_fields, extend_fields,
field_operation, field_separator, field_value, select_field,
start_fields_from_zero, value_separator) {
# Allow blank fields in a line (do not purge)?
allow_blank_fields => "$(allow_blank_fields)";
# Add new fields at end of line, if necessary, to complete edit
extend_fields => "$(extend_fields)";
# The method by which to edit a field in multi-field/column editing of
# tabular files. See reference guide for options; default is 'append'
field_operation => "$(field_operation)";
# Regular expression used to separate fields in a line
field_separator => "$(field_separator)";
# Set field to...
field_value => "$(field_value)";
# Integer index of field being edited
select_field => "$(select_field)";
# First field starts @ 0 instead of 1? Useful for coordinated iteration
# over arrays.
start_fields_from_zero => "$(start_fields_from_zero)";
# Character separator for subfields inside the selected field
# (i.e., ',' in /etc/group, where ':' is the field separator
value_separator => "$(value_separator)";
}
body edit_field editfield_settings_std(field_separator, select_field,
field_value, field_operation) {
field_separator => "$(field_separator)";
select_field => "$(select_field)";
value_separator => ",";
field_value => "$(field_value)";
field_operation => "$(field_operation)";
extend_fields => "true";
allow_blank_fields => "true";
}
################################################################################
#
# edit_line bundles and related bodies
#
################################################################################
# Equivalent of v2's AppendIfNoSuchLine
bundle edit_line append_if_no_such_line( line ) {
insert_lines:
"$(line)";
}
# Delete lines containing any of the regular expressions in slist "regexes"
bundle edit_line delete_lines_that_contain ( regexes ) {
delete_lines:
".*"
delete_select => delete_lines_containing( @(regexes) );
}
# Delete lines matching any of the regular expressions in slist "regexes"
bundle edit_line delete_lines_that_match ( regexes ) {
delete_lines:
".*"
delete_select => delete_lines_matching( @(regexes) );
}
# These bodies support their equivalent bundles. This looks like
# redundancy, but it isn't; bundles can be more complex, but we
# deliberately keep them very simple so we have reusable building
# blocks.
body delete_select delete_lines_containing( regexes ) {
delete_if_contains_from_list => { @(regexes) };
}
body delete_select delete_lines_matching( regexes ) {
delete_if_match_from_list => { @(regexes) };
}
################################################################################
#
# perms bodies
#
# Set file permissions.
#
################################################################################
# Full-featured body
body perms permissions( mode, owners, group, rxdirs ) {
mode => "$(mode)";
owners => { "$(owners)" };
groups => { "$(group)" };
# true/false add execute flag for directories if read flag is set
rxdirs => "$(rxdirs)";
}
# This should only be used if there's a compelling technical reason to do so.
# Otherwise, mode, owner and group should be explicitly set via the
# mode_owner_group body.
body perms mode( mode ) {
mode => "$(mode)";
}
# This should only be used if there's a compelling technical reason to do so.
# Otherwise, mode, owner and group should be explicitly set via the
# mode_owner_group body.
body perms owner_group( owners, group ) {
owners => { "$(owners)" };
groups => { "$(group)" };
}
# This should only be used if there's a compelling technical reason to do so.
# Otherwise, mode, owner and group should be explicitly set via the
# mode_owner_group body.
body perms mode_owner( mode, owners ) {
mode => "$(mode)";
owners => { "$(owners)" };
}
# Standard body
body perms mode_owner_group( mode, owners, group ) {
mode => "$(mode)";
owners => { "$(owners)" };
groups => { "$(group)" };
}
################################################################################
#
# copy_from bodies
#
################################################################################
# Full-featured body
body copy_from copy( source, servers, compare, copy_backup, encrypt,
check_root, portnumber, preserve, purge, stealth, verify ) {
# Server-side file location
source => "$(source)";
# Slist of motherships to attempt to copy from. If the first fails, the
# second will be attempted.
servers => { "@(servers)" };
# Method of determining whether a backup is necessary - mtime, hash, bitwise
# comparison, etc.
compare => "$(compare)";
# Method of backup (true/false/timestamp)
copy_backup => "$(copy_backup)";
# Pass the file over SSL? Leaving in this option in case we want to transfer
# large non-secret files in the future
encrypt => "$(encrypt)";
# Check permissions on the root directory when depth_search?
# Default=false
check_root => "$(check_root)";
# Connect to servers using this port (default=5308)
portnumber => "$(portnumber)";
# Maintain mode, owner and group from server-side copy of the file?
preserve => "$(preserve)";
# Wipe out contents of directory first, when doing a recursive copy?
purge => "$(purge)";
# Preserve file access and modification times on the promiser files?
stealth => "$(stealth)";
# Confirm that temporary landing file checksum matches server-side checksum
# before copying file into place?
verify => "$(verify)";
}
# Standard body
body copy_from copy_std( source, servers, purge, copy_backup ) {
source => "$(source)";
servers => { "@(servers)" };
compare => "digest";
purge => "$(purge)";
encrypt => "true";
verify => "true";
copy_backup => "$(copy_backup)";
}
################################################################################
#
# action bodies
#
# Describe general-purpose Cfengine features - attributes that apply to
# all promises, like logging, action policy (fix/warn/no-op), informing,
# etc.
#
################################################################################
# Full-featured body
body action actionsettings( action_policy, ifelapsed, expireafter,
log_level, audit, background, report_level) {
# What to do when a promiser doesn't conform with policy (fix/warn/nop)
action_policy => "$(action_policy)";
# Waiting period required before reattempting the same promise, in minutes.
# Default=1.
ifelapsed => "$(ifelapsed)";
# Put a bullet in promises from prior agent runs if they're found to be still
# lying around after this time, in minutes. Default=1.
expireafter => "$(expireafter)";
# Reporting level sent to syslog (inform/verbose/error/log).
log_level => "$(log_level)";
# Record detailed information in the audit log about whether this promise was
# kept?
audit => "$(audit)";
# Send this promise to the background?
background => "$(background)";
# Reporting (stdout) level. When agent is run non-interactively, this is the
# setting that affects how noisy mail will be (inform/verbose/error/log).
report_level => "$(report_level)";
}
# Standard body
body action actionsettings_fix_inform( report_level ) {
action_policy => "fix";
expireafter => "120";
log_level => "inform";
report_level => "$(report_level)";
}
# Use when you want to repair a promise but send nothing to stdout (=no mail).
body action actionsettings_fix_silent {
action_policy => "fix";
expireafter => "120";
log_level => "inform";
}
# Use when you don't want a promise to be repaired; just scream if something's
# amiss. Good for the occasional case in which we want to manually intervene
# on a particular erroneous system state.
body action actionsettings_warn_inform( report_level ) {
action_policy => "warn";
expireafter => "120";
log_level => "inform";
report_level => "$(report_level)";
}
# Log regardless of whether the promise succeeds. Created originally so we can
# log command execution regardless of return value. For example, we always want
# to know that a command has been run to take action on a class that gets
# defined due to an error condition.
body action actionsettings_fix_inform_noisylogs( report_level ) {
action_policy => "fix";
expireafter => "120";
log_level => "verbose";
report_level => "$(report_level)";
}
################################################################################
#
# depth_search bodies
#
################################################################################
# "searchsettings" is, admittedly, a kind of weird name, and it's not
# particularly consistent with the others in Yale's library (if
# searchsettings, why not copysettings?) But to me, just "search"
# suggests the thing you're actually looking for, and that's not this;
# depth_search is already a keyword, and search_depth is easily confused
# with depth_search.... -JG, 20101011
body depth_search searchsettings( depth, exclude_dirs, include_basedir,
include_dirs, rmdeadlinks, traverse_links, xdev ) {
# How far should we recurse? (0/n/inf)
depth => "$(depth)";
# Slist of regexes of directory names to exclude from promise
exclude_dirs => { "@(exclude_dirs)" };
# Include base-level directory in promise?
include_basedir => "$(include_basedir)";
# Slist of regexes of directory names to include in promise
include_dirs => { "$(include_dirs)" };
# Kill links that point nowhere?
rmdeadlinks => "$(rmdeadlinks)";
# Follow links? (Dangerous - use with caution)
traverse_links => "$(traverse_links)";
# Exclude directories that live on different devices?
xdev => "$(xdev)";
}
body depth_search searchsettings_std( depth, include_basedir ) {
depth => "$(depth)";
include_basedir => "$(include_basedir)";
}
# Another typical Yale use case - allows for recursive copies with dir
# exclusions (.svn, for example).
body depth_search searchsettings_exclude( depth, exclude_dirs,
include_basedir ) {
depth => "$(depth)";
exclude_dirs => { "@(exclude_dirs)" };
include_basedir => "$(include_basedir)";
}
################################################################################
#
# file_select bodies
#
# file_select is a filter - only apply the promise to files matching the
# condition listed in the boolean expression "file_result"
#
################################################################################
# Find files by leaf_name
body file_select files_matching_leaf( leaf_name, file_types ) {
leaf_name => { "@(leaf_name)" };
file_types => { "@(file_types)" };
file_result => "leaf_name.file_types";
}
# Find files by not leaf_name
body file_select files_matching_not_leaf( leaf_name, file_types ) {
leaf_name => { "@(leaf_name)" };
file_types => { "@(file_types)" };
file_result => "!leaf_name.file_types";
}
# Find files by path_name
### NOTE!!! path_name regexes are absolute (must start with '/')! ###
body file_select files_matching_path( path_name, file_types ) {
path_name => { "@(path_name)" };
file_types => { "@(file_types)" };
file_result => "path_name.file_types";
}
# Find files by not path_name
### NOTE!!! path_name regexes are absolute (must start with '/')! ###
body file_select files_matching_not_path( path_name, file_types ) {
path_name => { "@(path_name)" };
file_types => { "@(file_types)" };
file_result => "!path_name.file_types";
}
# Find files by path_name and leaf_name
### NOTE!!! path_name regexes are absolute (must start with '/')! ###
body file_select files_matching_path_and_leaf( path_name, leaf_name,
file_types ) {
path_name => { "@(path_name)" };
leaf_name => { "@(leaf_name)" };
file_types => { "@(file_types)" };
file_result => "leaf_name.path_name.file_types";
}
# Find files by path_name and not leaf_name
### NOTE!!! path_name regexes are absolute (must start with '/')! ###
body file_select files_matching_path_and_not_leaf( path_name, leaf_name,
file_types ) {
path_name => { "@(path_name)" };
leaf_name => { "@(leaf_name)" };
file_types => { "@(file_types)" };
file_result => "!leaf_name.path_name.file_types";
}
# Find files by not path_name and leaf_name
### NOTE!!! path_name regexes are absolute (must start with '/')! ###
body file_select files_matching_not_path_and_leaf( path_name, leaf_name,
file_types ) {
path_name => { "@(path_name)" };
leaf_name => { "@(leaf_name)" };
file_types => { "@(file_types)" };
file_result => "leaf_name.!path_name.file_types";
}
# Find files by not path_name and not leaf_name
### NOTE!!! path_name regexes are absolute (must start with '/')! ###
body file_select files_matching_not_path_and_not_leaf( path_name, leaf_name,
file_types ) {
path_name => { "@(path_name)" };
leaf_name => { "@(leaf_name)" };
file_types => { "@(file_types)" };
file_result => "!leaf_name.!path_name.file_types";
}
# Use case: tidies for files with mtime X and matching a particular regex
### NOTE!!! path_name regexes are absolute (must start with '/')! ###
body file_select files_older_than_x_days( path_name, leaf_name, days,
file_types ) {
path_name => { "@(path_name)" };
leaf_name => { "@(leaf_name)" };
mtime => irange(0, ago(0,0,"$(days)",0,0,0));
file_types => { "@(file_types)" };
file_result => "leaf_name.path_name.mtime.file_types";
}
# Use case: find files owned by a particular user - potentially
# for making deletions safer (only remove files owned by user X, not root)
body file_select files_with_owner( path_name, leaf_name, search_owners,
file_types ) {
path_name => { "@(path_name)" };
leaf_name => { "@(leaf_name)" };
search_owners => { "@(search_owners)" };
file_types => { "@(file_types)" };
file_result => "leaf_name.path_name.owner.file_types";
}
################################################################################
#
# link_from bodies
#
# Create links.
#
################################################################################
# Full-featured body
body link_from link( link_children, link_type, source,
when_linking_children, when_no_source ) {
# Link all directory's children to source originals?
link_children => "$(link_children)";
# Type of link used (symlink/hardlink/relative/absolute/none)
# Default=symlink
link_type => "$(link_type)";
# Source file to which the link should point
source => "$(source)";
# Policy for overriding existing files when linking directories of
# children (alternative: "override_file")
when_linking_children => "$(when_linking_children)";
# Behaviour when the source file to link to does not exist
# (force/delete/nop)
when_no_source => "$(when_no_source)";
}
# Standard body
body link_from link_std( source ) {
link_children => "false";
link_type => "symlink";
source => "$(source)";
when_linking_children => "if_no_such_file";
when_no_source => "nop";
}
################################################################################
#
# contain bodies
#
################################################################################
# Note: exec_timeout will not interrupt /bin/sh, so if you want to set a timeout
# for a command, use the full-featured version with useshell set to false.
# Full-featured body
body contain container( useshell, umask, exec_owner, exec_group, exec_timeout,
chdir, chroot, preview, no_output ) {
useshell => "$(useshell)";
# Umask for files created by commands run with this container.
# Default: 077
umask => "$(umask)";
exec_owner => "$(exec_owner)";
exec_group => "$(exec_group)";
# Put a bullet in the command if it's been running for more than X sec
exec_timeout => "$(exec_timeout)";
# Run in this working directory
chdir => "$(chdir)";
# Run in a chroot jail at this path
chroot => "$(chroot)";
# Preview command when running in dry-run mode (cf-agent -n)?
preview => "$(preview)";
# Pipe stdout and stderr to /dev/null
no_output => "$(no_output)";
}
# Standard body
body contain container_std( exec_owner, no_output ) {
useshell => "true";
exec_owner => "$(exec_owner)";
exec_timeout => "60";
no_output => "$(no_output)";
}
# Container for long-running jobs - give them 15m
body contain container_longjob( exec_owner, no_output ) {
useshell => "true";
exec_owner => "$(exec_owner)";
exec_timeout => "900";
no_output => "$(no_output)";
}
################################################################################
#
# rename bodies
#
################################################################################
# Full-featured body
body rename rename_settings ( disable, disable_mode, disable_suffix,
newname ) {
# Automatically rename and remove permissions to foo.$(disable_suffix)?
# Default=false
disable => "$(disable)";
# Permissions to set when a file is disabled
disable_mode => "$(disable_mode)";
# String to append to filename when disabled. Default=".cf-disabled"
disable_suffix => "$(disable_suffix)";
}
# Strip file of permissions, but don't change its name
body rename disarm_file () {
disable_mode => "000";
disable => "false";
}
# Strip file of permisssions and change its name to foo.cf-disabled
body rename disable_file () {
disable_mode => "000";
disable => "true";
}
################################################################################
#
# classes bodies
#
################################################################################
# If this promise was repaired, turn on class x
body classes if_repaired(x) {
promise_repaired => { "$(x)" };
}
# Set class "yes" if the promise was repaired or kept; set class "no" if
# the promise couldn't be kept/repaired.
body classes if_success_failure(yes,no) {
promise_kept => { "$(yes)" };
promise_repaired => { "$(yes)" };
repair_failed => { "$(no)" };
repair_denied => { "$(no)" };
repair_timeout => { "$(no)" };
}
################################################################################
#
# chkconfig bundles
#
################################################################################
bundle agent chkconfig_on(service) {
classes:
"service_is_enabled"
expression => returnszero("/sbin/chkconfig --list $(service) 2>&1 | /bin/grep '[0-6]:on' > /dev/null", "useshell");
commands:
!service_is_enabled::
"/sbin/chkconfig $(service) on"
contain => container_std("root", true),
action => actionsettings_fix_inform_noisylogs("verbose");
}
bundle agent chkconfig_off(service) {
classes:
"service_is_enabled"
expression => returnszero("/sbin/chkconfig --list $(service) 2>&1 | /bin/grep '[0-6]:on' > /dev/null", "useshell");
commands:
service_is_enabled::
"/sbin/chkconfig $(service) off"
contain => container_std("root", true),
action => actionsettings_fix_inform_noisylogs("verbose");
}
bundle agent chkconfig_add(service) {
classes:
"service_is_in_chkconfig"
expression => returnszero("/sbin/chkconfig --list $(service) > /dev/null 2>&1", "useshell");
commands:
# Here, we don't test for the existence or validity of /etc/init.d/<service>
# chkconfig will error and yell if the init script does not support chkconfig
!service_is_in_chkconfig::
"/sbin/chkconfig --add $(service)"
contain => container_std("root", true),
action => actionsettings_fix_inform_noisylogs("verbose");
}
bundle agent chkconfig_del(service) {
classes:
"service_is_in_chkconfig"
expression => returnszero("/sbin/chkconfig --list $(service) > /dev/null 2>&1", "useshell");
commands:
service_is_in_chkconfig::
"/sbin/chkconfig --del $(service)"
contain => container_std("root", true),
action => actionsettings_fix_inform_noisylogs("verbose");
}
################################################################################
#
# Templatization bundles
#
################################################################################
# Draw in a template file, agent-side, and expand any cf3 variables embedded
# in it; write that copy into the promiser of a files promise.
# Make sure to use the full-featured editsettings body in conjunction with this
# bundle, to take advantage of "empty_file_before_editing"
# Note that all vars embedded in the template must be scoped to the bundle they
# reside in - i.e. $(mybundle.myvar)
bundle edit_line expand_variables(templatefile) {
insert_lines:
"$(templatefile)"
insert_type => "file",
expand_scalars => "true";
}
# Populates $(file).staging based on a template $(file).template at $(prefix) on
# host $(fileserver). This bundle is to be used as a tester for bundle
# template_std - should never be used in production.
#
# Use this to stand up $(file).staging client-side; once $(file).staging looks
# like $(file) should look, switch template_std.
bundle agent template_staging_std(file, prefix, fileserver, mode, owner, group) {
files:
"$(file).template"
copy_from => copy_std("$(prefix)$(file).template",
"$(fileserver)", "false", "timestamp"),
perms => mode_owner_group("$(mode)", "$(owner)", "$(group)"),
action => actionsettings_fix_inform("inform");
"$(file).staging"
perms => mode_owner_group("$(mode)", "$(owner)", "$(group)"),
create => "true",
edit_line => expand_variables("$(file).template"),
# Using the full-featured body here because we need to empty the file
# client-side first.
edit_defaults => editsettings("timestamp", "true", "100K"),
action => actionsettings_fix_inform("inform");
}
# Populates $(file) based on a template $(file).template at $(prefix) on host
# $(fileserver). Note that $(file).template, as well as any Cfengine-created
# backup copies of $(file) and $(file).template land in the same dir as
# $(file), so this bundle is inappropriate for use where those files would be
# grokked by a process (/etc/httpd/conf.d, for example).
bundle agent template_std(file, prefix, fileserver, mode, owner, group) {
files:
"$(file).template"
copy_from => copy_std("$(prefix)$(file).template",
"$(fileserver)", "false", "timestamp"),
perms => mode_owner_group("$(mode)", "$(owner)", "$(group)"),
action => actionsettings_fix_inform("inform");
"$(file)"
perms => mode_owner_group("$(mode)", "$(owner)", "$(group)"),
create => "true",
edit_line => expand_variables("$(file).template"),
# Using the full-featured body here because we need to empty the file
# client-side first.
edit_defaults => editsettings("timestamp", "true", "100K"),
action => actionsettings_fix_inform("inform");
}
# Populates $(file) based on a template $(template_file).template at $(prefix) on host
# $(fileserver). Note that $(template_file).template, as well as any Cfengine-created
# backup copies of $(file) and $(template_file).template land in the same dir as
# $(file), so this bundle is inappropriate for use where those files would be
# grokked by a process (/etc/httpd/conf.d, for example).
bundle agent template_std_full(template_file, file, prefix, fileserver, mode, owner, group) {
files:
"$(template_file)"
copy_from => copy_std("$(prefix)$(template_file).template",
"$(fileserver)", "false", "timestamp"),
perms => mode_owner_group("$(mode)", "$(owner)", "$(group)"),
action => actionsettings_fix_inform("inform");
"$(file)"
perms => mode_owner_group("$(mode)", "$(owner)", "$(group)"),
create => "true",
edit_line => expand_variables("$(template_file)"),
# Using the full-featured body here because we need to empty the file
# client-side first.
edit_defaults => editsettings("timestamp", "true", "100K"),
action => actionsettings_fix_inform("inform");
}
# Populates $(file) based on a template $(file).template at $(prefix) on host
# $(fileserver).
#
# This leaves nothing in dest workdirs on host apart from $(file).
# No dot-template, no dot-cf-before-edit, no timestamp, no backup are kept there.
# Dot-templates stashed in /var/cfengine/templates.
bundle agent template_std_clean(file, prefix, fileserver, mode, owner, group) {
files:
"/var/cfengine/templates/$(file).template"
copy_from => copy_std("$(prefix)$(file).template",
"$(fileserver)", "false", "false"),
perms => mode_owner_group("$(mode)", "$(owner)", "$(group)"),
action => actionsettings_fix_inform("inform");
"$(file)"
perms => mode_owner_group("$(mode)", "$(owner)", "$(group)"),
create => "true",
edit_line => expand_variables("/var/cfengine/templates/$(file).template"),
# Using the full-featured body here because we need to empty the file
# client-side first.
edit_defaults => editsettings("false", "true", "100K"),
action => actionsettings_fix_inform("inform");
}
################################################################################
#
# Package management bodies
#
################################################################################
## You *must* specify "package_version" in any promises where this body is used!
## Otherwise, the version gets set to "*", which causes Cfengine to refer to
## the package in terms of package-* (see package_name_convention) - which
## could install or delete all kinds of packages unintentionally.
body package_method yum_rpm_exact
{
package_changes => "individual";
package_list_command => "/bin/rpm -qa --qf '%{name} %{version}-%{release} %{arch}\n'";
package_list_name_regex => "^(\S+?)\s\S+?\s\S+$";
package_list_version_regex => "^\S+?\s(\S+?)\s\S+$";
package_list_arch_regex => "^\S+?\s\S+?\s(\S+)$";
# Force list of installed packages to update on every agent run
package_list_update_ifelapsed => "0";
package_installed_regex => ".*";
package_name_convention => "$(name)-$(version).$(arch)";
package_add_command => "/usr/bin/yum -y install";
package_update_command => "/usr/bin/yum -y update";
package_delete_command => "/usr/bin/yum -y erase";
package_verify_command => "/bin/rpm -V";
}
## You *must* specify "package_version" in any promises where this body is used!
## Otherwise, the version gets set to "*", which causes Cfengine to refer to
## the package in terms of package-* (see package_name_convention) - which
## could install or delete all kinds of packages unintentionally.
body package_method yum_rpm_exact_enablerepo(repo)
{
package_changes => "individual";
package_list_command => "/bin/rpm -qa --qf '%{name} %{version}-%{release} %{arch}\n'";
package_list_name_regex => "^(\S+?)\s\S+?\s\S+$";
package_list_version_regex => "^\S+?\s(\S+?)\s\S+$";
package_list_arch_regex => "^\S+?\s\S+?\s(\S+)$";
# Force list of installed packages to update on every agent run
package_list_update_ifelapsed => "0";
package_installed_regex => ".*";
package_name_convention => "$(name)-$(version).$(arch)";
package_add_command => "/usr/bin/yum -y install --enablerepo=$(repo)";
package_update_command => "/usr/bin/yum -y update --enablerepo=$(repo)";
package_delete_command => "/usr/bin/yum -y erase";
package_verify_command => "/bin/rpm -V";
}
## Do not use package_policy "addupdate" or "update" with this body, since
## package_name_convention is "$(name)" rather than "$(name)-$(version)" we do
## not want "yum -y update wireshark" being run blindly.
body package_method yum_rpm_byname
{
package_changes => "individual";
package_list_command => "/bin/rpm -qa --qf '%{name} %{version}-%{release} %{arch}\n'";
package_list_name_regex => "^(\S+?)\s\S+?\s\S+$";
package_list_version_regex => "^\S+?\s(\S+?)\s\S+$";
package_list_arch_regex => "^\S+?\s\S+?\s(\S+)$";
# Force list of installed packages to update on every agent run
package_list_update_ifelapsed => "0";
package_installed_regex => ".*";
package_name_convention => "$(name)";
package_add_command => "/usr/bin/yum -y install";
package_update_command => "/usr/bin/yum -y update";
package_delete_command => "/usr/bin/yum -y erase";
package_verify_command => "/bin/rpm -V";
}
## Do not use package_policy "addupdate" or "update" with this body, since
## package_name_convention is "$(name)" rather than "$(name)-$(version)" we do
## not want "yum -y update wireshark" being run blindly.
body package_method yum_rpm_byname_enablerepo(repo)
{
package_changes => "individual";
package_list_command => "/bin/rpm -qa --qf '%{name} %{version}-%{release} %{arch}\n'";
package_list_name_regex => "^(\S+?)\s\S+?\s\S+$";
package_list_version_regex => "^\S+?\s(\S+?)\s\S+$";
package_list_arch_regex => "^\S+?\s\S+?\s(\S+)$";
# Force list of installed packages to update on every agent run
package_list_update_ifelapsed => "0";
package_installed_regex => ".*";
package_name_convention => "$(name)";
package_add_command => "/usr/bin/yum -y install --enablerepo=$(repo)";
package_update_command => "/usr/bin/yum -y update --enablerepo=$(repo)";
package_delete_command => "/usr/bin/yum -y erase";
package_verify_command => "/bin/rpm -V";
}
################################################################################
#
# Special-purpose bundles
#
################################################################################
# Report if a mail server has more than $(threshold) messages in queue
bundle agent bigq(threshold) {
vars:
linux::
# count of live queue
"count"
string =>
execresult("/usr/bin/mailq | /bin/awk -F': ' '/Total requests/{print $2}'",
"useshell"),
policy => "overridable";
classes:
linux::
"q_big" expression => isgreaterthan("$(count)","$(threshold)");
commands:
linux.q_big::
"/bin/echo -n \"Thresh: $(threshold). Count: `/usr/bin/mailq | /bin/awk -F': ' '/Total requests/{print $2}'`\" | /usr/bin/logger -p mail.crit",
contain => container_std("root", "false"),
# Using full-featured body to extend ifelapsed; don't yell more
# than once every 4 hours
# LIBRARY STUB: body action actionsettings( action_policy, ifelapsed,
# expireafter, log_level, audit, background, report_level) {
action => actionsettings("fix", "240", "120", "inform", "false",
"false", "inform");
}
Jump to Line
Something went wrong with that request. Please try again.