pax_global_header00006660000000000000000000000064124130047330014507gustar00rootroot0000000000000052 comment=4625272d9f5879a6371032d1f791974a41024708 masterfiles-3.6.2/000077500000000000000000000000001241300473300140355ustar00rootroot00000000000000masterfiles-3.6.2/.gitignore000066400000000000000000000004511241300473300160250ustar00rootroot00000000000000# autotools stuff Makefile Makefile.in stamp-h1 /aclocal.m4 /autom4te.cache /compile /config.guess /config.log /config.status /config.sub /configure /depcomp /install-sh /libtool /ltmain.sh /m4/libtool.m4 /m4/lt*.m4 /missing /revision /ylwrap /test-driver # Misc. /cf_promises_* # vim .*.sw[po] masterfiles-3.6.2/CONTRIBUTING.md000066400000000000000000000004721241300473300162710ustar00rootroot00000000000000# Contributing to the CFEngine masterfiles * indent properly (CFEngine has a reindentation script in `contrib/reindent.pl`) * test thoroughly (the same test procedures apply as in [core](https://github.com/cfengine/core/blob/master/HACKING.md)) * document well * lurk for a bit * don't be afraid to ask questions masterfiles-3.6.2/LICENSE000066400000000000000000000023101241300473300150360ustar00rootroot00000000000000All software in this repository except where explicitly marked otherwise is under the folowing license. MIT Public License http://www.opensource.org/licenses/MIT Copyright (C) 2012-2014 CFEngine AS Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. masterfiles-3.6.2/Makefile.am000066400000000000000000000002471241300473300160740ustar00rootroot00000000000000SUBDIRS = tests/acceptance # See configure.ac for MASTERFILES_INSTALL_TARGETS. nobase_dist_masterfiles_DATA = @MASTERFILES_INSTALL_TARGETS@ masterfilesdir=$(datadir) masterfiles-3.6.2/README.md000066400000000000000000000032011241300473300153100ustar00rootroot00000000000000# CFEngine 3 masterfiles CFEngine 3 is a popular open source configuration management system. Its primary function is to provide automated configuration and maintenance of large-scale computer systems. This repository is intended to provide a stable base policy for installations and upgrades, and is used by CFEngine 3.6 and newer. The documentation for the masterfiles, highly recommended, is at https://docs.cfengine.com/docs/master/guide-writing-and-serving-policy-policy-framework.html ## Installation The contents of this repository are intended to live in `/var/cfengine/masterfiles` or wherever `$(sys.masterdir)` points. Use the convenience install target: ``` ./autogen.sh make install ``` to install only what's needed (without `tests`, only policies). By default it installs in `/var/cfengine/masterfiles` but you can override that easily: ``` ./autogen.sh --prefix=/my/other/install/directory make install ``` Note that the last directory component will always be called `masterfiles`. ## Host report A very important piece of functionality, which you may want for your own use but will certainly be helpful for debugging or submitting bugs to CFEngine (core, masterfiles, or any other are) is the host report. Run the host report like so: `cf-agent -b host_info_report` You should see output like: ``` R: Host info report generated and avilable at '/var/cfengine/reports/host_info_report.txt' ``` Take a look at the resulting file, it has lots of useful information about the system. ## Contributing Please see the [CONTRIBUTING.md](CONTRIBUTING.md) file. The CFEngine masterfiles are under the MIT license, see [LICENSE](LICENSE) masterfiles-3.6.2/autogen.sh000077500000000000000000000012411241300473300160340ustar00rootroot00000000000000# try_exec() { type "$1" > /dev/null 2>&1 && exec "$@" } unset foo (: ${foo%%bar}) 2> /dev/null T1="$?" if test "$T1" != 0; then try_exec /usr/xpg4/bin/sh "$0" "$@" echo "No compatible shell script interpreter found." echo "Please find a POSIX shell for your system." exit 42 fi # # Do not set -e before switching to POSIX shell, as it will break the test # above. # set -e srcdir=`dirname $0` test -z "$srcdir" && srcdir=. ORIGDIR=`pwd` cd $srcdir if ! test -d m4; then mkdir m4 fi autoreconf -Wno-portability --force --install -I m4 || exit 1 cd $ORIGDIR || exit $? if [ -z "$NO_CONFIGURE" ]; then $srcdir/configure --enable-maintainer-mode "$@" fi masterfiles-3.6.2/cf_null000066400000000000000000000000001241300473300153700ustar00rootroot00000000000000masterfiles-3.6.2/cfe_internal/000077500000000000000000000000001241300473300164665ustar00rootroot00000000000000masterfiles-3.6.2/cfe_internal/CFE_cfengine.cf000066400000000000000000000140241241300473300212340ustar00rootroot00000000000000################################################################## # # DO NOT EDIT THIS FILE. All policy files prefixed with CFE_ are maintained # by CFEngine and its original state is required for internal operations of # CFEngine. If the file has been modified CFEngine’s upgrades may require # manual intervention. Contact CFEngine support if additional information # and/or recommendation is needed. # ################################################################## ################################################################## # # cfe_internal_management # - manage internal CFE functionalities (any:: can be modified) # - some agent bundles are in CFE_hub_specific.cf # ################################################################## bundle agent cfe_internal_management { methods: # # CFEngine internals # am_policy_hub:: "hub" usebundle => cfe_internal_update_folders, handle => "cfe_internal_management_update_folders", comment => "Create empty directories for CFE self-upgrade"; am_policy_hub.enterprise:: "hub" usebundle => cfe_internal_webserver("on"), handle => "cfe_internal_management_web_server", comment => "Manage Apache Web server (on/off)"; "hub" usebundle => cfe_internal_setup_knowledge, handle => "cfe_internal_management_setup_knowledge", comment => "Manage CFE Knowledge Map"; "hub" usebundle => cfe_internal_apache_sudoer, handle => "cfe_internal_management_apache_sudoer", comment => "Permit Apache user to run passwordless sudo cf-runagent"; "hub" usebundle => cfe_internal_httpd_related, handle => "cfe_internal_management_httpd_related", comment => "To run MP on another TCP port (80 by default)"; "hub" usebundle => cfe_internal_php_runalerts, handle => "cfe_internal_management_php_runalerts", comment => "To run PHP runalerts to check bundle status on SQL and Sketch"; # As passive hub is supposed to run read-only PostgreSQL instance # doing maintenance makes no sense and is not possible at all. (am_policy_hub.enterprise.!ha_enabled)||(ha_enabled.hub_active):: "hub" usebundle => cfe_internal_hub_maintain, handle => "cfe_internal_management_hub_maintain", comment => "Start the hub maintenance process"; "hub" usebundle => cfe_internal_truncate_events, handle => "cfe_internal_truncate_events", comment => "To run CFE truncate to pending"; postgresql_full_maintenance|postgresql_monitoring_maintenance:: "hub" usebundle => cfe_internal_postgresql_maintenance, handle => "cfe_internal_management_postgresql_maintenance", comment => "Run vacuumdb to clean up PostgreSQL database"; any:: "any" usebundle => cfe_internal_limit_robot_agents, handle => "cfe_internal_management_limit_cfe_agents", comment => "Manage CFE processes"; "any" usebundle => cfe_internal_log_rotation, handle => "cfe_internal_management_log_rotation", comment => "Rotate CFEngine logs so we dont fill the disk"; } ################################################################## # # cfe_internal_limit_rebot_agents # - kill CFE processes and restart it when the process grown # ################################################################## bundle agent cfe_internal_limit_robot_agents { processes: !windows:: "bin/cf-execd" process_count => check_execd("1"), comment => "Check cf-execd process if exceed the number", handle => "cfe_internal_limit_robot_agents_processes_check_cf_execd"; "bin/cf-monitord" process_count => check_monitord("1"), comment => "Check cf-monitord process if exceed the number", handle => "cfe_internal_limit_robot_agents_processes_check_cf_monitord"; # # Do not do this for cf-hub because cf-hub may have unlimited processes # something_wrong_execd:: "bin/cf-execd" signals => { "term", "kill" }, restart_class => "restart_execd", comment => "When cf-execd comes undone then kill all and restart the process", handle => "cfe_internal_limit_robot_agents_processes_kill_cf_execd"; something_wrong_monitord:: "bin/cf-monitord" signals => { "term", "kill" }, restart_class => "restart_monitord", comment => "When cf-monitord comes undone then kill all and restart the process", handle => "cfe_internal_limit_robot_agents_processes_kill_cf_monitord"; # commands: restart_execd:: "$(sys.cf_execd)" comment => "Restart cf-execd process", classes => kept_successful_command, handle => "cfe_internal_limit_robot_agents_commands_restart_cf_execd"; restart_monitord:: "$(sys.cf_monitord)" comment => "Restart cf-monitord process", classes => kept_successful_command, handle => "cfe_internal_limit_robot_agents_commands_restart_cf_monitord"; } # body process_count check_execd(n) { match_range => "0,$(n)"; out_of_range_define => {"something_wrong_execd"}; } body process_count check_monitord(n) { match_range => "0,$(n)"; out_of_range_define => {"something_wrong_monitord"}; } ################################################################## # # cfe_internal_log_rotation # - Rotate logs and clean up old files so the disk doesnt get full # ################################################################## bundle agent cfe_internal_log_rotation # @brief Manage CFEngine log files so they dont fill up disks # See def.cf to enable rotation { methods: cfengine_internal_rotate_logs:: # CFEngine generates internal log files that need to be rotated. # Have a look at def.cf to enable rotation of these files "rotate_promise_summary" usebundle => logrotate("@(def.cfe_log_files)", "1m", "10"), comment => "Rotate log files once their size reach 1MB, keep 10 versions"; "rotate_outputs" usebundle => prunedir("@(def.cfe_log_dirs)", "30"), comment => "Delete outputs/* files older than 30 days"; } masterfiles-3.6.2/cfe_internal/CFE_hub_specific.cf000066400000000000000000000375171241300473300221150ustar00rootroot00000000000000################################################################## # # DO NOT EDIT THIS FILE. All policy files prefixed with CFE_ are maintained # by CFEngine and its original state is required for internal operations of # CFEngine. If the file has been modified CFEngine’s upgrades may require # manual intervention. Contact CFEngine support if additional information # and/or recommendation is needed. # ################################################################## ################################################################## # # cfe_internal_hub_vars # - define a default location of Mission Portal WebGUI # ################################################################## bundle common cfe_internal_hub_vars { vars: linux:: "docroot" string => "$(sys.workdir)/httpd/htdocs", comment => "Root directory of Enterprise Web interface", handle => "cfe_internal_hub_vars_docroot"; } ################################################################## # # cfe_internal_update_folders # - create temp directories to make CFE silent (self-upgrading) # ################################################################## bundle agent cfe_internal_update_folders { vars: "dirs" slist => { "aix_5_powerpc", "aix_6_powerpc", "aix_7_powerpc", "ubuntu_8_i686", "ubuntu_8_x86_64", "ubuntu_10_i686", "ubuntu_10_x86_64", "ubuntu_11_i686", "ubuntu_11_x86_64", "ubuntu_12_i686", "ubuntu_12_x86_64", "ubuntu_13_i686", "ubuntu_13_x86_64", "ubuntu_14_i686", "ubuntu_14_x86_64", "centos_5_i686", "centos_5_x86_64", "centos_6_i686", "centos_6_x86_64", "redhat_4_i686", "redhat_4_x86_64", "redhat_5_i686", "redhat_5_x86_64", "redhat_6_i686", "redhat_6_x86_64", "redhat_7_i686", "redhat_7_x86_64", "SuSE_10_i686", "SuSE_10_x86_64", "SuSE_11_i686", "SuSE_11_x86_64", "debian_5_i686", "debian_5_x86_64", "debian_6_i686", "debian_6_x86_64", "debian_7_i686", "debian_7_x86_64", "debian_8_i686", "debian_8_x86_64", "windows_i686", "windows_x86_64", "sunos_5.8_sun4u", "sunos_5.8_sun4v", "sunos_5.9_sun4u", "sunos_5.9_sun4v", "sunos_5.10_sun4u", "sunos_5.10_sun4v", "sunos_5.10_i86pc", }, comment => "Define a list for $(sys.flavour)_$(sys.arch) directories", handle => "cfe_internal_update_folders_vars_dirs"; # files: "$(sys.workdir)/master_software_updates/$(dirs)/." -> { "goal_updated" } comment => "Prepare binary upgrade folders for all distributions in our environment", handle => "cfe_internal_update_folders_files_create_dirs", create => "true"; } ################################################################## # # cfe_internal_apache_sudoer # - permit apache user to run passwordless sudo to cf-runagent # ################################################################## bundle agent cfe_internal_apache_sudoer { classes: !windows:: "sudoers_exists" expression => fileexists("/etc/sudoers"), comment => "Check if there is /etc/sudoers", handle => "cfe_internal_apache_sudoer_vars_linux_sudoers_exists"; # files: sudoers_exists.cfengine_internal_sudoers_editing_enable:: "/etc/sudoers" comment => "Permit Apache user to run passwordless sudo cf-runagent", handle => "cfe_internal_apache_sudoer_files_etc_sudoer", edit_line => apache_sudoer; reports: inform_mode.!cfengine_internal_sudoers_editing_enable:: "$(this.bundle): editing of the sudoers file is disabled; the Apache user may not be able to run passwordless sudo cf-runagent"; } # bundle edit_line apache_sudoer { insert_lines: linux:: "$(def.cf_apache_user) ALL=(ALL) NOPASSWD:/var/cfengine/bin/cf-runagent *" comment => "Add Apache user to run passwordless sudo cf-runagent", handle => "apache_sudoer_insert_lines"; } ################################################################## # # cfe_internal_webserver(on/off) # ***this is a new one*** ################################################################## bundle agent cfe_internal_webserver(state) { classes: "on" expression => strcmp("$(state)","on"), comment => "Check if a keyword \"on\" is inputs", handle => "cfe_internal_webserver_classes_on"; "off" expression => strcmp("$(state)","off"), comment => "Check if a keyword \"off\" is inputs", handle => "cfe_internal_webserver_classes_off"; # processes: am_policy_hub.on:: ".*/var/cfengine/httpd/bin/httpd.*" restart_class => "start_cfe_httpd", comment => "Check if CFE httpd process exists or not", handle => "cfe_internal_webserver_processes_start_cfe_httpd"; # commands: start_cfe_httpd:: "LD_LIBRARY_PATH=/var/cfengine/lib:$LD_LIBRARY_PATH /var/cfengine/httpd/bin/apachectl start" comment => "Start CFE httpd process if not exist", classes => kept_successful_command, handle => "cfe_internal_webserver_commands_start_cfe_httpd", contain => in_shell; } ################################################################## # # cfe_internal_httpd_related # - to change default TCP (80) port of MP # ################################################################## bundle agent cfe_internal_httpd_related { vars: am_policy_hub:: "tcp_port" string => "80", comment => "TCP port that MP is using", handle => "cfe_internal_httpd_related_vars_tcp_port"; # files: am_policy_hub:: "/var/cfengine/httpd/conf/httpd.conf" comment => "Change TCP port on CFEngine httpd configuration", handle => "cfe_internal_httpd_related_files_httpd_conf", edit_line => change_port("$(tcp_port)"), classes => if_repaired("restart_cfe_httpd"); "/var/cfengine/httpd/htdocs/application/config/appsettings.php" comment => "Add TCP port to MP setting", handle => "cfe_internal_httpd_related_files_appsettings_php", edit_line => change_appsettings("$(tcp_port)"); # commands: restart_cfe_httpd:: "LD_LIBRARY_PATH=/var/cfengine/lib:$LD_LIBRARY_PATH /var/cfengine/httpd/bin/apachectl restart" comment => "Restart CFEngine httpd if there is a change on configuration", classes => kept_successful_command, handle => "cfe_internal_httpd_related_commands_apachectl_restart", contain => in_shell; } # bundle edit_line change_port(p) { replace_patterns: any:: "^Listen(\s+)(?!$(p)).*" comment => "Match Listen line and replace", handle => "cfe_internal_change_port_edit_line_listen_port", replace_with => value("Listen $(p)"); } # bundle edit_line change_appsettings(p) { classes: any:: "original_config" expression => strcmp("$(p)","80"), comment => "If the port is 80 then create a class", handle => "cfe_internal_change_appsettings_classes_port_80"; # replace_patterns: original_config:: "\s+\$config\['rest_server'\]\s+=\s+\$protocol\s+\.\s+\$_SERVER\['SERVER_NAME'\]\s+\.\s+'(?!/api).*" comment => "Match a line and replace", handle => "cfe_internal_change_appsetting_replace_patterns_port_80", replace_with => value(" $config['rest_server'] = $protocol . $_SERVER['SERVER_NAME'] . '/api';"); !original_config:: "\s+\$config\['rest_server'\]\s+=\s+\$protocol\s+\.\s+\$_SERVER\['SERVER_NAME'\]\s+\.\s+'(?!\:$(p)/api).*" comment => "Match a line and replace", handle => "cfe_internal_change_appsetting_replace_patterns_not_port_80", replace_with => value(" $config['rest_server'] = $protocol . $_SERVER['SERVER_NAME'] . ':$(p)/api';"); } bundle agent cfe_internal_php_runalerts #@brief create and run PHP alerts # - Bundle status need to be updated and displayed on MP. We do it # by running php binary with some parameters. cfe_internal_php_runalerts # is a bundle to create a shell script on the fly and keep running # the command by a specific interval (every 60s by default) { vars: any:: "runalerts_script" string => "/var/cfengine/bin/runalerts.sh", comment => "location of php runalerts script", handle => "cfe_internal_php_runalerts_vars_runalerts_script"; "runalerts_stampfiles_dir" string => "/var/cfengine/httpd/php", comment => "location of runalerts stamp file directory", handle => "cfe_internal_php_runalerts_var_runalerts_stampfiles_dir"; "sleep_time" string => "60", comment => "how often that php_runalerts will run in every seconds", handle => "cfe_internal_php_runalerts_vars_sleep_time"; "stale_time" string => "10", comment => "if script does not function in minutes, restart the script", handle => "cfe_internal_php_runalerts_vars_stale_time"; "sql[name]" string => "sql", comment => "name of query type - sql", handle => "cfe_internal_php_runalerts_vars_sql_name"; "sql[limit]" string => "300", comment => "query limit of sql", handle => "cfe_internal_php_runalerts_vars_sql_limit"; "sql[running]" string => "20", comment => "how many query at a time of sql", handle => "cfe_internal_php_runalerts_vars_sql_running"; "sketch[name]" string => "sketch", comment => "name of query type - sketch", handle => "cfe_internal_php_runalerts_vars_sketch_name"; "sketch[limit]" string => "300", comment => "query limit of sketch", handle => "cfe_internal_php_runalerts_vars_sketch_limit"; "sketch[running]" string => "10", comment => "how many query at a time of sketch", handle => "cfe_internal_php_runalerts_vars_sketch_running"; # files: any:: "$(runalerts_script)" comment => "create php run alerts script", handle => "cfe_internal_php_runalerts_files_create_php_runalerts_script", create => "true", perms => mog("0755","root","root"), edit_defaults => empty, edit_line => my_php_runalerts_script("sql","sketch","$(runalerts_stampfiles_dir)","$(sleep_time)"); "$(runalerts_stampfiles_dir)/runalerts_.*" comment => "sanity check for the run alerts script. if not, restart it.", handle => "cfe_internal_php_runalerts_files_status_check", delete => tidy, file_select => mins_old("$(stale_time)"), classes => if_repaired("kill_script"); # processes: # Make sure to kill script on non active hub(s). kill_script||(ha_enabled.!hub_active):: "$(runalerts_script)" comment => "kill the php runalerts script because it is stale for some reason", handle => "cfe_internal_php_runalerts_process_kill_php_runalerts_script", signals => { "term" }, classes => if_repaired("run_script"); # Run script only on active hub to not send duplicated alert emails. !ha_enabled||(ha_enabled.hub_active):: "$(runalerts_script)" comment => "check if the php runalerts script is running or not", handle => "cfe_internal_php_runalerts_process_check_php_runalerts_script", restart_class => "run_script"; # commands: # Run script only on active hub to not send duplicated alert emails. (run_script.!ha_enabled)||(run_script.ha_enabled.hub_active):: "$(runalerts_script) > /dev/null < /dev/null 2>&1 &" comment => "to run php alerts script", handle => "cfe_internal_php_runalerts_commands_run_php_runalerts_script", classes => kept_successful_command, contain => in_shell, action => cfe_internal_bg; } # body action cfe_internal_bg { background => "true"; } # body file_select mins_old(mins) { mtime => irange(0,ago(0,0,0,0,"$(mins)",0)); file_result => "mtime"; } # bundle edit_line my_php_runalerts_script(v1,v2,sdir,stime) { insert_lines: any:: "#!/bin/bash while true; do touch $(sdir)/runalerts_$(cfe_internal_php_runalerts.sql[name]) if [ -f /var/cfengine/httpd/php/runalerts_$(cfe_internal_php_runalerts.sql[name]) ]; then /var/cfengine/httpd/php/bin/php /var/cfengine/httpd/htdocs/index.php cli_tasks runalerts $(cfe_internal_php_runalerts.sql[limit]) $(cfe_internal_php_runalerts.sql[running]) $(cfe_internal_php_runalerts.sql[name]) >/dev/null 2>&1 fi touch $(sdir)/runalerts_$(cfe_internal_php_runalerts.sketch[name]) if [ -f /var/cfengine/httpd/php/runalerts_$(cfe_internal_php_runalerts.sketch[name]) ]; then /var/cfengine/httpd/php/bin/php /var/cfengine/httpd/htdocs/index.php cli_tasks runalerts $(cfe_internal_php_runalerts.sketch[limit]) $(cfe_internal_php_runalerts.sketch[running]) $(cfe_internal_php_runalerts.sketch[name]) >/dev/null 2>&1 fi sleep $(stime) done" comment => "contents inside php runalerts script", handle => "my_php_runalerts_script_insert_lines_php_runalerts_script"; } bundle agent cfe_internal_truncate_events #@brief cancel all the pending events once in a day { commands: Hr05.Min00_05:: "$(sys.workdir)/httpd/php/bin/php $(cfe_internal_hub_vars.docroot)/index.php cli_tasks truncate_events" comment => "Turncate all the pending notifications if there is any", classes => kept_successful_command, handle => "cfe_internal_truncate_event_mp"; } bundle agent cfe_internal_postgresql_maintenance #@ignore #@brief PostgreSQL needs to be cleaned regularly with the vacuumdb command { vars: "postgres_vacuum_options" string => ifelse("postgresql_full_maintenance", "--full --dbname=cfdb", "--full --dbname=cfdb --table=__monitoringmg"); "maintenance_type" string => ifelse("postgresql_full_maintenance", "full", "monitoring_only"); "vacuumdb_cmd" string => "$(sys.bindir)/vacuumdb $(postgres_vacuum_options)", comment => "Command for cleaning a PostgreSQL database - $(maintenance_type)", handle => "cfe_internal_postgresql_maintenance_vars_vacuum_cmd_$(maintenance_type)"; policy_server.enterprise.!cfengine_3_5:: "cf_consumer_pid" string => readfile("$(sys.workdir)/cf-consumer.pid", 0), comment => "Read cf-consumer.pid for the main cf-consumer PID"; classes: "cf_consumer_pid_correct" expression => isvariable("cf_consumer_pid"), comment => "Check if cf-consumer pid is correctly defined"; processes: any:: "cf-hub" signals => { "term" }, comment => "Terminate cf-hub while doing $(maintenance_type) PostgreSQL maintenance", handle => "cfe_internal_postgresql_$(maintenance_type)_maintenance_processes_term_cf_hub"; cf_consumer_pid_correct:: "cf-consumer" signals => { "kill" }, process_select => by_pid("$(cf_consumer_pid)"), comment => "Kill cf-consumer while doing PostgreSQL maintenance", handle => "cfe_internal_postgresql_$(maintenance_type)_maintenance_processes_kill_cf_consumer"; # commands: any:: "$(vacuumdb_cmd)" comment => "Run $(maintenance_type) vacuumdb command", classes => kept_successful_command, handle => "cfe_internal_postgresql_maintenance_commands_run_vacuumdb_cmd_$(maintenance_type)"; } masterfiles-3.6.2/cfe_internal/CFE_knowledge.cf000066400000000000000000000166661241300473300214530ustar00rootroot00000000000000################################################################## # # DO NOT EDIT THIS FILE. All policy files prefixed with CFE_ are maintained # by CFEngine and its original state is required for internal operations of # CFEngine. If the file has been modified CFEngine’s upgrades may require # manual intervention. Contact CFEngine support if additional information # and/or recommendation is needed. # ################################################################## ################################################################## # # cfe_internal_setup_knowledge # - populate knowledge bank database (CFE Enterprise) # ################################################################## bundle agent cfe_internal_setup_knowledge { classes: # # check when updates arrive, new compared to the database # files: "$(cfe_internal_hub_vars.docroot)" comment => "Copy the basic knowledge base configuration from the installation to doc root", handle => "cfe_internal_setup_knowledge_files_doc_root_1", copy_from => no_backup_cp("$(sys.workdir)/share/GUI"), depth_search => recurse("inf"); "$(cfe_internal_hub_vars.docroot)" comment => "All files in there should be at least 0644", handle => "cfe_internal_setup_knowledge_files_doc_root_2", perms => m("0644"), depth_search => recurse_exclude("inf"); # see exclude dirs in recurse_exclude() body "$(cfe_internal_hub_vars.docroot)/.htaccess" comment => "Correct up htaccess file in doc root", handle => "cfe_internal_setup_knowledge_files_doc_root_htaccess", perms => mog("0644","root","root"), copy_from => no_backup_cp("$(sys.workdir)/share/GUI/Apache-htaccess"); "$(cfe_internal_hub_vars.docroot)/hub/." comment => "Create a necessary folder for cf-hub", handle => "cfe_internal_setup_knowledge_files_doc_root_hub", create => "true", depth_search => recurse_basedir("inf"), perms => mog("0755","root","root"); "$(cfe_internal_hub_vars.docroot)/scripts/." comment => "Ensure permissions for $(cfe_internal_hub_vars.docroot)/scripts", handle => "cfe_internal_setup_knowledge_files_doc_root_scripts", create => "true", depth_search => recurse_basedir("inf"), perms => mog("0644","root","root"); "$(cfe_internal_hub_vars.docroot)/tmp/." comment => "Ensure permissions for $(cfe_internal_hub_vars.docroot)/tmp (temp files to email)", handle => "cfe_internal_setup_knowledge_files_doc_root_tmp", create => "true", depth_search => recurse_basedir("inf"), perms => mog("0644",$(def.cf_apache_user),$(def.cf_apache_group)); "$(cfe_internal_hub_vars.docroot)/application/logs/." comment => "Make sure log folder has been created and has right permisions", handle => "cfe_internal_setup_knowledge_files_doc_root_application_logs", create => "true", depth_search => recurse_basedir("inf"), file_select => cfe_internal_exclude_index_html, perms => mog("0644",$(def.cf_apache_user),$(def.cf_apache_group)); "$(cfe_internal_hub_vars.docroot)/application" comment => "Ensure permissions to all directiories in application to 755", handle => "cfe_internal_setup_knowledge_files_all_folders_in_application", file_select => dirs, depth_search => recurse("inf"), perms => m("0755"); "$(cfe_internal_hub_vars.docroot)/application" comment => "Ensure permissions to all files in application to 644", handle => "cfe_internal_setup_knowledge_files_all_files_in_application", file_select => plain, depth_search => recurse("inf"), perms => m("0644"); "$(cfe_internal_hub_vars.docroot)/api" comment => "Ensure permissions for $(cfe_internal_hub_vars.docroot)/api", handle => "cfe_internal_setup_knowledge_files_doc_root_api", file_select => cfe_internal_exclude_sh_pl_scripts, depth_search => recurse_basedir_exclude("inf"), perms => mog("0644","root","root"); "$(cfe_internal_hub_vars.docroot)/api/static/." comment => "Ensure permissions for $(cfe_internal_hub_vars.docroot)/api/static (writing exported reports PDF/CSV)", handle => "cfe_internal_setup_knowledge_files_doc_root_api_static", depth_search => recurse_basedir("inf"), perms => mog("0644",$(def.cf_apache_user),$(def.cf_apache_group)); "$(cfe_internal_hub_vars.docroot)/api/dc-scripts" comment => "Ensure permissions for $(cfe_internal_hub_vars.docroot)/api/dc-scripts (execute git push/pull)", handle => "cfe_internal_setup_knowledge_files_doc_root_api_dc_scripts", file_select => cfe_internal_sh_pl_scripts, depth_search => recurse_basedir("inf"), perms => mog("0755","root","root"); "$(cfe_internal_hub_vars.docroot)/sql_lite/." comment => "Create a directory sql_lite for analytic to be working", handle => "cfe_internal_setup_knowledge_files_doc_root_sql_lite", create => "true", depth_search => recurse_basedir("inf"), perms => mog("0644",$(def.cf_apache_user),$(def.cf_apache_group)); "$(cfe_internal_hub_vars.docroot)/tmp/." create => "true", perms => mog("0644",$(def.cf_apache_user),$(def.cf_apache_group)), depth_search => recurse_basedir("inf"), comment => "Create tmp directories for httpd internal use", handle => "cfe_internal_setup_knowledge_files_tmp_dir"; "$(sys.workdir)/httpd/logs/." comment => "Ensure permissions for $(sys.workdir)/httpd/logs", handle => "cfe_internal_setup_knowledge_files_httpd_logs", create => "true", perms => mog("0664","root","cfapache"); } ############################################################################# body action aggregator { ifelapsed => "120"; expireafter => "240"; background => "true"; } ############################################################################ body file_select folder(regex) { leaf_name => { ".*$(regex)$"}; file_result => "leaf_name"; } ############################################################################ body depth_search recurse_basedir(d) { depth => "$(d)"; include_basedir => "true"; } ########################################################################### body depth_search recurse_basedir_exclude(d) { depth => "$(d)"; include_basedir => "true"; exclude_dirs => { "static" }; } ############################################################################ body depth_search recurse_exclude(d) { depth => "$(d)"; exclude_dirs => { "hub" , "graphs", "scripts", "tmp", "logs", "api", "sql_lite", "rest", "application", "dc-scripts" }; } ############################################################################ body process_count check_process(in,out) { match_range => "1,1"; in_range_define => { "$(in)" }; out_of_range_define => { "$(out)" }; } ############################################################################ body file_select cfe_internal_exclude_sh_pl_scripts { leaf_name => { ".*\.sh",".*\.pl"}; file_result => "!leaf_name"; } ############################################################################ body file_select cfe_internal_sh_pl_scripts { leaf_name => { ".*\.sh",".*\.pl" }; file_result => "leaf_name"; } ############################################################################ body file_select cfe_internal_exclude_index_html { leaf_name => { "index.html" }; file_result => "!leaf_name"; } masterfiles-3.6.2/cfe_internal/cfengine_processes.cf000066400000000000000000000141061241300473300226460ustar00rootroot00000000000000################################################################## # # cfe_internal_processes # - restart CFE processes by specific time (not in service) # ################################################################## bundle agent cfe_internal_processes { vars: "cf_components" slist => { "cf-key", "cf-monitord", "cf-promises", "cf-runagent", "cf-serverd", "cf-hub" }, comment => "Define all cfengine robot agents", handle => "cfe_internal_processes_vars_cf_components"; windows:: "stop_signal" string => "kill", comment => "Define a stop signal for Windows", handle => "cfe_internal_processes_vars_stop_signal_windows"; !windows:: "stop_signal" string => "term", comment => "Define a stop signal for *NIX", handle => "cfe_internal_processes_vars_stop_signal_unix"; # classes: # NOTE: We do not restart by default, can be added if desired # "restart_cf" expression => "Monday.Hr05.Min00_05" # comment => "Define a class to restart cfengine processes", # handle => "cfe_internal_processes_classes_restart_cf"; # processes: restart_cf:: "$(cf_components)" signals => { "$(stop_signal)" }, comment => "Kill cfengine processes", handle => "cfe_internal_processes_stop_cf_components"; restart_cf.!windows:: "cf-execd" signals => { "$(stop_signal)" }, comment => "Kill cf-execd process on *NIX", handle => "cfe_internal_processes_stop_cf_execd"; # commands: restart_cf.!windows:: "$(sys.cf_execd)" comment => "Restart cf-execd process", classes => kept_successful_command, handle => "cfe_internal_processes_commands_cf_execd"; # services: restart_cf.windows:: "CfengineNovaExec" service_policy => "stop", comment => "Stop the executor service, part of scheduled restart", handle => "cfe_internal_processes_services_stop_cf_execd_windows"; "CfengineNovaExec" service_policy => "start", comment => "Start the executor service, part of scheduled restart", handle => "cfe_internal_processes_services_start_cf_execd_windows"; # reports: restart_cf:: "Reloaded configuration of all Cfengine components", comment => "Alert restarting message", handle => "cfe_internal_processes_reports"; } ################################################################## # # cfe_internal_enable # - start CFE agents when booting (not in service) # ################################################################## bundle agent cfe_internal_enable { vars: freebsd:: "rc_conf[cfengine_enable]" string => "\"YES\"", comment => "Define a variable to start cfengine at boot time", handle => "cfe_internal_enable_vars_rc_conf_freebsd"; netbsd:: "rc_conf[cfengine_enable]" string => "\"YES\"", comment => "Define a variable to start cfengine at boot time", handle => "cfe_internal_enable_vars_rc_conf_netbsd"; linux:: "rc_files" slist => { "/etc/rc1.d/K11cfengine3", "/etc/rc2.d/S90cfengine3", "/etc/rc3.d/S90cfengine3", "/etc/rc4.d/S90cfengine3", "/etc/rc5.d/S90cfengine3", "/etc/rc6.d/K11cfengine3" }, comment => "Define a list of rc files on Linux", handle => "cfe_internal_enable_vars_rc_files"; # files: freebsd:: "/usr/local/etc/rc.d/cfengine3.sh" comment => "Ensure that the cfengine rc.d script is executable", handle => "cfe_internal_enable_files_cfengine3_sh_freebsd", perms => mog("755", "root", "wheel"); "/etc/rc.conf" comment => "cfengine libraries should be enabled in rc.conf if appropriate", handle => "cfe_internal_enable_files_rc_conf_freebsd_1", edit_line => append_if_no_line("[ -e /var/cfengine/lib ] && /sbin/ldconfig -m /var/cfengine/lib"); "/etc/rc.conf" comment => "cfengine should be enabled in rc.conf", handle => "cfe_internal_enable_files_rc_conf_freebsd_2", edit_line => set_variable_values("cfengine_enable.rc_conf"); netbsd:: "/usr/local/etc/rc.d/cfengine3.sh" comment => "Ensure that the cfengine rc.d script is executable", handle => "cfe_internal_enable_files_cfengine3_sh_netbsd", perms => mog("755", "root", "wheel"); "/etc/rc.d/cfengine" comment => "Move cfengine rc.d script to the correct location", handle => "cfe_internal_enable_files_rc_d_netbsd", copy_from => local_cp("/usr/local/etc/rc.d/cfengine3.sh"); "/etc/rc.conf" comment => "cfengine should be enabled in rc.conf", handle => "cfe_internal_enable_files_rc_conf_netbsd", edit_line => set_variable_values("cfengine_enable.rc_conf"); linux:: "$(rc_files)" comment => "Ensure that startup scripts are properly linked", handle => "cfe_internal_enable_files_rc_files_linux", link_from => ln_s("/etc/init.d/cfengine3"); } ################################################################## # # cfe_internal_build_software_report # - force machines to have package promises to be able to generate # software reports (not in service) # ################################################################## bundle agent cfe_internal_build_software_report { packages: redhat:: "wget" comment => "Install packages from the list", handle => "cfe_internal_build_software_report_redhat", package_policy => "add", package_method => yum; debian:: "wget" comment => "Install packages from the list", handle => "cfe_internal_build_software_report_debian", package_policy => "add", package_method => apt; (SuSE|suse):: "wget" comment => "Install packages from the list", handle => "cfe_internal_build_software_report_suse", package_policy => "add", package_method => zypper; } masterfiles-3.6.2/cfe_internal/ha/000077500000000000000000000000001241300473300170565ustar00rootroot00000000000000masterfiles-3.6.2/cfe_internal/ha/ha.cf000066400000000000000000000111731241300473300177630ustar00rootroot00000000000000bundle agent ha_main { vars: ha_enabled:: "policy_servers" slist => { @(ha_def.ips) }; "connected_servers" slist => filter("$(sys.policy_hub)", policy_servers, false, true, 10); classes: ha_enabled:: "ha_master_valid" expression => isvariable("sys.hub_active_ip"); methods: policy_server.enterprise:: "manage_mp_ha_enabled_file" usebundle => ha_manage_mp_status_file; policy_server.ha_enabled:: "sync_client_keys" usebundle => ha_hub_sync_clients_keys; "copy_hubs_keys" usebundle => ha_hub_copy_hubs_keys; policy_server.ha_enabled.!hub_active:: "sync_config_data" usebundle => ha_hub_sync_config_data; policy_server.keys_staged:: "establish trust" usebundle => ha_update_staged_ppkeys; !policy_server.ha_enabled:: "Copy hub keys to clients" usebundle => ha_node_sync_hub_keys; "Write new master IP on hub" usebundle => update_master_ip_server; } # ha_enabled file is used by MP as a first test to figure out if # HA functionality is switched on or not. Based on existence of this # file further actions are performed. bundle agent ha_manage_mp_status_file { files: policy_server.!ha_enabled:: "$(sys.workdir)/httpd/htdocs/ha_enabled" delete => tidy; policy_server.ha_enabled:: "$(sys.workdir)/httpd/htdocs/ha_enabled" create => "true", perms => mog("0644",$(def.cf_apache_user),$(def.cf_apache_group)); } bundle agent ha_hub_sync_config_data { files: "$(sys.workdir)/httpd/htdocs/application/config/cf_robot.php" copy_from => no_backup_scp("$(sys.workdir)/httpd/htdocs/application/config/cf_robot.php", $(sys.hub_active_ip)), comment => "Synchronize cf_robot configuration", handle => "ha_sync_robot_config"; "$(sys.workdir)/share/GUI/application/config/appsettings.php" copy_from => no_backup_scp("$(sys.workdir)/share/GUI/application/config/appsettings.php", $(sys.hub_active_ip)), comment => "Synchronize appsetings configuration", handle => "ha_sync_appsettings_config"; "/opt/cfengine/notification_scripts" copy_from => no_backup_scp("/opt/cfengine/notification_scripts", $(sys.hub_active_ip)), comment => "Copy MP notification scripts", handle => "ha_copy_notification_scripts", depth_search => recurse("1"); } bundle agent ha_hub_copy_hubs_keys { files: "$(ha_def.ppkeys_hubs)" copy_from => no_backup_cp("$(sys.workdir)/ppkeys"), file_select => hubs_keys_select, comment => "Copy all hubs keys to directory accessible by clients", handle => "ha_copy_hubs_keys", depth_search => recurse("1"), classes => if_repaired("hubs_keys_staged"); } bundle agent update_master_ip_server { files: !policy_server:: "$(sys.workdir)/policy_server.dat" copy_from => u_rcp("$(sys.workdir)/state/master_hub.dat", @(def.policy_servers)), comment => "Update master hub IP on CFEngine node", handle => "ha_cfengine_node_update_master"; } bundle agent ha_hub_sync_clients_keys { vars: "exclude_files" slist => {"localhost.priv", "localhost.pub", @(ha_def.hub_shas)}; files: "$(ha_def.ppkeys_staging)" copy_from => no_backup_scp("$(sys.workdir)/ppkeys", @(ha_main.connected_servers)), file_select => ex_list(@(exclude_files)), comment => "Distribute all client keys between replica set servers", handle => "ha_copy_client_keys_between_replica_set_servers", depth_search => recurse("1"), classes => if_repaired("keys_staged"); } bundle agent ha_update_staged_ppkeys { files: "$(sys.workdir)/ppkeys" copy_from => no_backup_cp("$(ha_def.ppkeys_staging)"), file_select => plain, comment => "Copy staged client keys to ppkeys", handle => "ha_copy_staged_client_keys", depth_search => recurse("1"), classes => if_repaired("ppkeys_updated"); } bundle agent ha_node_sync_hub_keys { files: !policy_server:: "$(sys.workdir)/ppkeys" copy_from => no_backup_scp("$(ha_def.ppkeys_hubs)", @(def.policy_servers)), file_select => hub_all_keys, depth_search => u_recurse("inf"), comment => "Distribute all hub keys to clients", handle => "ha_copy_hub_keys_to_nodes", classes => if_repaired("keys_copied_clients"); } body file_select hub_all_keys { leaf_name => {".*.pub"}; file_result => "leaf_name"; } body file_select hubs_keys_select { search_size => irange("426", "426"); leaf_name => {escape("root-SHA=$(ha_def.config[$(ha_main.connected_servers)][sha]).pub")}; file_result => "leaf_name"; } body copy_from no_backup_scp(from,server) { servers => { "$(server)" }; source => "$(from)"; compare => "digest"; copy_backup => "false"; encrypt => "true"; trustkey => "true"; } masterfiles-3.6.2/cfe_internal/ha/ha_def.cf000066400000000000000000000015621241300473300206020ustar00rootroot00000000000000bundle common ha_def { classes: any:: "ha_enabled" expression => "!any"; #"ha_enabled" expression => "enterprise"; vars: ha_enabled:: "config_file" string => "$(this.promise_dirname)/ha_info.json"; "ppkeys_staging" string => "$(sys.workdir)/ppkeys_staging"; "ppkeys_hubs" string => "$(sys.workdir)/ppkeys_hubs"; "config" data => readjson("$(config_file)", "4k"); "ips" slist => getindices("config"); "hub_sha[$(ips)]" string => escape("root-SHA=$(config[$(ips)][sha]).pub"), comment => "We need to construct an intermediary array so that we can extract a combined list of all hub keys."; "hub_shas" slist => getvalues("hub_sha"), comment => "We use the list of hub key files for restricting clients access only to those"; reports: verbose_mode:: "HA hub $(ips) $(config[$(ips)][sha])"; } masterfiles-3.6.2/cfe_internal/ha/ha_info.json000066400000000000000000000005001241300473300213470ustar00rootroot00000000000000{ "192.168.100.10": { "sha": "3e9df4ec8c9826eaa2c397f99eeae22e0a35a22307474d56f7fdedadff7dd485", "internal_ip": "192.168.100.10", "tags": ["node1"] }, "192.168.100.11": { "sha": "37baa6f2f18a907131dadbf3e255d4ed0eda2f403e2123bab2c5f82f7ac8cd79", "internal_ip": "192.168.100.11", "tags": ["node2"] } } masterfiles-3.6.2/cfe_internal/host_info_report.cf000066400000000000000000000131211241300473300223610ustar00rootroot00000000000000bundle agent host_info_report # @brief Generates a short high level summary of the executing host information # # **Example:** # `cf-agent -b host_info_report` { vars: "host_info_report_template" handle => "host_info_report_vars_host_info_report_template", string => "$(this.promise_dirname)/../templates/$(this.bundle).mustache", comment => "Where the report template is found"; "host_info_report_output" handle => "host_info_report_vars_host_info_report_output", string => "$(sys.workdir)/reports/$(this.bundle).txt", comment => "Where the host info report should be generated"; methods: show_software:: "Software" handle => "host_info_report_methods_software", usebundle => host_info_report_software, comment => "Collect information about software installed"; any:: "CFEngine" handle => "host_info_report_methods_cfengine", usebundle => host_info_report_cfengine, comment => "Collect information about CFEngine"; "Render" usebundle => host_info_report_render_txt, comment => "Render the host info report in plain text"; } bundle agent host_info_report_software # @brief Collect information about software installed { vars: "packages" data => packagesmatching(".*", ".*", ".*", ".*"), comment => "Get information about all packages currently on system"; "package_names" slist => getindices("package_state[name]"); DEBUG:: "printable" string => format("%S", packages); reports: DEBUG:: "$(printable)"; "$(package_names)"; } bundle agent host_info_report_cfengine # @brief Collect information about CFEngine { classes: "have_masterdir_cf_promises_validated" expression => fileexists("$(sys.masterdir)/cf_promises_validated"), handle => "host_info_report_cfengine_classes_have_masterdir_cf_promises_validated", comment => "We need to know if we have the files, because if we try to read them when they don't exist we get error messages. Look in masterdir because we are interested in the last time when policy was changed and validated (indicating when a policy release was received). "; "have_inputdir_cf_promises_release_id" expression => fileexists("$(sys.inputdir)/cf_promises_release_id"), handle => "host_info_report_cfengine_classes_have_masterdir_cf_promises_release_id", comment => "We need to know if we have the files, because if we try to read them when they don't exist we get error messages. Look in inputdir because we are interested in the current policy release id as determined on the policyserver, not as calculated locally."; vars: # doesn't work :( # "interface_flags" slist => maparray("$(this.k): IP $(sys.ipv4[$(this.k)]), flags $(this.v)", "sys.interface_flags"); "interface_flags" slist => maparray("$(this.k): $(this.v)", "sys.interface_flags"); "interface_ips" slist => maparray("$(this.k): IPv4 $(this.v)", "sys.ipv4"); "interface_info_unsorted" slist => { @(interface_flags), @(interface_ips) }; "interface_info" slist => sort(interface_info_unsorted, "lex"); any:: "cfengine_info_files" handle => "host_info_report_vars_cfengine_info_files", slist => { "cf_promises_validated", "cf_promises_release_id" }, comment => "These files are required for CFEngine related information, and if we try to read them when they don't exist we get ugly error messages"; have_masterdir_cf_promises_validated:: "cf_promises_validated" data => readjson("$(sys.masterdir)/cf_promises_validated", 1K), comment => "This contains information about the last time policy was updated and subsequently validated, it indicates when policy was last updated from the policy server."; "cf_promises_validated_timestamp_formatted" string => strftime("localtime", "%F %T %Z", $(cf_promises_validated[timestamp])), comment => "It's useful to display when policy was last updated and verified, in a human readable format."; have_inputdir_cf_promises_release_id:: "cf_promises_release_id" data => readjson("$(sys.inputdir)/cf_promises_release_id", 1K); any:: "last_agent_run" string => strftime("localtime", "%F %T %Z", filestat("$(sys.workdir)/outputs/previous", "mtime")); DEBUG:: "printable" string => format("%S", cf_promises_release_id); reports: DEBUG:: "$(printable)"; reports: DEBUG.have_masterdir_cf_promises_validated:: "I have cf_promises_validated"; DEBUG.have_inputdir_cf_promises_release_id:: "I have a policy release ID"; } bundle agent host_info_report_render_txt # @brief Generates a report with the collected information { files: "$(host_info_report.host_info_report_output)" create => "true", edit_template => "$(host_info_report.host_info_report_template)", handle => "host_info_report_files_host_info_report_output", classes => scoped_classes_generic("bundle", "host_info_report_output"), template_method => "mustache"; reports: host_info_report_output_repaired:: "Host info report generated and available at '$(host_info_report.host_info_report_output)'"; host_info_report_output_not_ok:: "There was a problem generating your host info report at '$(host_info_report.host_info_report_output)'"; } masterfiles-3.6.2/configure.ac000066400000000000000000000067701241300473300163350ustar00rootroot00000000000000dnl ########################################################################## dnl # dnl # Build CFEngine dnl # dnl # Run ./autogen.sh to build configure script dnl # dnl ########################################################################## AC_PREREQ(2.59) dnl Version is unused, it will be grabbed from core. AC_INIT([cfengine], [1.0]) _AM_SET_OPTION([tar-ustar]) AM_INIT_AUTOMAKE([foreign]) AM_MAINTAINER_MODE([enable]) AC_DEFINE_UNQUOTED(ABS_TOP_SRCDIR, "`cd -- "$srcdir"; pwd`", [Absolute path of source tree]) m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])]) dnl Libtool madness AC_CONFIG_MACRO_DIR([m4]) dnl dnl hide [s]include macros, so old aclocal (automake < 1.10) won't find them and dnl won't complain about something/something.m4 not found dnl m4_define(incstart,sinc) m4_define(incend,lude) AC_PROG_MKDIR_P AC_PROG_INSTALL dnl ###################################################################### dnl Figure out core and enterprise directory. dnl ###################################################################### AC_ARG_WITH(core, [AS_HELP_STRING(--with-core=, [Build against core in directory . Defaults to "../core"])], [AS_IF([test "x$with_core" == "xno"], [AC_MSG_ERROR([You cannot build without a core directory (--without-core)], [2])], core_dir=$with_core )], core_dir=$(pwd)/../core ) AS_IF([test ! -d "$core_dir/libpromises"], [AC_MSG_ERROR([$with_core is not a valid core directory (--with-core=$core_dir)], [2])]) AS_CASE([$core_dir], [/*], [], [core_dir=$(pwd)/$core_dir]) AC_SUBST([core_dir]) AC_ARG_WITH(enterprise, [AS_HELP_STRING(--with-enterprise=, [Build against enterprise in directory . Defaults to "../enterprise"])], [AS_IF([test "x$with_enterprise" == "xno"], [ enterprise_dir= ],[ enterprise_dir=$with_enterprise ])], enterprise_dir=$(pwd)/../enterprise ) AS_CASE([$enterprise_dir], [/*], [], [enterprise_dir=$(pwd)/$enterprise_dir]) AM_CONDITIONAL([HAVE_ENTERPRISE], [test -d "$enterprise_dir/libcfenterprise"]) AC_SUBST([enterprise_dir]) dnl ###################################################################### dnl Set prefix to correct directory. dnl ###################################################################### AS_IF([test x"$prefix" = xNONE], prefix=/var/cfengine ) datadir=${prefix}/masterfiles dnl ###################################################################### dnl Generate install target list. dnl ###################################################################### AC_MSG_NOTICE([generating install targets]) MASTERFILES_INSTALL_TARGETS= for i in cfe_internal controls inventory lib services sketches/meta update; do MASTERFILES_INSTALL_TARGETS="$MASTERFILES_INSTALL_TARGETS $(find "$srcdir/$i" -name '*.cf' -exec printf '%s ' '{}' ';')" done for i in templates; do MASTERFILES_INSTALL_TARGETS="$MASTERFILES_INSTALL_TARGETS $(find "$srcdir/$i" -name '*.mustache' -exec printf '%s ' '{}' ';')" done MASTERFILES_INSTALL_TARGETS="$MASTERFILES_INSTALL_TARGETS $(echo ./*.cf)" AC_SUBST(MASTERFILES_INSTALL_TARGETS) dnl ###################################################################### dnl Now make the Makefiles dnl ###################################################################### AC_CONFIG_FILES([Makefile tests/acceptance/Makefile]) AC_OUTPUT AC_MSG_RESULT(DONE: Configuration done. Run make/gmake install to install CFEngine Community Masterfiles.) masterfiles-3.6.2/controls/000077500000000000000000000000001241300473300157005ustar00rootroot00000000000000masterfiles-3.6.2/controls/3.4/000077500000000000000000000000001241300473300162045ustar00rootroot00000000000000masterfiles-3.6.2/controls/3.4/cf_serverd.cf000066400000000000000000000114271241300473300206450ustar00rootroot00000000000000############################################################################### # This part is for cf-serverd # # General IP access policy for the connection protocol # i.e. access to the server itself. # Access to specific files must be granted in addition. # # This file should be for 3.4 client hosts only. # (No report_data_select attributes) ############################################################################### body server control { # List of ciphers the server accepts. For Syntax help see man page # for "openssl ciphers". Default is "AES256-GCM-SHA384:AES256-SHA" #allowciphers => "AES256-GCM-SHA384:AES256-SHA"; # Allow connections from nodes which are out-of-sync denybadclocks => "false"; # By default deny all connections but the following: ## List of hosts that may connect allowconnects => { "127.0.0.1" , "::1", @(def.acl) }; ## List of hosts that may have more than one connection established at the same time allowallconnects => { "127.0.0.1" , "::1", @(def.acl) }; ## List of hosts that we'll accept any key they present (open this only for bootstrapping) trustkeysfrom => { "127.0.0.1" , "::1", @(def.acl) }; allowusers => { "root" }; maxconnections => "100"; windows:: cfruncommand => "$(sys.cf_twin) -f \"$(sys.update_policy_path)\" & $(sys.cf_agent)"; hpux:: cfruncommand => "$(def.cf_runagent_shell) -c \"SHLIB_PATH=\"/var/cfengine/lib-twin\" $(sys.cf_twin) -f $(sys.update_policy_path)\" ; $(sys.cf_agent)"; aix:: cfruncommand => "$(def.cf_runagent_shell) -c \"LIBPATH=\"/var/cfengine/lib-twin\" $(sys.cf_twin) -f $(sys.update_policy_path)\" ; $(sys.cf_agent)"; solaris:: cfruncommand => "$(def.cf_runagent_shell) -c \"LD_LIBRARY_PATH=\"/var/cfengine/lib-twin\" $(sys.cf_twin) -f $(sys.update_policy_path)\" ; $(sys.cf_agent)"; !(windows|hpux|aix|solaris):: cfruncommand => "$(def.cf_runagent_shell) -c \"LD_LIBRARY_PATH=\"/var/cfengine/lib-twin\" $(sys.cf_twin) -f $(sys.update_policy_path)\" ; $(sys.cf_agent)"; } ############################################################################### bundle server access_rules() { access: any:: "$(def.dir_masterfiles)" handle => "server_access_grant_access_policy", comment => "Grant access to the policy updates", admit => { ".*$(def.domain)", @(def.acl) }; "$(def.dir_software)" handle => "server_access_grant_access_datafiles", comment => "Grant access to software updates", admit => { ".*$(def.domain)", @(def.acl) }; "$(def.dir_bin)" handle => "server_access_grant_access_binary", comment => "Grant access to binary for cf-runagent", admit => { ".*$(def.domain)", @(def.acl) }; "$(def.dir_modules)" handle => "server_access_grant_access_modules", comment => "Grant access to modules directory", admit => { ".*$(def.domain)", @(def.acl) }; "$(def.dir_plugins)" handle => "server_access_grant_access_plugins", comment => "Grant access to plugins directory", admit => { ".*$(def.domain)", @(def.acl) }; "$(def.cf_runagent_shell)" handle => "server_access_grant_access_shell_cmd", comment => "Grant access to shell for cfruncommand", admit => { "$(sys.policy_hub)" }; !am_policy_hub.enterprise:: "delta" handle => "server_access_grant_delta_for_hosts", comment => "Grant delta reporting query for the hub on the hosts", resource_type => "query", admit => { "$(sys.policy_hub)" }; "full" handle => "server_access_grant_full_for_hosts", comment => "Grant full reporting query for the hub on the hosts", resource_type => "query", admit => { "$(sys.policy_hub)" }; am_policy_hub.enterprise:: "delta" handle => "server_access_grant_delta_for_hub", comment => "Grant delta reporting query for the hub on the policy server", resource_type => "query", admit => { "$(sys.policy_hub)" }; "full" handle => "server_access_grant_full_for_hub", comment => "Grant full reporting query for the hub on the policy server", resource_type => "query", admit => { "$(sys.policy_hub)" }; # Uncomment the promise below to allow cf-runagent to # access cf-agent on Windows machines # # "c:\program files\cfengine\bin\cf-agent.exe" # # handle => "grant_access_policy_agent", # comment => "Grant access to the agent (for cf-runagent)", # admit => { ".*$(def.domain)", @(def.acl) }; roles: # Use roles to allow specific remote cf-runagent users to # define certain soft-classes when running cf-agent on this host ".*" authorize => { "root" }; } masterfiles-3.6.2/controls/cf_agent.cf000066400000000000000000000017771241300473300177740ustar00rootroot00000000000000############################################################################### # # This part is for cf-agent # # Settings describing the details of the fixed behavioural promises made # by cf-agent # ############################################################################### body agent control { # Global default for time that must elapse before promise will be rechecked. # Don't keep any promises. any:: # This should normally be set to an interval like 1-5 mins # We set it to one initially to avoid confusion. ifelapsed => "1"; # Do not send IP/name during server connection if address resolution is broken. # Comment it out if you do NOT have a problem with DNS skipidentify => "true"; # Environment variables based on Distro debian:: environment => { "DEBIAN_FRONTEND=noninteractive", # "APT_LISTBUGS_FRONTEND=none", # "APT_LISTCHANGES_FRONTEND=none", }; } masterfiles-3.6.2/controls/cf_execd.cf000066400000000000000000000044621241300473300177600ustar00rootroot00000000000000############################################################################### # This part is for cf-execd # # These body settings determine the behaviour of cf-execd, # including scheduling times and output capture to # $(sys.workdir)/outputs and relay via email. ############################################################################### body executor control { any:: splaytime => "4"; cfengine_internal_agent_email:: mailto => "root@$(def.domain)"; mailfrom => "root@$(sys.host).$(def.domain)"; smtpserver => "localhost"; any:: # Default: # # schedule => { "Min00", "Min05", "Min10", "Min15", "Min20", # "Min25", "Min30", "Min35", "Min40", "Min45", # "Min50", "Min55" }; # The full path and command to the executable run by default (overriding builtin). # cf-twin needs its own safe environment because of the update mechanism windows.(cfengine_3_4|cfengine_3_5):: exec_command => "$(sys.cf_twin) -f \"$(sys.workdir)\inputs\update.cf\" & $(sys.cf_agent) -Dcf_execd_initiated"; windows.!(cfengine_3_4|cfengine_3_5):: exec_command => "$(sys.cf_agent) -f \"$(sys.update_policy_path)\" & $(sys.cf_agent) -Dcf_execd_initiated"; hpux.(cfengine_3_4|cfengine_3_5):: exec_command => "SHLIB_PATH=\"/var/cfengine/lib-twin\" $(sys.cf_twin) -f \"$(sys.workdir)/inputs/update.cf\" ; $(sys.cf_agent) -Dcf_execd_initiated"; hpux.!(cfengine_3_4|cfengine_3_5):: exec_command => "$(sys.cf_agent) -f \"$(sys.update_policy_path)\" ; $(sys.cf_agent) -Dcf_execd_initiated"; aix.(cfengine_3_4|cfengine_3_5):: exec_command => "LIBPATH=\"/var/cfengine/lib-twin\" $(sys.cf_twin) -f \"$(sys.workdir)/inputs/update.cf\" ; $(sys.cf_agent) -Dcf_execd_initiated"; aix.!(cfengine_3_4|cfengine_3_5):: exec_command => "$(sys.cf_agent) -f \"$(sys.update_policy_path)\" ; $(sys.cf_agent) -Dcf_execd_initiated"; !(windows|hpux|aix).(cfengine_3_4|cfengine_3_5):: exec_command => "LD_LIBRARY_PATH=\"/var/cfengine/lib-twin\" $(sys.cf_twin) -f \"$(sys.workdir)/inputs/update.cf\" ; $(sys.cf_agent) -Dcf_execd_initiated"; !(windows|hpux|aix).!(cfengine_3_4|cfengine_3_5):: exec_command => "$(sys.cf_agent) -f \"$(sys.update_policy_path)\" ; $(sys.cf_agent) -Dcf_execd_initiated"; } masterfiles-3.6.2/controls/cf_hub.cf000066400000000000000000000013231241300473300174370ustar00rootroot00000000000000############################################################################### # # This part is for cf-hub # # Settings describing the details of the fixed behavioural promises made # by cf-monitord. The system defaults will be sufficient for most users. # ############################################################################### body hub control { am_policy_hub:: # export_zenoss => "/var/www/reports/summary.z"; # federation => { "host1", "host2" }; # exclude_hosts => { "192.168.12.21", "10.10", "10.12.*" }; # cf-hub collects up reports from registered hosts every 5 minutes. # hub_schedule => { "Min00", "Min30", "(Evening|Night).Min45_50" }; # port => "5308"; } masterfiles-3.6.2/controls/cf_monitord.cf000066400000000000000000000012111241300473300205100ustar00rootroot00000000000000############################################################################### # # This part is for cf-monitord # # Settings describing the details of the fixed behavioural promises made # by cf-monitord. The system defaults will be sufficient for most users. # This configurability potential, however, will be a key to developing # the integrated monitoring capabilities of CFEngine. # ############################################################################### body monitor control { any:: forgetrate => "0.7"; histograms => "true"; # tcpdump => "false"; # tcpdumpcommand => "/usr/sbin/tcpdump -t -n -v"; } masterfiles-3.6.2/controls/cf_runagent.cf000066400000000000000000000010611241300473300205030ustar00rootroot00000000000000############################################################################### # # This part is for cf-runagent # # Settings describing the details of the fixed behavioural promises made # by cf-runagent. The most important parameter here is the list of hosts # that the agent will poll for connections. # ############################################################################### body runagent control { # A list of hosts to contact when using cf-runagent any:: hosts => { "127.0.0.1" }; # , "myhost.example.com:5308", ... } masterfiles-3.6.2/controls/cf_serverd.cf000066400000000000000000000147441241300473300203460ustar00rootroot00000000000000############################################################################### # This part is for cf-serverd # # General IP access policy for the connection protocol # i.e. access to the server itself. # Access to specific files must be granted in addition. ############################################################################### body server control { # List of ciphers the server accepts. For Syntax help see man page # for "openssl ciphers". Default is "AES256-GCM-SHA384:AES256-SHA" #allowciphers => "AES256-GCM-SHA384:AES256-SHA"; # List of hosts that may connect (change the ACL in def.cf) allowconnects => { "127.0.0.1" , "::1", @(def.acl) }; # Out of them, which ones should be allowed to have more than one # connection established at the same time? allowallconnects => { "127.0.0.1" , "::1", @(def.acl) }; # Out of the hosts in allowconnects, trust new keys only from the # following ones. SEE COMMENTS IN def.cf trustkeysfrom => { @(def.trustkeysfrom) }; ## List of hosts that we'll accept connections not using latest protocol ## (absence of this option means allow all, empty list means allow none) # allowlegacyconnects => { }; # Maximum number of concurrent connections. # Suggested value >= total number of hosts maxconnections => "200"; allowusers => { "root" }; # Allow connections from nodes which are out-of-sync denybadclocks => "false"; windows:: cfruncommand => "$(sys.cf_agent) -f \"$(sys.update_policy_path)\" & $(sys.cf_agent)"; hpux:: cfruncommand => "$(def.cf_runagent_shell) -c \"$(sys.cf_agent) -f $(sys.update_policy_path)\" ; $(sys.cf_agent)"; aix:: cfruncommand => "$(def.cf_runagent_shell) -c \"$(sys.cf_agent) -f $(sys.update_policy_path)\" ; $(sys.cf_agent)"; solaris:: cfruncommand => "$(def.cf_runagent_shell) -c \"$(sys.cf_agent) -f $(sys.update_policy_path)\" ; $(sys.cf_agent)"; !(windows|hpux|aix|solaris):: cfruncommand => "$(def.cf_runagent_shell) -c \"$(sys.cf_agent) -f $(sys.update_policy_path)\" ; $(sys.cf_agent)"; } ############################################################################### bundle server access_rules() { vars: enterprise:: "query_types" slist => {"delta", "rebase", "full"}; access: any:: "$(def.dir_masterfiles)" handle => "server_access_grant_access_policy", comment => "Grant access to the policy updates", admit => { @(def.acl) }; "$(def.dir_software)" handle => "server_access_grant_access_datafiles", comment => "Grant access to software updates", admit => { @(def.acl) }; "$(def.dir_bin)" handle => "server_access_grant_access_binary", comment => "Grant access to binary for cf-runagent", admit => { @(def.acl) }; "$(def.dir_modules)" handle => "server_access_grant_access_modules", comment => "Grant access to modules directory", admit => { @(def.acl) }; "$(def.dir_plugins)" handle => "server_access_grant_access_plugins", comment => "Grant access to plugins directory", admit => { @(def.acl) }; !windows:: "$(def.cf_runagent_shell)" handle => "server_access_grant_access_shell_cmd", comment => "Grant access to shell for cfruncommand", admit => { @(def.policy_servers) }; policy_server.ha_enabled:: "$(sys.workdir)/ppkeys" handle => "server_access_grant_access_ppkeys_hubs", comment => "Grant access to ppkeys for HA hubs", admit => { @(def.policy_servers) }; # Allow slave hub to synchronize cf_robot and appsettings content. # Files are containing configuration that must be the same on all hubs. "$(sys.workdir)/httpd/htdocs/application/config/cf_robot.php" handle => "server_access_grant_access_cf_robot", comment => "Grant access to cf_robot file for HA hubs", admit => { @(def.policy_servers) }; "$(sys.workdir)/share/GUI/application/config/appsettings.php" handle => "server_access_grant_access_appsettings", comment => "Grant access to appsettings for HA hubs", admit => { @(def.policy_servers) }; # Allow access to notification_scripts directory so passive hub # will be able to synchronize its content. Once passive hub will # be promoted to act as a master all the custom scripts will be # accessible. "/opt/cfengine/notification_scripts" handle => "server_access_grant_access_notification scripts", comment => "Grant access tonotification scripts", admit => { @(def.policy_servers) }; # When HA is enabled clients are updating active hub IP address # using data stored in master_hub.dat file. "$(sys.workdir)/state/master_hub.dat" handle => "server_access_grant_access_policy_server_dat", comment => "Grant access to policy_server.dat", admit => { @(def.acl) }; # Hubs keys working in HA configuration are stored in ppkeys_hubs directory. # In order to perform failover while active hub is down clients needs to # have all hubs keys. This gives ability to connect to slave hub promoted to active role # once active is down. "$(sys.workdir)/ppkeys_hubs" handle => "server_access_grant_access_to_clients", comment => "Grant access to hubs' keys to clients", admit => { @(def.acl) }; windows:: "c:\program files\cfengine\bin\cf-agent.exe" handle => "server_access_grant_access_agent", comment => "Grant access to the agent (for cf-runagent)", admit => { @(def.policy_servers) }; !policy_server.enterprise:: "$(query_types)" handle => "server_access_grant_$(query_types)_for_hosts", comment => "Grant $(query_types) reporting query for the hub on the hosts", resource_type => "query", report_data_select => default_data_select_host, admit => { @(def.policy_servers) }; policy_server.enterprise:: "$(query_types)" handle => "server_access_grant_$(query_types)_for_hub", comment => "Grant $(query_types) reporting query for the hub on the policy server", resource_type => "query", report_data_select => default_data_select_policy_hub, admit => { @(def.policy_servers) }; roles: # Use roles to allow specific remote cf-runagent users to # define certain soft-classes when running cf-agent on this host ".*" authorize => { "root" }; } masterfiles-3.6.2/def.cf000066400000000000000000000263441241300473300151160ustar00rootroot00000000000000############################################################################### # # bundle common def # - common/global variables and classes here # ############################################################################### bundle common def { vars: any:: # Begin change # Your domain name, for use in access control "domain" string => "$(sys.domain)", # this default may be inaccurate! comment => "Define a global domain for all hosts", handle => "common_def_vars_domain"; # List here the IP masks that we grant access to on the server "acl" slist => { # Allow everything in my own domain. # Note that this: # 1. requires def.domain to be correctly set # 2. will cause a DNS lookup for every access ".*$(def.domain)", # Assume /16 LAN clients to start with "$(sys.policy_hub)/16", # "2001:700:700:3.*", # "217.77.34.18", # "217.77.34.19", }, comment => "Define an acl for the machines to be granted accesses", handle => "common_def_vars_acl"; # Out of the hosts in allowconnects, trust new keys only from the # following ones. This is open by default for bootstrapping. "trustkeysfrom" slist => { # COMMENT THE NEXT LINE OUT AFTER ALL MACHINES HAVE BEEN BOOTSTRAPPED. "0.0.0.0/0", # allow any IP }, comment => "Define from which machines keys can be trusted"; # End change # cfengine_3_4|cfengine_3_5:: "dir_masterfiles" string => translatepath("$(sys.workdir)/masterfiles"), comment => "Define masterfiles path", handle => "common_def_vars_dir_masterfiles_backport"; !cfengine_3_4.!cfengine_3_5:: "dir_masterfiles" string => translatepath("$(sys.masterdir)"), comment => "Define masterfiles path", handle => "common_def_vars_dir_masterfiles"; "dir_reports" string => translatepath("$(sys.workdir)/reports"), comment => "Define reports path", handle => "common_def_vars_dir_reports"; "dir_software" string => translatepath("$(sys.workdir)/master_software_updates"), comment => "Define software path", handle => "common_def_vars_dir_software"; "dir_bin" string => translatepath("$(sys.bindir)"), comment => "Define binary path", handle => "common_def_vars_dir_bin"; "dir_modules" string => translatepath("$(sys.workdir)/modules"), comment => "Define modules path", handle => "common_def_vars_dir_modules"; "dir_plugins" string => translatepath("$(sys.workdir)/plugins"), comment => "Define plugins path", handle => "common_def_vars_dir_plugins"; cfengine_3_4|cfengine_3_5:: "cf_apache_user" string => "apache", comment => "User that CFEngine Enterprise webserver runs as", handle => "common_def_vars_cf_apache_user"; "cf_apache_group" string => "apache", comment => "Group that CFEngine Enterprise webserver runs as", handle => "common_def_vars_cf_apache_group"; !cfengine_3_4.!cfengine_3_5:: "cf_apache_user" string => "cfapache", comment => "User that CFEngine Enterprise webserver runs as", handle => "common_def_vars_cf_cfapache_user"; "cf_apache_group" string => "cfapache", comment => "Group that CFEngine Enterprise webserver runs as", handle => "common_def_vars_cf_cfapache_group"; solaris:: "cf_runagent_shell" string => "/usr/bin/sh", comment => "Define path to shell used by cf-runagent", handle => "common_def_vars_solaris_cf_runagent_shell"; !(windows|solaris):: "cf_runagent_shell" string => "/bin/sh", comment => "Define path to shell used by cf-runagent", handle => "common_def_vars_cf_runagent_shell"; any:: "base_log_files" slist => { "$(sys.workdir)/cf3.$(sys.host).runlog", "$(sys.workdir)/promise_summary.log", }; "enterprise_log_files" slist => { "$(sys.workdir)/cf_notkept.log", "$(sys.workdir)/cf_repair.log", "$(sys.workdir)/state/cf_value.log", "$(sys.workdir)/outputs/dc-scripts.log", }; "hub_log_files" slist => { "$(sys.workdir)/httpd/logs/access_log", # Mission Portal "$(sys.workdir)/httpd/logs/error_log", # Mission Portal }; enterprise.!am_policy_hub:: # CFEngine's own log files "cfe_log_files" slist => { @(base_log_files), @(enterprise_log_files) }; enterprise.am_policy_hub:: # CFEngine's own log files "cfe_log_files" slist => { @(base_log_files), @(enterprise_log_files), @(hub_log_files) }; !enterprise:: # CFEngine's own log files "cfe_log_files" slist => { @(base_log_files) }; any:: "cfe_log_dirs" slist => { "$(sys.workdir)/outputs", "$(sys.workdir)/reports", }; # ha_enabled is defined in WORKDIR/cfe_internal/ha/ha_def.cf # Disabled by default ha_enabled:: "policy_servers" slist => {"$(sys.policy_hub)", @(ha_def.ips)}; !ha_enabled:: "policy_servers" slist => {"$(sys.policy_hub)"}; classes: ### Enable special features policies. Set to "any" to enable. # Auto-load files in "services/autorun" and run bundles tagged "autorun". # Disabled by default! "services_autorun" expression => "!any"; # Internal CFEngine log files rotation "cfengine_internal_rotate_logs" expression => "any"; # Disable agent email output "cfengine_internal_agent_email" expression => "any"; # Transfer policies and binaries with encryption # you can also request it from the command line with # -Dcfengine_internal_encrypt_transfers # NOTE THAT THIS CLASS ALSO NEEDS TO BE SET IN update.cf "cfengine_internal_encrypt_transfers" expression => "!any"; # Purge policies that don't exist on the server side. # you can also request it from the command line with # -Dcfengine_internal_purge_policies # NOTE THAT THIS CLASS ALSO NEEDS TO BE SET IN update.cf "cfengine_internal_purge_policies" expression => "!any"; # Class defining which versions of cfengine are (not) supported # by this policy version. # Also note that this policy will only be run on enterprise policy_server "postgresql_maintenance_supported" expression => "policy_server.enterprise.!(cfengine_3_4|cfengine_3_5)"; # Allow the hub to edit sudoers in order for the Apache user to # run passwordless sudo cf-runagent. Enable this if you want the # Mission Portal to be able to troubleshoot failed Design Center # sketch activations on a host. "cfengine_internal_sudoers_editing_enable" expression => "!any"; # Class defining which versions of cfengine are (not) supported # by this policy version. # Also note that this policy will only be run on enterprise policy_server "postgresql_maintenance_supported" expression => "(policy_server.enterprise.!cfengine_3_5.!ha_enabled)|(policy_server.enterprise.ha_enabled.hub_active)"; # This class is for PosgreSQL maintenance # pre-defined to every Sunday at 2 a.m. # This can be changed later on. "postgresql_full_maintenance" expression => "postgresql_maintenance_supported.Sunday.Hr02.Min00_05"; # Vacuum monitoring_mg table every day (except Sunday, when vacuum is run on entire db) "postgresql_monitoring_maintenance" expression => "postgresql_maintenance_supported.!Sunday.Hr02.Min00_05"; } bundle common inventory_control # @brief Inventory control bundle # # This common bundle is for controlling whether some inventory bundles # are disabled. { vars: "dmidecoder" string => "/usr/sbin/dmidecode"; "lldpctl_exec" string => "/usr/bin/lldpctl"; "lsb_exec" string => "/usr/bin/lsb_release"; "mtab" string => "/etc/mtab"; "proc" string => "/proc"; classes: # setting this disables all the inventory modules except package_refresh "disable_inventory" expression => "!any"; # disable specific inventory modules below # by default disable the LSB inventory if the general inventory # is disabled or the binary is missing. Note that the LSB # binary is typically not very fast. "disable_inventory_lsb" expression => "disable_inventory"; "disable_inventory_lsb" not => fileexists($(lsb_exec)); # by default disable the dmidecode inventory if the general # inventory is disabled or the binary does not exist. Note that # typically this is a very fast binary. "disable_inventory_dmidecode" expression => "disable_inventory"; "disable_inventory_dmidecode" not => fileexists($(dmidecoder)); # by default disable the LLDP inventory if the general inventory # is disabled or the binary does not exist. Note that typically # this is a reasonably fast binary but still may require network # I/O. "disable_inventory_LLDP" expression => "disable_inventory"; "disable_inventory_LLDP" not => fileexists($(lldpctl_exec)); # by default run the package inventory refresh every time, even # if disable_inventory is set "disable_inventory_package_refresh" expression => "!any"; # by default disable the mtab inventory if the general inventory # is disabled or $(mtab) is missing. Note that this is very # fast. "disable_inventory_mtab" expression => "disable_inventory"; "disable_inventory_mtab" not => fileexists($(mtab)); # by default disable the fstab inventory if the general # inventory is disabled or $(sys.fstab) is missing. Note that # this is very fast. "disable_inventory_fstab" expression => "disable_inventory"; "disable_inventory_fstab" not => fileexists($(sys.fstab)); # by default disable the proc inventory if the general # inventory is disabled or /proc is missing. Note that # this is typically fast. "disable_inventory_proc" expression => "disable_inventory"; "disable_inventory_proc" not => isdir($(proc)); # by default don't run the CMDB integration every time, even if # disable_inventory is not set "disable_inventory_cmdb" expression => "any"; reports: verbose_mode.disable_inventory:: "$(this.bundle): All inventory modules disabled"; verbose_mode.!disable_inventory_lsb:: "$(this.bundle): LSB module enabled"; verbose_mode.!disable_inventory_dmidecode:: "$(this.bundle): dmidecode module enabled"; verbose_mode.!disable_inventory_LLDP:: "$(this.bundle): LLDP module enabled"; verbose_mode.!disable_inventory_mtab:: "$(this.bundle): mtab module enabled"; verbose_mode.!disable_inventory_fstab:: "$(this.bundle): fstab module enabled"; verbose_mode.!disable_inventory_proc:: "$(this.bundle): proc module enabled"; verbose_mode.!disable_inventory_package_refresh:: "$(this.bundle): package_refresh module enabled"; verbose_mode.!disable_inventory_cmdb:: "$(this.bundle): CMDB module enabled"; } masterfiles-3.6.2/inventory/000077500000000000000000000000001241300473300160725ustar00rootroot00000000000000masterfiles-3.6.2/inventory/README.md000066400000000000000000000007761241300473300173630ustar00rootroot00000000000000# CFEngine 3 inventory modules The CFEngine 3 inventory modules are pieces of CFEngine policy that are loaded and used by the `promises.cf` mechanism in order to *inventory* the system. CFEngine Enterprise has specific functionality to show and use inventory data, but users of the Community Version can use them as well locally on each host. The documentation for the inventory system, highly recommended, is at https://docs.cfengine.com/docs/master/guide-writing-and-serving-policy-policy-framework.html masterfiles-3.6.2/inventory/any.cf000066400000000000000000000636161241300473300172070ustar00rootroot00000000000000bundle common inventory_any # @brief Do inventory for any OS # # This common bundle is for any OS work not handled by specific # bundles. { } bundle agent inventory_autorun # @brief Autorun some inventory bundles # # This agent bundle runs other "autorun" inventory agent bundles # explicitly. It will use bundlesmatching() when CFEngine 3.5 and # earlier are no longer supported. { methods: !disable_inventory_cmdb:: "cmdb" usebundle => cfe_autorun_inventory_cmdb(), handle => "cfe_internal_autorun_inventory_cmdb"; !disable_inventory_LLDP:: "LLDP" usebundle => cfe_autorun_inventory_LLDP(), handle => "cfe_internal_autorun_inventory_LLDP"; !disable_inventory_package_refresh:: "packages_refresh" usebundle => cfe_autorun_inventory_packages(), handle => "cfe_internal_autorun_inventory_packages"; !disable_inventory_proc:: "proc" usebundle => cfe_autorun_inventory_proc(), handle => "cfe_internal_autorun_inventory_proc"; !disable_inventory_fstab:: "fstab" usebundle => cfe_autorun_inventory_fstab(), handle => "cfe_internal_autorun_inventory_fstab"; !disable_inventory_mtab:: "mtab" usebundle => cfe_autorun_inventory_mtab(), handle => "cfe_internal_autorun_inventory_mtab"; !disable_inventory_dmidecode:: "dmidecode" usebundle => cfe_autorun_inventory_dmidecode(), handle => "cfe_internal_autorun_inventory_dmidecode"; any:: "listening ports" usebundle => cfe_autorun_inventory_listening_ports(), handle => "cfe_internal_autorun_listening_ports"; "disk" usebundle => cfe_autorun_inventory_disk(), handle => "cfe_internal_autorun_disk"; "memory" usebundle => cfe_autorun_inventory_memory(), handle => "cfe_internal_autorun_memory"; "loadaverage" usebundle => cfe_autorun_inventory_loadaverage(), handle => "cfe_internal_autorun_loadaverage"; } bundle agent cfe_autorun_inventory_listening_ports # @brief Inventory the listening ports # # This bundle uses `mon.listening_ports` and is always enabled by # default, as it runs instantly and has no side effects. { vars: "ports" slist => sort( "mon.listening_ports", "int"), meta => { "inventory", "attribute_name=Ports listening" }; } bundle agent cfe_autorun_inventory_disk # @brief Inventory the disk (Enterprise only) { vars: enterprise:: "free" string => "$(mon.value_diskfree)", meta => { "inventory", "attribute_name=Disk free (%)" }; } bundle agent cfe_autorun_inventory_memory # @brief Inventory the memory (Enterprise only) { vars: enterprise:: # due to a Windows issue this is set to 0 there for now "total" string => ifelse("windows", "0", $(mon.value_mem_total)), meta => { "inventory", "attribute_name=Memory size (MB)" }; "free" string => ifelse("windows", "0", $(mon.value_mem_free)), meta => { "report" }; } bundle agent cfe_autorun_inventory_loadaverage # @brief Inventory the loadaverage (Enterprise only) { vars: enterprise:: "value" string => "$(mon.value_loadavg)", meta => { "report" }; } bundle agent cfe_autorun_inventory_proc # @brief Do procfs inventory # # This bundle will parse these /proc files: consoles, cpuinfo, # meminfo, modules, partitions, version, vmstat. There are # some general patterns you can follow to extend it for other /proc # items of interest. # # Contributions welcome. /proc/net and /proc/sys in general are of # wide interest, if you're looking for something fun. For instance, # the network interfaces could be extracted here without calling # `ifconfig`. { vars: "basefiles" slist => { "consoles", "cpuinfo", "modules", "partitions", "version" }; "files[$(basefiles)]" string => "$(inventory_control.proc)/$(basefiles)"; _have_proc_consoles:: "console_count" int => readstringarrayidx("consoles", "$(files[consoles])", "\s*#[^\n]*", "\s+", 500, 50000); "console_idx" slist => getindices("consoles"); _have_proc_modules:: "module_count" int => readstringarrayidx("modules", "$(files[modules])", "\s*#[^\n]*", "\s+", 2500, 250000); "module_idx" slist => getindices("modules"); _have_proc_cpuinfo:: # this will extract all the keys in one bunch, so you won't get # detailed info for processor 0 for example "cpuinfo_count" int => readstringarrayidx("cpuinfo_array", "$(files[cpuinfo])", "\s*#[^\n]*", "\s*:\s*", 500, 50000); "cpuinfo_idx" slist => getindices("cpuinfo_array"); "cpuinfo[$(cpuinfo_array[$(cpuinfo_idx)][0])]" string => "$(cpuinfo_array[$(cpuinfo_idx)][1])"; "cpuinfo_keys" slist => getindices("cpuinfo"); _have_proc_partitions:: "partitions_count" int => readstringarrayidx("partitions_array", "$(files[partitions])", "major[^\n]*", "\s+", 500, 50000); "partitions_idx" slist => getindices("partitions_array"); "partitions[$(partitions_array[$(partitions_idx)][4])]" string => "$(partitions_array[$(partitions_idx)][3])"; "partitions_keys" slist => getindices("partitions"); _have_proc_version:: "version" string => readfile("$(files[version])", 2048); classes: "have_proc" expression => isdir($(inventory_control.proc)); have_proc:: "_have_proc_$(basefiles)" expression => fileexists("$(files[$(basefiles)])"); _have_proc_consoles:: "have_console_$(consoles[$(console_idx)][0])" expression => "any", scope => "namespace"; _have_proc_modules:: "have_module_$(modules[$(module_idx)][0])" expression => "any", scope => "namespace"; reports: _have_proc_consoles.verbose_mode:: "$(this.bundle): we have console $(consoles[$(console_idx)][0])"; _have_proc_modules.verbose_mode:: "$(this.bundle): we have module $(modules[$(module_idx)][0])"; _have_proc_cpuinfo.verbose_mode:: "$(this.bundle): we have cpuinfo $(cpuinfo_keys) = $(cpuinfo[$(cpuinfo_keys)])"; _have_proc_partitions.verbose_mode:: "$(this.bundle): we have partitions $(partitions_keys) with $(partitions[$(partitions_keys)]) blocks"; _have_proc_version.verbose_mode:: "$(this.bundle): we have kernel version '$(version)'"; } bundle agent cfe_autorun_inventory_mtab # @brief Do mtab inventory # # The mtab format is simple: each line looks like this format: # `/dev/sda1 / ext4 rw,noatime,data=ordered 0 0` (in order: `DEV # MOUNTPOINT FSTYPE OPTIONS DUMP-FREQ PASS`). Some older Unices have # a different format and it's really not portable, so enable this only # if you know you want it. It's very handy if you want to check if a # file system is mounted. { vars: have_mtab:: "mount_count" int => readstringarrayidx("mounts", $(inventory_control.mtab), "\s*#[^\n]*", "\s+", 500, 50000); "idx" slist => getindices("mounts"); classes: "have_mtab" expression => fileexists($(inventory_control.mtab)); # define classes like have_mount_ext4__var for a ext4 /var mount "have_mount_$(mounts[$(idx)][2])_$(mounts[$(idx)][1])" expression => "any", scope => "namespace"; # define classes like have_mount_ext4 if there is a ext4 mount "have_mount_$(mounts[$(idx)][2])" expression => "any", scope => "namespace"; reports: verbose_mode:: "$(this.bundle): we have a $(mounts[$(idx)][2]) mount under $(mounts[$(idx)][1])"; } bundle agent cfe_autorun_inventory_fstab # @brief Do fstab inventory # # The fstab format is simple: each line looks like this format: # `/dev/sda1 / auto noatime 0 1` (in order: `DEV MOUNTPOINT FSTYPE # OPTIONS DUMP-FREQ PASS`). Note the FSTYPE is not known from the # fstab. # # Solaris has 'MOUNTDEV FSCKDEV MOUNTPOINT FSTYPE PASS MOUNT-AD-BOOT # OPTIONS' but is not supported here. Contributions welcome. { vars: have_fstab:: "mount_count" int => readstringarrayidx("mounts", $(sys.fstab), "\s*#[^\n]*", "\s+", 500, 50000); "idx" slist => getindices("mounts"); classes: "have_fstab" expression => fileexists($(sys.fstab)); # define classes like have_fs_ext4__var for a ext4 /var entry "have_fs_$(mounts[$(idx)][2])_$(mounts[$(idx)][1])" expression => "any", scope => "namespace"; # define classes like have__var for a /var entry "have_fs_$(mounts[$(idx)][1])" expression => "any", scope => "namespace"; # define classes like have_fs_ext4 if there is a ext4 entry "have_fs_$(mounts[$(idx)][2])" expression => "any", scope => "namespace"; reports: verbose_mode:: "$(this.bundle): we have a $(mounts[$(idx)][2]) fstab entry under $(mounts[$(idx)][1])"; } bundle agent cfe_autorun_inventory_dmidecode # @brief Do dmidecode-based inventory # # This common bundle runs dmidecode { vars: "dmidefs" data => parsejson(' { "bios-vendor": "BIOS vendor", "bios-version": "BIOS version", "system-serial-number": "System serial number", "system-manufacturer": "System manufacturer", "system-version": "System version", "processor-version": "CPU model" }'); # other dmidecode variables you may want: # baseboard-asset-tag # baseboard-manufacturer # baseboard-product-name # baseboard-serial-number # baseboard-version # bios-release-date # chassis-asset-tag # chassis-manufacturer # chassis-serial-number # chassis-type # chassis-version # processor-family # processor-frequency # processor-manufacturer # system-product-name # system-uuid "dmivars" slist => getindices(dmidefs); have_dmidecode:: "decoder" string => "$(inventory_control.dmidecoder)"; have_dmidecode.!(redhat_4|redhat_3):: "dmi[$(dmivars)]" string => execresult("$(decoder) -s $(dmivars)", "useshell"), meta => { "inventory", "attribute_name=$(dmidefs[$(dmivars)])" }; windows:: "dmi[bios-vendor]" string => $(bios_array[1]), meta => { "inventory", "attribute_name=BIOS vendor" }; "dmi[system-serial-number]" string => $(bios_array[2]), meta => { "inventory", "attribute_name=System serial number" }; "dmi[bios-version]" string => $(bios_array[3]), meta => { "inventory", "attribute_name=BIOS version" }; "dmi[system-version]" string => $(bios_array[4]), meta => { "inventory", "attribute_name=System version" }; "dmi[processor-version]" string => $(processor_array[1]), meta => { "inventory", "attribute_name=CPU model" }; "split_pscomputername" slist => string_split($(system_array[1]), "PSComputerName\s.*", 2), comment => "Work around weird appearance of PSComputerName into System manufacturer"; "dmi[system-manufacturer]" string => nth(split_pscomputername, 0), meta => { "inventory", "attribute_name=System manufacturer" }; classes: "have_dmidecode" expression => fileexists($(inventory_control.dmidecoder)); windows:: "bios_match" expression => regextract(".*Manufacturer\s+:\s([a-zA-Z0-9 ]+)\n.*SerialNumber\W+([a-zA-Z0-9 ]+).*SMBIOSBIOSVersion\W+([a-zA-Z0-9 ]+).*Version\W+([a-zA-Z0-9 -]+)", execresult("gwmi -query 'SELECT SMBIOSBIOSVersion, Manufacturer, SerialNumber, Version FROM WIN32_BIOS'", "powershell"), "bios_array"); "processor_match" expression => regextract(".*Name\W+(.*)", execresult("gwmi -query 'SELECT Name FROM WIN32_PROCESSOR'", "powershell"), "processor_array"); "system_match" expression => regextract(".*Manufacturer\W+(.*)", execresult("gwmi -query 'SELECT Manufacturer FROM WIN32_COMPUTERSYSTEM'", "powershell"), "system_array"); reports: inform_mode:: "$(this.bundle): Obtained $(dmidefs[$(dmivars)]) = '$(dmi[$(dmivars)])'"; } bundle agent cfe_autorun_inventory_LLDP # @brief Do LLDP-based inventory # # This agent bundle runs lldpctl to discover information. See # http://vincentbernat.github.io/lldpd/ to run this yourself for # testing, and your Friendly Network Admin may be of help too. { classes: "disable_inventory_LLDP" not => fileexists($(inventory_control.lldpctl_exec)); commands: !disable_inventory_LLDP:: "$(inventory_control.lldpctl_exec) | perl -n -e 'my ($k, $v) = m/([^=]+)=(.*)/; $k =~ s/\W/_/g; print \"=$k=$v\";" classes => kept_successful_command, module => "true"; } bundle agent cfe_autorun_inventory_packages # @brief Package inventory auto-refresh # # This bundle is for refreshing the package inventory. It runs on # startup, unless disabled. Other package methods can be added below. { classes: "have_patches" or => { "community_edition", # not in Community fileexists("$(sys.workdir)/state/software_patches_avail.csv") }; "have_inventory" and => { "have_patches", fileexists("$(sys.workdir)/state/software_packages.csv"), }; vars: # if we have the patches, 7 days; otherwise keep trying "refresh" string => ifelse("have_inventory", "10080", "0"); packages: debian:: "cfe_internal_non_existing_package" package_policy => "add", package_method => inventory_apt_get($(refresh)); redhat:: "cfe_internal_non_existing_package" package_policy => "add", package_method => inventory_yum_rpm($(refresh)); suse:: "cfe_internal_non_existing_package" package_policy => "add", package_method => inventory_zypper($(refresh)); aix:: "cfe_internal_non_existing_package" package_policy => "add", package_method => inventory_lslpp($(refresh)); gentoo:: "cfe_internal_non_existing_package" package_policy => "add", package_method => emerge; !redhat.!debian.!gentoo.!suse.!aix:: "cfe_internal_non_existing_package" package_policy => "add", package_method => generic; reports: inform_mode:: "$(this.bundle): refresh interval is $(refresh)"; inform_mode.have_inventory:: "$(this.bundle): we have the inventory files."; inform_mode.!have_inventory:: "$(this.bundle): we don't have the inventory files."; } body package_method inventory_apt_get(update_interval) # @depends debian_knowledge # @brief APT installation package method for inventory purposes only # @param update_interval how often to update the package and patch list # # This package method is a copy of the yum_rpm method just for # inventory purposes. # # This package method interacts with the APT package manager through # `apt-get`. It will never run "apt-get update" but is otherwise # exactly like the `apt_get` package method and *may* use the network # to install packages, as APT may decide. { 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 => $(update_interval); # 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)"; } body package_method inventory_yum_rpm(update_interval) # @depends common_knowledge redhat_knowledge rpm_knowledge # @brief Yum+RPM installation method for inventory purposes only # @param update_interval how often to update the package and patch list # # This package method is a copy of the yum_rpm method just for # inventory purposes. # # It will never run "yum update" but is otherwise exactly like the # `yum_rpm()` package method and *may* use the network to install # packages, as Yum may decide. { 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_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 => $(update_interval); 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"; } body package_method inventory_lslpp(update_interval) # @brief AIX lslpp installation method for inventory purposes only # @param update_interval how often to update the package and patch list { package_changes => "individual"; package_list_update_command => "/usr/bin/true"; package_list_update_ifelapsed => $(update_interval); package_list_command => "/usr/bin/lslpp -Lqc"; # list RPMs too package_list_name_regex => "([^:]+):.*"; package_list_version_regex => "[^:]+:[^:]+:([^:]+):.*"; package_installed_regex => "[^:]+:[^:]+:[^:]+:[^:]+:[^:]+:([CA]):.*"; package_name_convention => "$(name)-$(version).+"; package_add_command => "/usr/bin/true"; package_update_command => "/usr/bin/true"; package_patch_command => "/usr/bin/true"; package_delete_command => "/usr/bin/true"; package_verify_command => "/usr/bin/true"; } body package_method inventory_zypper(update_interval) # @depends common_knowledge rpm_knowledge suse_knowledge # @brief SUSE zypper installation method for inventory purposes only # @param update_interval how often to update the package and patch list # # This package method is a copy of the SUSE zypper method just for # inventory purposes. { package_changes => "bulk"; package_list_command => "$(paths.path[rpm]) -qa --queryformat \"i | repos | %{name} | %{version}-%{release} | %{arch}\n\""; # 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 => $(update_interval); 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$"; } bundle agent cfe_autorun_inventory_cmdb # @brief Copy and load the CMDB inventory # # This bundle is for refreshing the CMDB inventory. It copies the # file me.json from the server, then loads it to create variables and # classes. { vars: "cmdb_dir" string => "$(sys.workdir)/cmdb", comment => "CMDB directory location", meta => { "cmdb" }; "cmdb_file" string => "$(cmdb_dir)/me.json", comment => "CMDB file location", meta => { "cmdb" }; files: "$(cmdb_file)" copy_from => inventory_cmdb_copy_from, classes => inventory_scoped_classes_generic("bundle", "cmdb_file"); methods: cmdb_file_ok:: "load CMDB file" usebundle => inventory_cmdb_load($(cmdb_file)); } bundle agent inventory_cmdb_load(file) # @brief Load the CMDB inventory # # This bundle is for loading the CMDB inventory. { classes: "have_cmdb_data" expression => isvariable("cmdb"); "$(ckeys)" expression => "any", scope => "namespace"; vars: "cmdb" data => readjson($(file), "999999"); "cmdb_string" string => format("%S", cmdb); "bkeys" slist => getindices("cmdb[vars]"); "vkeys_$(bkeys)" slist => getindices("cmdb[vars][$(bkeys)]"); "$(vkeys_$(bkeys))" string => nth("cmdb[vars][$(bkeys)]", $(vkeys)); "ckeys" slist => getindices("cmdb[classes]"); reports: inform_mode.have_cmdb_data:: "$(this.bundle): Got CMDB data from $(file): $(cmdb_string)"; verbose_mode.have_cmdb_data:: "$(this.bundle): Got CMDB key = $(vkeys_$(bkeys)), CMDB value = $((vkeys_$(bkeys)))"; "$(this.bundle): Got CMDB class = $(ckeys)"; inform_mode.!have_cmdb_data:: "$(this.bundle): Could not read the CMDB data from $(file)"; } body copy_from inventory_cmdb_copy_from # @brief Copy from the CMDB source { !cfe_inventory_cmdb_override_file:: source => "me.json"; servers => { "$(sys.policy_hub)" }; cfe_inventory_cmdb_override_file:: source => "$(sys.inputdir)/me.json"; any:: compare => "digest"; encrypt => "true"; verify => "true"; } body classes inventory_scoped_classes_generic(scope, x) # @brief Define `x` prefixed/suffixed with promise outcome # **See also:** `scope` # # @param scope The scope in which the class should be defined # @param x The unique part of the classes to be defined # # Copy of `scoped_classes_generic`, which see. { scope => "$(scope)"; promise_repaired => { "promise_repaired_$(x)", "$(x)_repaired", "$(x)_ok", "$(x)_reached" }; repair_failed => { "repair_failed_$(x)", "$(x)_failed", "$(x)_not_ok", "$(x)_not_kept", "$(x)_not_repaired", "$(x)_reached" }; repair_denied => { "repair_denied_$(x)", "$(x)_denied", "$(x)_not_ok", "$(x)_not_kept", "$(x)_not_repaired", "$(x)_reached" }; repair_timeout => { "repair_timeout_$(x)", "$(x)_timeout", "$(x)_not_ok", "$(x)_not_kept", "$(x)_not_repaired", "$(x)_reached" }; promise_kept => { "promise_kept_$(x)", "$(x)_kept", "$(x)_ok", "$(x)_not_repaired", "$(x)_reached" }; } body contain inventory_in_shell # @brief run command in shell # # Copy of `in_shell`, which see. { useshell => "true"; # canonical "useshell" but this is backwards-compatible } masterfiles-3.6.2/inventory/debian.cf000066400000000000000000000073021241300473300176300ustar00rootroot00000000000000bundle common inventory_debian # @brief Debian inventory # # This common bundle is for Debian inventory work. { vars: has_lsb_release:: "lsb_release_info" string => readfile("/etc/lsb-release","256"), comment => "Read more OS info" ; has_etc_linuxmint_info:: "linuxmint_info" string => readfile("/etc/linuxmint/info","1024"), comment => "Read Linux Mint specific info" ; "lm_info_count" int => parsestringarray("mint_info", # array to populate "$(linuxmint_info)", # data to parse "\s*#[^\n]*", # comments "=", # split 100, # maxentries 2048) ; # maxbytes "mint_release" string => "$(mint_info[RELEASE][1])" ; "mint_codename" string => "$(mint_info[CODENAME][1])" ; classes: any:: "debian_derived_evaluated" scope => "bundle", or => { "has_os_release", "has_lsb_release", "has_etc_linuxmint_info" } ; "linuxmint" expression => "has_etc_linuxmint_info", comment => "this is a Linux Mint system, of some sort", meta => { "inventory", "attribute_name=none" } ; has_lsb_release:: "linuxmint" expression => regcmp("(?ms).*^DISTRIB_ID=LinuxMint$.*", "$(lsb_release_info)"), comment => "this is a Linux Mint system, of some sort", meta => { "inventory", "attribute_name=none" } ; linuxmint.has_os_release:: "lmde" expression => regcmp('(?ms).*^NAME="Linux Mint LMDE"$.*', "$(inventory_linux.os_release_info)"), comment => "this is a Linux Mint Debian Edition", meta => { "inventory", "attribute_name=none", "derived-from=inventory_linux.os_release_info" } ; linuxmint.has_lsb_release:: "lmde" expression => regcmp('(?ms).*^DISTRIB_DESCRIPTION="LMDE.*', "$(lsb_release_info)"), comment => "this is a Linux Mint Debian Edition", meta => { "inventory", "attribute_name=none", "derived-from=inventory_debian.lsb_release_info" } ; has_etc_linuxmint_info:: "lmde" expression => regcmp('(?ms).*^DESCRIPTION="LMDE.*',"$(linuxmint_info)"), comment => "this is a Linux Mint Debian Edition", meta => { "inventory", "attribute_name=none", "derived-from=inventory_debian.linuxmint_info" } ; debian_derived_evaluated.has_etc_linuxmint_info.!lmde:: # These need to be evaluated only after debian_derived_evaluated is defined # to ensure that the mint_info array has been evaluated as well. # Failing to do that will create meaningless classes # On non-LMDE Mint systems, this will create classes like, e.g.: # linuxmint_14, nadia, linuxmint_nadia "linuxmint_$(mint_release)" expression => "any", meta => { "inventory", "attribute_name=none" } ; "$(mint_codename)" expression => "any", meta => { "inventory", "attribute_name=none" } ; "linuxmint_$(mint_codename)" expression => "any", meta => { "inventory", "attribute_name=none" } ; debian_derived_evaluated:: "debian_pure" expression => "debian.!(ubuntu|linuxmint)", comment => "pure Debian", meta => { "inventory", "attribute_name=none" }; "debian_derived" expression => "debian.!debian_pure", comment => "derived from Debian", meta => { "inventory", "attribute_name=none" }; any:: "has_lsb_release" expression => fileexists("/etc/lsb-release"), comment => "Check if we can get more info from /etc/lsb-release"; "has_etc_linuxmint_info" expression => fileexists("/etc/linuxmint/info"), comment => "If this is a Linux Mint system, this *could* be available"; } masterfiles-3.6.2/inventory/generic.cf000066400000000000000000000002501241300473300200150ustar00rootroot00000000000000bundle common inventory_generic # @brief Generic (unknown OS) inventory # # This common bundle is for unknown operating systems, not handled by # specific bundles. { } masterfiles-3.6.2/inventory/linux.cf000066400000000000000000000043061241300473300175460ustar00rootroot00000000000000bundle common inventory_linux # @brief Linux inventory # # This common bundle is for Linux inventory work. { vars: has_os_release:: "os_release_info" string => readfile("/etc/os-release", "512"), comment => "Read /etc/os-release" ; os_release_has_id:: "os_release_id" string => canonify("$(id_array[1])"); os_release_has_version:: "os_release_version" string => canonify("$(version_array[1])"); has_proc_1_cmdline:: "proc_1_cmdline_split" slist => string_split(readfile("/proc/1/cmdline", "512"), " ", "2"), comment => "Read /proc/1/cmdline and split off arguments"; "proc_1_cmdline" string => nth("proc_1_cmdline_split", 0), comment => "Get argv[0] of /proc/1/cmdline"; # this is the same as the original file for non-links "proc_1_process" string => filestat($(proc_1_cmdline), "linktarget"); classes: any:: "has_os_release" expression => fileexists("/etc/os-release"), comment => "Check if we can get more info from /etc/os-release"; "os_release_has_id" expression => regextract('^ID="?([^"\s]+)"?$', $(os_release_info), "id_array"), comment => "Extract ID= line from os-release to id_array"; "os_release_has_version" expression => regextract('^VERSION_ID="?([^"]+)"?$', $(os_release_info), "version_array"), comment => "Extract VERSION_ID= line from os-release to version_array"; "has_proc_1_cmdline" expression => fileexists("/proc/1/cmdline"), comment => "Check if we can read /proc/1/cmdline"; os_release_has_id:: "$(os_release_id)" expression => "any"; os_release_has_version:: "$(os_release_id)_$(os_release_version)" expression => "any"; has_proc_1_cmdline:: "systemd" expression => strcmp(lastnode($(proc_1_process), "/"), "systemd"), comment => "Check if (the link target of) /proc/1/cmdline is systemd"; reports: inform_mode:: "$(this.bundle): OS release ID = $(os_release_id), OS release version = $(os_release_version)"; } masterfiles-3.6.2/inventory/lsb.cf000066400000000000000000000056111241300473300171670ustar00rootroot00000000000000bundle agent inventory_lsb # @brief LSB inventory bundle # # This common bundle is for LSB inventory work. { classes: "have_lsb" expression => fileexists($(lsb_exec)); "_inventory_lsb_found" expression => regcmp("^[1-9][0-9]*$", $(dim)), scope => "namespace"; _inventory_lsb_found:: "lsb_$(os)" expression => "any", comment => "LSB Distributor ID", depends_on => { "inventory_lsb_os" }, scope => "namespace", meta => { "inventory", "attribute_name=none" }; "lsb_$(os)_$(release)" expression => "any", comment => "LSB Distributor ID and Release", depends_on => { "inventory_lsb_os", "inventory_lsb_release" }, scope => "namespace", meta => { "inventory", "attribute_name=none" }; "lsb_$(os)_$(codename)" expression => "any", comment => "LSB Distributor ID and Codename", depends_on => { "inventory_lsb_os", "inventory_lsb_codename" }, scope => "namespace", meta => { "inventory", "attribute_name=none" }; vars: "lsb_exec" string => "$(inventory_control.lsb_exec)"; have_lsb:: "data" string => execresult("$(lsb_exec) -a", "noshell"); "dim" int => parsestringarray( "lsb", $(data), "\s*#[^\n]*", "\s*:\s+", "15", "4095" ); _inventory_lsb_found:: "lsb_keys" slist => getindices("lsb"); "os" string => canonify("$(lsb[Distributor ID][1])"), handle => "inventory_lsb_os", comment => "LSB-provided OS name", meta => { "inventory", "attribute_name=none" }; "codename" string => canonify("$(lsb[Codename][1])"), handle => "inventory_lsb_codename", comment => "LSB-provided OS code name", meta => { "inventory", "attribute_name=none" }; "release" string => "$(lsb[Release][1])", handle => "inventory_lsb_release", comment => "LSB-provided OS release", meta => { "inventory", "attribute_name=none" }; "flavor" string => canonify("$(lsb[Distributor ID][1])_$(lsb[Release][1])"), handle => "inventory_lsb_flavor", comment => "LSB-provided OS flavor", meta => { "inventory", "attribute_name=none" }; "description" string => "$(lsb[Description][1])", handle => "inventory_lsb_description", comment => "LSB-provided OS description", meta => { "inventory", "attribute_name=none" }; reports: inform_mode._inventory_lsb_found:: "$(this.bundle): OS = $(os), codename = $(codename), release = $(release), flavor = $(flavor), description = $(description)"; verbose_mode._inventory_lsb_found:: "$(this.bundle): got $(dim) LSB keys"; "$(this.bundle): prepared LSB key $(lsb_keys) = '$(lsb[$(lsb_keys)][1])'"; } masterfiles-3.6.2/inventory/macos.cf000066400000000000000000000001741241300473300175100ustar00rootroot00000000000000bundle common inventory_macos # @brief Mac OS X inventory bundle # # This common bundle is for Mac OS X inventory work. { } masterfiles-3.6.2/inventory/os.cf000066400000000000000000000007601241300473300170300ustar00rootroot00000000000000bundle common inventory_os { vars: _inventory_lsb_found:: "description" string => "$(inventory_lsb.os) $(inventory_lsb.release)", meta => { "inventory", "attribute_name=OS" }; !_inventory_lsb_found.windows:: "description" string => "$(sys.release)", meta => { "inventory", "attribute_name=OS" }; !_inventory_lsb_found.!windows:: "description" string => "$(sys.flavor) (LSB missing)", meta => { "inventory", "attribute_name=OS" }; } masterfiles-3.6.2/inventory/redhat.cf000066400000000000000000000006631241300473300176600ustar00rootroot00000000000000bundle common inventory_redhat # @brief Red Hat inventory bundle # # This common bundle is for Red Hat Linux inventory work. { classes: "redhat_pure" expression => "redhat.!centos", comment => "pure Red Hat", meta => { "inventory", "attribute_name=none" }; "redhat_derived" expression => "redhat.!redhat_pure", comment => "derived from Red Hat", meta => { "inventory", "attribute_name=none" }; } masterfiles-3.6.2/inventory/suse.cf000066400000000000000000000006501241300473300173640ustar00rootroot00000000000000bundle common inventory_suse # @brief SUSE inventory bundle # # This common bundle is for SUSE Linux inventory work. { classes: "suse_pure" expression => "(sles|sled).!opensuse", comment => "pure SUSE", meta => { "inventory", "attribute_name=none" }; "suse_derived" expression => "opensuse.!suse_pure", comment => "derived from SUSE", meta => { "inventory", "attribute_name=none" }; } masterfiles-3.6.2/inventory/windows.cf000066400000000000000000000001741241300473300201000ustar00rootroot00000000000000bundle common inventory_windows # @brief Windows inventory bundle # # This common bundle is for Windows inventory work. { } masterfiles-3.6.2/lib/000077500000000000000000000000001241300473300146035ustar00rootroot00000000000000masterfiles-3.6.2/lib/3.5/000077500000000000000000000000001241300473300151105ustar00rootroot00000000000000masterfiles-3.6.2/lib/3.5/bundles.cf000066400000000000000000000270561241300473300170700ustar00rootroot00000000000000############################################################################ # Copyright (C) CFEngine AS # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License LGPL 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. # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ########################################################################### # # CFEngine Community Open Promise-Body Library # # This initiative started by CFEngine promotes a # standardized set of names and promise specifications # for template functionality within CFEngine 3. # # The aim is to promote an industry standard for # naming of configuration patterns, leading to a # de facto middleware of standardized syntax. # # Names should be intuitive and parameters should be # minimal to assist readability and comprehensibility. # Contributions to this file are voluntarily given to # the cfengine community, and are moderated by CFEngine. # No liability or warranty for misuse is implied. # # If you add to this file, please try to make the # contributions "self-documenting". Comments made # after the bundle/body statement are retained in # the online docs # # For CFEngine Core: 3.5.1 to 3.5.x # Bundles ################################################### # If you find CFEngine useful, please consider # # purchasing a commercial version of the software.# ################################################### ################################################### # agent bundles ################################################### bundle agent cronjob(commands,user,hours,mins) # For adding lines to crontab for a user # methods: # "cron" usebundle => cronjob("/bin/ls","mark","*","5,10"); { vars: SuSE:: "crontab" string => "/var/spool/cron/tabs"; redhat|fedora:: "crontab" string => "/var/spool/cron"; freebsd:: "crontab" string => "/var/cron/tabs"; !(SuSE|redhat|fedora|freebsd):: "crontab" string => "/var/spool/cron/crontabs"; files: !windows:: "$(crontab)/$(user)" comment => "A user's regular batch jobs are added to this file", create => "true", edit_line => append_if_no_line("$(mins) $(hours) * * * $(commands)"), perms => mo("600","$(user)"), classes => if_repaired("changed_crontab"); processes: changed_crontab:: "cron" comment => "Most crons need to be huped after file changes", signals => { "hup" }; } bundle agent rm_rf(name) # @brief recursively remove `name` to any depth, including base # @depends rm_rf_depth # @param name the file or directory name # # This bundle will remove `name` to any depth, including `name` itself. # # **Example:** # # ```cf3 # methods: # "bye" usebundle => rm_rf("/var/tmp/oldstuff"); # ``` { methods: "rm" usebundle => rm_rf_depth($(name),"inf"); } bundle agent rm_rf_depth(name,depth) # @brief recursively remove `name` to depth `depth`, including base # @depends recurse_with_base tidy all # @param name the file or directory name # @param depth how far to descend # # This bundle will remove `name` to depth `depth`, including `name` itself. # # **Example:** # # ```cf3 # methods: # "bye" usebundle => rm_rf_depth("/var/tmp/oldstuff", "100"); # ``` { classes: "isdir" expression => isdir($(name)); files: isdir:: "$(name)" file_select => all, depth_search => recurse_with_base($(depth)), delete => tidy; !isdir:: "$(name)" delete => tidy; } bundle agent fileinfo(f) # @brief provide access to file stat fields from the bundle caller and report # file stat info for file "f" if "verbose_mode" class is defined # @param f file or files to stat # # **Example:** # # ```cf3 # bundle agent example # { # vars: # "files" slist => { "/tmp/example1", "/tmp/example2" }; # # files: # "$(files)" # create => "true", # classes => if_ok("verbose_mode"), # comment => "verbose_mode is defined because the fileinfo bundle restricts the report of the file info to verbose mode"; # # "/tmp/example3" # create => "true", # classes => if_ok("verbose_mode"), # comment => "verbose_mode is defined because the fileinfo bundle restricts the report of the file info to verbose mode"; # # # methods: # "fileinfo" usebundle => fileinfo( @(files) ); # "fileinfo" usebundle => fileinfo( "/tmp/example3" ); # # reports: # "$(this.bundle): $(fileinfo.stat[/tmp/example3][size])"; # "$(this.bundle): $(fileinfo.stat[/tmp/example3][gid])"; # "$(this.bundle): $(fileinfo.stat[/tmp/example3][uid])"; # "$(this.bundle): $(fileinfo.stat[/tmp/example3][ino])"; # "$(this.bundle): $(fileinfo.stat[/tmp/example3][nlink])"; # "$(this.bundle): $(fileinfo.stat[/tmp/example3][ctime])"; # "$(this.bundle): $(fileinfo.stat[/tmp/example3][atime])"; # "$(this.bundle): $(fileinfo.stat[/tmp/example3][mtime])"; # "$(this.bundle): $(fileinfo.stat[/tmp/example3][mode])"; # "$(this.bundle): $(fileinfo.stat[/tmp/example3][modeoct])"; # "$(this.bundle): $(fileinfo.stat[/tmp/example3][permstr])"; # "$(this.bundle): $(fileinfo.stat[/tmp/example3][permoct])"; # "$(this.bundle): $(fileinfo.stat[/tmp/example3][type])"; # "$(this.bundle): $(fileinfo.stat[/tmp/example3][devno])"; # "$(this.bundle): $(fileinfo.stat[/tmp/example3][dev_minor])"; # "$(this.bundle): $(fileinfo.stat[/tmp/example3][dev_major])"; # "$(this.bundle): $(fileinfo.stat[/tmp/example3][basename])"; # "$(this.bundle): $(fileinfo.stat[/tmp/example3][dirname])"; # } # ``` { vars: "fields" slist => splitstring("size,gid,uid,ino,nlink,ctime,atime,mtime,mode,modeoct,permstr,permoct,type,devno,dev_minor,dev_major,basename,dirname", ",", 999); "stat[$(f)][$(fields)]" string => filestat($(f), $(fields)); reports: verbose_mode:: "$(this.bundle): file $(f) has $(fields) = $(stat[$(f)][$(fields)])"; } bundle agent logrotate(log_files, max_size, rotate_levels) # @brief rotate specified "log_files" larger than "max_size". Keep # "rotate_levels" versions of the files before overwriting the oldest one # @depends rotate # @depends bigger_than # @param log_files single file or list of files to evaluate for rotation # @param max_size minimum size in bytes that the file will grow to before being rotated # @param rotate_levels number of rotations to keep before overwriting the oldest one # # **Example:** # # ```cf3 # bundle agent example # { # vars: # "logdirs" slist => { "/var/log/syslog", "/var/log/maillog"}; # # methods: # "logrotate" usebundle => logrotate( @(logdirs), "1M", "2" ); # "logrotate" usebundle => logrotate( "/var/log/mylog, "1", "5" ); # "logrotate" usebundle => logrotate( "/var/log/alog, "500k", "7" ); # } # ``` { files: "$(log_files)" comment => "Rotate file if above specified size", rename => rotate("$(rotate_levels)"), file_select => bigger_than("$(max_size)"); } bundle agent prunedir(dir, max_days) # @brief delete plain files inside "dir" older than "max_days" (not recursively). # @depends tidy # @depends recurse # @depends filetype_older_than # @param dir directory to examine for files # @param max_days maximum number of days old a files mtime is allowed to before deletion # # **Example:** # # ```cf3 # bundle agent example # { # vars: # "dirs" slist => { "/tmp/logs", "/tmp/logs2" }; # # methods: # "prunedir" usebundle => prunedir( @(dirs), "1" ); # } # ``` { files: "$(dir)" comment => "Delete plain files inside directory older than max_days", delete => tidy, file_select => filetype_older_than("plain", "$(max_days)"), depth_search => recurse("1"); } bundle agent tcdb_fix # @brief Optimize tcdb and repair tcdb corruption # # **Example**: # ```cf3 # methods: # "Manage Tokyo Cabinet Corruption" # usebundle => tcdb_fix, # handle => "main_methods_tcdb_fix", # comment => "Optimize/Repair or regenerate corrupt tcdb files"; # ``` # This bundle works around corruption issues with Tokyo Cabinet database files # in CFEngine 3.5. Find all tcdb files in $(sys.workdir) and run tchmgr # optimize on them. If any invalid record headers are found we remove the # affected database so that it can be re-created. This occurs hourly based on # `splayclass` and assumes a 5 minute agent execution interval. { vars: linux:: "db" slist => splitstring( execresult("/usr/bin/find $(sys.workdir) -name '*.tcdb' 2>/dev/null", "useshell"), "\n", "1000"); classes: # NOTE: assumes that CFEngine is set to run every 5 minutes "hourly_class" expression => splayclass("$(sys.host)$(sys.ipv4)", "hourly"); hourly_class.linux:: "detected_invalid_record_$(db)" expression => returnszero("/var/cfengine/bin/tchmgr optimize $(db) 2>&1 | grep -q 'invalid record header'", "useshell"); commands: "$(paths.rm)" args => "-f $(db)", ifvarclass => canonify("detected_invalid_record_$(db)"), classes => scoped_classes_generic("bundle", "absent_$(db)"), handle => "fix_tcdb_commands_detected_invalid_record_rm_$(db)", comment => "Invalid record headers indicate that the database corruption is beyond repair. It will be automatically re-created."; reports: "$(this.bundle) $(sys.fqhost): Detected invalid record header in $(db) - tried to repair" ifvarclass => canonify("detected_invalid_record_$(db)"); "$(this.bundle) $(sys.fqhost): Repair failed, removed corrupt database: $(db)" ifvarclass => canonify("absent_$(db)_repaired"); } bundle agent url_ping(host, method, port, uri) # @brief ping HOST:PORT/URI using METHOD # @param host the host name # @param method the HTTP method (HEAD or GET) # @param port the port number, e.g. 80 # @param uri the URI, e.g. /path/to/resource # # This bundle will send a simple HTTP request and read 20 bytes back, # then compare them to `200 OK.*` (ignoring leading spaces). # # If the data matches, the global class "url_ok_HOST" will be set, where # HOST is the canonified host name, i.e. `canonify($(host))` # # **Example:** # # ```cf3 # methods: # "check" usebundle => url_ping("cfengine.com", "HEAD", "80", "/bill/was/here"); # reports: # url_ok_cfengine_com:: # "CFEngine's web site is up"; # url_not_ok_cfengine_com:: # "CFEngine's web site *may* be down. Or you're offline."; # ``` { vars: "url_check" string => readtcp($(host), $(port), "$(method) $(uri) HTTP/1.1$(const.r)$(const.n)Host:$(host)$(const.r)$(const.n)$(const.r)$(const.n)", 20); "chost" string => canonify($(host)); classes: "url_ok_$(chost)" scope => "namespace", expression => regcmp("[^\n]*200 OK.*\n.*", $(url_check)); "url_not_ok_$(chost)" scope => "namespace", not => regcmp("[^\n]*200 OK.*\n.*", $(url_check)); reports: verbose_mode:: "$(this.bundle): $(method) $(host):$(port)/$(uri) got 200 OK" ifvarclass => "url_ok_$(chost)"; "$(this.bundle): $(method) $(host):$(port)/$(uri) did *not* get 200 OK" ifvarclass => "url_not_ok_$(chost)"; } masterfiles-3.6.2/lib/3.5/cfe_internal.cf000066400000000000000000000052131241300473300200540ustar00rootroot00000000000000############################################################################ # Copyright (C) CFEngine AS # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License LGPL 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. # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ########################################################################### # # CFEngine Community Open Promise-Body Library # # This initiative started by CFEngine promotes a # standardized set of names and promise specifications # for template functionality within CFEngine 3. # # The aim is to promote an industry standard for # naming of configuration patterns, leading to a # de facto middleware of standardized syntax. # # Names should be intuitive and parameters should be # minimal to assist readability and comprehensibility. # Contributions to this file are voluntarily given to # the cfengine community, and are moderated by CFEngine. # No liability or warranty for misuse is implied. # # If you add to this file, please try to make the # contributions "self-documenting". Comments made # after the bundle/body statement are retained in # the online docs # # For CFEngine Core: 3.5.0 to 3.5.x # Internal hub maintenance bundles ################################################### # If you find CFEngine useful, please consider # # purchasing a commercial version of the software.# ################################################### bundle agent cfe_internal_hub_maintain # @brief Executes reporting database maintenance process # When modifying this, the following must be considered: # - Intervals less than 6 hours must be used with caution # as maintenance process could take a considerable time # - parameters to action => bg("", "") # must be changed accordingly { commands: (Hr00|Hr06|Hr12|Hr18).Min00_05:: "$(sys.cf_hub) -m" comment => "Perform hub database maintenance. This removes expired entries in the enterprise database and creates a total compliance cache for Mission Portal", classes => kept_successful_command, handle => "cfe_internal_start_hub_start_maintenance", action => bg("60","60"); } masterfiles-3.6.2/lib/3.5/commands.cf000066400000000000000000000114611241300473300172260ustar00rootroot00000000000000############################################################################ # Copyright (C) CFEngine AS # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License LGPL 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. # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ########################################################################### # # CFEngine Community Open Promise-Body Library # # This initiative started by CFEngine promotes a # standardized set of names and promise specifications # for template functionality within CFEngine 3. # # The aim is to promote an industry standard for # naming of configuration patterns, leading to a # de facto middleware of standardized syntax. # # Names should be intuitive and parameters should be # minimal to assist readability and comprehensibility. # Contributions to this file are voluntarily given to # the cfengine community, and are moderated by CFEngine. # No liability or warranty for misuse is implied. # # If you add to this file, please try to make the # contributions "self-documenting". Comments made # after the bundle/body statement are retained in # the online docs # # For CFEngine Core: 3.5.1 to 3.5.x # Commands bodies ################################################### # If you find CFEngine useful, please consider # # purchasing a commercial version of the software.# ################################################### bundle agent daemonize(command) # @brief Run a command as a daemon. I.e., fully detaches from Cfengine. # @param command The command to run detached # Note: There will be no output from the command reported by cf-agent. This # bundle has no effect on windows # # **Example:** # ```cf3 # methods: # "Launch Daemon" # usebundle => daemonize("/bin/sleep 30"); # ``` { commands: !windows:: "exec 1>&-; exec 2>&-; $(command) &" contain => in_shell; reports: windows.(inform_mode|verbose_mode):: "$(this.bundle): This bundle does not support Windows"; } ##------------------------------------------------------- ## contain ##------------------------------------------------------- body contain silent { no_output => "true"; } ## body contain in_dir(s) { chdir => "$(s)"; } ## body contain in_dir_shell(s) { chdir => "$(s)"; useshell => "true"; # canonical "useshell" but this is backwards-compatible } ## body contain silent_in_dir(s) { chdir => "$(s)"; no_output => "true"; } ## body contain in_shell { useshell => "true"; # canonical "useshell" but this is backwards-compatible } ## body contain in_shell_bg { useshell => "true"; # canonical "useshell" but this is backwards-compatible } ## body contain in_shell_and_silent { useshell => "true"; # canonical "useshell" but this is backwards-compatible no_output => "true"; } ## body contain in_dir_shell_and_silent(dir) { useshell => "true"; # canonical "useshell" but this is backwards-compatible no_output => "true"; chdir => "$(dir)"; } ## body contain setuid(x) { exec_owner => "$(x)"; useshell => "false"; # canonical "noshell" but this is backwards-compatible } ## body contain setuid_sh(x) { exec_owner => "$(x)"; useshell => "true"; # canonical "useshell" but this is backwards-compatible } ## body contain setuidgid_sh(owner,group) { exec_owner => "$(owner)"; exec_group => "$(group)"; useshell => "true"; # canonical "useshell" but this is backwards-compatible } ## body contain jail(owner,root,dir) { exec_owner => "$(owner)"; useshell => "true"; # canonical "useshell" but this is backwards-compatible chdir => "$(dir)"; chroot => "$(root)"; } ## body contain setuid_umask(uid, umask) ################################################### # | Files | Directories # ################################################### # Umask | Octal Symbolic | Octal Symbolic # ########+#####################+###################+ # 000 | 666 (rw-rw-rw-) | 777 (rwxrwxrwx) # 002 | 664 (rw-rw-r--) | 775 (rwxrwxr-x) # 022 | 644 (rw-r--r--) | 755 (rwxr-xr-x) # 027 | 640 (rw-r-----) | 750 (rwxr-x---) # 077 | 600 (rw-------) | 700 (rwx------) # 277 | 400 (r--------) | 500 (r-x------) { exec_owner => "$(uid)"; umask => "$(umask)"; } masterfiles-3.6.2/lib/3.5/common.cf000066400000000000000000000152521241300473300167170ustar00rootroot00000000000000############################################################################ # Copyright (C) CFEngine AS # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License LGPL 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. # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ########################################################################### # # CFEngine Community Open Promise-Body Library # # This initiative started by CFEngine promotes a # standardized set of names and promise specifications # for template functionality within CFEngine 3. # # The aim is to promote an industry standard for # naming of configuration patterns, leading to a # de facto middleware of standardized syntax. # # Names should be intuitive and parameters should be # minimal to assist readability and comprehensibility. # Contributions to this file are voluntarily given to # the cfengine community, and are moderated by CFEngine. # No liability or warranty for misuse is implied. # # If you add to this file, please try to make the # contributions "self-documenting". Comments made # after the bundle/body statement are retained in # the online docs # # For CFEngine Core: 3.5.1 to 3.5.x # Common bodies ################################################### # If you find CFEngine useful, please consider # # purchasing a commercial version of the software.# ################################################### #################################################### ## agent bodyparts #################################################### ##------------------------------------------------------- ## action ##------------------------------------------------------- body action if_elapsed(x) { ifelapsed => "$(x)"; expireafter => "$(x)"; } ## body action if_elapsed_day { ifelapsed => "1440"; # 60 x 24 expireafter => "1400"; } ## body action measure_performance(x) { measurement_class => "Detect changes in $(this.promiser)"; ifelapsed => "$(x)"; expireafter => "$(x)"; } ## body action warn_only { action_policy => "warn"; ifelapsed => "60"; } ## body action bg(elapsed,expire) { ifelapsed => "$(elapsed)"; expireafter => "$(expire)"; background => "true"; } ## body action ifwin_bg { windows:: background => "true"; } ## body action immediate { ifelapsed => "0"; } ## body action policy(p) { action_policy => "$(p)"; } ## # Log a message to log=[/file|stdout] body action log_repaired(log,message) { log_string => "$(sys.date), $(message)"; log_repaired => "$(log)"; } ### body action log_verbose { log_level => "verbose"; } ## body action sample_rate(x) { ifelapsed => "$(x)"; expireafter => "10"; } ##------------------------------------------------------- ## classes ##------------------------------------------------------- body classes if_repaired(x) { promise_repaired => { "$(x)" }; } ## body classes if_else(yes,no) { promise_kept => { "$(yes)" }; promise_repaired => { "$(yes)" }; repair_failed => { "$(no)" }; repair_denied => { "$(no)" }; repair_timeout => { "$(no)" }; } ## body classes cf2_if_else(yes,no) # meant to match cf2 semantics { promise_repaired => { "$(yes)" }; repair_failed => { "$(no)" }; repair_denied => { "$(no)" }; repair_timeout => { "$(no)" }; } ## body classes if_notkept(x) { repair_failed => { "$(x)" }; repair_denied => { "$(x)" }; repair_timeout => { "$(x)" }; } ## body classes if_ok(x) { promise_repaired => { "$(x)" }; promise_kept => { "$(x)" }; } ## body classes if_ok_cancel(x) { cancel_repaired => { "$(x)" }; cancel_kept => { "$(x)" }; } ## body classes cmd_repair(code,cl) { repaired_returncodes => { "$(code)" }; promise_repaired => { "$(cl)" }; } body classes classes_generic(x) # Define x prefixed/suffixed with promise outcome { promise_repaired => { "promise_repaired_$(x)", "$(x)_repaired", "$(x)_ok", "$(x)_reached" }; repair_failed => { "repair_failed_$(x)", "$(x)_failed", "$(x)_not_ok", "$(x)_error", "$(x)_not_kept", "$(x)_not_repaired", "$(x)_reached" }; repair_denied => { "repair_denied_$(x)", "$(x)_denied", "$(x)_not_ok", "$(x)_error", "$(x)_not_kept", "$(x)_not_repaired", "$(x)_reached" }; repair_timeout => { "repair_timeout_$(x)", "$(x)_timeout", "$(x)_not_ok", "$(x)_error", "$(x)_not_kept", "$(x)_not_repaired", "$(x)_reached" }; promise_kept => { "promise_kept_$(x)", "$(x)_kept", "$(x)_ok", "$(x)_not_repaired", "$(x)_reached" }; } body classes scoped_classes_generic(scope, x) # Define x prefixed/suffixed with promise outcome { scope => "$(scope)"; promise_repaired => { "promise_repaired_$(x)", "$(x)_repaired", "$(x)_ok", "$(x)_reached" }; repair_failed => { "repair_failed_$(x)", "$(x)_failed", "$(x)_not_ok", "$(x)_error", "$(x)_not_kept", "$(x)_not_repaired", "$(x)_reached" }; repair_denied => { "repair_denied_$(x)", "$(x)_denied", "$(x)_not_ok", "$(x)_error", "$(x)_not_kept", "$(x)_not_repaired", "$(x)_reached" }; repair_timeout => { "repair_timeout_$(x)", "$(x)_timeout", "$(x)_not_ok", "$(x)_error", "$(x)_not_kept", "$(x)_not_repaired", "$(x)_reached" }; promise_kept => { "promise_kept_$(x)", "$(x)_kept", "$(x)_ok", "$(x)_not_repaired", "$(x)_reached" }; } ##------------------------------------------------------- ## Persistent classes ##------------------------------------------------------- body classes state_repaired(x) { promise_repaired => { "$(x)" }; persist_time => "10"; } ## body classes enumerate(x) # # This is used by commercial editions to count # instances of jobs in a cluster # { promise_repaired => { "mXC_$(x)" }; promise_kept => { "mXC_$(x)" }; persist_time => "15"; } ## body classes always(x) # Define a class no matter what the outcome of the promise is { promise_repaired => { "$(x)" }; promise_kept => { "$(x)" }; repair_failed => { "$(x)" }; repair_denied => { "$(x)" }; repair_timeout => { "$(x)" }; } body classes kept_successful_command # @brief Set command to "kept" instead of "repaired" if it returns 0 { kept_returncodes => { "0" }; } masterfiles-3.6.2/lib/3.5/databases.cf000066400000000000000000000050331241300473300173520ustar00rootroot00000000000000############################################################################ # Copyright (C) CFEngine AS # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License LGPL 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. # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ########################################################################### # # CFEngine Community Open Promise-Body Library # # This initiative started by CFEngine promotes a # standardized set of names and promise specifications # for template functionality within CFEngine 3. # # The aim is to promote an industry standard for # naming of configuration patterns, leading to a # de facto middleware of standardized syntax. # # Names should be intuitive and parameters should be # minimal to assist readability and comprehensibility. # Contributions to this file are voluntarily given to # the cfengine community, and are moderated by CFEngine. # No liability or warranty for misuse is implied. # # If you add to this file, please try to make the # contributions "self-documenting". Comments made # after the bundle/body statement are retained in # the online docs # # For CFEngine Core: 3.5.1 to 3.5.x # Databases bodies ################################################### # If you find CFEngine useful, please consider # # purchasing a commercial version of the software.# ################################################### ##------------------------------------------------------- ## database promises ##------------------------------------------------------- body database_server local_mysql(username, password) { db_server_owner => "$(username)"; db_server_password => "$(password)"; db_server_host => "localhost"; db_server_type => "mysql"; db_server_connection_db => "mysql"; } ## body database_server local_postgresql(username, password) { db_server_owner => "$(username)"; db_server_password => "$(password)"; db_server_host => "localhost"; db_server_type => "postgres"; db_server_connection_db => "postgres"; } masterfiles-3.6.2/lib/3.5/feature.cf000066400000000000000000000064741241300473300170700ustar00rootroot00000000000000bundle agent feature # @brief Finds feature_set_X and feature_unset_X classes and sets/unsets X persistently # # Finds all classes named `feature_unset_X` and clear class X. # # Finds all classes named `feature_set_DURATION_X` and sets class X # persistently for DURATION. DURATION can be any digits followed by # `k`, `m`, or `g`. # # In inform mode (`-I`) it will report what it does. # # **Example:** # Set class `xyz` for 10 minutes, class `qpr` for 100 minutes, and # `ijk` for 90m minutes. Unset class `abc`. # `cf-agent -I -f ./feature.cf -b feature -Dfeature_set_10_xyz,feature_set_100_qpr,feature_set_90m_ijk,feature_unset_abc` { classes: "parsed_$(on)" expression => regextract("feature_set_([0-9]+[kmgKMG]?)_(.*)", $(on), "extract_$(on)"); "parsed_$(off)" expression => regextract("feature_unset_(.*)", $(off), "extract_$(off)"); "$(extract_$(on)[2])" expression => "parsed_$(on)", persistence => "$(extract_$(on)[1])"; vars: "on" slist => classesmatching("feature_set_.*"); "off" slist => classesmatching("feature_unset_.*"); "_$(off)" string => "off", classes => feature_cancel("$(extract_$(off)[1])"); reports: inform_mode:: "$(this.bundle): $(on) => SET class '$(extract_$(on)[2]) for '$(extract_$(on)[1])'" ifvarclass => "parsed_$(on)"; "$(this.bundle): $(off) => UNSET class '$(extract_$(off)[1])'" ifvarclass => "parsed_$(off)"; "$(this.bundle): have $(extract_$(on)[2])" ifvarclass => "$(extract_$(on)[2])"; "$(this.bundle): have no $(extract_$(on)[2])" ifvarclass => "!$(extract_$(on)[2])"; "$(this.bundle): have $(extract_$(off)[1])" ifvarclass => "$(extract_$(off)[1])"; "$(this.bundle): have no $(extract_$(off)[1])" ifvarclass => "!$(extract_$(off)[1])"; } bundle agent feature_test # @brief Finds feature_set_X and feature_unset_X classes and reports X # # Note that this bundle is intended to be used exactly like `feature` # and just show what's defined or undefined. # # **Example:** # Check classes `xyz`, `qpr`, `ijk`, and `abc`. # `cf-agent -I -f ./feature.cf -b feature_test -Dfeature_set_10_xyz,feature_set_100_qpr,feature_set_90m_ijk,feature_unset_abc` { classes: "parsed_$(on)" expression => regextract("feature_set_([0-9]+[kmgKMG]?)_(.*)", $(on), "extract_$(on)"); "parsed_$(off)" expression => regextract("feature_unset_(.*)", $(off), "extract_$(off)"); vars: "on" slist => classesmatching("feature_set_.*"); "off" slist => classesmatching("feature_unset_.*"); reports: "$(this.bundle): have $(extract_$(on)[2])" ifvarclass => "$(extract_$(on)[2])"; "$(this.bundle): have no $(extract_$(on)[2])" ifvarclass => "!$(extract_$(on)[2])"; "$(this.bundle): have $(extract_$(off)[1])" ifvarclass => "$(extract_$(off)[1])"; "$(this.bundle): have no $(extract_$(off)[1])" ifvarclass => "!$(extract_$(off)[1])"; } body classes feature_cancel(x) { cancel_kept => { "$(x)" }; cancel_repaired => { "$(x)" }; } masterfiles-3.6.2/lib/3.5/files.cf000066400000000000000000001131761241300473300165350ustar00rootroot00000000000000############################################################################ # Copyright (C) CFEngine AS # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License LGPL 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. # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ########################################################################### # # CFEngine Community Open Promise-Body Library # # This initiative started by CFEngine promotes a # standardized set of names and promise specifications # for template functionality within CFEngine 3. # # The aim is to promote an industry standard for # naming of configuration patterns, leading to a # de facto middleware of standardized syntax. # # Names should be intuitive and parameters should be # minimal to assist readability and comprehensibility. # Contributions to this file are voluntarily given to # the cfengine community, and are moderated by CFEngine. # No liability or warranty for misuse is implied. # # If you add to this file, please try to make the # contributions "self-documenting". Comments made # after the bundle/body statement are retained in # the online docs # # For CFEngine Core: 3.5.1 to 3.5.x # Files bodies ################################################### # If you find CFEngine useful, please consider # # purchasing a commercial version of the software.# ################################################### ################################################### # edit_line bundles ################################################### bundle edit_line insert_lines(lines) { insert_lines: "$(lines)" comment => "Append lines if they don't exist"; } ## bundle edit_line insert_file(templatefile) { insert_lines: "$(templatefile)" comment => "Insert the template file into the file being edited", insert_type => "file"; } ## bundle edit_line comment_lines_matching(regex,comment) # Comment lines of a file matching a regex { replace_patterns: "^($(regex))$" replace_with => comment("$(comment)"), comment => "Search and replace string"; } ## bundle edit_line uncomment_lines_matching(regex,comment) # Uncomment lines of a file where the regex matches # the text after the comment string { replace_patterns: "^$(comment)\s?($(regex))$" replace_with => uncomment, comment => "Uncomment lines matching a regular expression"; } ## bundle edit_line comment_lines_containing(regex,comment) # Comment lines of a file containing a regex { replace_patterns: "^((?!$(comment)).*$(regex).*)$" replace_with => comment("$(comment)"), comment => "Comment out lines in a file"; } ## bundle edit_line uncomment_lines_containing(regex,comment) # Uncomment lines of a file where the regex matches # the text after the comment string { replace_patterns: "^$(comment)\s?(.*$(regex).*)$" replace_with => uncomment, comment => "Uncomment a line containing a fragment"; } ## bundle edit_line delete_lines_matching(regex) { delete_lines: "$(regex)" comment => "Delete lines matching regular expressions"; } ## bundle edit_line warn_lines_matching(regex) { delete_lines: "$(regex)" comment => "Warn about lines in a file", action => warn_only; } ## bundle edit_line append_if_no_line(str) { insert_lines: "$(str)" comment => "Append a line to the file if it doesn't already exist"; } ## bundle edit_line append_if_no_lines(list) { insert_lines: "$(list)" comment => "Append lines to the file if they don't already exist"; } ## bundle edit_line replace_line_end(start,end) # # Lines starting with "$(start)" will get the ending given in "$(end)", # whitespaces will be left unmodified. # For example, replace_line_end("ftp", "2121/tcp") would replace # "ftp 21/tcp" # with # "ftp 2121/tcp" { field_edits: "\s*$(start)\s.*" comment => "Replace lines with $(this.start) and $(this.end)", edit_field => line("(^|\s)$(start)\s*", "2", "$(end)","set"); } ## bundle edit_line append_to_line_end(start,end) # @brief Append `end` to any lines beginning with `start` # @param start pattern to match lines of interest # @param end string to append to matched lines # # `end` will be appended to all lines starting with `start` and not # already ending with `end`. Whitespaces will be left unmodified. # # For example, `append_to_line_end("kernel", "vga=791")` would replace # `kernel /boot/vmlinuz root=/dev/sda7` # with # `kernel /boot/vmlinuz root=/dev/sda7 vga=791` # # **WARNING**: Be careful not to have multiple promises matching the same line, which would result in the line growing indefinitely. # # **Example:** # # ```cf3 # files: # "/tmp/boot-options" edit_line => append_to_line_end("kernel", "vga=791"); # ``` # { field_edits: "\s*$(start)\s.*" comment => "Append lines with $(this.start) and $(this.end)", edit_field => line("(^|\s)$(start)\s*", "2", "$(end)","append"); } ## bundle edit_line regex_replace(find,replace) # You can think of this like a PCRE powered sed. # Find exactly a regular expression and replace exactly the match with a string. { replace_patterns: "$(find)" replace_with => value("$(replace)"), comment => "Search and replace string"; } ## bundle edit_line resolvconf(search,list) # search is the search domains with space # list is an slist of nameserver addresses { delete_lines: "search.*" comment => "Reset search lines from resolver"; "nameserver.*" comment => "Reset nameservers in resolver"; insert_lines: "search $(search)" comment => "Add search domains to resolver"; "nameserver $(list)" comment => "Add name servers to resolver"; } ## bundle edit_line resolvconf_o(search,list,options) # search is the search domains with space # list is an slist of nameserver addresses # options is an slist of variables to modify the resolver { delete_lines: "search.*" comment => "Reset search lines from resolver"; "nameserver.*" comment => "Reset nameservers in resolver"; "options.*" comment => "Reset options in resolver"; insert_lines: "search $(search)" comment => "Add search domains to resolver"; "nameserver $(list)" comment => "Add name servers to resolver"; "options $(options)" comment => "Add options to resolver"; } ## bundle edit_line manage_variable_values_ini(tab, sectionName) # Sets the RHS of configuration items in the file of the form # LHS=RHS # If the line is commented out with #, it gets uncommented first. # Adds a new line if none exists. # Removes any variable value pairs not defined for the ini section # The argument is an associative array containing tab[SectionName][LHS]="RHS" # don't change value when the RHS is dontchange # Based on set_variable_values_ini # Added delete lines section to empty out undefined variable values for INI section # CAUTION : for it to work nicely, you should use CFEngine with the commit n°3229 # otherwise you may risk a segfault # # If you are running 3.2.1 or earlier or more specifically git commit # or # earlier you can use this to work around the segfault bug. # vars: # "$(file)" # edit_line => append_if_no_line("[#EOF#]"), # create => "true", # comment => "Work around bug where eof did not mean end # of section and thus cannot select a region. This promise # should be placed before your call to this bundle"; # "$(file)" # edit_line => manage_variable_values_ini("context.array", "SectionName"), # create => "true", # comment => "Set the variale values only in the specified ini region"; # { vars: "index" slist => getindices("$(tab)[$(sectionName)]"); # Be careful if the index string contains funny chars "cindex[$(index)]" string => canonify("$(index)"); classes: "edit_$(cindex[$(index)])" not => strcmp("$($(tab)[$(sectionName)][$(index)])","dontchange"), comment => "Create conditions to make changes"; field_edits: # If the line is there, but commented out, first uncomment it "#+\s*$(index)\s*=.*" select_region => INI_section("$(sectionName)"), edit_field => col("=","1","$(index)","set"), ifvarclass => "edit_$(cindex[$(index)])"; # match a line starting like the key something "$(index)\s*=.*" edit_field => col("=","2","$($(tab)[$(sectionName)][$(index)])","set"), select_region => INI_section("$(sectionName)"), classes => if_ok("manage_variable_values_ini_not_$(cindex[$(index)])"), ifvarclass => "edit_$(cindex[$(index)])"; delete_lines: ".*" select_region => INI_section("$(sectionName)"), comment => "Remove all entries in the region so there are no extra entries"; insert_lines: "[$(sectionName)]" location => start, comment => "Insert lines"; "$(index)=$($(tab)[$(sectionName)][$(index)])" select_region => INI_section("$(sectionName)"), ifvarclass => "!manage_variable_values_ini_not_$(cindex[$(index)]).edit_$(cindex[$(index)])"; } ## bundle edit_line set_variable_values_ini(tab, sectionName) # Sets the RHS of configuration items in the file of the form # LHS=RHS # If the line is commented out with #, it gets uncommented first. # Adds a new line if none exists. # The argument is an associative array containing tab[SectionName][LHS]="RHS" # don't change value when the RHS is dontchange # Based on set_variable_values from cfengine_stdlib.cf, modified to # use section to define were to write, and to handle commented-out lines. # CAUTION : for it to work nicely, you should use CFEngine with the commit n°3229 # otherwise you may risk a segfault # # If you are running 3.2.1 or earlier or more specifically git commit # or # earlier you can use this to work around the segfault bug. # vars: # "$(file)" # edit_line => append_if_no_line("[#EOF#]"), # create => "true", # comment => "Work around bug where eof did not mean end # of section and thus cannot select a region. This promise # should be placed before your call to this bundle"; # "$(file)" # edit_line => set_variable_values_ini("context.array", "SectionName"), # create => "true", # comment => "Set the variale values only in the specified ini region"; # { vars: "index" slist => getindices("$(tab)[$(sectionName)]"); # Be careful if the index string contains funny chars "cindex[$(index)]" string => canonify("$(index)"); classes: "edit_$(cindex[$(index)])" not => strcmp("$($(tab)[$(sectionName)][$(index)])","dontchange"), comment => "Create conditions to make changes"; field_edits: # If the line is there, but commented out, first uncomment it "#+\s*$(index)\s*=.*" select_region => INI_section("$(sectionName)"), edit_field => col("=","1","$(index)","set"), ifvarclass => "edit_$(cindex[$(index)])"; # match a line starting like the key something "$(index)\s*=.*" edit_field => col("=","2","$($(tab)[$(sectionName)][$(index)])","set"), select_region => INI_section("$(sectionName)"), classes => if_ok("set_variable_values_ini_not_$(cindex[$(index)])"), ifvarclass => "edit_$(cindex[$(index)])"; insert_lines: "[$(sectionName)]" location => start, comment => "Insert lines"; "$(index)=$($(tab)[$(sectionName)][$(index)])" select_region => INI_section("$(sectionName)"), ifvarclass => "!set_variable_values_ini_not_$(cindex[$(index)]).edit_$(cindex[$(index)])"; } bundle edit_line set_quoted_values(v) { # Sets the RHS of variables in shell-like files # that is: # LHS="RHS" # Adds a new line if no LHS exists # repairs RHS values if one does exist # If the line is commented out with #, it gets uncommented first. # # To use: # 1) Define an array, where the keys are the LHS and the values are the RHS # "stuff[lhs-1]" string => "rhs1"; # "stuff[lhs-2]" string => "rhs2"; # 2) The parameter passed to the edit_line promise is the fully qualified # name of the array (i.e., "bundlename.stuff") WITHOUT any "$" or "@" vars: "index" slist => getindices("$(v)"); # Be careful if the index string contains funny chars "cindex[$(index)]" string => canonify("$(index)"); field_edits: # If the line is there, but commented out, first uncomment it "#+\s*$(index)\s*=.*" edit_field => col("=","1","$(index)","set"); # match a line starting like the key = something "\s*$(index)\s*=.*" edit_field => col("=","2",'"$($(v)[$(index)])"',"set"), classes => if_ok("$(cindex[$(index)])_in_file"), comment => "Match a line starting like key = something"; insert_lines: '$(index)="$($(v)[$(index)])"' comment => "Insert a variable definition", ifvarclass => "!$(cindex[$(index)])_in_file"; } ## bundle edit_line set_variable_values(v) # Sets the RHS of variables in the file of the form # LHS = RHS # Adds a new line if no LHS exists, repairs RHS values if one does exist # # To use: # 1) Define an array, where the keys are the LHS and the values are the RHS # "stuff[lhs-1]" string => "rhs1"; # "stuff[lhs-2]" string => "rhs2"; # 2) The parameter passed to the edit_line promise is the fully qualified # name of the array (i.e., "bundlename.stuff") WITHOUT any "$" or "@" { vars: "index" slist => getindices("$(v)"); # Be careful if the index string contains funny chars "cindex[$(index)]" string => canonify("$(index)"); "cv" string => canonify("$(v)"); field_edits: # match a line starting like the key = something "\s*$(index)\s*=.*" edit_field => col("\s*$(index)\s*=","2","$($(v)[$(index)])","set"), classes => if_ok("$(cv)_$(cindex[$(index)])_in_file"), comment => "Match a line starting like key = something"; insert_lines: "$(index)=$($(v)[$(index)])" comment => "Insert a variable definition", ifvarclass => "!$(cv)_$(cindex[$(index)])_in_file"; } bundle edit_line set_config_values(v) # Sets the RHS of configuration items in the file of the form # LHS RHS # If the line is commented out with #, it gets uncommented first. # Adds a new line if none exists. # The argument is the fully-qualified name of an associative array containing v[LHS]="rhs" { vars: "index" slist => getindices("$(v)"); # Be careful if the index string contains funny chars "cindex[$(index)]" string => canonify("$(index)"); # Escape the value (had a problem with special characters and regex's) "ev[$(index)]" string => escape("$($(v)[$(index)])"); # Do we have more than one line commented out? "index_comment_matches_$(cindex[$(index)])" int => countlinesmatching("^\s*#\s*($(index)\s+.*|$(index))$","$(edit.filename)"); classes: # Check to see if this line exists "line_exists_$(cindex[$(index)])" expression => regline("^\s*($(index)\s.*|$(index))$","$(edit.filename)"); # if there's more than one comment, just add new (don't know who to use) "multiple_comments_$(cindex[$(index)])" expression => isgreaterthan("$(index_comment_matches_$(cindex[$(index)]))","1"); replace_patterns: # If the line is commented out, uncomment and replace with # the correct value "^\s*#\s*($(index)\s+.*|$(index))$" comment => "Uncommented the value $(index)", replace_with => value("$(index) $($(v)[$(index)])"), ifvarclass => "!line_exists_$(cindex[$(index)]).!replace_attempted_$(cindex[$(index)]).!multiple_comments_$(cindex[$(index)])", classes => always("uncommented_$(cindex[$(index)])"); # If the line is there with the wrong value, replace with # the correct value "^\s*($(index)\s+(?!$(ev[$(index)])$).*|$(index))$" comment => "Correct the value $(index)", replace_with => value("$(index) $($(v)[$(index)])"), classes => always("replace_attempted_$(cindex[$(index)])"); insert_lines: # If the line doesn't exist, or there is more than one occurrence # of the LHS commented out, insert a new line and try to place it # after the commented LHS (keep new line with old comments) "$(index) $($(v)[$(index)])" comment => "Insert the value, marker exists $(index)", location => after("^\s*#\s*($(index)\s+.*|$(index))$"), ifvarclass => "replace_attempted_$(cindex[$(index)]).multiple_comments_$(cindex[$(index)])"; # If the line doesn't exist and there are no occurances # of the LHS commented out, insert a new line at the eof "$(index) $($(v)[$(index)])" comment => "Insert the value, marker doesn't exist $(index)", ifvarclass => "replace_attempted_$(cindex[$(index)]).!multiple_comments_$(cindex[$(index)])"; } bundle edit_line set_config_values_matching(v,pat) # Sets the RHS of configuration items in the file of the form # LHS RHS # If the line is commented out with #, it gets uncommented first. # Adds a new line if none exists. # Only elements of "v" that match the regex "pat" are used # The argument is the fully-qualified name of an associative array containing v[LHS]="rhs" { vars: "allparams" slist => getindices("$(v)"); "index" slist => grep("$(pat)", "allparams"); # Be careful if the index string contains funny chars "cindex[$(index)]" string => canonify("$(index)"); replace_patterns: # If the line is there, maybe commented out, uncomment and replace with # the correct value "^\s*($(index)\s+(?!$($(v)[$(index)])).*|# ?$(index)\s+.*)$" comment => "Correct the value", replace_with => value("$(index) $($(v)[$(index)])"), classes => always("replace_attempted_$(cindex[$(index)])"); insert_lines: "$(index) $($(v)[$(index)])" ifvarclass => "replace_attempted_$(cindex[$(index)])"; } ## bundle edit_line maintain_key_values(v,sep) # Contributed by David Lee # Purpose: Sets the RHS of configuration items with an giving separator { vars: "index" slist => getindices("$(v)"); # Be careful if the index string contains funny chars "cindex[$(index)]" string => canonify("$(index)"); # Matching pattern for line (basically key-and-separator) "keypat[$(index)]" string => "\s*$(index)\s*$(sep)\s*"; # Values may contain regexps. Escape them for replace_pattern matching. "ve[$(index)]" string => escape("$($(v)[$(index)])"); classes: "$(cindex[$(index)])_key_in_file" comment => "Dynamic Class created if patterns matching", expression => regline("^$(keypat[$(index)]).*", "$(edit.filename)"); replace_patterns: # For convergence need to use negative lookahead on value: # "key sep (?!value).*" "^($(keypat[$(index)]))(?!$(ve[$(index)])$).*" comment => "Replace definition of $(index)", replace_with => value("$(match.1)$($(v)[$(index)])"); insert_lines: "$(index)$(sep)$($(v)[$(index)])" comment => "Insert definition of $(index)", ifvarclass => "!$(cindex[$(index)])_key_in_file"; } ## bundle edit_line append_users_starting(v) # For adding to /etc/passwd or etc/shadow, needs # an array v[username] string => "line..." { vars: "index" slist => getindices("$(v)"); classes: "add_$(index)" not => userexists("$(index)"), comment => "Class created if user does not exist"; insert_lines: "$($(v)[$(index)])" comment => "Append users into a password file format", ifvarclass => "add_$(index)"; } ## bundle edit_line append_groups_starting(v) # For adding groups to /etc/group, needs # an array v[groupname] string => "line..." { vars: "index" slist => getindices("$(v)"); classes: "add_$(index)" not => groupexists("$(index)"), comment => "Class created if group does not exist"; insert_lines: "$($(v)[$(index)])" comment => "Append users into a group file format", ifvarclass => "add_$(index)"; } ## bundle edit_line set_colon_field(key,field,val) # Set the value of field number "field" of the # line whose first field is "key", in a colon-separated file. { field_edits: "$(key):.*" comment => "Edit a colon-separated file, using the first field as a key", edit_field => col(":","$(field)","$(val)","set"); } ## bundle edit_line set_user_field(user,field,val) # Set the value of field number "field" in # a :-field formatted file like /etc/passwd { field_edits: "$(user):.*" comment => "Edit a user attribute in the password file", edit_field => col(":","$(field)","$(val)","set"); } ## bundle edit_line append_user_field(group,field,allusers) # For adding users to to a file like /etc/group # at field position "field", comma separated subfields { vars: "val" slist => { @(allusers) }; field_edits: "$(group):.*" comment => "Append users into a password file format", edit_field => col(":","$(field)","$(val)","alphanum"); } ## bundle edit_line expand_template(templatefile) # Read in the named text file and expand $(var) # inside the file { insert_lines: "$(templatefile)" insert_type => "file", comment => "Expand variables in the template file", expand_scalars => "true"; } bundle edit_line replace_or_add(pattern,line) # Replace a pattern in a file with a single line. # If the pattern is not found, add the line to the file. # The pattern must match the whole line (it is automatically # anchored to the start and end of the line) to avoid # ambiguity. { vars: "cline" string => canonify("$(line)"); "eline" string => escape("$(line)"); replace_patterns: "^(?!$(eline)$)$(pattern)$" comment => "Replace a pattern here", replace_with => value("$(line)"), classes => always("replace_done_$(cline)"); insert_lines: "$(line)" ifvarclass => "replace_done_$(cline)"; } bundle edit_line fstab_option_editor(method, mount, option) # @brief Add or remove /etc/fstab options for a mount # @param method `field_operation` to apply # @param mount the mount point # @param option the option to add or remove # # This bundle edits the options field of a mount. The `method` is a # `field_operation` which can be `append`, `prepend`, `set`, `delete`, # or `alphanum`. The option is OS-specific. # # **Example:** # # ```cf3 # files: # "/etc/fstab" edit_line => fstab_option_editor("delete", "/", "acl"); # "/etc/fstab" edit_line => fstab_option_editor("append", "/", "acl"); # ``` { field_edits: "(?!#)\S+\s+$(mount)\s.+" edit_field => fstab_options($(option), $(method)); } ################################################### # edit_xml bundles ################################################### bundle edit_xml xml_insert_tree_nopath(treestring) # @brief Insert XML tree with no path # # This `edit_xml` bundle inserts the given XML tree. Use with an # empty XML document. # # @param treestring The XML tree, as a string # # **Example:** # # ```cf3 # files: # "/newfile" edit_xml => xml_insert_tree_nopath('y'); # ``` { insert_tree: '$(treestring)'; } bundle edit_xml xml_insert_tree(treestring, xpath) # @brief Insert XML tree at the given XPath # # This `edit_xml` bundle inserts the given XML tree at a specific # XPath. Uses `insert_tree`. # # @param treestring The XML tree, as a string # @param xpath A valid XPath string # # **Example:** # # ```cf3 # files: # "/file.xml" edit_xml => xml_insert_tree('y', '/a/b/c'); # ``` { insert_tree: '$(treestring)'; } bundle edit_xml xml_set_value(value, xpath) # @brief Sets or replaces a value in XML at the given XPath # # This `edit_xml` bundle sets or replaces the value at a specific # XPath with the given value. Uses `set_text`. # # @param value The new value # @param xpath A valid XPath string # # **Example:** # # ```cf3 # files: # "/file.xml" edit_xml => xml_set_value('hello', '/a/b/c'); # ``` { set_text: "$(value)" select_xpath => "$(xpath)"; } bundle edit_xml xml_set_attribute(attr, value, xpath) # @brief Sets or replaces an attribute in XML at the given XPath # # This `edit_xml` bundle sets or replaces an attribute at a specific # XPath with the given value. Uses `set_attribute`. # # @param attr The attribute name # @param value The new attribute value # @param xpath A valid XPath string # # **Example:** # # ```cf3 # files: # "/file.xml" edit_xml => xml_set_attribute('parameter', 'ha', '/a/b/c'); # ``` { set_attribute: "$(attr)" attribute_value => "$(value)", select_xpath => "$(xpath)"; } ##------------------------------------------------------- ## editing bodies ##------------------------------------------------------- body edit_field fstab_options(newval, method) # @brief Edit the options field in a fstab format # @param newval the new option # @param method `field_operation` to apply # # This body edits the options field in the fstab file format. The # `method` is a `field_operation` which can be `append`, `prepend`, # `set`, `delete`, or `alphanum`. The `newval` option is OS-specific. # # **Example:** # # ```cf3 # # from the `fstab_options_editor` # field_edits: # "(?!#)\S+\s+$(mount)\s.+" # edit_field => fstab_options($(option), $(method)); # ``` { field_separator => "\s+"; select_field => "4"; value_separator => ","; field_value => "$(newval)"; field_operation => "$(method)"; } body edit_field quoted_var(newval,method) { field_separator => "\""; select_field => "2"; value_separator => " "; field_value => "$(newval)"; field_operation => "$(method)"; extend_fields => "false"; allow_blank_fields => "true"; } ## body edit_field col(split,col,newval,method) { field_separator => "$(split)"; select_field => "$(col)"; value_separator => ","; field_value => "$(newval)"; field_operation => "$(method)"; extend_fields => "true"; allow_blank_fields => "true"; } ## body edit_field line(split,col,newval,method) { field_separator => "$(split)"; select_field => "$(col)"; value_separator => " "; field_value => "$(newval)"; field_operation => "$(method)"; extend_fields => "true"; allow_blank_fields => "true"; } ## body replace_with value(x) { replace_value => "$(x)"; occurrences => "all"; } ## body select_region INI_section(x) { select_start => "\[$(x)\]\s*"; select_end => "\[.*\]\s*"; } ##------------------------------------------------------- ## edit_defaults ##------------------------------------------------------- body edit_defaults std_defs { empty_file_before_editing => "false"; edit_backup => "false"; #max_file_size => "300000"; } ## body edit_defaults empty { empty_file_before_editing => "true"; edit_backup => "false"; #max_file_size => "300000"; } ## body edit_defaults no_backup { edit_backup => "false"; } ## body edit_defaults backup_timestamp { empty_file_before_editing => "false"; edit_backup => "timestamp"; #max_file_size => "300000"; } ##------------------------------------------------------- ## location ##------------------------------------------------------- body location start { before_after => "before"; } ## body location after(str) { before_after => "after"; select_line_matching => "$(str)"; } ## body location before(str) { before_after => "before"; select_line_matching => "$(str)"; } ##------------------------------------------------------- ## replace_with ##------------------------------------------------------- ## body replace_with comment(c) { replace_value => "$(c) $(match.1)"; occurrences => "all"; } ## body replace_with uncomment { replace_value => "$(match.1)"; occurrences => "all"; } ##------------------------------------------------------- ## copy_from ##------------------------------------------------------- body copy_from secure_cp(from,server) { source => "$(from)"; servers => { "$(server)" }; compare => "digest"; encrypt => "true"; verify => "true"; } ## body copy_from remote_cp(from,server) { servers => { "$(server)" }; source => "$(from)"; compare => "mtime"; } ## body copy_from remote_dcp(from,server) { servers => { "$(server)" }; source => "$(from)"; compare => "digest"; } ## body copy_from local_cp(from) { source => "$(from)"; } ## body copy_from local_dcp(from) { source => "$(from)"; compare => "digest"; } ## body copy_from perms_cp(from) { source => "$(from)"; preserve => "true"; } body copy_from backup_local_cp(from) # Local copy, keeping a backup of old versions { source => "$(from)"; copy_backup => "timestamp"; } ## # Copy only if the file does not already exist, i.e. seed the placement body copy_from seed_cp(from) { source => "$(from)"; compare => "exists"; } ## body copy_from sync_cp(from,server) { servers => { "$(server)" }; source => "$(from)"; purge => "true"; preserve => "true"; type_check => "false"; } ## body copy_from no_backup_cp(from) { source => "$(from)"; copy_backup => "false"; } ## body copy_from no_backup_dcp(from) { source => "$(from)"; copy_backup => "false"; compare => "digest"; } ## body copy_from no_backup_rcp(from,server) { servers => { "$(server)" }; source => "$(from)"; compare => "mtime"; copy_backup => "false"; } ##------------------------------------------------------- ## link_from ##------------------------------------------------------- body link_from ln_s(x) { link_type => "symlink"; source => "$(x)"; when_no_source => "force"; } ## body link_from linkchildren(tofile) { source => "$(tofile)"; link_type => "symlink"; when_no_source => "force"; link_children => "true"; when_linking_children => "if_no_such_file"; # "override_file"; } ##------------------------------------------------------- ## perms ##------------------------------------------------------- body perms m(mode) { mode => "$(mode)"; } ## body perms mo(mode,user) { owners => { "$(user)" }; mode => "$(mode)"; } ## body perms mog(mode,user,group) { owners => { "$(user)" }; groups => { "$(group)" }; mode => "$(mode)"; } ## body perms og(u,g) { owners => { "$(u)" }; groups => { "$(g)" }; } ## body perms owner(user) { owners => { "$(user)" }; } body perms system_owned(mode) # @brief Set the file owner and group to the system default # @param mode the access permission in octal format # # **Example:** # # ```cf3 # files: # "/etc/passwd" perms => system_owned("0644"); # ``` { mode => "$(mode)"; owners => { "root" }; freebsd|openbsd|netbsd|darwin:: groups => { "wheel" }; linux:: groups => { "root" }; solaris:: groups => { "sys" }; } ##------------------------------------------------------- ## ACLS (extended Unix perms) ##------------------------------------------------------- body acl access_generic(acl) # default/inherited ACLs are left unchanged, # applicable for both files and directories on all platforms { acl_method => "overwrite"; aces => { "@(acl)" }; windows:: acl_type => "ntfs"; !windows:: acl_type => "posix"; } ## body acl ntfs(acl) { acl_type => "ntfs"; acl_method => "overwrite"; aces => { "@(acl)" }; } ## body acl strict # NOTE: May need to take ownership of file/dir # to be sure no-one else is allowed access { acl_method => "overwrite"; windows:: aces => { "user:Administrator:rwx" }; !windows:: aces => { "user:root:rwx" }; } ##------------------------------------------------------- ## depth_search ##------------------------------------------------------- body depth_search recurse(d) { depth => "$(d)"; xdev => "true"; } ## body depth_search recurse_ignore(d,list) { depth => "$(d)"; exclude_dirs => { @(list) }; } ## body depth_search include_base { include_basedir => "true"; } body depth_search recurse_with_base(d) { depth => "$(d)"; xdev => "true"; include_basedir => "true"; } ##------------------------------------------------------- ## delete ##------------------------------------------------------- body delete tidy { dirlinks => "delete"; rmdirs => "true"; } ##------------------------------------------------------- ## rename ##------------------------------------------------------- body rename disable { disable => "true"; } ## body rename rotate(level) { rotate => "$(level)"; } ## body rename to(file) { newname => "$(file)"; } ##------------------------------------------------------- ## file_select ##------------------------------------------------------- body file_select name_age(name,days) { leaf_name => { "$(name)" }; mtime => irange(0,ago(0,0,"$(days)",0,0,0)); file_result => "mtime.leaf_name"; } ## body file_select days_old(days) { mtime => irange(0,ago(0,0,"$(days)",0,0,0)); file_result => "mtime"; } ## body file_select size_range(from,to) { search_size => irange("$(from)","$(to)"); file_result => "size"; } ## body file_select bigger_than(size) { search_size => irange("0","$(size)"); file_result => "!size"; } ## body file_select exclude(name) { leaf_name => { "$(name)"}; file_result => "!leaf_name"; } ## body file_select plain { file_types => { "plain" }; file_result => "file_types"; } body file_select dirs { file_types => { "dir" }; file_result => "file_types"; } ## body file_select by_name(names) { leaf_name => { @(names)}; file_result => "leaf_name"; } ## body file_select ex_list(names) { leaf_name => { @(names)}; file_result => "!leaf_name"; } ## body file_select all { leaf_name => { ".*" }; file_result => "leaf_name"; } ## body file_select older_than(years, months, days, hours, minutes, seconds) # Generic older_than selection body, aimed to have a common definition handy # for every case possible. { mtime => irange(0,ago("$(years)","$(months)","$(days)","$(hours)","$(minutes)","$(seconds)")); file_result => "mtime"; } ## body file_select filetype_older_than(filetype, days) # Select files of specified type older than specified number of days # Note: This body only takes a single filetype, see filetypes_older_than # if you want to select more than one type of file { file_types => { "$(filetype)" }; mtime => irange(0,ago(0,0,"$(days)",0,0,0)); file_result => "file_types.mtime"; } ## body file_select filetypes_older_than(filetypes, days) # Select files of specified type older than specified number of days # Note: This body only takes a list of filetypes { file_types => { @(filetypes) }; mtime => irange(0,ago(0,0,"$(days)",0,0,0)); file_result => "file_types.mtime"; } ##------------------------------------------------------- ## changes ##------------------------------------------------------- body changes detect_all_change # This is fierce, and will cost disk cycles { hash => "best"; report_changes => "all"; update_hashes => "yes"; } ## body changes detect_all_change_using(hash) # Detect all changes using a configurable hashing algorithm # for times when you care about both content and file stats e.g. mtime # hash - supported hashing algorithm (md5, sha1, sha224, sha256, sha384, # sha512, best) { hash => "$(hash)"; report_changes => "all"; update_hashes => "yes"; } ## body changes detect_content # This is a cheaper alternative { hash => "md5"; report_changes => "content"; update_hashes => "yes"; } ## body changes detect_content_using(hash) # Detect content changes using a configurable hashing algorithm # for times when you only care about content, not file stats e.g. mtime # hash - supported hashing algorithm (md5, sha1, sha224, sha256, sha384, # sha512, best) { hash => "$(hash)"; report_changes => "content"; update_hashes => "yes"; } ## body changes noupdate # Use on (small) files that should never change { hash => "sha256"; report_changes => "content"; update_hashes => "no"; } ## body changes diff # Generates diff report (Nova and above) { hash => "sha256"; report_changes => "content"; report_diffs => "true"; update_hashes => "yes"; } ## body changes all_changes # Generates diff report (Nova and above) { hash => "sha256"; report_changes => "all"; report_diffs => "true"; update_hashes => "yes"; } ## body changes diff_noupdate { hash => "sha256"; report_changes => "content"; report_diffs => "true"; update_hashes => "no"; } masterfiles-3.6.2/lib/3.5/guest_environments.cf000066400000000000000000000055411241300473300213650ustar00rootroot00000000000000############################################################################ # Copyright (C) CFEngine AS # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License LGPL 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. # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ########################################################################### # # CFEngine Community Open Promise-Body Library # # This initiative started by CFEngine promotes a # standardized set of names and promise specifications # for template functionality within CFEngine 3. # # The aim is to promote an industry standard for # naming of configuration patterns, leading to a # de facto middleware of standardized syntax. # # Names should be intuitive and parameters should be # minimal to assist readability and comprehensibility. # Contributions to this file are voluntarily given to # the cfengine community, and are moderated by CFEngine. # No liability or warranty for misuse is implied. # # If you add to this file, please try to make the # contributions "self-documenting". Comments made # after the bundle/body statement are retained in # the online docs # # For CFEngine Core: 3.5.1 to 3.5.x # Guest environments bodies ################################################### # If you find CFEngine useful, please consider # # purchasing a commercial version of the software.# ################################################### ##------------------------------------------------------- ## guest_environment promises ##------------------------------------------------------- body environment_resources kvm(name, arch, cpu_count, mem_kb, disk_file) { env_spec => " $(name) $(mem_kb) $(mem_kb) $(cpu_count) hvm destroy restart restart /usr/bin/kvm "; } masterfiles-3.6.2/lib/3.5/monitor.cf000066400000000000000000000064651241300473300171240ustar00rootroot00000000000000############################################################################ # Copyright (C) CFEngine AS # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License LGPL 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. # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ########################################################################### # # CFEngine Community Open Promise-Body Library # # This initiative started by CFEngine promotes a # standardized set of names and promise specifications # for template functionality within CFEngine 3. # # The aim is to promote an industry standard for # naming of configuration patterns, leading to a # de facto middleware of standardized syntax. # # Names should be intuitive and parameters should be # minimal to assist readability and comprehensibility. # Contributions to this file are voluntarily given to # the cfengine community, and are moderated by CFEngine. # No liability or warranty for misuse is implied. # # If you add to this file, please try to make the # contributions "self-documenting". Comments made # after the bundle/body statement are retained in # the online docs # # For CFEngine Core: 3.5.1 to 3.5.x # Monitor bodies ################################################### # If you find CFEngine useful, please consider # # purchasing a commercial version of the software.# ################################################### #################################################### ## monitor bodyparts #################################################### body match_value scan_log(line) { select_line_matching => "$(line)"; track_growing_file => "true"; } ## body match_value scan_changing_file(line) { select_line_matching => "$(line)"; track_growing_file => "false"; } ## body match_value single_value(regex) { select_line_matching => "$(regex)"; extraction_regex => "($(regex))"; } ## body match_value line_match_value(line_match, extract_regex) # @brief Find lines matching line_match and extract a value matching extract_regex # @param line_match Regular expression matching line where value is found # @param extract_regex Regular expression matching value to extract # # ** Example:** # ```cf3 # bundle monitor example # { # vars: # "regex_vsz" string => "root\s+[0-9]+\s+[0-9]+\s+[0-9]+\s+[0-9.]+\s+[0-9.]+\s+([0-9]+).*"; # measurements: # "/var/cfengine/state/cf_procs" # handle => "cf_serverd_vsz", # comment => "Tracking the memory consumption of a process can help us identify possible memory leaks", # stream_type => "file", # data_type => "int", # history_type => "weekly", # units => "kB", # match_value => line_match_value(".*cf-serverd.*", "$(regex_vsz)"); # } { select_line_matching => "$(line_match)"; extraction_regex => "$(extract_regex)"; } masterfiles-3.6.2/lib/3.5/packages.cf000066400000000000000000001732361241300473300172140ustar00rootroot00000000000000############################################################################ # Copyright (C) CFEngine AS # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License LGPL 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. # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ########################################################################### # # CFEngine Community Open Promise-Body Library # # This initiative started by CFEngine promotes a # standardized set of names and promise specifications # for template functionality within CFEngine 3. # # The aim is to promote an industry standard for # naming of configuration patterns, leading to a # de facto middleware of standardized syntax. # # Names should be intuitive and parameters should be # minimal to assist readability and comprehensibility. # Contributions to this file are voluntarily given to # the cfengine community, and are moderated by CFEngine. # No liability or warranty for misuse is implied. # # If you add to this file, please try to make the # contributions "self-documenting". Comments made # after the bundle/body statement are retained in # the online docs # # For CFEngine Core: 3.5.1 to 3.5.x # Packages bodies ################################################### # If you find CFEngine useful, please consider # # purchasing a commercial version of the software.# ################################################### ##-------------------------------------------------------------- ## Packages promises ##-------------------------------------------------------------- bundle common common_knowledge # @brief common packages knowledge bundle # # This common bundle defines general things about platforms. { vars: "list_update_ifelapsed" string => "240"; "list_update_ifelapsed_now" string => "0"; } bundle common debian_knowledge # @depends paths # @brief common Debian knowledge bundle # # This common bundle has useful information about Debian. { vars: "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+.*"; } bundle common redhat_knowledge # @depends paths # @brief common Redhat knowledge bundle # # This common bundle has useful information about Redhat. { vars: "call_yum" string => "$(paths.path[yum])"; "call_rpm" string => "$(paths.path[rpm])"; "yum_options" string => "--quiet"; # used with rpm format '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]+).*"; # used with rpm format '%{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+)$"; # used with rpm format '%{name}.%{arch} %{version}-%{release}\n' "rpm3_name_regex" string => "([^.]+).*"; "rpm3_version_regex" string => "[^\s]\s+([^\s]+).*"; "rpm3_arch_regex" string => "[^.]+\.([^\s]+).*"; } bundle common darwin_knowledge # @depends paths # @brief common Darwin / Mac OS X knowledge bundle # # This common bundle has useful information about Darwin / Mac OS X. { 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]+)"; } bundle common npm_knowledge # @depends paths # @brief Node.js `npm' knowledge bundle # # This common bundle has useful information about the Node.js `npm' package manager. { 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.]+)"; } bundle common pip_knowledge # @depends paths # @brief Python `pip' knowledge bundle # # This common bundle has useful information about the Python `pip' package manager. { 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.]+\))"; } body package_method pip(flags) # @depends common_knowledge pip_knowledge # @brief 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 # # Note: "update" command preforms recursive upgrade (of dependencies) by # default. Set $flags to "--no-deps" to preform non-recursive upgrade. # http://www.pip-installer.org/en/latest/cookbook.html#non-recursive-upgrades # # **Example:** # # ```cf3 # 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! # # eg. pip search django | egrep "^Django\s+-" # # Django - A high-level Python Web framework [..output trimmed..] # ``` { 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)"; } body package_method npm(dir) # @depends common_knowledge npm_knowledge # @brief Node.js `npm' local-mode package management # # `npm' is a package manager for Node.js # https://npmjs.org/package/npm # # $(dir) is the prefix path to ./node_modules/ # # For the difference between local and global install see here: # https://npmjs.org/doc/cli/npm-install.html # # Available commands : add, delete, (add)update, verify # # **Example:** # # ```cf3 # 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"; # ``` { 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)"; } body package_method npm_g # @depends common_knowledge npm_knowledge # @brief Node.js `npm' global-mode package management # # `npm' is a package manager for Node.js # https://npmjs.org/package/npm # # For the difference between global and local install see here: # https://npmjs.org/doc/cli/npm-install.html # # Available commands : add, delete, (add)update, verify # # **Example:** # # ```cf3 # packages: # "express" package_method => npm_g, package_policy => "add"; # "redis" package_method => npm_g, package_policy => "delete"; # ``` { 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"; } body package_method brew(user) # @depends common_knowledge darwin_knowledge # @brief Darwin/Mac OS X + Homebrew installation method # # Homebrew is a package manager for OS X -- http://brew.sh # 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 it seems CFEngine don't give the possibility to run package_add_command # with a different user, we'll use sudo -u. # # Available commands : add, delete, (add)update (with package_version). # # **Example:** # # ```cf3 # packages: # "mypackage" package_method => brew("adminuser"), package_policy => "add"; # "uppackage" package_method => brew("adminuser"), package_policy => "update", package_version => "3.5.2"; # ``` { 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"; } body package_method zypper # @depends common_knowledge redhat_knowledge # @brief SuSE installation method # # This package method interacts with the SuSE Zypper package manager # # **Example:** # # ```cf3 # packages: # "mypackage" package_method => zypper, package_policy => "add"; # ``` { package_changes => "bulk"; package_list_command => "$(paths.path[rpm]) -qa --queryformat \"i | repos | %{name} | %{version}-%{release} | %{arch}\n\""; # set it to "0" to avoid caching of list during upgrade package_list_update_command => "$(paths.path[zypper]) list-updates"; package_list_update_ifelapsed => "$(common_knowledge.list_update_ifelapsed)"; package_patch_list_command => "$(paths.path[zypper]) patches"; package_installed_regex => "i.*"; package_list_name_regex => "$(redhat_knowledge.rpm_name_regex)"; package_list_version_regex => "$(redhat_knowledge.rpm_version_regex)"; package_list_arch_regex => "$(redhat_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 => "$(paths.path[zypper]) --non-interactive install"; package_delete_command => "$(paths.path[zypper]) --non-interactive remove --force-resolution"; package_update_command => "$(paths.path[zypper]) --non-interactive update"; package_patch_command => "$(paths.path[zypper]) --non-interactive patch$"; # $ means no args package_verify_command => "$(paths.path[zypper]) --non-interactive verify$"; } ## body package_method apt # @depends debian_knowledge # @brief APT installation package method # # This package method interacts with the APT package manager through `aptitude`. # # **Example:** # # ```cf3 # packages: # "mypackage" package_method => apt, package_policy => "add"; # ``` { 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)"; } # Ignore aptitude because: # 1) aptitude will remove "unneeded" packages unexpectly # 2) aptitude return codes are useless # 3) aptitude is a high level interface # 4) aptitude provides little benefit # 5) have_aptitude is a hard class and thus cannot be unset body package_method apt_get # @depends debian_knowledge # @brief APT installation package method # # This package method interacts with the APT package manager through `apt-get`. # # **Example:** # # ```cf3 # packages: # "mypackage" package_method => apt_get, package_policy => "add"; # ``` { 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)"; } body package_method apt_get_release(release) # @depends debian_knowledge # @brief APT installation package method # @param release specific release to use # # This package method interacts with the APT package manager through `apt-get` but sets a specific target release. # # **Example:** # # ```cf3 # packages: # "mypackage" package_method => apt_get_release("xyz"), package_policy => "add"; # ``` { 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)"; } ## body package_method dpkg_version(repo) # @depends debian_knowledge # @brief dpkg installation package method # @param repo specific repo to use # # This package method interacts with `dpkg`. # # **Example:** # # ```cf3 # packages: # "mypackage" package_method => dpkg_version("xyz"), package_policy => "add"; # ``` { 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)"; } ## body package_method rpm_version(repo) # @depends common_knowledge redhat_knowledge # @brief RPM direct installation method # @param repo the specific repository for `package_file_repositories` # # This package method interacts with the RPM package manager for a specific repo. # # **Example:** # # ```cf3 # packages: # "mypackage" package_method => rpm_version("myrepo"), package_policy => "add"; # ``` { package_changes => "individual"; package_list_command => "$(redhat_knowledge.call_rpm) -qa --queryformat \"i | repos | %{name} | %{version}-%{release} | %{arch}\n\""; # 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"; package_list_update_ifelapsed => "$(common_knowledge.list_update_ifelapsed)"; package_list_name_regex => "$(redhat_knowledge.rpm_name_regex)"; package_list_version_regex => "$(redhat_knowledge.rpm_version_regex)"; package_list_arch_regex => "$(redhat_knowledge.rpm_arch_regex)"; package_installed_regex => "i.*"; package_file_repositories => { "$(repo)" }; package_name_convention => "$(name)-$(version).$(arch).rpm"; package_add_command => "$(redhat_knowledge.call_rpm) -ivh "; package_update_command => "$(redhat_knowledge.call_rpm) -Uvh "; package_patch_command => "$(redhat_knowledge.call_rpm) -Uvh "; package_delete_command => "$(redhat_knowledge.call_rpm) -e --nodeps"; package_verify_command => "$(redhat_knowledge.call_rpm) -V"; package_noverify_regex => ".*[^\s].*"; } ## 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}\""; } ## body package_method msi_implicit(repo) # Use 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 { 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"; } ## body package_method msi_explicit(repo) # use software name as promiser, e.g. "7-Zip", and explicitly # specify any package_version and package_arch { 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"; } ## body package_method yum # @depends common_knowledge redhat_knowledge # @brief Yum+RPM installation method # # This package method interacts with the Yum and RPM package managers. # It is inferior to the `yum_rpm` package method. # # 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:** # # ```cf3 # packages: # "mypackage" package_method => yum, package_policy => "add"; # ``` { package_changes => "bulk"; package_list_command => "$(redhat_knowledge.call_yum) $(redhat_knowledge.yum_options) list installed"; package_patch_list_command => "$(redhat_knowledge.call_yum) $(redhat_knowledge.yum_options) check-update"; # Remember to escape special characters like | package_list_name_regex => "([^.]+).*"; package_list_version_regex => "[^\s]\s+([^\s]+).*"; package_list_arch_regex => "[^.]+\.([^\s]+).*"; package_installed_regex => ".*(installed|\s+@).*"; 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"; package_list_update_ifelapsed => "$(common_knowledge.list_update_ifelapsed)"; package_patch_name_regex => "([^.]+).*"; package_patch_version_regex => "[^\s]\s+([^\s]+).*"; package_patch_arch_regex => "[^.]+\.([^\s]+).*"; 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 => "$(redhat_knowledge.call_rpm) -e --nodeps"; package_verify_command => "$(redhat_knowledge.call_rpm) -V"; package_noverify_returncode => "1"; } ## body package_method yum_rpm # @depends common_knowledge redhat_knowledge # @brief 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:** # # ```cf3 # packages: # "mypackage" package_method => yum_rpm, package_policy => "add"; # ``` { package_changes => "bulk"; package_list_command => "$(redhat_knowledge.call_rpm) -qa --qf '%{name}.%{arch} %{version}-%{release}\n'"; package_patch_list_command => "$(redhat_knowledge.call_yum) $(redhat_knowledge.yum_options) check-update"; package_list_name_regex => "$(redhat_knowledge.rpm3_name_regex)"; package_list_version_regex => "$(redhat_knowledge.rpm3_version_regex)"; package_list_arch_regex => "$(redhat_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"; package_list_update_ifelapsed => "$(common_knowledge.list_update_ifelapsed)"; package_patch_name_regex => "([^.]+).*"; package_patch_version_regex => "[^\s]\s+([^\s]+).*"; package_patch_arch_regex => "[^.]+\.([^\s]+).*"; 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 => "$(redhat_knowledge.call_rpm) -e --nodeps"; package_verify_command => "$(redhat_knowledge.call_rpm) -V"; package_noverify_returncode => "1"; } ## body package_method yum_rpm_enable_repo(repoid) # @depends common_knowledge redhat_knowledge # @brief Yum+RPM repo-specific installation method # @param 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:** # # ```cf3 # packages: # "mypackage" package_method => yum_rpm_enable_repo("myrepo"), package_policy => "add"; # ``` { package_changes => "bulk"; package_list_command => "$(redhat_knowledge.call_rpm) -qa --qf '%{name} %{version}-%{release} %{arch}\n'"; package_patch_list_command => "$(redhat_knowledge.call_yum) $(redhat_knowledge.yum_options) check-update"; package_list_name_regex => "$(redhat_knowledge.rpm2_name_regex)"; package_list_version_regex => "$(redhat_knowledge.rpm2_version_regex)"; package_list_arch_regex => "$(redhat_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"; package_list_update_ifelapsed => "$(common_knowledge.list_update_ifelapsed)"; package_patch_name_regex => "([^.]+).*"; package_patch_version_regex => "[^\s]\s+([^\s]+).*"; package_patch_arch_regex => "[^.]+\.([^\s]+).*"; 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 => "$(redhat_knowledge.call_rpm) -e --nodeps --allmatches"; package_verify_command => "$(redhat_knowledge.call_rpm) -V"; package_noverify_returncode => "1"; } ## body package_method yum_group # @depends common_knowledge redhat_knowledge # @brief 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. # ```shell # $ yum grouplist -v|grep Networking|head -n 1 # Networking Tools (network-tools) # ``` # # **Example:** # # ```cf3 # 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; # ``` { 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"; 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"; } ## body package_method rpm_filebased(path) # @depends common_knowledge redhat_knowledge # @brief install packages from local filesystem-based RPM repository. # @param path the path to the local package repository # # Contributed by Aleksey Tsalolikhin. Written on 29-Feb-2012. # Based on yum_rpm body in COPBL by Trond Hasle Amundsen. # # **Example:** # # ```cf3 # packages: # "epel-release" # package_policy => "add", # package_version => "5-4", # package_architectures => { "noarch" }, # package_method => rpm_filebased("/repo/RPMs"); # ``` { package_file_repositories => { "$(path)" }; # the above is an addition to Trond's yum_rpm body package_add_command => "$(redhat_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"; 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 => "$(redhat_knowledge.call_rpm) -qa --qf '%{name} %{version}-%{release} %{arch}\n'"; package_list_name_regex => "$(redhat_knowledge.rpm2_name_regex)"; package_list_version_regex => "$(redhat_knowledge.rpm2_version_regex)"; package_list_arch_regex => "$(redhat_knowledge.rpm2_arch_regex)"; package_installed_regex => ".*"; package_delete_command => "$(redhat_knowledge.call_rpm) -e --allmatches"; package_verify_command => "$(redhat_knowledge.call_rpm) -V"; package_noverify_returncode => "1"; } ## # OpenSolaris based systems (Solaris 11, Illumos, etc) use the much better # Image Package System. # # 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"; body package_method ips # @depends paths # @depends common_knowledge { 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 (solaris 10 fork by Joyent) uses pkgin body package_method smartos # @depends common_knowledge { package_changes => "bulk"; package_list_command => "/opt/local/bin/pkgin list"; 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_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"; } # OpenCSW (Solaris software packages) body package_method opencsw # @depends common_knowledge { 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"; } # 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 body package_method solaris (pkgname, spoolfile, adminfile) # @depends paths # @depends common_knowledge { package_changes => "individual"; package_list_command => "$(paths.path[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 => "$(paths.path[pkgadd]) -n -a /tmp/$(adminfile) -d /tmp/$(spoolfile)"; package_delete_command => "$(paths.path[pkgrm]) -n -a /tmp/$(adminfile)"; } ## # # The following bundle is part of a package setup for solaris, see unit examples # bundle edit_line create_solaris_admin_file { insert_lines: "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" comment => "Insert contents of Solaris admin file (automatically install packages)"; } ## body package_method freebsd # @depends common_knowledge # @brief 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: # # ```cf3 # vars: # environment => { "PACKAGESITE=http://repo.example.com/private/8_STABLE/" }; # packages: # "perl5" # package_policy => "add", # package_method => freebsd; # # ``` { package_changes => "individual"; 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_add -r"; package_delete_command => "/usr/sbin/pkg_delete"; } body package_method freebsd_portmaster # @depends common_knowledge # @brief 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:** # # ```cf3 # # packages: # "perl5.14" # package_policy => "add", # 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"; } ## body package_method alpinelinux # @brief Alpine Linux apk package installation method # # This package method interacts with apk to manage packages. # # **Example:** # # ```cf3 # # packages: # "vim" # package_policy => "add", # 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"; } ## body package_method emerge # @depends common_knowledge # @brief Gentoo emerge package installation method # # This package method interacts with emerge to build and install packages. # # **Example:** # # ```cf3 # # packages: # "zsh" # package_policy => "add", # 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).*"; } ## body package_method pacman # @depends common_knowledge { 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"; } ## body package_method generic # @depends paths # @depends common_knowledge debian_knowledge redhat_knowledge # @brief Generic installation package method # # This package method attempts to handle all platforms. # # **Example:** # # ```cf3 # packages: # "mypackage" package_method => generic, package_policy => "add"; # ``` { SuSE:: package_changes => "bulk"; package_list_command => "$(redhat_knowledge.call_rpm) -qa --queryformat \"i | repos | %{name} | %{version}-%{release} | %{arch}\n\""; # set it to "0" to avoid caching of list during upgrade package_list_update_command => "$(paths.path[zypper]) list-updates"; package_list_update_ifelapsed => "$(common_knowledge.list_update_ifelapsed_now)"; package_patch_list_command => "$(paths.path[zypper]) patches"; package_installed_regex => "i.*"; package_list_name_regex => "$(redhat_knowledge.rpm_name_regex)"; package_list_version_regex => "$(redhat_knowledge.rpm_version_regex)"; package_list_arch_regex => "$(redhat_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 => "$(paths.path[zypper]) --non-interactive install"; package_delete_command => "$(paths.path[zypper]) --non-interactive remove --force-resolution"; package_update_command => "$(paths.path[zypper]) --non-interactive update"; package_patch_command => "$(paths.path[zypper]) --non-interactive patch$"; # $ means no args package_verify_command => "$(paths.path[zypper]) --non-interactive verify$"; redhat:: package_changes => "bulk"; package_list_command => "$(redhat_knowledge.call_rpm) -qa --qf '%{name} %{version}-%{release} %{arch}\n'"; package_patch_list_command => "$(redhat_knowledge.call_yum) $(redhat_knowledge.yum_options) check-update"; package_list_name_regex => "$(redhat_knowledge.rpm_name_regex)"; package_list_version_regex => "$(redhat_knowledge.rpm_version_regex)"; package_list_arch_regex => "$(redhat_knowledge.rpm_arch_regex)"; package_installed_regex => ".*"; package_name_convention => "$(name)"; package_list_update_command => "$(redhat_knowledge.call_yum) $(redhat_knowledge.yum_options) check-update"; package_list_update_ifelapsed => "$(common_knowledge.list_update_ifelapsed_now)"; package_patch_name_regex => "([^.]+).*"; package_patch_version_regex => "[^\s]\s+([^\s]+).*"; package_patch_arch_regex => "[^.]+\.([^\s]+).*"; 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 => "$(redhat_knowledge.call_rpm) -e --nodeps --allmatches"; package_verify_command => "$(redhat_knowledge.call_rpm) -V"; package_noverify_returncode => "1"; 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)"; # 4 hours # 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_add -r"; 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 => ".*/([^\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).*"; 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"; } ## masterfiles-3.6.2/lib/3.5/paths.cf000066400000000000000000000515551241300473300165540ustar00rootroot00000000000000############################################################################ # Copyright (C) CFEngine AS # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License LGPL 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. # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ########################################################################### # # CFEngine Community Open Promise-Body Library # # This initiative started by CFEngine promotes a # standardized set of names and promise specifications # for template functionality within CFEngine 3. # # The aim is to promote an industry standard for # naming of configuration patterns, leading to a # de facto middleware of standardized syntax. # # Names should be intuitive and parameters should be # minimal to assist readability and comprehensibility. # Contributions to this file are voluntarily given to # the cfengine community, and are moderated by CFEngine. # No liability or warranty for misuse is implied. # # If you add to this file, please try to make the # contributions "self-documenting". Comments made # after the bundle/body statement are retained in # the online docs # # For CFEngine Core: 3.5.1 to 3.5.x # Paths bundle (used by other bodies) ################################################### # If you find CFEngine useful, please consider # # purchasing a commercial version of the software.# ################################################### bundle common paths # In addition to defining common paths, this bundle also defines context # classes for paths that are defined (_stdlib_has_path_xxx) and paths that # exist (_stdlib_path_exists_xxx) { vars: # # Common full pathname of commands for OS # any:: "path[getfacl]" string => "/usr/bin/getfacl"; "path[npm]" string => "/usr/bin/npm"; "path[pip]" string => "/usr/bin/pip"; aix:: "path[awk]" string => "/usr/bin/awk"; "path[bc]" string => "/usr/bin/bc"; "path[cat]" string => "/bin/cat"; "path[cksum]" string => "/usr/bin/cksum"; "path[crontabs]" string => "/var/spool/cron/crontabs"; "path[cut]" string => "/usr/bin/cut"; "path[dc]" string => "/usr/bin/dc"; "path[df]" string => "/usr/bin/df"; "path[diff]" string => "/usr/bin/diff"; "path[dig]" string => "/usr/bin/dig"; "path[echo]" string => "/usr/bin/echo"; "path[egrep]" string => "/usr/bin/egrep"; "path[find]" string => "/usr/bin/find"; "path[grep]" string => "/usr/bin/grep"; "path[ls]" string => "/usr/bin/ls"; "path[netstat]" string => "/usr/bin/netstat"; "path[ping]" string => "/usr/bin/ping"; "path[perl]" string => "/usr/bin/perl"; "path[printf]" string => "/usr/bin/printf"; "path[sed]" string => "/usr/bin/sed"; "path[sort]" string => "/usr/bin/sort"; "path[tr]" string => "/usr/bin/tr"; archlinux:: "path[awk]" string => "/usr/bin/awk"; "path[bc]" string => "/usr/bin/bc"; "path[cat]" string => "/usr/bin/cat"; "path[cksum]" string => "/usr/bin/cksum"; "path[crontab]" string => "/usr/bin/crontab"; "path[cut]" string => "/usr/bin/cut"; "path[dc]" string => "/usr/bin/dc"; "path[df]" string => "/usr/bin/df"; "path[diff]" string => "/usr/bin/diff"; "path[dig]" string => "/usr/bin/dig"; "path[dmidecode]" string => "/usr/bin/dmidecode"; "path[echo]" string => "/usr/bin/echo"; "path[egrep]" string => "/usr/bin/egrep"; "path[ethtool]" string => "/usr/bin/ethtool"; "path[find]" string => "/usr/bin/find"; "path[free]" string => "/usr/bin/free"; "path[grep]" string => "/usr/bin/grep"; "path[hostname]" string => "/usr/bin/hostname"; "path[init]" string => "/usr/bin/init"; "path[iptables]" string => "/usr/bin/iptables"; "path[iptables_save]" string => "/usr/bin/iptables-save"; "path[iptables_restore]" string => "/usr/bin/iptables-restore"; "path[ls]" string => "/usr/bin/ls"; "path[lsof]" string => "/usr/bin/lsof"; "path[netstat]" string => "/usr/bin/netstat"; "path[ping]" string => "/usr/bin/ping"; "path[perl]" string => "/usr/bin/perl"; "path[printf]" string => "/usr/bin/printf"; "path[sed]" string => "/usr/bin/sed"; "path[sort]" string => "/usr/bin/sort"; "path[test]" string => "/usr/bin/test"; "path[top]" string => "/usr/bin/top"; "path[tr]" string => "/usr/bin/tr"; # "path[pacman]" string => "/usr/bin/pacman"; "path[yaourt]" string => "/usr/bin/yaourt"; "path[useradd]" string => "/usr/bin/useradd"; "path[groupadd]" string => "/usr/bin/groupadd"; "path[ip]" string => "/usr/bin/ip"; "path[ifconfig]" string => "/usr/bin/ifconfig"; "path[journalctl]" string => "/usr/bin/journalctl"; "path[systemctl]" string => "/usr/bin/systemctl"; "path[netctl]" string => "/usr/bin/netctl"; freebsd|netbsd:: "path[awk]" string => "/usr/bin/awk"; "path[bc]" string => "/usr/bin/bc"; "path[cat]" string => "/bin/cat"; "path[cksum]" string => "/usr/bin/cksum"; "path[crontabs]" string => "/var/cron/tabs"; "path[cut]" string => "/usr/bin/cut"; "path[dc]" string => "/usr/bin/dc"; "path[df]" string => "/bin/df"; "path[diff]" string => "/usr/bin/diff"; "path[dig]" string => "/usr/bin/dig"; "path[echo]" string => "/bin/echo"; "path[egrep]" string => "/usr/bin/egrep"; "path[find]" string => "/usr/bin/find"; "path[grep]" string => "/usr/bin/grep"; "path[ls]" string => "/bin/ls"; "path[netstat]" string => "/usr/bin/netstat"; "path[ping]" string => "/usr/bin/ping"; "path[perl]" string => "/usr/bin/perl"; "path[printf]" string => "/usr/bin/printf"; "path[sed]" string => "/usr/bin/sed"; "path[sort]" string => "/usr/bin/sort"; "path[tr]" string => "/usr/bin/tr"; "path[realpath]" string => "/bin/realpath"; openbsd:: "path[awk]" string => "/usr/bin/awk"; "path[bc]" string => "/usr/bin/bc"; "path[cat]" string => "/bin/cat"; "path[cksum]" string => "/bin/cksum"; "path[crontabs]" string => "/var/cron/tabs"; "path[cut]" string => "/usr/bin/cut"; "path[dc]" string => "/usr/bin/dc"; "path[df]" string => "/bin/df"; "path[diff]" string => "/usr/bin/diff"; "path[dig]" string => "/usr/sbin/dig"; "path[echo]" string => "/bin/echo"; "path[egrep]" string => "/usr/bin/egrep"; "path[find]" string => "/usr/bin/find"; "path[grep]" string => "/usr/bin/grep"; "path[ls]" string => "/bin/ls"; "path[netstat]" string => "/usr/bin/netstat"; "path[ping]" string => "/usr/bin/ping"; "path[perl]" string => "/usr/bin/perl"; "path[printf]" string => "/usr/bin/printf"; "path[sed]" string => "/usr/bin/sed"; "path[sort]" string => "/usr/bin/sort"; "path[tr]" string => "/usr/bin/tr"; smartos:: "path[npm]" string => "/opt/local/bin/npm"; "path[pip]" string => "/opt/local/bin/pip"; solaris:: "path[awk]" string => "/usr/bin/awk"; "path[bc]" string => "/usr/bin/bc"; "path[cat]" string => "/usr/bin/cat"; "path[cksum]" string => "/usr/bin/cksum"; "path[crontab]" string => "/usr/bin/crontab"; "path[crontabs]" string => "/var/spool/cron/crontabs"; "path[curl]" string => "/usr/bin/curl"; "path[cut]" string => "/usr/bin/cut"; "path[dc]" string => "/usr/bin/dc"; "path[df]" string => "/usr/bin/df"; "path[diff]" string => "/usr/bin/diff"; "path[dig]" string => "/usr/sbin/dig"; "path[echo]" string => "/usr/bin/echo"; "path[egrep]" string => "/usr/bin/egrep"; "path[find]" string => "/usr/bin/find"; "path[grep]" string => "/usr/bin/grep"; "path[ls]" string => "/usr/bin/ls"; "path[netstat]" string => "/usr/bin/netstat"; "path[ping]" string => "/usr/bin/ping"; "path[perl]" string => "/usr/bin/perl"; "path[printf]" string => "/usr/bin/printf"; "path[sed]" string => "/usr/bin/sed"; "path[sort]" string => "/usr/bin/sort"; "path[tr]" string => "/usr/bin/tr"; "path[wget]" string => "/usr/bin/wget"; # "path[svcs]" string => "/usr/bin/svcs"; "path[svcadm]" string => "/usr/sbin/svcadm"; "path[svccfg]" string => "/usr/sbin/svccfg"; "path[netadm]" string => "/usr/sbin/netadm"; "path[dladm]" string => "/usr/sbin/dladm"; "path[ipadm]" string => "/usr/sbin/ipadm"; "path[pkg]" string => "/usr/bin/pkg"; "path[pkginfo]" string => "/usr/bin/pkginfo"; "path[pkgadd]" string => "/usr/sbin/pkgadd"; "path[pkgrm]" string => "/usr/sbin/pkgrm"; "path[zoneadm]" string => "/usr/sbin/zoneadm"; "path[zonecfg]" string => "/usr/sbin/zonecfg"; redhat:: "path[awk]" string => "/bin/awk"; "path[bc]" string => "/usr/bin/bc"; "path[cat]" string => "/bin/cat"; "path[cksum]" string => "/usr/bin/cksum"; "path[createrepo]" string => "/usr/bin/createrepo"; "path[crontab]" string => "/usr/bin/crontab"; "path[crontabs]" string => "/var/spool/cron"; "path[curl]" string => "/usr/bin/curl"; "path[cut]" string => "/bin/cut"; "path[dc]" string => "/usr/bin/dc"; "path[df]" string => "/bin/df"; "path[diff]" string => "/usr/bin/diff"; "path[dig]" string => "/usr/bin/dig"; "path[domainname]" string => "/bin/domainname"; "path[echo]" string => "/bin/echo"; "path[egrep]" string => "/bin/egrep"; "path[ethtool]" string => "/usr/sbin/ethtool"; "path[find]" string => "/usr/bin/find"; "path[grep]" string => "/bin/grep"; "path[hostname]" string => "/bin/hostname"; "path[init]" string => "/sbin/init"; "path[iptables]" string => "/sbin/iptables"; "path[iptables_save]" string => "/sbin/iptables-save"; "path[ls]" string => "/bin/ls"; "path[lsof]" string => "/usr/sbin/lsof"; "path[netstat]" string => "/bin/netstat"; "path[nologin]" string => "/sbin/nologin"; "path[ping]" string => "/usr/bin/ping"; "path[perl]" string => "/usr/bin/perl"; "path[printf]" string => "/usr/bin/printf"; "path[sed]" string => "/bin/sed"; "path[sort]" string => "/bin/sort"; "path[test]" string => "/usr/bin/test"; "path[wget]" string => "/usr/bin/wget"; "path[tr]" string => "/usr/bin/tr"; "path[realpath]" string => "/usr/bin/realpath"; # "path[chkconfig]" string => "/sbin/chkconfig"; "path[groupadd]" string => "/usr/sbin/groupadd"; "path[groupdel]" string => "/usr/sbin/groupdel"; "path[ifconfig]" string => "/sbin/ifconfig"; "path[ip]" string => "/sbin/ip"; "path[rpm]" string => "/bin/rpm"; "path[service]" string => "/sbin/service"; "path[svc]" string => "/sbin/service"; "path[useradd]" string => "/usr/sbin/useradd"; "path[userdel]" string => "/usr/sbin/userdel"; "path[yum]" string => "/usr/bin/yum"; darwin:: "path[awk]" string => "/usr/bin/awk"; "path[bc]" string => "/usr/bin/bc"; "path[cat]" string => "/bin/cat"; "path[cksum]" string => "/usr/bin/cksum"; "path[createrepo]" string => "/usr/bin/createrepo"; "path[crontab]" string => "/usr/bin/crontab"; "path[crontabs]" string => "/usr/lib/cron/tabs"; "path[cut]" string => "/usr/bin/cut"; "path[dc]" string => "/usr/bin/dc"; "path[df]" string => "/bin/df"; "path[diff]" string => "/usr/bin/diff"; "path[dig]" string => "/usr/bin/dig"; "path[domainname]" string => "/bin/domainname"; "path[echo]" string => "/bin/echo"; "path[egrep]" string => "/usr/bin/egrep"; "path[find]" string => "/usr/bin/find"; "path[grep]" string => "/usr/bin/grep"; "path[hostname]" string => "/bin/hostname"; "path[ls]" string => "/bin/ls"; "path[lsof]" string => "/usr/sbin/lsof"; "path[netstat]" string => "/usr/sbin/netstat"; "path[ping]" string => "/sbin/ping"; "path[perl]" string => "/usr/bin/perl"; "path[printf]" string => "/usr/bin/printf"; "path[sed]" string => "/usr/bin/sed"; "path[sort]" string => "/usr/bin/sort"; "path[test]" string => "/bin/test"; "path[tr]" string => "/usr/bin/tr"; # "path[brew]" string => "/usr/local/bin/brew"; "path[sudo]" string => "/usr/bin/sudo"; debian:: "path[awk]" string => "/usr/bin/awk"; "path[bc]" string => "/usr/bin/bc"; "path[cat]" string => "/bin/cat"; "path[chkconfig]" string => "/sbin/chkconfig"; "path[cksum]" string => "/usr/bin/cksum"; "path[createrepo]" string => "/usr/bin/createrepo"; "path[crontab]" string => "/usr/bin/crontab"; "path[crontabs]" string => "/var/spool/cron/crontabs"; "path[curl]" string => "/usr/bin/curl"; "path[cut]" string => "/usr/bin/cut"; "path[dc]" string => "/usr/bin/dc"; "path[df]" string => "/bin/df"; "path[diff]" string => "/usr/bin/diff"; "path[dig]" string => "/usr/bin/dig"; "path[dmidecode]" string => "/usr/sbin/dmidecode"; "path[domainname]" string => "/bin/domainname"; "path[echo]" string => "/bin/echo"; "path[egrep]" string => "/bin/egrep"; "path[ethtool]" string => "/sbin/ethtool"; "path[find]" string => "/usr/bin/find"; "path[grep]" string => "/bin/grep"; "path[hostname]" string => "/bin/hostname"; "path[init]" string => "/sbin/init"; "path[iptables]" string => "/sbin/iptables"; "path[iptables_save]" string => "/sbin/iptables-save"; "path[ls]" string => "/bin/ls"; "path[lsof]" string => "/usr/bin/lsof"; "path[netstat]" string => "/bin/netstat"; "path[nologin]" string => "/usr/sbin/nologin"; "path[ping]" string => "/bin/ping"; "path[perl]" string => "/usr/bin/perl"; "path[printf]" string => "/usr/bin/printf"; "path[sed]" string => "/bin/sed"; "path[sort]" string => "/usr/bin/sort"; "path[test]" string => "/usr/bin/test"; "path[tr]" string => "/usr/bin/tr"; "path[wget]" string => "/usr/bin/wget"; "path[realpath]" string => "/usr/bin/realpath"; # "path[apt_cache]" string => "/usr/bin/apt-cache"; "path[apt_config]" string => "/usr/bin/apt-config"; "path[apt_get]" string => "/usr/bin/apt-get"; "path[apt_key]" string => "/usr/bin/apt-key"; "path[aptitude]" string => "/usr/bin/aptitude"; "path[dpkg]" string => "/usr/bin/dpkg"; "path[groupadd]" string => "/usr/sbin/groupadd"; "path[ifconfig]" string => "/sbin/ifconfig"; "path[ip]" string => "/sbin/ip"; "path[service]" string => "/usr/sbin/service"; "path[svc]" string => "/usr/sbin/service"; "path[update_alternatives]" string => "/usr/bin/update-alternatives"; "path[update_rc_d]" string => "/usr/sbin/update-rc.d"; "path[useradd]" string => "/usr/sbin/useradd"; archlinux||darwin:: "path[sysctl]" string => "/usr/bin/sysctl"; !(archlinux||darwin):: "path[sysctl]" string => "/sbin/sysctl"; !(SuSE||SUSE||suse):: "path[logger]" string => "/usr/bin/logger"; SuSE||SUSE||suse:: "path[awk]" string => "/usr/bin/awk"; "path[bc]" string => "/usr/bin/bc"; "path[cat]" string => "/bin/cat"; "path[cksum]" string => "/usr/bin/cksum"; "path[createrepo]" string => "/usr/bin/createrepo"; "path[crontab]" string => "/usr/bin/crontab"; "path[crontabs]" string => "/var/spool/cron/tabs"; "path[curl]" string => "/usr/bin/curl"; "path[cut]" string => "/usr/bin/cut"; "path[dc]" string => "/usr/bin/dc"; "path[df]" string => "/bin/df"; "path[diff]" string => "/usr/bin/diff"; "path[dig]" string => "/usr/bin/dig"; "path[dmidecode]" string => "/usr/sbin/dmidecode"; "path[domainname]" string => "/bin/domainname"; "path[echo]" string => "/bin/echo"; "path[egrep]" string => "/usr/bin/egrep"; "path[ethtool]" string => "/usr/sbin/ethtool"; "path[find]" string => "/usr/bin/find"; "path[free]" string => "/usr/bin/free"; "path[grep]" string => "/usr/bin/grep"; "path[hostname]" string => "/bin/hostname"; "path[init]" string => "/sbin/init"; "path[iptables]" string => "/usr/sbin/iptables"; "path[iptables_save]" string => "/usr/sbin/iptables-save"; "path[ls]" string => "/bin/ls"; "path[lsof]" string => "/usr/bin/lsof"; "path[netstat]" string => "/bin/netstat"; "path[nologin]" string => "/sbin/nologin"; "path[ping]" string => "/bin/ping"; "path[perl]" string => "/usr/bin/perl"; "path[printf]" string => "/usr/bin/printf"; "path[sed]" string => "/bin/sed"; "path[sort]" string => "/usr/bin/sort"; "path[test]" string => "/usr/bin/test"; "path[tr]" string => "/usr/bin/tr"; "path[logger]" string => "/bin/logger"; "path[wget]" string => "/usr/bin/wget"; # "path[chkconfig]" string => "/sbin/chkconfig"; "path[groupadd]" string => "/usr/sbin/groupadd"; "path[groupdel]" string => "/usr/sbin/groupdel"; "path[groupmod]" string => "/usr/sbin/groupmod"; "path[ifconfig]" string => "/sbin/ifconfig"; "path[ip]" string => "/sbin/ip"; "path[rpm]" string => "/bin/rpm"; "path[service]" string => "/sbin/service"; "path[useradd]" string => "/usr/sbin/useradd"; "path[userdel]" string => "/usr/sbin/userdel"; "path[usermod]" string => "/usr/sbin/usermod"; "path[zypper]" string => "/usr/bin/zypper"; linux|solaris:: "path[shadow]" string => "/etc/shadow"; freebsd|openbsd|netbsd|darwin:: "path[shadow]" string => "/etc/master.passwd"; aix:: "path[shadow]" string => "/etc/security/passwd"; any:: "all_paths" slist => getindices("path"); "$(all_paths)" string => "$(path[$(all_paths)])"; classes: "_stdlib_has_path_$(all_paths)" expression => isvariable("$(all_paths)"), comment => "It's useful to know if a given path is defined"; "_stdlib_path_exists_$(all_paths)" expression => fileexists("$(path[$(all_paths)])"), comment => "It's useful to know if $(all_paths) exists on the filesystem as defined"; } masterfiles-3.6.2/lib/3.5/processes.cf000066400000000000000000000060121241300473300174270ustar00rootroot00000000000000############################################################################ # Copyright (C) CFEngine AS # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License LGPL 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. # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ########################################################################### # # CFEngine Community Open Promise-Body Library # # This initiative started by CFEngine promotes a # standardized set of names and promise specifications # for template functionality within CFEngine 3. # # The aim is to promote an industry standard for # naming of configuration patterns, leading to a # de facto middleware of standardized syntax. # # Names should be intuitive and parameters should be # minimal to assist readability and comprehensibility. # Contributions to this file are voluntarily given to # the cfengine community, and are moderated by CFEngine. # No liability or warranty for misuse is implied. # # If you add to this file, please try to make the # contributions "self-documenting". Comments made # after the bundle/body statement are retained in # the online docs # # For CFEngine Core: 3.5.1 to 3.5.x # Processes bodies ################################################### # If you find CFEngine useful, please consider # # purchasing a commercial version of the software.# ################################################### ##------------------------------------------------------- ## process promises ##------------------------------------------------------- body process_select exclude_procs(x) { command => "$(x)"; process_result => "!command"; } ## body process_select days_older_than(d) { stime_range => irange(ago(0,0,"$(d)",0,0,0),now); process_result => "stime"; } ## body process_select by_owner(u) # Takes user as parameter and matches it against the given username # and the given username's uid in case only uid is visible in process list. { process_owner => { "$(u)", canonify(getuid("$(u)")) }; process_result => "process_owner"; } ## body process_select by_pid(pid) # @brief Select a process matching the given PID # @param pid PID of the process to be matched { pid => irange("$(pid)","$(pid)"); process_result => "pid"; } ## body process_count any_count(cl) { match_range => "0,0"; out_of_range_define => { "$(cl)" }; } ## body process_count check_range(name,lower,upper) { match_range => irange("$(lower)","$(upper)"); out_of_range_define => { "$(name)_out_of_range" }; } masterfiles-3.6.2/lib/3.5/reports.cf000066400000000000000000000062251241300473300171250ustar00rootroot00000000000000############################################################################ # Copyright (C) CFEngine AS # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License LGPL 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. # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ########################################################################### # # CFEngine Community Open Promise-Body Library # # This initiative started by CFEngine promotes a # standardized set of names and promise specifications # for template functionality within CFEngine 3. # # The aim is to promote an industry standard for # naming of configuration patterns, leading to a # de facto middleware of standardized syntax. # # Names should be intuitive and parameters should be # minimal to assist readability and comprehensibility. # Contributions to this file are voluntarily given to # the cfengine community, and are moderated by CFEngine. # No liability or warranty for misuse is implied. # # If you add to this file, please try to make the # contributions "self-documenting". Comments made # after the bundle/body statement are retained in # the online docs # # For CFEngine Core: 3.5.0 to 3.5.x # Reporting bodies ################################################### # If you find CFEngine useful, please consider # # purchasing a commercial version of the software.# ################################################### body report_data_select default_data_select_host # @brief Data to collect from remote hosts by default # By convention variables and classes known to be internal, (having no # reporting value) should be prefixed with an underscore. By default the policy # framework explicitly excludes these variables and classes from collection. { variables_include => { "sys..*", "mon..*" }; variables_exclude => { "_.*", ".*\._.*" }; classes_exclude => { "_.*" }; monitoring_include => { "cpu.*", "mem_total", "mem_free", "mem_cached", "mem_swap", "mem_freeswap", "loadavg", "diskfree" }; } body report_data_select default_data_select_policy_hub # @brief Data to collect from policy servers by default # By convention variables and classes known to be internal, (having no # reporting value) should be prefixed with an underscore. By default the policy # framework explicitly excludes these variables and classes from collection. { variables_include => { "sys..*", "mon..*" }; variables_exclude => { "_.*", ".*\._.*" }; classes_exclude => { "_.*" }; } masterfiles-3.6.2/lib/3.5/services.cf000066400000000000000000001247011241300473300172520ustar00rootroot00000000000000############################################################################ # Copyright (C) CFEngine AS # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License LGPL 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. # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ########################################################################### # # CFEngine Community Open Promise-Body Library # # This initiative started by CFEngine promotes a # standardized set of names and promise specifications # for template functionality within CFEngine 3. # # The aim is to promote an industry standard for # naming of configuration patterns, leading to a # de facto middleware of standardized syntax. # # Names should be intuitive and parameters should be # minimal to assist readability and comprehensibility. # Contributions to this file are voluntarily given to # the cfengine community, and are moderated by CFEngine. # No liability or warranty for misuse is implied. # # If you add to this file, please try to make the # contributions "self-documenting". Comments made # after the bundle/body statement are retained in # the online docs # # For CFEngine Core: 3.5.1 to 3.5.x # Services bodies ################################################### # If you find CFEngine useful, please consider # # purchasing a commercial version of the software.# ################################################### ##------------------------------------------------------- ## service promises ##------------------------------------------------------- body service_method bootstart { service_autostart_policy => "boot_time"; service_dependence_chain => "start_parent_services"; windows:: service_type => "windows"; } ## body service_method force_deps { service_dependence_chain => "all_related"; windows:: service_type => "windows"; } ## bundle agent standard_services(service,state) { # DATA, vars: any:: "stakeholders[cfengine3]" slist => { "cfengine_in" }; "stakeholders[acpid]" slist => { "cpu", "cpu0", "cpu1", "cpu2", "cpu3" }; "stakeholders[mongod]" slist => { "mongo_in" }; "stakeholders[postfix]" slist => { "smtp_in" }; "stakeholders[sendmail]" slist => { "smtp_in" }; "stakeholders[www]" slist => { "www_in", "wwws_in", "www_alt_in" }; "stakeholders[ssh]" slist => { "ssh_in" }; "stakeholders[mysql]" slist => { "mysql_in" }; "stakeholders[nfs]" slist => { "nfsd_in" }; "stakeholders[syslog]" slist => { "syslog" }; "stakeholders[rsyslog]" slist => { "syslog" }; "stakeholders[tomcat5]" slist => { "www_alt_in" }; "stakeholders[tomcat6]" slist => { "www_alt_in" }; linux:: "startcommand[acpid]" string => "/etc/init.d/acpid start"; "restartcommand[acpid]" string => "/etc/init.d/acpid restart"; "reloadcommand[acpid]" string => "/etc/init.d/acpid reload"; "stopcommand[acpid]" string => "/etc/init.d/acpid stop"; "pattern[acpid]" string => ".*acpid.*"; "startcommand[cfengine3]" string => "/etc/init.d/cfengine3 start"; "restartcommand[cfengine3]" string => "/etc/init.d/cfengine3 restart"; "reloadcommand[cfengine3]" string => "/etc/init.d/cfengine3 reload"; "stopcommand[cfengine3]" string => "/etc/init.d/cfengine3 stop"; "pattern[cfengine3]" string => ".*cf-execd.*"; "startcommand[fancontrol]" string => "/etc/init.d/fancontrol start"; "restartcommand[fancontrol]" string => "/etc/init.d/fancontrol restart"; "reloadcommand[fancontrol]" string => "/etc/init.d/fancontrol reload"; "stopcommand[fancontrol]" string => "/etc/init.d/fancontrol stop"; "pattern[fancontrol]" string => ".*fancontrol.*"; "startcommand[hddtemp]" string => "/etc/init.d/hddtemp start"; "restartcommand[hddtemp]" string => "/etc/init.d/hddtemp restart"; "reloadcommand[hddtemp]" string => "/etc/init.d/hddtemp reload"; "stopcommand[hddtemp]" string => "/etc/init.d/hddtemp stop"; "pattern[hddtemp]" string => ".*hddtemp.*"; "startcommand[irqbalance]" string => "/etc/init.d/irqbalance start"; "restartcommand[irqbalance]" string => "/etc/init.d/irqbalance restart"; "reloadcommand[irqbalance]" string => "/etc/init.d/irqbalance reload"; "stopcommand[irqbalance]" string => "/etc/init.d/irqbalance stop"; "pattern[irqbalance]" string => ".*irqbalance.*"; "startcommand[lm-sensor]" string => "/etc/init.d/lm-sensor start"; "restartcommand[lm-sensor]" string => "/etc/init.d/lm-sensor restart"; "reloadcommand[lm-sensor]" string => "/etc/init.d/lm-sensor reload"; "stopcommand[lm-sensor]" string => "/etc/init.d/lm-sensor stop"; "pattern[lm-sensor]" string => ".*psensor.*"; "startcommand[mongod]" string => "/etc/init.d/mongod start"; "restartcommand[mongod]" string => "/etc/init.d/mongod restart"; "reloadcommand[mongod]" string => "/etc/init.d/mongod reload"; "stopcommand[mongod]" string => "/etc/init.d/mongod stop"; "pattern[mongod]" string => ".*mongod.*"; "startcommand[openvpn]" string => "/etc/init.d/openvpn start"; "restartcommand[openvpn]" string => "/etc/init.d/openvpn restart"; "reloadcommand[openvpn]" string => "/etc/init.d/openvpn reload"; "stopcommand[openvpn]" string => "/etc/init.d/openvpn stop"; "pattern[openvpn]" string => ".*openvpn.*"; "startcommand[postfix]" string => "/etc/init.d/postfix start"; "restartcommand[postfix]" string => "/etc/init.d/postfix restart"; "reloadcommand[postfix]" string => "/etc/init.d/postfix reload"; "stopcommand[postfix]" string => "/etc/init.d/postfix stop"; "pattern[postfix]" string => ".*postfix.*"; "startcommand[rsync]" string => "/etc/init.d/rsync start"; "restartcommand[rsync]" string => "/etc/init.d/rsync restart"; "reloadcommand[rsync]" string => "/etc/init.d/rsync reload"; "stopcommand[rsync]" string => "/etc/init.d/rsync stop"; "pattern[rsync]" string => ".*rsync.*"; "startcommand[rsyslog]" string => "/etc/init.d/rsyslog start"; "restartcommand[rsyslog]" string => "/etc/init.d/rsyslog restart"; "reloadcommand[rsyslog]" string => "/etc/init.d/rsyslog reload"; "stopcommand[rsyslog]" string => "/etc/init.d/rsyslog stop"; "pattern[rsyslog]" string => ".*rsyslogd.*"; "startcommand[sendmail]" string => "/etc/init.d/sendmail start"; "restartcommand[sendmail]" string => "/etc/init.d/sendmail restart"; "reloadcommand[sendmail]" string => "/etc/init.d/sendmail reload"; "stopcommand[sendmail]" string => "/etc/init.d/sendmail stop"; "pattern[sendmail]" string => ".*sendmail.*"; "startcommand[tomcat5]" string => "/etc/init.d/tomcat5 start"; "restartcommand[tomcat5]" string => "/etc/init.d/tomcat5 restart"; "reloadcommand[tomcat5]" string => "/etc/init.d/tomcat5 reload"; "stopcommand[tomcat5]" string => "/etc/init.d/tomcat5 stop"; "pattern[tomcat5]" string => ".*tomcat5.*"; "startcommand[tomcat6]" string => "/etc/init.d/tomcat6 start"; "restartcommand[tomcat6]" string => "/etc/init.d/tomcat6 restart"; "reloadcommand[tomcat6]" string => "/etc/init.d/tomcat6 reload"; "stopcommand[tomcat6]" string => "/etc/init.d/tomcat6 stop"; "pattern[tomcat6]" string => ".*tomcat6.*"; "startcommand[varnish]" string => "/etc/init.d/varnish start"; "restartcommand[varnish]" string => "/etc/init.d/varnish restart"; "reloadcommand[varnish]" string => "/etc/init.d/varnish reload"; "stopcommand[varnish]" string => "/etc/init.d/varnish stop"; "pattern[varnish]" string => ".*varnish.*"; "startcommand[wpa_supplicant]" string => "/etc/init.d/wpa_supplicant start"; "restartcommand[wpa_supplicant]" string => "/etc/init.d/wpa_supplicant restart"; "reloadcommand[wpa_supplicant]" string => "/etc/init.d/wpa_supplicant reload"; "stopcommand[wpa_supplicant]" string => "/etc/init.d/wpa_supplicant stop"; "pattern[wpa_supplicant]" string => ".*wpa_supplicant.*"; SuSE|suse:: "startcommand[mysql]" string => "/etc/init.d/mysqld start"; "restartcommand[mysql]" string => "/etc/init.d/mysqld restart"; "reloadcommand[mysql]" string => "/etc/init.d/mysqld reload"; "stopcommand[mysql]" string => "/etc/init.d/mysqld stop"; "pattern[mysql]" string => ".*mysqld.*"; "startcommand[www]" string => "/etc/init.d/apache2 start"; "restartcommand[www]" string => "/etc/init.d/apache2 restart"; "reloadcommand[www]" string => "/etc/init.d/apache2 reload"; "stopcommand[www]" string => "/etc/init.d/apache2 stop"; "pattern[www]" string => ".*apache2.*"; "startcommand[ntpd]" string => "/etc/init.d/ntpd start"; "restartcommand[ntpd]" string => "/etc/init.d/ntpd restart"; "reloadcommand[ntpd]" string => "/etc/init.d/ntpd reload"; "stopcommand[ntpd]" string => "/etc/init.d/ntpd stop"; "pattern[ntpd]" string => ".*ntpd.*"; "startcommand[ssh]" string => "/etc/init.d/sshd start"; "restartcommand[ssh]" string => "/etc/init.d/sshd restart"; "reloadcommand[ssh]" string => "/etc/init.d/sshd reload"; "stopcommand[ssh]" string => "/etc/init.d/sshd stop"; "pattern[ssh]" string => ".*sshd.*"; redhat:: "startcommand[anacron]" string => "/etc/init.d/anacron start"; "restartcommand[anacron]" string => "/etc/init.d/anacron restart"; "reloadcommand[anacron]" string => "/etc/init.d/anacron reload"; "stopcommand[anacron]" string => "/etc/init.d/anacron stop"; "pattern[anacron]" string => ".*anacron.*"; "startcommand[atd]" string => "/etc/init.d/atd start"; "restartcommand[atd]" string => "/etc/init.d/atd restart"; "reloadcommand[atd]" string => "/etc/init.d/atd reload"; "stopcommand[atd]" string => "/etc/init.d/atd stop"; "pattern[atd]" string => ".*sbin/atd.*"; "startcommand[auditd]" string => "/etc/init.d/auditd start"; "restartcommand[auditd]" string => "/etc/init.d/auditd restart"; "reloadcommand[auditd]" string => "/etc/init.d/auditd reload"; "stopcommand[auditd]" string => "/etc/init.d/auditd stop"; "pattern[auditd]" string => ".*auditd$"; "startcommand[autofs]" string => "/etc/init.d/autofs start"; "restartcommand[autofs]" string => "/etc/init.d/autofs restart"; "reloadcommand[autofs]" string => "/etc/init.d/autofs reload"; "stopcommand[autofs]" string => "/etc/init.d/autofs stop"; "pattern[autofs]" string => ".*automount.*"; "startcommand[bluetoothd]" string => "/etc/init.d/bluetooth start"; "restartcommand[bluetoothd]" string => "/etc/init.d/bluetooth restart"; "reloadcommand[bluetoothd]" string => "/etc/init.d/bluetooth reload"; "stopcommand[bluetoothd]" string => "/etc/init.d/bluetooth stop"; "pattern[bluetoothd]" string => ".*hcid.*"; "startcommand[capi]" string => "/etc/init.d/capi start"; "restartcommand[capi]" string => "/etc/init.d/capi restart"; "reloadcommand[capi]" string => "/etc/init.d/capi reload"; "stopcommand[capi]" string => "/etc/init.d/capi stop"; "pattern[capi]" string => ".*capiinit.*"; "startcommand[conman]" string => "/etc/init.d/conman start"; "restartcommand[conman]" string => "/etc/init.d/conman restart"; "reloadcommand[conman]" string => "/etc/init.d/conman reload"; "stopcommand[conman]" string => "/etc/init.d/conman stop"; "pattern[conman]" string => ".*conmand.*"; "startcommand[cpuspeed]" string => "/etc/init.d/cpuspeed start"; "restartcommand[cpuspeed]" string => "/etc/init.d/cpuspeed restart"; "reloadcommand[cpuspeed]" string => "/etc/init.d/cpuspeed reload"; "stopcommand[cpuspeed]" string => "/etc/init.d/cpuspeed stop"; "pattern[cpuspeed]" string => ".*cpuspeed.*"; "startcommand[crond]" string => "/etc/init.d/crond start"; "restartcommand[crond]" string => "/etc/init.d/crond restart"; "reloadcommand[crond]" string => "/etc/init.d/crond reload"; "stopcommand[crond]" string => "/etc/init.d/crond stop"; "pattern[crond]" string => ".*crond.*"; "startcommand[dc_client]" string => "/etc/init.d/dc_client start"; "restartcommand[dc_client]" string => "/etc/init.d/dc_client restart"; "reloadcommand[dc_client]" string => "/etc/init.d/dc_client reload"; "stopcommand[dc_client]" string => "/etc/init.d/dc_client stop"; "pattern[dc_client]" string => ".*dc_client.*"; "startcommand[dc_server]" string => "/etc/init.d/dc_server start"; "restartcommand[dc_server]" string => "/etc/init.d/dc_server restart"; "reloadcommand[dc_server]" string => "/etc/init.d/dc_server reload"; "stopcommand[dc_server]" string => "/etc/init.d/dc_server stop"; "pattern[dc_server]" string => ".*dc_server.*"; "startcommand[dnsmasq]" string => "/etc/init.d/dnsmasq start"; "restartcommand[dnsmasq]" string => "/etc/init.d/dnsmasq restart"; "reloadcommand[dnsmasq]" string => "/etc/init.d/dnsmasq reload"; "stopcommand[dnsmasq]" string => "/etc/init.d/dnsmasq stop"; "pattern[dnsmasq]" string => ".*dnsmasq.*"; "startcommand[dund]" string => "/etc/init.d/dund start"; "restartcommand[dund]" string => "/etc/init.d/dund restart"; "reloadcommand[dund]" string => "/etc/init.d/dund reload"; "stopcommand[dund]" string => "/etc/init.d/dund stop"; "pattern[dund]" string => ".*dund.*"; "startcommand[gpm]" string => "/etc/init.d/gpm start"; "restartcommand[gpm]" string => "/etc/init.d/gpm restart"; "reloadcommand[gpm]" string => "/etc/init.d/gpm reload"; "stopcommand[gpm]" string => "/etc/init.d/gpm stop"; "pattern[gpm]" string => ".*gpm.*"; "startcommand[haldaemon]" string => "/etc/init.d/haldaemon start"; "restartcommand[haldaemon]" string => "/etc/init.d/haldaemon restart"; "reloadcommand[haldaemon]" string => "/etc/init.d/haldaemon reload"; "stopcommand[haldaemon]" string => "/etc/init.d/haldaemon stop"; "pattern[haldaemon]" string => ".*hald.*"; "startcommand[hidd]" string => "/etc/init.d/hidd start"; "restartcommand[hidd]" string => "/etc/init.d/hidd restart"; "reloadcommand[hidd]" string => "/etc/init.d/hidd reload"; "stopcommand[hidd]" string => "/etc/init.d/hidd stop"; "pattern[hidd]" string => ".*hidd.*"; # "startcommand[ip6tables]" string => "/etc/init.d/ip6tables start"; # "restartcommand[ip6tables]" string => "/etc/init.d/ip6tables restart"; # "reloadcommand[ip6tables]" string => "/etc/init.d/ip6tables reload"; # "stopcommand[ip6tables]" string => "/etc/init.d/ip6tables stop"; # "pattern[ip6tables]" string => ".*ip6tables.*"; # "startcommand[iptables]" string => "/etc/init.d/iptables start"; # "restartcommand[iptables]" string => "/etc/init.d/iptables restart"; # "reloadcommand[iptables]" string => "/etc/init.d/iptables reload"; # "stopcommand[iptables]" string => "/etc/init.d/iptables stop"; # "pattern[iptables]" string => ".*iptables.*"; "startcommand[irda]" string => "/etc/init.d/irda start"; "restartcommand[irda]" string => "/etc/init.d/irda restart"; "reloadcommand[irda]" string => "/etc/init.d/irda reload"; "stopcommand[irda]" string => "/etc/init.d/irda stop"; "pattern[irda]" string => ".*irattach.*"; "startcommand[iscsid]" string => "/etc/init.d/iscsid start"; "restartcommand[iscsid]" string => "/etc/init.d/iscsid restart"; "reloadcommand[iscsid]" string => "/etc/init.d/iscsid reload"; "stopcommand[iscsid]" string => "/etc/init.d/iscsid stop"; "pattern[iscsid]" string => ".*iscsid.*"; "startcommand[isdn]" string => "/etc/init.d/isdn start"; "restartcommand[isdn]" string => "/etc/init.d/isdn restart"; "reloadcommand[isdn]" string => "/etc/init.d/isdn reload"; "stopcommand[isdn]" string => "/etc/init.d/isdn stop"; "pattern[isdn]" string => ".*isdnlog.*"; "startcommand[lvm2-monitor]" string => "/etc/init.d/lvm2-monitor start"; "restartcommand[lvm2-monitor]" string => "/etc/init.d/lvm2-monitor restart"; "reloadcommand[lvm2-monitor]" string => "/etc/init.d/lvm2-monitor reload"; "stopcommand[lvm2-monitor]" string => "/etc/init.d/lvm2-monitor stop"; "pattern[lvm2-monitor]" string => ".*vgchange.*"; "startcommand[mcstrans]" string => "/etc/init.d/mcstrans start"; "restartcommand[mcstrans]" string => "/etc/init.d/mcstrans restart"; "reloadcommand[mcstrans]" string => "/etc/init.d/mcstrans reload"; "stopcommand[mcstrans]" string => "/etc/init.d/mcstrans stop"; "pattern[mcstrans]" string => ".*mcstransd.*"; "startcommand[mdmonitor]" string => "/etc/init.d/mdmonitor start"; "restartcommand[mdmonitor]" string => "/etc/init.d/mdmonitor restart"; "reloadcommand[mdmonitor]" string => "/etc/init.d/mdmonitor reload"; "stopcommand[mdmonitor]" string => "/etc/init.d/mdmonitor stop"; "pattern[mdmonitor]" string => ".*mdadm.*"; "startcommand[mdmpd]" string => "/etc/init.d/mdmpd start"; "restartcommand[mdmpd]" string => "/etc/init.d/mdmpd restart"; "reloadcommand[mdmpd]" string => "/etc/init.d/mdmpd reload"; "stopcommand[mdmpd]" string => "/etc/init.d/mdmpd stop"; "pattern[mdmpd]" string => ".*mdmpd.*"; "startcommand[messagebus]" string => "/etc/init.d/messagebus start"; "restartcommand[messagebus]" string => "/etc/init.d/messagebus restart"; "reloadcommand[messagebus]" string => "/etc/init.d/messagebus reload"; "stopcommand[messagebus]" string => "/etc/init.d/messagebus stop"; "pattern[messagebus]" string => ".*dbus-daemon.*"; "startcommand[microcode_ctl]" string => "/etc/init.d/microcode_ctl start"; "restartcommand[microcode_ctl]" string => "/etc/init.d/microcode_ctl restart"; "reloadcommand[microcode_ctl]" string => "/etc/init.d/microcode_ctl reload"; "stopcommand[microcode_ctl]" string => "/etc/init.d/microcode_ctl stop"; "pattern[microcode_ctl]" string => ".*microcode_ctl.*"; "startcommand[multipathd]" string => "/etc/init.d/multipathd start"; "restartcommand[multipathd]" string => "/etc/init.d/multipathd restart"; "reloadcommand[multipathd]" string => "/etc/init.d/multipathd reload"; "stopcommand[multipathd]" string => "/etc/init.d/multipathd stop"; "pattern[multipathd]" string => ".*multipathd.*"; "startcommand[mysql]" string => "/etc/init.d/mysqld start"; "restartcommand[mysql]" string => "/etc/init.d/mysqld restart"; "reloadcommand[mysql]" string => "/etc/init.d/mysqld reload"; "stopcommand[mysql]" string => "/etc/init.d/mysqld stop"; "pattern[mysql]" string => ".*mysqld.*"; "startcommand[netplugd]" string => "/etc/init.d/netplugd start"; "restartcommand[netplugd]" string => "/etc/init.d/netplugd restart"; "reloadcommand[netplugd]" string => "/etc/init.d/netplugd reload"; "stopcommand[netplugd]" string => "/etc/init.d/netplugd stop"; "pattern[netplugd]" string => ".*netplugd.*"; "startcommand[NetworkManager]" string => "/etc/init.d/NetworkManager start"; "restartcommand[NetworkManager]" string => "/etc/init.d/NetworkManager restart"; "reloadcommand[NetworkManager]" string => "/etc/init.d/NetworkManager reload"; "stopcommand[NetworkManager]" string => "/etc/init.d/NetworkManager stop"; "pattern[NetworkManager]" string => ".*NetworkManager.*"; "startcommand[nfs]" string => "/etc/init.d/nfs start"; "restartcommand[nfs]" string => "/etc/init.d/nfs restart"; "reloadcommand[nfs]" string => "/etc/init.d/nfs reload"; "stopcommand[nfs]" string => "/etc/init.d/nfs stop"; "pattern[nfs]" string => ".*nfsd.*"; "startcommand[nfslock]" string => "/etc/init.d/nfslock start"; "restartcommand[nfslock]" string => "/etc/init.d/nfslock restart"; "reloadcommand[nfslock]" string => "/etc/init.d/nfslock reload"; "stopcommand[nfslock]" string => "/etc/init.d/nfslock stop"; "pattern[nfslock]" string => ".*rpc.statd.*"; "startcommand[nscd]" string => "/etc/init.d/nscd start"; "restartcommand[nscd]" string => "/etc/init.d/nscd restart"; "reloadcommand[nscd]" string => "/etc/init.d/nscd reload"; "stopcommand[nscd]" string => "/etc/init.d/nscd stop"; "pattern[nscd]" string => ".*nscd.*"; "startcommand[ntpd]" string => "/etc/init.d/ntpd start"; "restartcommand[ntpd]" string => "/etc/init.d/ntpd restart"; "reloadcommand[ntpd]" string => "/etc/init.d/ntpd reload"; "stopcommand[ntpd]" string => "/etc/init.d/ntpd stop"; "pattern[ntpd]" string => ".*ntpd.*"; "startcommand[oddjobd]" string => "/etc/init.d/oddjobd start"; "restartcommand[oddjobd]" string => "/etc/init.d/oddjobd restart"; "reloadcommand[oddjobd]" string => "/etc/init.d/oddjobd reload"; "stopcommand[oddjobd]" string => "/etc/init.d/oddjobd stop"; "pattern[oddjobd]" string => ".*oddjobd.*"; "startcommand[pand]" string => "/etc/init.d/pand start"; "restartcommand[pand]" string => "/etc/init.d/pand restart"; "reloadcommand[pand]" string => "/etc/init.d/pand reload"; "stopcommand[pand]" string => "/etc/init.d/pand stop"; "pattern[pand]" string => ".*pand.*"; "startcommand[pcscd]" string => "/etc/init.d/pcscd start"; "restartcommand[pcscd]" string => "/etc/init.d/pcscd restart"; "reloadcommand[pcscd]" string => "/etc/init.d/pcscd reload"; "stopcommand[pcscd]" string => "/etc/init.d/pcscd stop"; "pattern[pcscd]" string => ".*pcscd.*"; "startcommand[portmap]" string => "/etc/init.d/portmap start"; "restartcommand[portmap]" string => "/etc/init.d/portmap restart"; "reloadcommand[portmap]" string => "/etc/init.d/portmap reload"; "stopcommand[portmap]" string => "/etc/init.d/portmap stop"; "pattern[portmap]" string => ".*portmap.*"; "startcommand[postgresql]" string => "/etc/init.d/postgresql start"; "restartcommand[postgresql]" string => "/etc/init.d/postgresql restart"; "reloadcommand[postgresql]" string => "/etc/init.d/postgresql reload"; "stopcommand[postgresql]" string => "/etc/init.d/postgresql stop"; "pattern[postgresql]" string => ".*postmaster.*"; "startcommand[rdisc]" string => "/etc/init.d/rdisc start"; "restartcommand[rdisc]" string => "/etc/init.d/rdisc restart"; "reloadcommand[rdisc]" string => "/etc/init.d/rdisc reload"; "stopcommand[rdisc]" string => "/etc/init.d/rdisc stop"; "pattern[rdisc]" string => ".*rdisc.*"; "startcommand[rdisc]" string => "/etc/init.d/rdisc start"; "restartcommand[rdisc]" string => "/etc/init.d/rdisc restart"; "reloadcommand[rdisc]" string => "/etc/init.d/rdisc reload"; "stopcommand[rdisc]" string => "/etc/init.d/rdisc stop"; "pattern[rdisc]" string => ".*rdisc.*"; "startcommand[readahead_early]" string => "/etc/init.d/readahead_early start"; "restartcommand[readahead_early]" string => "/etc/init.d/readahead_early restart"; "reloadcommand[readahead_early]" string => "/etc/init.d/readahead_early reload"; "stopcommand[readahead_early]" string => "/etc/init.d/readahead_early stop"; "pattern[readahead_early]" string => ".*readahead.*early.*"; "startcommand[readahead_later]" string => "/etc/init.d/readahead_later start"; "restartcommand[readahead_later]" string => "/etc/init.d/readahead_later restart"; "reloadcommand[readahead_later]" string => "/etc/init.d/readahead_later reload"; "stopcommand[readahead_later]" string => "/etc/init.d/readahead_later stop"; "pattern[readahead_later]" string => ".*readahead.*later.*"; "startcommand[restorecond]" string => "/etc/init.d/restorecond start"; "restartcommand[restorecond]" string => "/etc/init.d/restorecond restart"; "reloadcommand[restorecond]" string => "/etc/init.d/restorecond reload"; "stopcommand[restorecond]" string => "/etc/init.d/restorecond stop"; "pattern[restorecond]" string => ".*restorecond.*"; "startcommand[rhnsd]" string => "/sbin/service rhnsd start"; "restartcommand[rhnsd]" string => "/sbin/service rhnsd restart"; "reloadcommand[rhnsd]" string => "/sbin/service rhnsd reload"; "stopcommand[rhnsd]" string => "/sbin/service rhnsd stop"; "pattern[rhnsd]" string => "rhnsd"; "startcommand[rpcgssd]" string => "/etc/init.d/rpcgssd start"; "restartcommand[rpcgssd]" string => "/etc/init.d/rpcgssd restart"; "reloadcommand[rpcgssd]" string => "/etc/init.d/rpcgssd reload"; "stopcommand[rpcgssd]" string => "/etc/init.d/rpcgssd stop"; "pattern[rpcgssd]" string => ".*rpc.gssd.*"; "startcommand[rpcidmapd]" string => "/etc/init.d/rpcidmapd start"; "restartcommand[rpcidmapd]" string => "/etc/init.d/rpcidmapd restart"; "reloadcommand[rpcidmapd]" string => "/etc/init.d/rpcidmapd reload"; "stopcommand[rpcidmapd]" string => "/etc/init.d/rpcidmapd stop"; "pattern[rpcidmapd]" string => ".*rpc.idmapd.*"; "startcommand[rpcsvcgssd]" string => "/etc/init.d/rpcsvcgssd start"; "restartcommand[rpcsvcgssd]" string => "/etc/init.d/rpcsvcgssd restart"; "reloadcommand[rpcsvcgssd]" string => "/etc/init.d/rpcsvcgssd reload"; "stopcommand[rpcsvcgssd]" string => "/etc/init.d/rpcsvcgssd stop"; "pattern[rpcsvcgssd]" string => ".*rpc.svcgssd.*"; "startcommand[saslauthd]" string => "/etc/init.d/saslauthd start"; "restartcommand[saslauthd]" string => "/etc/init.d/saslauthd restart"; "reloadcommand[saslauthd]" string => "/etc/init.d/saslauthd reload"; "stopcommand[saslauthd]" string => "/etc/init.d/saslauthd stop"; "pattern[saslauthd]" string => ".*saslauthd.*"; "startcommand[smartd]" string => "/etc/init.d/smartd start"; "restartcommand[smartd]" string => "/etc/init.d/smartd restart"; "reloadcommand[smartd]" string => "/etc/init.d/smartd reload"; "stopcommand[smartd]" string => "/etc/init.d/smartd stop"; "pattern[smartd]" string => ".*smartd.*"; "startcommand[snmpd]" string => "/etc/init.d/snmpd start"; "restartcommand[snmpd]" string => "/sbin/service snmpd restart"; "reloadcommand[snmpd]" string => "/sbin/service snmpd reload"; "stopcommand[snmpd]" string => "/etc/init.d/snmpd stop"; "pattern[snmpd]" string => "/usr/sbin/snmpd"; "startcommand[svnserve]" string => "/etc/init.d/svnserve start"; "restartcommand[svnserve]" string => "/etc/init.d/svnserve restart"; "reloadcommand[svnserve]" string => "/etc/init.d/svnserve reload"; "stopcommand[svnserve]" string => "/etc/init.d/svnserve stop"; "pattern[svnserve]" string => ".*svnserve.*"; "startcommand[syslog]" string => "/etc/init.d/syslog start"; "restartcommand[syslog]" string => "/etc/init.d/syslog restart"; "reloadcommand[syslog]" string => "/etc/init.d/syslog reload"; "stopcommand[syslog]" string => "/etc/init.d/syslog stop"; "pattern[syslog]" string => ".*syslogd.*"; "startcommand[tcsd]" string => "/etc/init.d/tcsd start"; "restartcommand[tcsd]" string => "/etc/init.d/tcsd restart"; "reloadcommand[tcsd]" string => "/etc/init.d/tcsd reload"; "stopcommand[tcsd]" string => "/etc/init.d/tcsd stop"; "pattern[tcsd]" string => ".*tcsd.*"; "startcommand[www]" string => "/etc/init.d/httpd start"; "restartcommand[www]" string => "/etc/init.d/httpd restart"; "reloadcommand[www]" string => "/etc/init.d/httpd reload"; "stopcommand[www]" string => "/etc/init.d/httpd stop"; "pattern[www]" string => ".*httpd.*"; "startcommand[xfs]" string => "/etc/init.d/xfs start"; "restartcommand[xfs]" string => "/etc/init.d/xfs restart"; "reloadcommand[xfs]" string => "/etc/init.d/xfs reload"; "stopcommand[xfs]" string => "/etc/init.d/xfs stop"; "pattern[xfs]" string => ".*xfs.*"; "startcommand[ypbind]" string => "/etc/init.d/ypbind start"; "restartcommand[ypbind]" string => "/etc/init.d/ypbind restart"; "reloadcommand[ypbind]" string => "/etc/init.d/ypbind reload"; "stopcommand[ypbind]" string => "/etc/init.d/ypbind stop"; "pattern[ypbind]" string => ".*ypbind.*"; "startcommand[yum-updatesd]" string => "/etc/init.d/yum-updatesd start"; "restartcommand[yum-updatesd]" string => "/etc/init.d/yum-updatesd restart"; "reloadcommand[yum-updatesd]" string => "/etc/init.d/yum-updatesd reload"; "stopcommand[yum-updatesd]" string => "/etc/init.d/yum-updatesd stop"; "pattern[yum-updatesd]" string => ".*yum-updatesd.*"; "startcommand[ssh]" string => "/etc/init.d/sshd start"; "restartcommand[ssh]" string => "/etc/init.d/sshd restart"; "reloadcommand[ssh]" string => "/etc/init.d/sshd reload"; "stopcommand[ssh]" string => "/etc/init.d/sshd stop"; "pattern[ssh]" string => ".*sshd.*"; "startcommand[munin-node]" string => "/etc/init.d/munin-node start"; "restartcommand[munin-node]" string => "/etc/init.d/munin-node restart"; "reloadcommand[munin-node]" string => "/etc/init.d/munin-node reload"; "stopcommand[munin-node]" string => "/etc/init.d/munin-node stop"; "pattern[munin-node]" string => ".*munin-node.*"; debian|ubuntu:: "startcommand[atd]" string => "/etc/init.d/atd start"; "restartcommand[atd]" string => "/etc/init.d/atd restart"; "reloadcommand[atd]" string => "/etc/init.d/atd reload"; "stopcommand[atd]" string => "/etc/init.d/atd stop"; "pattern[atd]" string => "atd.*"; "startcommand[bluetoothd]" string => "/etc/init.d/bluetoothd start"; "restartcommand[bluetoothd]" string => "/etc/init.d/bluetoothd restart"; "reloadcommand[bluetoothd]" string => "/etc/init.d/bluetoothd reload"; "stopcommand[bluetoothd]" string => "/etc/init.d/bluetoothd stop"; "pattern[bluetoothd]" string => ".*bluetoothd.*"; "startcommand[bootlogd]" string => "/etc/init.d/bootlogd start"; "restartcommand[bootlogd]" string => "/etc/init.d/bootlogd restart"; "reloadcommand[bootlogd]" string => "/etc/init.d/bootlogd reload"; "stopcommand[bootlogd]" string => "/etc/init.d/bootlogd stop"; "pattern[bootlogd]" string => ".*bootlogd.*"; "startcommand[crond]" string => "/etc/init.d/cron start"; "restartcommand[crond]" string => "/etc/init.d/cron restart"; "reloadcommand[crond]" string => "/etc/init.d/cron reload"; "stopcommand[crond]" string => "/etc/init.d/cron stop"; "pattern[crond]" string => ".*cron.*"; "startcommand[kerneloops]" string => "/etc/init.d/kerneloops start"; "restartcommand[kerneloops]" string => "/etc/init.d/kerneloops restart"; "reloadcommand[kerneloops]" string => "/etc/init.d/kerneloops reload"; "stopcommand[kerneloops]" string => "/etc/init.d/kerneloops stop"; "pattern[kerneloops]" string => ".*kerneloops.*"; "startcommand[mysql]" string => "/etc/init.d/mysql start"; "restartcommand[mysql]" string => "/etc/init.d/mysql restart"; "reloadcommand[mysql]" string => "/etc/init.d/mysql reload"; "stopcommand[mysql]" string => "/etc/init.d/mysql stop"; "pattern[mysql]" string => ".*mysqld.*"; "startcommand[ntpd]" string => "/etc/init.d/ntp start"; "restartcommand[ntpd]" string => "/etc/init.d/ntp restart"; "reloadcommand[ntpd]" string => "/etc/init.d/ntp reload"; "stopcommand[ntpd]" string => "/etc/init.d/ntp stop"; "pattern[ntpd]" string => ".*ntpd.*"; "startcommand[NetworkManager]" string => "/etc/init.d/network-manager start"; "restartcommand[NetworkManager]" string => "/etc/init.d/network-manager restart"; "reloadcommand[NetworkManager]" string => "/etc/init.d/network-manager reload"; "stopcommand[NetworkManager]" string => "/etc/init.d/network-manager stop"; "pattern[NetworkManager]" string => ".*NetworkManager.*"; "startcommand[ondemand]" string => "/etc/init.d/ondemand start"; "restartcommand[ondemand]" string => "/etc/init.d/ondemand restart"; "reloadcommand[ondemand]" string => "/etc/init.d/ondemand reload"; "stopcommand[ondemand]" string => "/etc/init.d/ondemand stop"; "pattern[ondemand]" string => ".*ondemand.*"; "startcommand[plymouth]" string => "/etc/init.d/plymouthd start"; "restartcommand[plymouth]" string => "/etc/init.d/plymouthd restart"; "reloadcommand[plymouth]" string => "/etc/init.d/plymouthd reload"; "stopcommand[plymouth]" string => "/etc/init.d/plymouthd stop"; "pattern[plymouth]" string => ".*plymouthd.*"; "startcommand[postgresql84]" string => "/etc/init.d/postgresql-8.4 start"; "restartcommand[postgresql84]" string => "/etc/init.d/postgresql-8.4 restart"; "reloadcommand[postgresql84]" string => "/etc/init.d/postgresql-8.4 reload"; "stopcommand[postgresql84]" string => "/etc/init.d/postgresql-8.4 stop"; "pattern[postgresql84]" string => ".*postgresql.*"; "startcommand[postgresql91]" string => "/etc/init.d/postgresql-9.1 start"; "restartcommand[postgresql91]" string => "/etc/init.d/postgresql-9.1 restart"; "reloadcommand[postgresql91]" string => "/etc/init.d/postgresql-9.1 reload"; "stopcommand[postgresql91]" string => "/etc/init.d/postgresql-9.1 stop"; "pattern[postgresql91]" string => ".*postgresql.*"; "startcommand[saned]" string => "/etc/init.d/saned start"; "restartcommand[saned]" string => "/etc/init.d/saned restart"; "reloadcommand[saned]" string => "/etc/init.d/saned reload"; "stopcommand[saned]" string => "/etc/init.d/saned stop"; "pattern[saned]" string => ".*saned.*"; "startcommand[udev]" string => "/etc/init.d/udev start"; "restartcommand[udev]" string => "/etc/init.d/udev restart"; "reloadcommand[udev]" string => "/etc/init.d/udev reload"; "stopcommand[udev]" string => "/etc/init.d/udev stop"; "pattern[udev]" string => ".*udev.*"; "startcommand[udevmonitor]" string => "/etc/init.d/udevmonitor start"; "restartcommand[udevmonitor]" string => "/etc/init.d/udevmonitor restart"; "reloadcommand[udevmonitor]" string => "/etc/init.d/udevmonitor reload"; "stopcommand[udevmonitor]" string => "/etc/init.d/udevmonitor stop"; "pattern[udevmonitor]" string => ".*udevadm.*monitor.*"; "startcommand[www]" string => "/etc/init.d/apache2 start"; "restartcommand[www]" string => "/etc/init.d/apache2 restart"; "reloadcommand[www]" string => "/etc/init.d/apache2 reload"; "stopcommand[www]" string => "/etc/init.d/apache2 stop"; "pattern[www]" string => ".*apache2.*"; "startcommand[ssh]" string => "/etc/init.d/ssh start"; "restartcommand[ssh]" string => "/etc/init.d/ssh restart"; "reloadcommand[ssh]" string => "/etc/init.d/ssh reload"; "stopcommand[ssh]" string => "/etc/init.d/ssh stop"; "pattern[ssh]" string => ".*sshd.*"; "startcommand[snmpd]" string => "/etc/init.d/snmpd start"; "restartcommand[snmpd]" string => "/etc/init.d/snmpd restart"; "reloadcommand[snmpd]" string => "/etc/init.d/snmpd reload"; "stopcommand[snmpd]" string => "/etc/init.d/snmpd stop"; "pattern[snmpd]" string => "/usr/sbin/snmpd"; "startcommand[pgbouncer]" string => "/etc/init.d/pgbouncer start"; "restartcommand[pgbouncer]" string => "/etc/init.d/pgbouncer restart"; "reloadcommand[pgbouncer]" string => "/etc/init.d/pgbouncer reload"; "stopcommand[pgbouncer]" string => "/etc/init.d/pgbouncer stop"; "pattern[pgbouncer]" string => ".*pgbouncer.*"; "startcommand[supervisor]" string => "/etc/init.d/supervisor start"; "restartcommand[supervisor]" string => "/etc/init.d/supervisor restart"; "stopcommand[supervisor]" string => "/etc/init.d/supervisor stop"; "pattern[supervisor]" string => ".*supervisord.*"; "startcommand[nrpe]" string => "/etc/init.d/nagios-nrpe-server start"; "restartcommand[nrpe]" string => "/etc/init.d/nagios-nrpe-server restart"; "reloadcommand[nrpe]" string => "/etc/init.d/nagios-nrpe-server reload"; "stopcommand[nrpe]" string => "/etc/init.d/nagios-nrpe-server stop"; "pattern[nrpe]" string => ".*nrpe.*"; "startcommand[munin-node]" string => "/etc/init.d/munin-node start"; "restartcommand[munin-node]" string => "/etc/init.d/munin-node restart"; "reloadcommand[munin-node]" string => "/etc/init.d/munin-node reload"; "stopcommand[munin-node]" string => "/etc/init.d/munin-node stop"; "pattern[munin-node]" string => ".*munin-node.*"; "startcommand[carbon-cache]" string => "/etc/init.d/carbon-cache start"; "restartcommand[carbon-cache]" string => "/etc/init.d/carbon-cache restart"; "stopcommand[carbon-cache]" string => "/etc/init.d/carbon-cache stop"; "pattern[carbon-cache]" string => ".*carbon-cache.*"; "startcommand[cassandra]" string => "/etc/init.d/cassandra start"; "restartcommand[cassandra]" string => "/etc/init.d/cassandra restart"; "stopcommand[cassandra]" string => "/etc/init.d/cassandra stop"; "pattern[cassandra]" string => ".*jsvc\.exec.*apache-cassandra\.jar.*"; "startcommand[omsa-dataeng]" string => "/etc/init.d/dataeng start"; "restartcommand[omsa-dataeng]" string => "/etc/init.d/dataeng restart"; "stopcommand[omsa-dataeng]" string => "/etc/init.d/dataeng stop"; "pattern[omsa-dataeng]" string => ".*dsm_sa_datamgr.*"; freebsd:: "startcommand[ntpd]" string => "/etc/rc.d/ntpd start"; "restartcommand[ntpd]" string => "/etc/rc.d/ntpd restart"; "reloadcommand[ntpd]" string => "/etc/rc.d/ntpd reload"; "stopcommand[ntpd]" string => "/etc/rc.d/ntpd stop"; "pattern[ntpd]" string => "/usr/sbin/ntpd.*"; "startcommand[ssh]" string => "/etc/rc.d/sshd start"; "restartcommand[ssh]" string => "/etc/rc.d/sshd restart"; "reloadcommand[ssh]" string => "/etc/rc.d/sshd reload"; "stopcommand[ssh]" string => "/etc/rc.d/sshd stop"; "pattern[ssh]" string => "/usr/sbin/sshd.*"; "startcommand[syslog]" string => "/etc/rc.d/syslogd start"; "restartcommand[syslog]" string => "/etc/rc.d/syslogd restart"; "reloadcommand[syslog]" string => "/etc/rc.d/syslogd reload"; "stopcommand[syslog]" string => "/etc/rc.d/syslogd stop"; "pattern[syslog]" string => "/usr/sbin/syslogd.*"; "startcommand[crond]" string => "/etc/rc.d/cron start"; "restartcommand[crond]" string => "/etc/rc.d/cron restart"; "stopcommand[crond]" string => "/etc/rc.d/cron stop"; "pattern[crond]" string => "/usr/sbin/cron.*"; "startcommand[snmpd]" string => "/etc/rc.d/bsnmpd start"; "restartcommand[snmpd]" string => "/etc/rc.d/bsnmpd restart"; "stopcommand[snmpd]" string => "/etc/rc.d/bsnmpd stop"; "pattern[snmpd]" string => "/usr/sbin/bsnmpd.*"; "startcommand[newsyslog]" string => "/etc/rc.d/newsyslog start"; "restartcommand[newsyslog]" string => "/etc/rc.d/newsyslog restart"; "reloadcommand[newsyslog]" string => "/etc/rc.d/newsyslog reload"; "stopcommand[newsyslog]" string => "/etc/rc.d/newsyslog stop"; "pattern[newsyslog]" string => "/usr/sbin/newsyslog.*"; # METHODS that implement these ............................................ classes: "start" expression => strcmp("start","$(state)"), comment => "Check if to start a service"; "restart" expression => strcmp("restart","$(state)"), comment => "Check if to restart a service"; "reload" expression => strcmp("reload","$(state)"), comment => "Check if to reload a service"; "stop" expression => strcmp("stop","$(state)"), comment => "Check if to stop a service"; # Do we want to include the packages here too? processes: start:: "$(pattern[$(service)])" -> { "@(stakeholders[$(service)])" } comment => "Verify that the service appears in the process table", restart_class => "start_$(service)"; stop:: "$(pattern[$(service)])" -> { "@(stakeholders[$(service)])" } comment => "Verify that the service does not appear in the process", process_stop => "$(stopcommand[$(service)])", signals => { "term", "kill"}; commands: "$(startcommand[$(service)])" -> { "@(stakeholders[$(service)])" } comment => "Execute command to start the $(service) service", classes => kept_successful_command, ifvarclass => canonify("start_$(service)"); restart:: "$(restartcommand[$(service)])" -> { "@(stakeholders[$(service)])" } classes => kept_successful_command, comment => "Execute command to restart the $(service) service"; reload:: "$(reloadcommand[$(service)])" -> { "@(stakeholders[$(service)])" } classes => kept_successful_command, comment => "Execute command to reload the $(service) service"; } masterfiles-3.6.2/lib/3.5/storage.cf000066400000000000000000000052261241300473300170730ustar00rootroot00000000000000############################################################################ # Copyright (C) CFEngine AS # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License LGPL 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. # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ########################################################################### # # CFEngine Community Open Promise-Body Library # # This initiative started by CFEngine promotes a # standardized set of names and promise specifications # for template functionality within CFEngine 3. # # The aim is to promote an industry standard for # naming of configuration patterns, leading to a # de facto middleware of standardized syntax. # # Names should be intuitive and parameters should be # minimal to assist readability and comprehensibility. # Contributions to this file are voluntarily given to # the cfengine community, and are moderated by CFEngine. # No liability or warranty for misuse is implied. # # If you add to this file, please try to make the # contributions "self-documenting". Comments made # after the bundle/body statement are retained in # the online docs # # For CFEngine Core: 3.5.1 to 3.5.x # Storage bodies ################################################### # If you find CFEngine useful, please consider # # purchasing a commercial version of the software.# ################################################### ##------------------------------------------------------- ## storage promises ##------------------------------------------------------- body volume min_free_space(free) { check_foreign => "false"; freespace => "$(free)"; sensible_size => "10000"; sensible_count => "2"; } ## body mount nfs(server,source) { mount_type => "nfs"; mount_source => "$(source)"; mount_server => "$(server)"; edit_fstab => "true"; } ## body mount nfs_p(server,source,perm) { mount_type => "nfs"; mount_source => "$(source)"; mount_server => "$(server)"; mount_options => {"$(perm)"}; edit_fstab => "true"; } ## body mount unmount { mount_type => "nfs"; edit_fstab => "true"; unmount => "true"; } masterfiles-3.6.2/lib/3.6/000077500000000000000000000000001241300473300151115ustar00rootroot00000000000000masterfiles-3.6.2/lib/3.6/bundles.cf000066400000000000000000000277461241300473300170770ustar00rootroot00000000000000############################################################################ # Copyright (C) CFEngine AS # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License LGPL 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. # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ########################################################################### # # CFEngine Community Open Promise-Body Library # # This initiative started by CFEngine promotes a # standardized set of names and promise specifications # for template functionality within CFEngine 3. # # The aim is to promote an industry standard for # naming of configuration patterns, leading to a # de facto middleware of standardized syntax. # # Names should be intuitive and parameters should be # minimal to assist readability and comprehensibility. # Contributions to this file are voluntarily given to # the cfengine community, and are moderated by CFEngine. # No liability or warranty for misuse is implied. # # If you add to this file, please try to make the # contributions "self-documenting". Comments made # after the bundle/body statement are retained in # the online docs # # For CFEngine Core: 3.6.0 to 3.6.x # Bundles ################################################### # If you find CFEngine useful, please consider # # purchasing a commercial version of the software.# ################################################### bundle common bundles_common # @ignore { vars: "inputs" slist => { "$(this.promise_dirname)/paths.cf", "$(this.promise_dirname)/files.cf", "$(this.promise_dirname)/commands.cf" }; } body file control # @ignore { inputs => { @(bundles_common.inputs) }; } ################################################### # agent bundles ################################################### bundle agent cronjob(commands,user,hours,mins) # @brief Defines a cron job for `user` # # Adds a line to crontab, if necessary. # # @param commands The commands that should be run # @param user The owner of crontab # @param hours The hours at which the job should run # @param mins The minutes at which the job should run # # **Example:** # # ```cf3 # methods: # "cron" usebundle => cronjob("/bin/ls","mark","*","5,10"); # ``` { vars: suse:: "crontab" string => "/var/spool/cron/tabs"; redhat|fedora:: "crontab" string => "/var/spool/cron"; freebsd:: "crontab" string => "/var/cron/tabs"; !(suse|redhat|fedora|freebsd):: "crontab" string => "/var/spool/cron/crontabs"; files: !windows:: "$(crontab)/$(user)" comment => "A user's regular batch jobs are added to this file", create => "true", edit_line => append_if_no_line("$(mins) $(hours) * * * $(commands)"), perms => mo("600","$(user)"), classes => if_repaired("changed_crontab"); processes: changed_crontab:: "cron" comment => "Most crons need to be huped after file changes", signals => { "hup" }; } bundle agent rm_rf(name) # @brief recursively remove `name` to any depth, including base # @depends rm_rf_depth # @param name the file or directory name # # This bundle will remove `name` to any depth, including `name` itself. # # **Example:** # # ```cf3 # methods: # "bye" usebundle => rm_rf("/var/tmp/oldstuff"); # ``` { methods: "rm" usebundle => rm_rf_depth($(name),"inf"); } bundle agent rm_rf_depth(name,depth) # @brief recursively remove `name` to depth `depth`, including base # @depends recurse_with_base tidy all # @param name the file or directory name # @param depth how far to descend # # This bundle will remove `name` to depth `depth`, including `name` itself. # # **Example:** # # ```cf3 # methods: # "bye" usebundle => rm_rf_depth("/var/tmp/oldstuff", "100"); # ``` { classes: "isdir" expression => isdir($(name)); files: isdir:: "$(name)" file_select => all, depth_search => recurse_with_base($(depth)), delete => tidy; !isdir:: "$(name)" delete => tidy; } bundle agent fileinfo(f) # @brief provide access to file stat fields from the bundle caller and report # file stat info for file "f" if "verbose_mode" class is defined # @param f file or files to stat # # **Example:** # # ```cf3 # bundle agent example # { # vars: # "files" slist => { "/tmp/example1", "/tmp/example2" }; # # files: # "$(files)" # create => "true", # classes => if_ok("verbose_mode"), # comment => "verbose_mode is defined because the fileinfo bundle restricts the report of the file info to verbose mode"; # # "/tmp/example3" # create => "true", # classes => if_ok("verbose_mode"), # comment => "verbose_mode is defined because the fileinfo bundle restricts the report of the file info to verbose mode"; # # # methods: # "fileinfo" usebundle => fileinfo( @(files) ); # "fileinfo" usebundle => fileinfo( "/tmp/example3" ); # # reports: # "$(this.bundle): $(files): $(fileinfo.fields) = '$(fileinfo.stat[$(files)][$(fileinfo.fields)])'"; # "$(this.bundle): $(fileinfo.stat[/tmp/example3][size])"; # "$(this.bundle): $(fileinfo.stat[/tmp/example3][gid])"; # "$(this.bundle): $(fileinfo.stat[/tmp/example3][uid])"; # "$(this.bundle): $(fileinfo.stat[/tmp/example3][ino])"; # "$(this.bundle): $(fileinfo.stat[/tmp/example3][nlink])"; # "$(this.bundle): $(fileinfo.stat[/tmp/example3][ctime])"; # "$(this.bundle): $(fileinfo.stat[/tmp/example3][atime])"; # "$(this.bundle): $(fileinfo.stat[/tmp/example3][mtime])"; # "$(this.bundle): $(fileinfo.stat[/tmp/example3][mode])"; # "$(this.bundle): $(fileinfo.stat[/tmp/example3][modeoct])"; # "$(this.bundle): $(fileinfo.stat[/tmp/example3][permstr])"; # "$(this.bundle): $(fileinfo.stat[/tmp/example3][permoct])"; # "$(this.bundle): $(fileinfo.stat[/tmp/example3][type])"; # "$(this.bundle): $(fileinfo.stat[/tmp/example3][devno])"; # "$(this.bundle): $(fileinfo.stat[/tmp/example3][dev_minor])"; # "$(this.bundle): $(fileinfo.stat[/tmp/example3][dev_major])"; # "$(this.bundle): $(fileinfo.stat[/tmp/example3][basename])"; # "$(this.bundle): $(fileinfo.stat[/tmp/example3][dirname])"; # } # ``` { vars: "fields" slist => splitstring("size,gid,uid,ino,nlink,ctime,atime,mtime,mode,modeoct,permstr,permoct,type,devno,dev_minor,dev_major,basename,dirname,linktarget,linktarget_shallow", ",", 999); "stat[$(f)][$(fields)]" string => filestat($(f), $(fields)); reports: verbose_mode:: "$(this.bundle): file $(f) has $(fields) = $(stat[$(f)][$(fields)])"; } bundle agent logrotate(log_files, max_size, rotate_levels) # @brief rotate specified "log_files" larger than "max_size". Keep # "rotate_levels" versions of the files before overwriting the oldest one # @depends rotate # @depends bigger_than # @param log_files single file or list of files to evaluate for rotation # @param max_size minimum size in bytes that the file will grow to before being rotated # @param rotate_levels number of rotations to keep before overwriting the oldest one # # **Example:** # # ```cf3 # bundle agent example # { # vars: # "logdirs" slist => { "/var/log/syslog", "/var/log/maillog"}; # # methods: # "logrotate" usebundle => logrotate( @(logdirs), "1M", "2" ); # "logrotate" usebundle => logrotate( "/var/log/mylog, "1", "5" ); # "logrotate" usebundle => logrotate( "/var/log/alog, "500k", "7" ); # } # ``` { files: "$(log_files)" comment => "Rotate file if above specified size", rename => rotate("$(rotate_levels)"), file_select => bigger_than("$(max_size)"); } bundle agent prunedir(dir, max_days) # @brief delete plain files inside "dir" older than "max_days" (not recursively). # @depends tidy # @depends recurse # @depends filetype_older_than # @param dir directory to examine for files # @param max_days maximum number of days old a files mtime is allowed to before deletion # # **Example:** # # ```cf3 # bundle agent example # { # vars: # "dirs" slist => { "/tmp/logs", "/tmp/logs2" }; # # methods: # "prunedir" usebundle => prunedir( @(dirs), "1" ); # } # ``` { files: "$(dir)" comment => "Delete plain files inside directory older than max_days", delete => tidy, file_select => filetype_older_than("plain", "$(max_days)"), depth_search => recurse("1"); } bundle agent url_ping(host, method, port, uri) # @brief ping HOST:PORT/URI using METHOD # @param host the host name # @param method the HTTP method (HEAD or GET) # @param port the port number, e.g. 80 # @param uri the URI, e.g. /path/to/resource # # This bundle will send a simple HTTP request and read 20 bytes back, # then compare them to `200 OK.*` (ignoring leading spaces). # # If the data matches, the global class "url_ok_HOST" will be set, where # HOST is the canonified host name, i.e. `canonify($(host))` # # **Example:** # # ```cf3 # methods: # "check" usebundle => url_ping("cfengine.com", "HEAD", "80", "/bill/was/here"); # reports: # url_ok_cfengine_com:: # "CFEngine's web site is up"; # url_not_ok_cfengine_com:: # "CFEngine's web site *may* be down. Or you're offline."; # ``` { vars: "url_check" string => readtcp($(host), $(port), "$(method) $(uri) HTTP/1.1$(const.r)$(const.n)Host:$(host)$(const.r)$(const.n)$(const.r)$(const.n)", 20); "chost" string => canonify($(host)); classes: "url_ok_$(chost)" scope => "namespace", expression => regcmp("[^\n]*200 OK.*\n.*", $(url_check)); "url_not_ok_$(chost)" scope => "namespace", not => regcmp("[^\n]*200 OK.*\n.*", $(url_check)); reports: verbose_mode:: "$(this.bundle): $(method) $(host):$(port)/$(uri) got 200 OK" ifvarclass => "url_ok_$(chost)"; "$(this.bundle): $(method) $(host):$(port)/$(uri) did *not* get 200 OK" ifvarclass => "url_not_ok_$(chost)"; } bundle agent cmerge(name, varlist) # @brief bundle to merge many data containers into one # @param name the variable name to create # @param varlist a list of variable names (**MUST** be a list) # # The result will be in `cmerge.$(name)`. You can also use # `cmerge.$(name)_str` for a string version of the merged containers. # # The name is variable so you can call this bundle for more than one # merge. # # If you merge a key-value map into an array or vice versa, the map # always wins. So this example will result in a key-value map even # though `cmerge.$(name)` starts as an array. # # **Example:** # # ```cf3 # bundle agent run # { # vars: # # the "mymerge" tag is user-defined # "a" data => parsejson('{ "mark": "b" }'), meta => { "mymerge" }; # "b" data => parsejson('{ "volker": "h" }'), meta => { "mymerge" }; # # # you can list them explicitly: "default:run.a" through "default:run.d" # "todo" slist => variablesmatching(".*", "mymerge"); # # # you can use cmerge.all_str instead of accessing the merged data directly # "merged_str" string => format("%S", "cmerge.all"); # # methods: # "go" usebundle => cmerge("all", @(todo)); # merge a, b into container cmerge.all # # reports: # "merged = $(cmerge.all_str)"; # will print a map with keys "mark" and "volker" # } # ``` { vars: "$(name)" data => parsejson('[]'), policy => "free"; "$(name)" data => mergedata($(name), $(varlist)), policy => "free"; # iterates! "$(name)_str" string => format("%S", $(name)), policy => "free"; } masterfiles-3.6.2/lib/3.6/cfe_internal.cf000066400000000000000000000214641241300473300200630ustar00rootroot00000000000000############################################################################ # Copyright (C) CFEngine AS # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License LGPL 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. # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ########################################################################### # # CFEngine Community Open Promise-Body Library # # This initiative started by CFEngine promotes a # standardized set of names and promise specifications # for template functionality within CFEngine 3. # # The aim is to promote an industry standard for # naming of configuration patterns, leading to a # de facto middleware of standardized syntax. # # Names should be intuitive and parameters should be # minimal to assist readability and comprehensibility. # Contributions to this file are voluntarily given to # the cfengine community, and are moderated by CFEngine. # No liability or warranty for misuse is implied. # # If you add to this file, please try to make the # contributions "self-documenting". Comments made # after the bundle/body statement are retained in # the online docs # # For CFEngine Core: 3.6.0 to 3.6.x # Internal hub maintenance bundles, incompatible with 3.5.x ################################################### # If you find CFEngine useful, please consider # # purchasing a commercial version of the software.# ################################################### bundle common cfe_internal_common # @ignore { vars: "inputs" slist => { "$(this.promise_dirname)/common.cf", "$(this.promise_dirname)/commands.cf"}; } body file control # @ignore { inputs => { @(cfe_internal_common.inputs) }; } bundle agent cfe_internal_hub_maintain # @ignore # @brief Executes reporting database maintenance process # By default database clean up interval is 24 hours. # Length of log history in database is controlled # by modifying "history_length_days" key in report_settings # variable. # # Intervals less than 6 hours must be used with caution # as maintenance process could take a considerable time { vars: "report_settings" data => parsejson('[ { "report": "contexts", "table": "__ContextsLog", "history_length_days": 7, "time_key": "ChangeTimeStamp" }, { "report": "variables", "table": "__VariablesLog", "history_length_days": 7, "time_key": "ChangeTimeStamp" }, { "report": "software", "table": "__SoftwareLog", "history_length_days": 28, "time_key": "ChangeTimeStamp" }, { "report": "software_updates", "table": "__SoftwareUpdatesLog", "history_length_days": 28, "time_key": "ChangeTimeStamp" }, { "report": "filechanges", "table": "__FileChangesLog", "history_length_days": 365, "time_key": "ChangeTimeStamp" }, { "report": "benchmarks", "table": "__BenchmarksLog", "history_length_days": 7, "time_key": "CheckTimeStamp" }, { "report": "promise_executions", "table": "__PromiseExecutionsLog", "history_length_days": 7, "time_key": "ChangeTimeStamp" } ]'); "diagnostics_settings" data => parsejson('[ { "report": "hub_connection_errors", "table": "__HubConnectionErrors", "history_length_days": 1, "time_key": "CheckTimeStamp" }, { "report": "diagnostics", "table": "Diagnostics", "history_length_days": 1, "time_key": "TimeStamp" } ]'); methods: Hr00.Min00_05:: "Remove old report history" usebundle => cfe_internal_database_cleanup_reports(@(report_settings)), action => if_elapsed(5); "Remove cf-consumer history" usebundle => cfe_internal_database_cleanup_consumer_status("50000"), action => if_elapsed(5); "Remove diagnostics history" usebundle => cfe_internal_database_cleanup_diagnostics(@(diagnostics_settings)), action => if_elapsed(5); } bundle agent cfe_internal_database_cleanup_reports (settings) # @ignore # @brief clean up the reporting tables { vars: "index" slist => getindices(settings); "remove_query_$(settings[$(index)][report])" string => "DELETE FROM $(settings[$(index)][table]) AS T USING (SELECT HostKey, (LastAgentLocalExecutionTimestamp - INTERVAL '$(settings[$(index)][history_length_days]) day') AS purge_time FROM __agentstatus) AS A WHERE T.HostKey = A.HostKey AND T.$(settings[$(index)][time_key]) <= A.purge_time;"; commands: "$(sys.bindir)/psql cfdb -c \"$(remove_query_$(settings[$(index)][report]))\"" contain => in_shell_and_silent, classes => kept_successful_command, handle => "cf_database_maintain_report_$(settings[$(index)][report])"; } bundle agent cfe_internal_database_cleanup_consumer_status (row_count) # @ignore # @brief keep up to row_count entries in the database { vars: "remove_query" string => "DELETE FROM status WHERE ts IN (SELECT ts FROM status ORDER BY ts DESC OFFSET $(row_count));"; commands: "$(sys.bindir)/psql cfdb -c \"$(remove_query)\"" contain => in_shell_and_silent, classes => kept_successful_command, handle => "cf_database_maintain_consumer_status"; } bundle agent cfe_internal_database_cleanup_diagnostics (settings) { vars: "index" slist => getindices("settings"); "remove_query_$(settings[$(index)][report])" string => "DELETE FROM $(settings[$(index)][table]) WHERE $(settings[$(index)][time_key]) < (CURRENT_TIMESTAMP - INTERVAL '$(settings[$(index)][history_length_days]) day');"; commands: "$(sys.bindir)/psql cfdb -c \"$(remove_query_$(settings[$(index)][report]))\"" contain => in_shell_and_silent, classes => kept_successful_command, handle => "cf_database_maintain_diagnostics_$(settings[$(index)][report])"; } masterfiles-3.6.2/lib/3.6/commands.cf000066400000000000000000000216241241300473300172310ustar00rootroot00000000000000############################################################################ # Copyright (C) CFEngine AS # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License LGPL 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. # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ########################################################################### # # CFEngine Community Open Promise-Body Library # # This initiative started by CFEngine promotes a # standardized set of names and promise specifications # for template functionality within CFEngine 3. # # The aim is to promote an industry standard for # naming of configuration patterns, leading to a # de facto middleware of standardized syntax. # # Names should be intuitive and parameters should be # minimal to assist readability and comprehensibility. # Contributions to this file are voluntarily given to # the cfengine community, and are moderated by CFEngine. # No liability or warranty for misuse is implied. # # If you add to this file, please try to make the # contributions "self-documenting". Comments made # after the bundle/body statement are retained in # the online docs # # For CFEngine Core: 3.6.0 to 3.6.x # Commands bodies ################################################### # If you find CFEngine useful, please consider # # purchasing a commercial version of the software.# ################################################### bundle agent daemonize(command) # @brief Run a command as a daemon. I.e., fully detaches from Cfengine. # @param command The command to run detached # Note: There will be no output from the command reported by cf-agent. This # bundle has no effect on windows # # **Example:** # ```cf3 # methods: # "Launch Daemon" # usebundle => daemonize("/bin/sleep 30"); # ``` { commands: !windows:: "exec 1>&-; exec 2>&-; $(command) &" contain => in_shell; reports: windows.(inform_mode|verbose_mode):: "$(this.bundle): This bundle does not support Windows"; } ##------------------------------------------------------- ## contain ##------------------------------------------------------- body contain silent # @brief suppress command output { no_output => "true"; } ## body contain in_dir(dir) # @brief run command after switching to directory "dir" # @param dir directory to change into # # **Example:** # # ```cf3 # commands: # "/bin/pwd" # contain => in_dir("/tmp"); # ``` { chdir => "$(dir)"; } ## body contain in_dir_shell(dir) # @brief run command after switching to directory "dir" with full shell # @param dir directory to change into # # **Example:** # # ```cf3 # commands: # "/bin/pwd | /bin/cat" # contain => in_dir_shell("/tmp"); # ``` { chdir => "$(dir)"; useshell => "true"; # canonical "useshell" but this is backwards-compatible } ## body contain silent_in_dir(dir) # @brief run command after switching to directory and suppress output # @param dir directory to change into # # **Example:** # # ```cf3 # "/bin/pwd" # contain => silent_in_dir("/tmp"); # ``` { chdir => "$(dir)"; no_output => "true"; } ## body contain in_shell # @brief run command in shell # # **Example:** # # ```cf3 # commands: # "/bin/pwd | /bin/cat" # contain => in_shell; # ``` { useshell => "true"; # canonical "useshell" but this is backwards-compatible } ## body contain in_shell_bg # @brief deprecated # This bundle previously had an invalid background attribute that was caught by # parser strictness enhancements. Backgrounding is handeled by the body action # background attribute. { useshell => "true"; # canonical "useshell" but this is backwards-compatible } ## body contain in_shell_and_silent # @brief run command in shell and suppress output # # **Example:** # # ```cf3 # commands: # "/bin/pwd | /bin/cat" # contain => in_shell_and_silent, # comment => "Silently run command in shell"; # ``` { useshell => "true"; # canonical "useshell" but this is backwards-compatible no_output => "true"; } ## body contain in_dir_shell_and_silent(dir) # @brief run command in shell after switching to 'dir' and suppress output # @param dir directory to change into # # **Example:** # # ```cf3 # commands: # "/bin/pwd | /bin/cat" # contain => in_dir_shell_and_silent("/tmp"), # comment => "Silently run command in shell"; # ``` { useshell => "true"; # canonical "useshell" but this is backwards-compatible no_output => "true"; chdir => "$(dir)"; } ## body contain setuid(owner) # @brief run command as specified user # @param owner username or uid to run command as # # **Example:** # # ```cf3 # commands: # "/usr/bin/id" # contain => setuid("apache"); # "/usr/bin/id" # contain => setuid("503"); # ``` { exec_owner => "$(owner)"; } ## body contain setuid_sh(owner) # @brief run command as specified user in shell # @param owner username or uid to run command as # # **Example:** # # ```cf3 # commands: # "/usr/bin/id | /bin/cat" # contain => setuid("apache"); # "/usr/bin/id | /bin/cat" # contain => setuid("503"); # ``` { exec_owner => "$(owner)"; useshell => "true"; # canonical "useshell" but this is backwards-compatible } ## body contain setuidgid_dir(owner,group,dir) # @brief run command as specified owner and group in shell # @param owner username or uid to run command as # @param group groupname or gid to run command as # @param dir directory to run command from { exec_owner => "$(owner)"; exec_group => "$(group)"; chdir => "$(dir)"; } ## body contain setuidgid_sh(owner,group) # @brief run command as specified owner and group in shell # @param owner username or uid to run command as # @param group groupname or gid to run command as { exec_owner => "$(owner)"; exec_group => "$(group)"; useshell => "true"; # canonical "useshell" but this is backwards-compatible } ## body contain jail(owner,jail_root,dir) # @brief run command as specified user in specified directory of jail # @param owner username or uid to run command as # @param jail_root path that will be the root directory for the process # @param dir directory to change to before running command (must be within 'jail_root') { exec_owner => "$(owner)"; useshell => "true"; # canonical "useshell" but this is backwards-compatible chdir => "$(dir)"; chroot => "$(jail_root)"; } ## body contain setuid_umask(owner, umask) # @brief run command as specified user with umask # # # | Valid Values | Umask | Octal (files) | Symbolic (files) | Octal (dirs) | Symbolic (dirs) | # |--------------|-------|-------|-------------|-------|-------------| # | `0` | `000` | `666` | `(rw-rw-rw-)` | `777` | `(rwxrwxrwx)` | # | `002` | `002` | `664` | `(rw-rw-r--)` | `775` | `(rwxrwxr-x)` | # | `22`, `022` | `022` | `644` | `(rw-r--r--)` | `755` | `(rwxr-xr-x)` | # | `27`, `027` | `027` | `640` | `(rw-r-----)` | `750` | `(rwxr-x---)` | # | `77`, `077` | `077` | `600` | `(rw-------)` | `700` | `(rwx------)` | # | `72`, `072` | `072` | `604` | `(rw----r--)` | `705` | `(rwx---r-x)` | # # @param owner username or uid to run command as # @param umask controls permissions of created files and directories # # **Example:** # # ```cf3 # commands: # "/usr/bin/git pull" # contain => setuid_umask("git", "022"); # ``` { exec_owner => "$(owner)"; umask => "$(umask)"; } body contain setuid_gid_umask(uid, gid, umask) # @brief run command as specified user with umask # # # | Valid Values | Umask | Octal (files) | Symbolic (files) | Octal (dirs) | Symbolic (dirs) | # |--------------|-------|-------|-------------|-------|-------------| # | `0` | `000` | `666` | `(rw-rw-rw-)` | `777` | `(rwxrwxrwx)` | # | `002` | `002` | `664` | `(rw-rw-r--)` | `775` | `(rwxrwxr-x)` | # | `22`, `022` | `022` | `644` | `(rw-r--r--)` | `755` | `(rwxr-xr-x)` | # | `27`, `027` | `027` | `640` | `(rw-r-----)` | `750` | `(rwxr-x---)` | # | `77`, `077` | `077` | `600` | `(rw-------)` | `700` | `(rwx------)` | # | `72`, `072` | `072` | `604` | `(rw----r--)` | `705` | `(rwx---r-x)` | # # @param uid username or uid to run command as # @param gid group name or gid to run command as # @param umask controls permissions of created files and directories # # **Example:** # # ```cf3 # commands: # "/usr/bin/git pull" # contain => setuid_gid_umask("git", "minions", "022"); # ``` { exec_owner => "$(uid)"; exec_group => "$(uid)"; umask => "$(umask)"; } masterfiles-3.6.2/lib/3.6/common.cf000066400000000000000000000234251241300473300167210ustar00rootroot00000000000000############################################################################ # Copyright (C) CFEngine AS # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License LGPL 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. # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ########################################################################### # # CFEngine Community Open Promise-Body Library # # This initiative started by CFEngine promotes a # standardized set of names and promise specifications # for template functionality within CFEngine 3. # # The aim is to promote an industry standard for # naming of configuration patterns, leading to a # de facto middleware of standardized syntax. # # Names should be intuitive and parameters should be # minimal to assist readability and comprehensibility. # Contributions to this file are voluntarily given to # the cfengine community, and are moderated by CFEngine. # No liability or warranty for misuse is implied. # # If you add to this file, please try to make the # contributions "self-documenting". Comments made # after the bundle/body statement are retained in # the online docs # # For CFEngine Core: 3.6.0 to 3.6.x # Common bodies ################################################### # If you find CFEngine useful, please consider # # purchasing a commercial version of the software.# ################################################### #################################################### ## agent bodyparts #################################################### ##------------------------------------------------------- ## action ##------------------------------------------------------- body action if_elapsed(x) # @brief Evaluate the promise every `x` minutes # @param x The time in minutes between promise evaluations { ifelapsed => "$(x)"; expireafter => "$(x)"; } ## body action if_elapsed_day # @brief Evalute the promise once every 24 hours { ifelapsed => "1440"; # 60 x 24 expireafter => "1400"; } ## body action measure_performance(x) # @brief Measure repairs of the promiser every `x` minutes # # Repair-attempts are cancelled after `x` minutes. # # @param x The time in minutes between promise evaluations. { measurement_class => "Detect changes in $(this.promiser)"; ifelapsed => "$(x)"; expireafter => "$(x)"; } ## body action warn_only # @brief Warn once an hour if the promise needs to be repaired # # The promise does not get repaired. { action_policy => "warn"; ifelapsed => "60"; } ## body action bg(elapsed,expire) # @brief Evaluate the promise in the background every `elapsed` minutes, for at most `expire` minutes # @param elapsed The time in minutes between promise evaluations # @param expire The time in minutes after which a repair-attempt gets cancelled { ifelapsed => "$(elapsed)"; expireafter => "$(expire)"; background => "true"; } ## body action ifwin_bg # @brief Evaluate the promise in the background when running on Windows { windows:: background => "true"; } ## body action immediate # @brief Evaluate the promise at every `cf-agent` execution. { ifelapsed => "0"; } ## body action policy(p) # @brief Set the `action_policy` to `p` # @param p The action policy { action_policy => "$(p)"; } ## body action log_repaired(log,message) # @brief Log `message` to a file `log`=[/file|stdout] # @param log The log file for repaired messages # @param message The log message { log_string => "$(sys.date), $(message)"; log_repaired => "$(log)"; } ### body action log_verbose # @brief Sets the `log_level` attribute to "verbose" { log_level => "verbose"; } ## body action sample_rate(x) # @brief Evaluate the promise every `x` minutes, # A repair-attempt is cancelled after 10 minutes # @param x The time in minutes between promise evaluation { ifelapsed => "$(x)"; expireafter => "10"; } ##------------------------------------------------------- ## classes ##------------------------------------------------------- body classes if_repaired(x) # @brief Define class `x` if the promise has been repaired # @param x The name of the class { promise_repaired => { "$(x)" }; } ## body classes if_else(yes,no) # @brief Define the classes `yes` or `no` depending on promise outcome # @param yes The name of the class that should be defined if the promise is kept or repaired # @param no The name of the class that should be defined if the promise could not be repaired { promise_kept => { "$(yes)" }; promise_repaired => { "$(yes)" }; repair_failed => { "$(no)" }; repair_denied => { "$(no)" }; repair_timeout => { "$(no)" }; } ## body classes cf2_if_else(yes,no) # @brief Define the classes `yes` or `no`, depending on promise outcome # # A version of `if_else` that matches CFEngine2 semantics. Neither class is set if the promise # does not require any repair. # # @param yes The name of the class that should be defined if the promise is repaired # @param no The name of the class that should be defind if teh promise could not be repaired { promise_repaired => { "$(yes)" }; repair_failed => { "$(no)" }; repair_denied => { "$(no)" }; repair_timeout => { "$(no)" }; } ## body classes if_notkept(x) # @brief Define the class `x` if the promise is not kept and cannot be repaired. # @param x The name of the class that should be defined { repair_failed => { "$(x)" }; repair_denied => { "$(x)" }; repair_timeout => { "$(x)" }; } ## body classes if_ok(x) # @brief Define the class `x` if the promise is kept or could be repaired # @param x The name of the class that should be defined { promise_repaired => { "$(x)" }; promise_kept => { "$(x)" }; } ## body classes if_ok_cancel(x) # @brief Cancel the class `x` if the promise ks kept or repaired # @param x The name of the class that should be cancelled { cancel_repaired => { "$(x)" }; cancel_kept => { "$(x)" }; } ## body classes cmd_repair(code,cl) # @brief Define the class `cl` if an external command in a `commands`, `file` or `packages` # promise is executed with return code `code` # @param code The return codes that indicate a successful repair # @param cl The name of the class that should be defined # # **See also:** `repaired_returncodes` { repaired_returncodes => { "$(code)" }; promise_repaired => { "$(cl)" }; } body classes classes_generic(x) # @brief Define `x` prefixed/suffixed with promise outcome # @param x The unique part of the classes to be defined { promise_repaired => { "promise_repaired_$(x)", "$(x)_repaired", "$(x)_ok", "$(x)_reached" }; repair_failed => { "repair_failed_$(x)", "$(x)_failed", "$(x)_not_ok", "$(x)_error", "$(x)_not_kept", "$(x)_not_repaired", "$(x)_reached" }; repair_denied => { "repair_denied_$(x)", "$(x)_denied", "$(x)_not_ok", "$(x)_error", "$(x)_not_kept", "$(x)_not_repaired", "$(x)_reached" }; repair_timeout => { "repair_timeout_$(x)", "$(x)_timeout", "$(x)_not_ok", "$(x)_error","$(x)_not_kept", "$(x)_not_repaired", "$(x)_reached" }; promise_kept => { "promise_kept_$(x)", "$(x)_kept", "$(x)_ok", "$(x)_not_repaired", "$(x)_reached" }; } body classes scoped_classes_generic(scope, x) # @brief Define `x` prefixed/suffixed with promise outcome # # **See also:** [`scope`][Promise Types and Attributes#scope] # # @param scope The scope in which the class should be defined # @param x The unique part of the classes to be defined { scope => "$(scope)"; promise_repaired => { "promise_repaired_$(x)", "$(x)_repaired", "$(x)_ok", "$(x)_reached" }; repair_failed => { "repair_failed_$(x)", "$(x)_failed", "$(x)_not_ok", "$(x)_error", "$(x)_not_kept", "$(x)_not_repaired", "$(x)_reached" }; repair_denied => { "repair_denied_$(x)", "$(x)_denied", "$(x)_not_ok", "$(x)_error", "$(x)_not_kept", "$(x)_not_repaired", "$(x)_reached" }; repair_timeout => { "repair_timeout_$(x)", "$(x)_timeout", "$(x)_not_ok", "$(x)_error", "$(x)_not_kept", "$(x)_not_repaired", "$(x)_reached" }; promise_kept => { "promise_kept_$(x)", "$(x)_kept", "$(x)_ok", "$(x)_not_repaired", "$(x)_reached" }; } ##------------------------------------------------------- ## Persistent classes ##------------------------------------------------------- body classes state_repaired(x) # @brief Define `x` for 10 minutes if the promise was repaired # @param x The name of the class that should be defined { promise_repaired => { "$(x)" }; persist_time => "10"; } ## body classes enumerate(x) # @brief Define `x` for 15 minutes if the promise is either kept or repaired # This is used by commercial editions to count instances of jobs in a cluster # @param x The unqiue part of the class that should be defind # The class defined is prefixed with `mXC_` { promise_repaired => { "mXC_$(x)" }; promise_kept => { "mXC_$(x)" }; persist_time => "15"; } ## body classes always(x) # @brief Define class `x` no matter what the outcome of the promise is # @param x The name of the class to be defined { promise_repaired => { "$(x)" }; promise_kept => { "$(x)" }; repair_failed => { "$(x)" }; repair_denied => { "$(x)" }; repair_timeout => { "$(x)" }; } body classes kept_successful_command # @brief Set command to "kept" instead of "repaired" if it returns 0 { kept_returncodes => { "0" }; } masterfiles-3.6.2/lib/3.6/databases.cf000066400000000000000000000057421241300473300173620ustar00rootroot00000000000000############################################################################ # Copyright (C) CFEngine AS # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License LGPL 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. # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ########################################################################### # # CFEngine Community Open Promise-Body Library # # This initiative started by CFEngine promotes a # standardized set of names and promise specifications # for template functionality within CFEngine 3. # # The aim is to promote an industry standard for # naming of configuration patterns, leading to a # de facto middleware of standardized syntax. # # Names should be intuitive and parameters should be # minimal to assist readability and comprehensibility. # Contributions to this file are voluntarily given to # the cfengine community, and are moderated by CFEngine. # No liability or warranty for misuse is implied. # # If you add to this file, please try to make the # contributions "self-documenting". Comments made # after the bundle/body statement are retained in # the online docs # # For CFEngine Core: 3.6.0 to 3.6.x # Databases bodies ################################################### # If you find CFEngine useful, please consider # # purchasing a commercial version of the software.# ################################################### ##------------------------------------------------------- ## database promises ##------------------------------------------------------- body database_server local_mysql(username, password) # @brief Defines a MySQL server running on localhost # @param username The username for the server connection # @param password The password for the server connection # # **See also:** `db_server_owner`, `db_server_password` { db_server_owner => "$(username)"; db_server_password => "$(password)"; db_server_host => "localhost"; db_server_type => "mysql"; db_server_connection_db => "mysql"; } ## body database_server local_postgresql(username, password) # @brief Defines a PostgreSQL server running on localhost # @param username The username for the server connection # @param password The password for the server connection # # **See also:** `db_server_owner`, `db_server_password` { db_server_owner => "$(username)"; db_server_password => "$(password)"; db_server_host => "localhost"; db_server_type => "postgres"; db_server_connection_db => "postgres"; } masterfiles-3.6.2/lib/3.6/edit_xml.cf000066400000000000000000000073531241300473300172400ustar00rootroot00000000000000############################################################################ # Copyright (C) CFEngine AS # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License LGPL 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. # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ########################################################################### # # CFEngine Community Open Promise-Body Library # # This initiative started by CFEngine promotes a # standardized set of names and promise specifications # for template functionality within CFEngine 3. # # The aim is to promote an industry standard for # naming of configuration patterns, leading to a # de facto middleware of standardized syntax. # # Names should be intuitive and parameters should be # minimal to assist readability and comprehensibility. # Contributions to this file are voluntarily given to # the cfengine community, and are moderated by CFEngine. # No liability or warranty for misuse is implied. # # If you add to this file, please try to make the # contributions "self-documenting". Comments made # after the bundle/body statement are retained in # the online docs # # For CFEngine Core: 3.6.0 to 3.6.x # edit_xml bundles ################################################### # If you find CFEngine useful, please consider # # purchasing a commercial version of the software.# ################################################### bundle edit_xml xml_insert_tree_nopath(treestring) # @brief Insert XML tree with no path # # This `edit_xml` bundle inserts the given XML tree. Use with an # empty XML document. # # @param treestring The XML tree, as a string # # **Example:** # # ```cf3 # files: # "/newfile" edit_xml => xml_insert_tree_nopath('y'); # ``` { insert_tree: '$(treestring)'; } bundle edit_xml xml_insert_tree(treestring, xpath) # @brief Insert XML tree at the given XPath # # This `edit_xml` bundle inserts the given XML tree at a specific # XPath. Uses `insert_tree`. # # @param treestring The XML tree, as a string # @param xpath A valid XPath string # # **Example:** # # ```cf3 # files: # "/file.xml" edit_xml => xml_insert_tree('y', '/a/b/c'); # ``` { insert_tree: '$(treestring)' select_xpath => "$(xpath)"; } bundle edit_xml xml_set_value(value, xpath) # @brief Sets or replaces a value in XML at the given XPath # # This `edit_xml` bundle sets or replaces the value at a specific # XPath with the given value. Uses `set_text`. # # @param value The new value # @param xpath A valid XPath string # # **Example:** # # ```cf3 # files: # "/file.xml" edit_xml => xml_set_value('hello', '/a/b/c'); # ``` { set_text: "$(value)" select_xpath => "$(xpath)"; } bundle edit_xml xml_set_attribute(attr, value, xpath) # @brief Sets or replaces an attribute in XML at the given XPath # # This `edit_xml` bundle sets or replaces an attribute at a specific # XPath with the given value. Uses `set_attribute`. # # @param attr The attribute name # @param value The new attribute value # @param xpath A valid XPath string # # **Example:** # # ```cf3 # files: # "/file.xml" edit_xml => xml_set_attribute('parameter', 'ha', '/a/b/c'); # ``` { set_attribute: "$(attr)" attribute_value => "$(value)", select_xpath => "$(xpath)"; } masterfiles-3.6.2/lib/3.6/examples.cf000066400000000000000000000104101241300473300172350ustar00rootroot00000000000000############################################################################ # Copyright (C) CFEngine AS # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License LGPL 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. # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ########################################################################### # # CFEngine Community Open Promise-Body Library # # This initiative started by CFEngine promotes a # standardized set of names and promise specifications # for template functionality within CFEngine 3. # # The aim is to promote an industry standard for # naming of configuration patterns, leading to a # de facto middleware of standardized syntax. # # Names should be intuitive and parameters should be # minimal to assist readability and comprehensibility. # Contributions to this file are voluntarily given to # the cfengine community, and are moderated by CFEngine. # No liability or warranty for misuse is implied. # # If you add to this file, please try to make the # contributions "self-documenting". Comments made # after the bundle/body statement are retained in # the online docs # # For CFEngine Core: 3.6.0 to 3.6.x # Examples you may find useful ################################################### # If you find CFEngine useful, please consider # # purchasing a commercial version of the software.# ################################################### bundle agent probabilistic_usebundle(probability, bundlename) # @brief activate named bundle probabilistically # @param probability probability that the named bundle will be activated during # a given agent execution # @param bundlename the bundle to activate based on the probability # # **Example:** # # ```cf3 # bundle agent example # { # methods: # "Toss Coin" # usebundle => probabilistic_usebundle("50", "heads"), # comment => "Call bundle heads ~ 50% of the time"; # # "Trick Coin" # usebundle => probabilistic_usebundle("75", "heads"), # comment => "Call bundle heads ~ 75% of the time"; # } # ``` { classes: "fifty_fifty" expression => strcmp("$(probability)", "50"), comment => "We have to special case 50 because of the way dist classes work you would always get 50 defined"; "not_fifty_fifty" expression => "!fifty_fifty"; "have_remainder" expression => isvariable("remainder"); fifty_fifty.have_remainder:: "activate_bundle" dist => { "$(probability)000", "$(remainder)"}; not_fifty_fifty.have_remainder:: "activate_bundle" dist => { "$(probability)", "$(remainder)"}; vars: fifty_fifty:: "remainder" string => format("%d", eval("((100 - $(probability)) * 1000) +1", "math", "infix")); not_fifty_fifty:: "remainder" string => format("%d", eval("100 - $(probability)", "math", "infix")); methods: fifty_fifty:: "Activate bundle probabilistically" handle => "probabilistic_usebundle_methods_special_case_fifty_fifty_activate_bundle", usebundle => $(bundlename), ifvarclass => "activate_bundle_$(probability)000", comment => "Activate $(bundlename) $(probability)%ish of the time"; not_fifty_fifty:: "Activate bundle probabilistically" handle => "probabilistic_usebundle_methods_activate_bundle", usebundle => $(bundlename), ifvarclass => "activate_bundle_$(probability)", comment => "Activate $(bundlename) $(probability)% of the time"; reports: DEBUG.fifty_fifty:: "$(this.bundle) Special case for 50/50"; "$(this.bundle) activate_bundle_$(probability)000" ifvarclass => "activate_bundle_$(probability)000"; "$(this.bundle) activate_bundle_$(probability)001" ifvarclass => "activate_bundle_$(probability)001"; } masterfiles-3.6.2/lib/3.6/feature.cf000066400000000000000000000065541241300473300170700ustar00rootroot00000000000000bundle agent feature # @brief Finds feature_set_X and feature_unset_X classes and sets/unsets X persistently # # Finds all classes named `feature_unset_X` and clear class X. # # Finds all classes named `feature_set_DURATION_X` and sets class X # persistently for DURATION. DURATION can be any digits followed by # `k`, `m`, or `g`. # # In inform mode (`-I`) it will report what it does. # # **Example:** # Set class `xyz` for 10 minutes, class `qpr` for 100 minutes, and # `ijk` for 90m minutes. Unset class `abc`. # `cf-agent -I -f ./feature.cf -b feature -Dfeature_set_10_xyz,feature_set_100_qpr,feature_set_90m_ijk,feature_unset_abc` { classes: "parsed_$(on)" expression => regextract("feature_set_([0-9]+[kmgKMG]?)_(.*)", $(on), "extract_$(on)"); "parsed_$(off)" expression => regextract("feature_unset_(.*)", $(off), "extract_$(off)"); "$(extract_$(on)[2])" expression => "parsed_$(on)", persistence => "$(extract_$(on)[1])"; vars: "on" slist => classesmatching("feature_set_.*"); "off" slist => classesmatching("feature_unset_.*"); "_$(off)" string => "off", classes => feature_cancel("$(extract_$(off)[1])"); reports: inform_mode:: "$(this.bundle): $(on) => SET class '$(extract_$(on)[2]) for '$(extract_$(on)[1])'" ifvarclass => "parsed_$(on)"; "$(this.bundle): $(off) => UNSET class '$(extract_$(off)[1])'" ifvarclass => "parsed_$(off)"; "$(this.bundle): have $(extract_$(on)[2])" ifvarclass => "$(extract_$(on)[2])"; "$(this.bundle): have no $(extract_$(on)[2])" ifvarclass => "!$(extract_$(on)[2])"; "$(this.bundle): have $(extract_$(off)[1])" ifvarclass => "$(extract_$(off)[1])"; "$(this.bundle): have no $(extract_$(off)[1])" ifvarclass => "!$(extract_$(off)[1])"; } bundle agent feature_test # @brief Finds feature_set_X and feature_unset_X classes and reports X # # Note that this bundle is intended to be used exactly like `feature` # and just show what's defined or undefined. # # **Example:** # Check classes `xyz`, `qpr`, `ijk`, and `abc`. # `cf-agent -I -f ./feature.cf -b feature_test -Dfeature_set_10_xyz,feature_set_100_qpr,feature_set_90m_ijk,feature_unset_abc` { classes: "parsed_$(on)" expression => regextract("feature_set_([0-9]+[kmgKMG]?)_(.*)", $(on), "extract_$(on)"); "parsed_$(off)" expression => regextract("feature_unset_(.*)", $(off), "extract_$(off)"); vars: "on" slist => classesmatching("feature_set_.*"); "off" slist => classesmatching("feature_unset_.*"); reports: "$(this.bundle): have $(extract_$(on)[2])" ifvarclass => "$(extract_$(on)[2])"; "$(this.bundle): have no $(extract_$(on)[2])" ifvarclass => "!$(extract_$(on)[2])"; "$(this.bundle): have $(extract_$(off)[1])" ifvarclass => "$(extract_$(off)[1])"; "$(this.bundle): have no $(extract_$(off)[1])" ifvarclass => "!$(extract_$(off)[1])"; } body classes feature_cancel(x) # @ignore # Used internally by bundle `feature` { cancel_kept => { "$(x)" }; cancel_repaired => { "$(x)" }; } masterfiles-3.6.2/lib/3.6/files.cf000066400000000000000000001577151241300473300165450ustar00rootroot00000000000000############################################################################ # Copyright (C) CFEngine AS # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License LGPL 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. # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ########################################################################### # # CFEngine Community Open Promise-Body Library # # This initiative started by CFEngine promotes a # standardized set of names and promise specifications # for template functionality within CFEngine 3. # # The aim is to promote an industry standard for # naming of configuration patterns, leading to a # de facto middleware of standardized syntax. # # Names should be intuitive and parameters should be # minimal to assist readability and comprehensibility. # Contributions to this file are voluntarily given to # the cfengine community, and are moderated by CFEngine. # No liability or warranty for misuse is implied. # # If you add to this file, please try to make the # contributions "self-documenting". Comments made # after the bundle/body statement are retained in # the online docs # # For CFEngine Core: 3.6.0 to 3.6.x # Files bodies ################################################### # If you find CFEngine useful, please consider # # purchasing a commercial version of the software.# ################################################### bundle common files_common # @ignore { vars: "inputs" slist => { "$(this.promise_dirname)/common.cf" }; } body file control # @ignore { inputs => { @(files_common.inputs) }; } ################################################### # edit_line bundles ################################################### bundle edit_line insert_lines(lines) # @brief Append `lines` if they don't exist in the file # @param lines The lines to be appended # # **See also:** [`insert_lines`][insert_lines] in # [`edit_line`][bundle edit_line] { insert_lines: "$(lines)" comment => "Append lines if they don't exist"; } ## bundle edit_line insert_file(templatefile) # @brief Reads the lines from `templatefile` and inserts those into the # file being edited. # @param templatefile The name of the file from which to import lines. { insert_lines: "$(templatefile)" comment => "Insert the template file into the file being edited", insert_type => "file"; } ## bundle edit_line comment_lines_matching(regex,comment) # @brief Comment lines in the file that matching an [anchored] regex # @param regex Anchored regex that the entire line needs to match # @param comment A string that is prepended to matching lines { replace_patterns: "^($(regex))$" replace_with => comment("$(comment)"), comment => "Search and replace string"; } ## bundle edit_line uncomment_lines_matching(regex,comment) # @brief Uncomment lines of the file where the regex matches # the entire text after the comment string # @param regex The regex that lines need to match after `comment` # @param comment The prefix of the line that is removed { replace_patterns: "^$(comment)\s?($(regex))$" replace_with => uncomment, comment => "Uncomment lines matching a regular expression"; } ## bundle edit_line comment_lines_containing(regex,comment) # @brief Comment lines of the file matching a regex # @param regex A regex that a part of the line needs to match # @param comment A string that is prepended to matching lines { replace_patterns: "^((?!$(comment)).*$(regex).*)$" replace_with => comment("$(comment)"), comment => "Comment out lines in a file"; } ## bundle edit_line uncomment_lines_containing(regex,comment) # @brief Uncomment lines of the file where the regex matches # parts of the text after the comment string # @param regex The regex that lines need to match after `comment` # @param comment The prefix of the line that is removed { replace_patterns: "^$(comment)\s?(.*$(regex).*)$" replace_with => uncomment, comment => "Uncomment a line containing a fragment"; } ## bundle edit_line delete_lines_matching(regex) # @brief Delete lines matching a regular expression # @param regex The regular expression that the lines need to match { delete_lines: "$(regex)" comment => "Delete lines matching regular expressions"; } ## bundle edit_line warn_lines_matching(regex) # @brief Warn about lines matching a regular expression # @param regex The regular expression that the lines need to match { delete_lines: "$(regex)" comment => "Warn about lines in a file", action => warn_only; } ## bundle edit_line prepend_if_no_line(string) # @brief Prepend `string` if it doesn't exist in the file # @param string The string to be prepended # # **See also:** [`insert_lines`][insert_lines] in # [`edit_line`][bundle edit_line] { insert_lines: "$(string)" location => start, comment => "Prepend a line to the file if it doesn't already exist"; } bundle edit_line append_if_no_line(str) # @ignore # This duplicates the insert_lines bundle { insert_lines: "$(str)" comment => "Append a line to the file if it doesn't already exist"; } ## bundle edit_line append_if_no_lines(list) # @ignore # This duplicates the insert_lines bundle { insert_lines: "$(list)" comment => "Append lines to the file if they don't already exist"; } ## bundle edit_line replace_line_end(start,end) # @brief Give lines starting with `start` the ending given in `end` # # Whitespaces will be left unmodified. For example, # `replace_line_end("ftp", "2121/tcp")` would replace # # `"ftp 21/tcp"` # # with # # `"ftp 2121/tcp"` # # @param start The string lines have to start with # @param end The string lines should end with { field_edits: "\s*$(start)\s.*" comment => "Replace lines with $(this.start) and $(this.end)", edit_field => line("(^|\s)$(start)\s*", "2", "$(end)","set"); } ## bundle edit_line append_to_line_end(start,end) # @brief Append `end` to any lines beginning with `start` # # `end` will be appended to all lines starting with `start` and not # already ending with `end`. Whitespaces will be left unmodified. # # For example, `append_to_line_end("kernel", "vga=791")` would replace # `kernel /boot/vmlinuz root=/dev/sda7` # # with # # `kernel /boot/vmlinuz root=/dev/sda7 vga=791` # # **WARNING**: Be careful not to have multiple promises matching the same line, which would result in the line growing indefinitely. # # @param start pattern to match lines of interest # @param end string to append to matched lines # # **Example:** # # ```cf3 # files: # "/tmp/boot-options" edit_line => append_to_line_end("kernel", "vga=791"); # ``` # { field_edits: "\s*$(start)\s.*" comment => "Append lines with $(this.start) and $(this.end)", edit_field => line("(^|\s)$(start)\s*", "2", "$(end)","append"); } ## bundle edit_line regex_replace(find,replace) # @brief Find exactly a regular expression and replace exactly the match with a string. # You can think of this like a PCRE powered sed. # @param find The regular expression # @param replace The replacement string { replace_patterns: "$(find)" replace_with => value("$(replace)"), comment => "Search and replace string"; } ## bundle edit_line resolvconf(search,list) # @brief Adds search domains and name servers to the system # resolver configuration. # # Use this bundle to modify `resolv.conf`. Existing entries for # `search` and `nameserver` are replaced. # # @param search The search domains with space # @param list An slist of nameserver addresses { delete_lines: "search.*" comment => "Reset search lines from resolver"; "nameserver.*" comment => "Reset nameservers in resolver"; insert_lines: "search $(search)" comment => "Add search domains to resolver"; "nameserver $(list)" comment => "Add name servers to resolver"; } ## bundle edit_line resolvconf_o(search,list,options) # @brief Adds search domains, name servers and options to the system # resolver configuration. # # Use this bundle to modify `resolv.conf`. Existing entries for # `search`, `nameserver` and `options` are replaced. # # @param search The search domains with space # @param list An slist of nameserver addresses # @param options is an slist of variables to modify the resolver { delete_lines: "search.*" comment => "Reset search lines from resolver"; "nameserver.*" comment => "Reset nameservers in resolver"; "options.*" comment => "Reset options in resolver"; insert_lines: "search $(search)" comment => "Add search domains to resolver"; "nameserver $(list)" comment => "Add name servers to resolver"; "options $(options)" comment => "Add options to resolver"; } ## bundle edit_line manage_variable_values_ini(tab, sectionName) # @brief Sets the RHS of configuration items in the file of the form # `LHS=RHS` # # If the line is commented out with `#`, it gets uncommented first. # Adds a new line if none exists. # Removes any variable value pairs not defined for the ini section. # # @param tab An associative array containing `tab[sectionName][LHS]="RHS"`. # The value is not changed when the `RHS` is "dontchange" # @param sectionName The section in the file within which values should be # modified # # **See also:** `set_variable_values_ini()` { vars: "index" slist => getindices("$(tab)[$(sectionName)]"); # Be careful if the index string contains funny chars "cindex[$(index)]" string => canonify("$(index)"); classes: "edit_$(cindex[$(index)])" not => strcmp("$($(tab)[$(sectionName)][$(index)])","dontchange"), comment => "Create conditions to make changes"; field_edits: # If the line is there, but commented out, first uncomment it "#+\s*$(index)\s*=.*" select_region => INI_section("$(sectionName)"), edit_field => col("=","1","$(index)","set"), ifvarclass => "edit_$(cindex[$(index)])"; # match a line starting like the key something "$(index)\s*=.*" edit_field => col("=","2","$($(tab)[$(sectionName)][$(index)])","set"), select_region => INI_section("$(sectionName)"), classes => if_ok("manage_variable_values_ini_not_$(cindex[$(index)])"), ifvarclass => "edit_$(cindex[$(index)])"; delete_lines: ".*" select_region => INI_section("$(sectionName)"), comment => "Remove all entries in the region so there are no extra entries"; insert_lines: "[$(sectionName)]" location => start, comment => "Insert lines"; "$(index)=$($(tab)[$(sectionName)][$(index)])" select_region => INI_section("$(sectionName)"), ifvarclass => "!manage_variable_values_ini_not_$(cindex[$(index)]).edit_$(cindex[$(index)])"; } ## bundle edit_line set_variable_values_ini(tab, sectionName) # @brief Sets the RHS of configuration items in the file of the form # `LHS=RHS` # # If the line is commented out with `#`, it gets uncommented first. # Adds a new line if none exists. # # @param tab An associative array containing `tab[sectionName][LHS]="RHS"`. # The value is not changed when the `RHS` is "dontchange" # @param sectionName The section in the file within which values should be # modified # # **See also:** `set_variable_values_ini()` { vars: "index" slist => getindices("$(tab)[$(sectionName)]"); # Be careful if the index string contains funny chars "cindex[$(index)]" string => canonify("$(index)"); classes: "edit_$(cindex[$(index)])" not => strcmp("$($(tab)[$(sectionName)][$(index)])","dontchange"), comment => "Create conditions to make changes"; field_edits: # If the line is there, but commented out, first uncomment it "#+\s*$(index)\s*=.*" select_region => INI_section("$(sectionName)"), edit_field => col("=","1","$(index)","set"), ifvarclass => "edit_$(cindex[$(index)])"; # match a line starting like the key something "$(index)\s*=.*" edit_field => col("=","2","$($(tab)[$(sectionName)][$(index)])","set"), select_region => INI_section("$(sectionName)"), classes => if_ok("set_variable_values_ini_not_$(cindex[$(index)])"), ifvarclass => "edit_$(cindex[$(index)])"; insert_lines: "[$(sectionName)]" location => start, comment => "Insert lines"; "$(index)=$($(tab)[$(sectionName)][$(index)])" select_region => INI_section("$(sectionName)"), ifvarclass => "!set_variable_values_ini_not_$(cindex[$(index)]).edit_$(cindex[$(index)])"; } bundle edit_line insert_ini_section(name, config) # @brief Inserts a INI section with content # # ``` # # given an array "barray" # files: # "myfile.ini" edit_line => insert_innit_section("foo", "barray"); # ``` # # Inserts a section in an INI file with the given configuration # key-values from the array `config`. # # @param name the name of the INI section # @param config The fully-qualified name of an associative array containing `v[LHS]="rhs"` { vars: "k" slist => getindices($(config)); insert_lines: "[$(name)]" location => start, comment => "Prepend a line to the file if it doesn't already exist"; "$(k)=$($(config)[$(k)])"; } bundle edit_line set_quoted_values(v) # @brief Sets the RHS of variables in shell-like files of the form: # # ``` # LHS="RHS" # ``` # # Adds a new line if no LHS exists, and replaces RHS values if one does exist. # If the line is commented out with #, it gets uncommented first. # # @param v The fully-qualified name of an associative array containing `v[LHS]="rhs"` # # **Example:** # # ```cf3 # vars: # "stuff[lhs-1]" string => "rhs1"; # "stuff[lhs-2]" string => "rhs2"; # # files: # "myfile" # edit_line => set_quoted_values(stuff) # ``` # # **See also:** `set_variable_values()` { meta: "tags" slist => { "deprecated=3.6.0", "deprecation-reason=Generic reimplementation", "replaced-by=set_line_based" }; vars: "index" slist => getindices("$(v)"); # Be careful if the index string contains funny chars "cindex[$(index)]" string => canonify("$(index)"); field_edits: # If the line is there, but commented out, first uncomment it "#+\s*$(index)\s*=.*" edit_field => col("=","1","$(index)","set"); # match a line starting like the key = something "\s*$(index)\s*=.*" edit_field => col("=","2",'"$($(v)[$(index)])"',"set"), classes => if_ok("$(cindex[$(index)])_in_file"), comment => "Match a line starting like key = something"; insert_lines: '$(index)="$($(v)[$(index)])"' comment => "Insert a variable definition", ifvarclass => "!$(cindex[$(index)])_in_file"; } ## bundle edit_line set_variable_values(v) # @brief Sets the RHS of variables in files of the form: # # ``` # LHS=RHS # ``` # # Adds a new line if no LHS exists, and replaces RHS values if one does exist. # If the line is commented out with #, it gets uncommented first. # # @param v The fully-qualified name of an associative array containing `v[LHS]="rhs"` # # **Example:** # # ```cf3 # vars: # "stuff[lhs-1]" string => "rhs1"; # "stuff[lhs-2]" string => "rhs2"; # # files: # "myfile" # edit_line => set_quoted_values(stuff) # ``` # # **See also:** `set_quoted_values()` { meta: "tags" slist => { "deprecated=3.6.0", "deprecation-reason=Generic reimplementation", "replaced-by=set_line_based" }; vars: "index" slist => getindices("$(v)"); # Be careful if the index string contains funny chars "cindex[$(index)]" string => canonify("$(index)"); "cv" string => canonify("$(v)"); field_edits: # match a line starting like the key = something "\s*$(index)\s*=.*" edit_field => col("\s*$(index)\s*=","2","$($(v)[$(index)])","set"), classes => if_ok("$(cv)_$(cindex[$(index)])_in_file"), comment => "Match a line starting like key = something"; insert_lines: "$(index)=$($(v)[$(index)])" comment => "Insert a variable definition", ifvarclass => "!$(cv)_$(cindex[$(index)])_in_file"; } bundle edit_line set_config_values(v) # @brief Sets the RHS of configuration items in the file of the form: # # ``` # LHS RHS # ``` # # If the line is commented out with `#`, it gets uncommented first. # # Adds a new line if none exists. # # @param v The fully-qualified name of an associative array containing `v[LHS]="rhs"` { meta: "tags" slist => { "deprecated=3.6.0", "deprecation-reason=Generic reimplementation", "replaced-by=set_line_based" }; vars: "index" slist => getindices("$(v)"); # Be careful if the index string contains funny chars "cindex[$(index)]" string => canonify("$(index)"); # Escape the value (had a problem with special characters and regex's) "ev[$(index)]" string => escape("$($(v)[$(index)])"); # Do we have more than one line commented out? "index_comment_matches_$(cindex[$(index)])" int => countlinesmatching("^\s*#\s*($(index)\s+.*|$(index))$","$(edit.filename)"); classes: # Check to see if this line exists "line_exists_$(cindex[$(index)])" expression => regline("^\s*($(index)\s.*|$(index))$","$(edit.filename)"); # if there's more than one comment, just add new (don't know who to use) "multiple_comments_$(cindex[$(index)])" expression => isgreaterthan("$(index_comment_matches_$(cindex[$(index)]))","1"); replace_patterns: # If the line is commented out, uncomment and replace with # the correct value "^\s*#\s*($(index)\s+.*|$(index))$" comment => "Uncommented the value $(index)", replace_with => value("$(index) $($(v)[$(index)])"), ifvarclass => "!line_exists_$(cindex[$(index)]).!replace_attempted_$(cindex[$(index)]).!multiple_comments_$(cindex[$(index)])", classes => always("uncommented_$(cindex[$(index)])"); # If the line is there with the wrong value, replace with # the correct value "^\s*($(index)\s+(?!$(ev[$(index)])$).*|$(index))$" comment => "Correct the value $(index)", replace_with => value("$(index) $($(v)[$(index)])"), classes => always("replace_attempted_$(cindex[$(index)])"); insert_lines: # If the line doesn't exist, or there is more than one occurance # of the LHS commented out, insert a new line and try to place it # after the commented LHS (keep new line with old comments) "$(index) $($(v)[$(index)])" comment => "Insert the value, marker exists $(index)", location => after("^\s*#\s*($(index)\s+.*|$(index))$"), ifvarclass => "replace_attempted_$(cindex[$(index)]).multiple_comments_$(cindex[$(index)])"; # If the line doesn't exist and there are no occurances # of the LHS commented out, insert a new line at the eof "$(index) $($(v)[$(index)])" comment => "Insert the value, marker doesn't exist $(index)", ifvarclass => "replace_attempted_$(cindex[$(index)]).!multiple_comments_$(cindex[$(index)])"; } bundle edit_line set_line_based(v, sep, bp, kp, cp) # @brief Sets the RHS of configuration items in the file of the form: # # ``` # LHS$(sep)RHS # ``` # # Example usage for `x=y` lines (e.g. rsyncd.conf): # # ```cf3 # "myfile" # edit_line => set_line_based("test.config", "=", "\s*=\s*", ".*", "\s*#\s*"); # ``` # # Example usage for `x y` lines (e.g. sshd_config): # # ```cf3 # "myfile" # edit_line => set_line_based("test.config", " ", "\s+", ".*", "\s*#\s*"); # ``` # # If the line is commented out with `$(cp)`, it gets uncommented first. # # Adds a new line if none exists or if more than one commented-out # possible matches exist. # # Originally `set_config_values` by Ed King. # # @param v The fully-qualified name of an associative array containing `v[LHS]="rhs"` # @param sep The separator to insert, e.g. ` ` for space-separated # @param bp The key-value separation regex, e.g. `\s+` for space-separated # @param kp The keys to select from v, use `.*` for all # @param cp The comment pattern from line-start, e.g. `\s*#\s*` { meta: "tags" slist => { "replaces=set_config_values", "replaces=set_config_values_matching", "replaces=set_variable_values", "replaces=set_quoted_values", "replaces=maintain_key_values", }; vars: "vkeys" slist => getindices("$(v)"); "i" slist => grep($(kp), vkeys); # Be careful if the index string contains funny chars "ci[$(i)]" string => canonify("$(i)"); # Escape the value (had a problem with special characters and regex's) "ev[$(i)]" string => escape("$($(v)[$(i)])"); # Do we have more than one line commented out? "comment_matches_$(ci[$(i)])" int => countlinesmatching("^$(cp)($(i)$(bp).*|$(i))$", $(edit.filename)); classes: # Check to see if this line exists "exists_$(ci[$(i)])" expression => regline("^\s*($(i)$(bp).*|$(i))$", $(edit.filename)); # if there's more than one comment, just add new (don't know who to use) "multiple_comments_$(ci[$(i)])" expression => isgreaterthan("$(comment_matches_$(ci[$(i)]))", "1"); replace_patterns: # If the line is commented out, uncomment and replace with # the correct value "^$(cp)($(i)$(bp).*|$(i))$" comment => "Uncommented the value '$(i)'", replace_with => value("$(i)$(sep)$($(v)[$(i)])"), ifvarclass => "!exists_$(ci[$(i)]).!replace_attempted_$(ci[$(i)]).!multiple_comments_$(ci[$(i)])", classes => always("uncommented_$(ci[$(i)])"); # If the line is there with the wrong value, replace with # the correct value "^\s*($(i)$(bp)(?!$(ev[$(i)])$).*|$(i))$" comment => "Correct the value '$(i)'", replace_with => value("$(i)$(sep)$($(v)[$(i)])"), classes => always("replace_attempted_$(ci[$(i)])"); insert_lines: # If the line doesn't exist, or there is more than one occurrence # of the LHS commented out, insert a new line and try to place it # after the commented LHS (keep new line with old comments) "$(i)$(sep)$($(v)[$(i)])" comment => "Insert the value, marker '$(i)' exists", location => after("^$(cp)($(i)$(bp).*|$(i))$"), ifvarclass => "replace_attempted_$(ci[$(i)]).multiple_comments_$(ci[$(i)])"; # If the line doesn't exist and there are no occurrences # of the LHS commented out, insert a new line at the eof "$(i)$(sep)$($(v)[$(i)])" comment => "Insert the value, marker '$(i)' doesn't exist", ifvarclass => "replace_attempted_$(ci[$(i)]).!multiple_comments_$(ci[$(i)]).!exists_$(ci[$(i)])"; reports: verbose_mode|EXTRA:: "$(this.bundle): Line for '$(i)' exists" ifvarclass => "exists_$(ci[$(i)])"; "$(this.bundle): Line for '$(i)' does not exist" ifvarclass => "!exists_$(ci[$(i)])"; } bundle edit_line set_config_values_matching(v,pat) # @brief Sets the RHS of configuration items in the file of the form # # ``` # LHS RHS # ``` # # If the line is commented out with `#`, it gets uncommented first. # Adds a new line if none exists. # # @param v the fully-qualified name of an associative array containing v[LHS]="rhs" # @param pat Only elements of `v` that match the regex `pat` are use { meta: "tags" slist => { "deprecated=3.6.0", "deprecation-reason=Generic reimplementation", "replaced-by=set_line_based" }; vars: "allparams" slist => getindices("$(v)"); "index" slist => grep("$(pat)", "allparams"); # Be careful if the index string contains funny chars "cindex[$(index)]" string => canonify("$(index)"); replace_patterns: # If the line is there, maybe commented out, uncomment and replace with # the correct value "^\s*($(index)\s+(?!$($(v)[$(index)])).*|# ?$(index)\s+.*)$" comment => "Correct the value", replace_with => value("$(index) $($(v)[$(index)])"), classes => always("replace_attempted_$(cindex[$(index)])"); insert_lines: "$(index) $($(v)[$(index)])" ifvarclass => "replace_attempted_$(cindex[$(index)])"; } ## bundle edit_line maintain_key_values(v,sep) # @ignore # @brief Sets the RHS of configuration items with an giving separator # # Contributed by David Lee { meta: "tags" slist => { "deprecated=3.6.0", "deprecation-reason=Generic reimplementation", "replaced-by=set_line_based" }; vars: "index" slist => getindices("$(v)"); # Be careful if the index string contains funny chars "cindex[$(index)]" string => canonify("$(index)"); # Matching pattern for line (basically key-and-separator) "keypat[$(index)]" string => "\s*$(index)\s*$(sep)\s*"; # Values may contain regexps. Escape them for replace_pattern matching. "ve[$(index)]" string => escape("$($(v)[$(index)])"); classes: "$(cindex[$(index)])_key_in_file" comment => "Dynamic Class created if patterns matching", expression => regline("^$(keypat[$(index)]).*", "$(edit.filename)"); replace_patterns: # For convergence need to use negative lookahead on value: # "key sep (?!value).*" "^($(keypat[$(index)]))(?!$(ve[$(index)])$).*" comment => "Replace definition of $(index)", replace_with => value("$(match.1)$($(v)[$(index)])"); insert_lines: "$(index)$(sep)$($(v)[$(index)])" comment => "Insert definition of $(index)", ifvarclass => "!$(cindex[$(index)])_key_in_file"; } ## bundle edit_line append_users_starting(v) # @brief For adding to `/etc/passwd` or `etc/shadow` # @param v An array `v[username] string => "line..."` # # **Note:** To manage local users with CFEngine 3.6 and later, # consider making `users` promises instead of modifying system files. { vars: "index" slist => getindices("$(v)"); classes: "add_$(index)" not => userexists("$(index)"), comment => "Class created if user does not exist"; insert_lines: "$($(v)[$(index)])" comment => "Append users into a password file format", ifvarclass => "add_$(index)"; } ## bundle edit_line append_groups_starting(v) # @brief For adding groups to `/etc/group` # @param v An array `v[groupname] string => "line..."` # # **Note:** To manage local users with CFEngine 3.6 and later, # consider making `users` promises instead of modifying system files. { vars: "index" slist => getindices("$(v)"); classes: "add_$(index)" not => groupexists("$(index)"), comment => "Class created if group does not exist"; insert_lines: "$($(v)[$(index)])" comment => "Append users into a group file format", ifvarclass => "add_$(index)"; } ## bundle edit_line set_colon_field(key,field,val) # @brief Set the value of field number `field` of the line whose # first field is `key` to the value `val`, in a colon-separated file. # @param key The value the first field has to match # @param field The field to be modified # @param val The new value of `field` { field_edits: "$(key):.*" comment => "Edit a colon-separated file, using the first field as a key", edit_field => col(":","$(field)","$(val)","set"); } ## bundle edit_line set_user_field(user,field,val) # @brief Set the value of field number "field" in a `:-field` # formatted file like `/etc/passwd` # @param user The user to be modified # @param field The field that should be modified # @param val The value for `field` # # **Note:** To manage local users with CFEngine 3.6 and later, # consider making `users` promises instead of modifying system files. { field_edits: "$(user):.*" comment => "Edit a user attribute in the password file", edit_field => col(":","$(field)","$(val)","set"); } ## bundle edit_line append_user_field(group,field,allusers) # @brief For adding users to to a file like `/etc/group` # at field position `field`, comma separated subfields # @param group The group to be modified # @param field The field where users should be added # @param allusers The list of users to add to `field` # # **Note:** To manage local users with CFEngine 3.6 and later, # consider making `users` promises instead of modifying system files. { vars: "val" slist => { @(allusers) }; field_edits: "$(group):.*" comment => "Append users into a password file format", edit_field => col(":","$(field)","$(val)","alphanum"); } ## bundle edit_line expand_template(templatefile) # @brief Read in the named text file and expand `$(var)` inside the file # @param templatefile The name of the file { insert_lines: "$(templatefile)" insert_type => "file", comment => "Expand variables in the template file", expand_scalars => "true"; } bundle edit_line replace_or_add(pattern,line) # @brief Replace a pattern in a file with a single line. # # If the pattern is not found, add the line to the file. # # @param pattern The pattern that should be replaced # The pattern must match the whole line (it is automatically # anchored to the start and end of the line) to avoid # ambiguity. # @param line The line with which to replace matches of `pattern` { vars: "cline" string => canonify("$(line)"); "eline" string => escape("$(line)"); replace_patterns: "^(?!$(eline)$)$(pattern)$" comment => "Replace a pattern here", replace_with => value("$(line)"), classes => always("replace_done_$(cline)"); insert_lines: "$(line)" ifvarclass => "replace_done_$(cline)"; } bundle edit_line converge(marker, lines) # @brief Converge `lines` marked with `marker` # # Any content marked with `marker` is removed, then `lines` are # inserted. Every `line` should contain `marker`. # # @param marker The marker (not a regular expression; will be escaped) # @param lines The lines to insert; all must contain `marker` { vars: "regex" string => escape($(marker)); delete_lines: "$(regex)" comment => "Delete lines matching the marker"; insert_lines: "$(lines)" comment => "Insert the given lines"; } bundle edit_line fstab_option_editor(method, mount, option) # @brief Add or remove `/etc/fstab` options for a mount # # This bundle edits the options field of a mount. The `method` is a # `field_operation` which can be `append`, `prepend`, `set`, `delete`, # or `alphanum`. The option is OS-specific. # # @param method `field_operation` to apply # @param mount the mount point # @param option the option to add or remove # # **Example:** # # ```cf3 # files: # "/etc/fstab" edit_line => fstab_option_editor("delete", "/", "acl"); # "/etc/fstab" edit_line => fstab_option_editor("append", "/", "acl"); # ``` { field_edits: "(?!#)\S+\s+$(mount)\s.+" edit_field => fstab_options($(option), $(method)); } ##------------------------------------------------------- ## editing bodies ##------------------------------------------------------- body edit_field fstab_options(newval, method) # @brief Edit the options field in a fstab format # @param newval the new option # @param method `field_operation` to apply # # This body edits the options field in the fstab file format. The # `method` is a `field_operation` which can be `append`, `prepend`, # `set`, `delete`, or `alphanum`. The `newval` option is OS-specific. # # **Example:** # # ```cf3 # # from the `fstab_options_editor` # field_edits: # "(?!#)\S+\s+$(mount)\s.+" # edit_field => fstab_options($(option), $(method)); # ``` { field_separator => "\s+"; select_field => "4"; value_separator => ","; field_value => "$(newval)"; field_operation => "$(method)"; } body edit_field quoted_var(newval,method) # @brief Edit the quoted value of the matching line # @param newval The new value # @param method The method by which to edit the field { field_separator => "\""; select_field => "2"; value_separator => " "; field_value => "$(newval)"; field_operation => "$(method)"; extend_fields => "false"; allow_blank_fields => "true"; } ## body edit_field col(split,col,newval,method) # @brief Edit tabluar data with comma-separated sub-values # @param split The separator that defines columns # @param col The (1-based) index of the value to change # @param newval The new value # @param method The method by which to edit the field { field_separator => "$(split)"; select_field => "$(col)"; value_separator => ","; field_value => "$(newval)"; field_operation => "$(method)"; extend_fields => "true"; allow_blank_fields => "true"; } ## body edit_field line(split,col,newval,method) # @brief Edit tabular data with space-separated sub-values # @param split The separator that defines columns # @param col The (1-based) index of the value to change # @param newval The new value # @param method The method by which to edit the field { field_separator => "$(split)"; select_field => "$(col)"; value_separator => " "; field_value => "$(newval)"; field_operation => "$(method)"; extend_fields => "true"; allow_blank_fields => "true"; } ## body replace_with value(x) # @brief Replace matching lines # @param x The replacement string { replace_value => "$(x)"; occurrences => "all"; } ## body select_region INI_section(x) # @brief Restrict the `edit_line` promise to the lines in section `[x]` # @param x The name of the section in an INI-like configuration file { select_start => "\[$(x)\]\s*"; select_end => "\[.*\]\s*"; } ##------------------------------------------------------- ## edit_defaults ##------------------------------------------------------- body edit_defaults std_defs # @brief Standard definitions for `edit_defaults` # Don't empty the file before editing starts and don't make a backup. { empty_file_before_editing => "false"; edit_backup => "false"; #max_file_size => "300000"; } ## body edit_defaults empty # @brief Empty the file before editing # # No backup is made { empty_file_before_editing => "true"; edit_backup => "false"; #max_file_size => "300000"; } ## body edit_defaults no_backup # @brief Don't make a backup of the file before editing { edit_backup => "false"; } ## body edit_defaults backup_timestamp # @brief Make a timestamped backup of the file before editing { empty_file_before_editing => "false"; edit_backup => "timestamp"; #max_file_size => "300000"; } ##------------------------------------------------------- ## location ##------------------------------------------------------- body location start # @brief Editing occurs before the matched line { before_after => "before"; } ## body location after(str) # @brief Editing occurs after the line matching `str` # @param str Regular expression matching the file line location { before_after => "after"; select_line_matching => "$(str)"; } ## body location before(str) # @brief Editing occurs before the line matching `str` # @param str Regular expression matching the file line location { before_after => "before"; select_line_matching => "$(str)"; } ##------------------------------------------------------- ## replace_with ##------------------------------------------------------- ## body replace_with comment(c) # @brief Comment all lines matching the pattern by preprending `c` # @param c The prefix that comments out lines { replace_value => "$(c) $(match.1)"; occurrences => "all"; } ## body replace_with uncomment # @brief Uncomment all lines matching the pattern by removing # anything outside the matching string { replace_value => "$(match.1)"; occurrences => "all"; } ##------------------------------------------------------- ## copy_from ##------------------------------------------------------- body copy_from secure_cp(from,server) # @brief Download a file from a remote server over an encrypted channel # # Only copy the file if it is different from the local copy, and verify # that the copy is correct. # # @param from The location of the file on the remote server # @param server The hostname or IP of the server from which to download { source => "$(from)"; servers => { "$(server)" }; compare => "digest"; encrypt => "true"; verify => "true"; } ## body copy_from remote_cp(from,server) # @brief Download a file from a remote server. # # @param from The location of the file on the remote server # @param server The hostname or IP of the server from which to download { servers => { "$(server)" }; source => "$(from)"; compare => "mtime"; } ## body copy_from remote_dcp(from,server) # @brief Download a file from a remote server if it is different from the local copy. # # @param from The location of the file on the remote server # @param server The hostname or IP of the server from which to download { servers => { "$(server)" }; source => "$(from)"; compare => "digest"; } ## body copy_from local_cp(from) # @brief Copy a local file. # # @param from The path to the source file. { source => "$(from)"; } ## body copy_from local_dcp(from) # @brief Copy a local file if it is different from the existing copy. # # @param from The path to the source file. { source => "$(from)"; compare => "digest"; } ## body copy_from perms_cp(from) # @brief Copy a local file and preserve file permissions on the local copy. # # @param from The path to the source file. { source => "$(from)"; preserve => "true"; } body copy_from perms_dcp(from) # @brief Copy a local file if it is different from the existing copy and # preserve file permissions on the local copy. # # @param from The path to the source file. { source => "$(from)"; preserve => "true"; compare => "digest"; } body copy_from backup_local_cp(from) # @brief Copy a local file and keep a backup of old versions. # # @param from The path to the source file. { source => "$(from)"; copy_backup => "timestamp"; } ## body copy_from seed_cp(from) # @brief Copy a local file if the file does not already exist, i.e. seed the placement # # @param from The path to the source file. { source => "$(from)"; compare => "exists"; } ## body copy_from sync_cp(from,server) # @brief Download a file if the local copy does not already exist, i.e. seed the placement # # @param from The location of the file on the remote server # @param server The hostname or IP of the server from which to download { servers => { "$(server)" }; source => "$(from)"; purge => "true"; preserve => "true"; type_check => "false"; } ## body copy_from no_backup_cp(from) # @brief Copy a local file and don't make any backup of the previous version # # @param from The path to the source file. { source => "$(from)"; copy_backup => "false"; } ## body copy_from no_backup_dcp(from) # @brief Copy a local file if contents have changed, and don't make any backup # of the previous version # # @param from The path to the source file. { source => "$(from)"; copy_backup => "false"; compare => "digest"; } ## body copy_from no_backup_rcp(from,server) # @brief Download a file if it's newer than the local copy, and don't make any # backup of the previous version # # @param from The location of the file on the remote server # @param server The hostname or IP of the server from which to download { servers => { "$(server)" }; source => "$(from)"; compare => "mtime"; copy_backup => "false"; } ##------------------------------------------------------- ## link_from ##------------------------------------------------------- body link_from ln_s(x) # @brief Create a symbolink link to `x` # The link is created even if the source of the link does not exist. # @param x The source of the link { link_type => "symlink"; source => "$(x)"; when_no_source => "force"; } ## body link_from linkchildren(tofile) # @brief Create a symbolink link to `tofile` # If the promiser is a directory, children are linked to the source, unless # entries with identical names already exist. # The link is created even if the source of the link does not exist. # # @param tofile The source of the link { source => "$(tofile)"; link_type => "symlink"; when_no_source => "force"; link_children => "true"; when_linking_children => "if_no_such_file"; # "override_file"; } body link_from linkfrom(source, type) # @brief Make any kind of link to a file # @param source link to this # @param type the link's type (`symlink` or `hardlink`) { source => $(source); link_type => $(type); } ##------------------------------------------------------- ## perms ##------------------------------------------------------- body perms m(mode) # @brief Set the file mode # @param mode The new mode { mode => "$(mode)"; } ## body perms mo(mode,user) # @brief Set the file's mode and owners # @param mode The new mode # @param user The username of the new owner { owners => { "$(user)" }; mode => "$(mode)"; } ## body perms mog(mode,user,group) # @brief Set the file's mode, owner and group # @param mode The new mode # @param user The username of the new owner # @param group The group name { owners => { "$(user)" }; groups => { "$(group)" }; mode => "$(mode)"; } ## body perms og(u,g) # @brief Set the file's owner and group # @param u The username of the new owner # @param g The group name { owners => { "$(u)" }; groups => { "$(g)" }; } ## body perms owner(user) # @brief Set the file's owner # @param user The username of the new owner { owners => { "$(user)" }; } body perms system_owned(mode) # @brief Set the file owner and group to the system default # @param mode the access permission in octal format # # **Example:** # # ```cf3 # files: # "/etc/passwd" perms => system_owned("0644"); # ``` { mode => "$(mode)"; owners => { "root" }; freebsd|openbsd|netbsd|darwin:: groups => { "wheel" }; linux:: groups => { "root" }; solaris:: groups => { "sys" }; } ##------------------------------------------------------- ## ACLS (extended Unix perms) ##------------------------------------------------------- body acl access_generic(acl) # @brief Set the `aces` of the access control as specified # # Default/inherited ACLs are left unchanged. This body is # applicable for both files and directories on all platforms. # # @param acl The aces to be set { acl_method => "overwrite"; aces => { "@(acl)" }; windows:: acl_type => "ntfs"; !windows:: acl_type => "posix"; } ## body acl ntfs(acl) # @brief Set the `aces` on NTFS file systems, and overwrite # existing ACLs. # # This body requires CFEngine Enterprise. # # @param acl The aces to be set { acl_type => "ntfs"; acl_method => "overwrite"; aces => { "@(acl)" }; } ## body acl strict # @brief Limit file access via ACLs to users with administrator privileges, # overwriting existing ACLs. # # **Note:** May need to take ownership of file/dir to be sure no-one else is # allowed access. { acl_method => "overwrite"; windows:: aces => { "user:Administrator:rwx" }; !windows:: aces => { "user:root:rwx" }; } ##------------------------------------------------------- ## depth_search ##------------------------------------------------------- body depth_search recurse(d) # @brief Search files and direcories recursively, up to the specified depth # Directories on different devices are included. # # @param d The maximum search depth { depth => "$(d)"; xdev => "true"; } ## body depth_search recurse_ignore(d,list) # @brief Search files and directories recursively, # but don't recurse into the specified directories # # @param d The maximum search depth # @param list The list of directories to be excluded { depth => "$(d)"; exclude_dirs => { @(list) }; } ## body depth_search include_base # @brief Search files and directories recursively, # starting from the base directory. { include_basedir => "true"; } body depth_search recurse_with_base(d) # @brief Search files and directories recursively up to the specified # depth, starting from the base directory and including directories on # other devices. # # @param d The maximum search depth { depth => "$(d)"; xdev => "true"; include_basedir => "true"; } ##------------------------------------------------------- ## delete ##------------------------------------------------------- body delete tidy # @brief Delete the file and remove empty directories # and links to directories { dirlinks => "delete"; rmdirs => "true"; } ##------------------------------------------------------- ## rename ##------------------------------------------------------- body rename disable # @brief Disable the file { disable => "true"; } ## body rename rotate(level) # @brief Rotate and store up to `level` backups of the file # @param level The number of backups to store { rotate => "$(level)"; } ## body rename to(file) # @brief Rename the file to `file` # @param file The new name of the file { newname => "$(file)"; } ##------------------------------------------------------- ## file_select ##------------------------------------------------------- body file_select name_age(name,days) # @brief Select files that have a matching `name` and have not been modified for at least `days` # @param name A regex that matches the file name # @param days Number of days { leaf_name => { "$(name)" }; mtime => irange(0,ago(0,0,"$(days)",0,0,0)); file_result => "mtime.leaf_name"; } ## body file_select days_old(days) # @brief Select files that have not been modified for at least `days` # @param days Number of days { mtime => irange(0,ago(0,0,"$(days)",0,0,0)); file_result => "mtime"; } ## body file_select size_range(from,to) # @brief Select files that have a size within the specified range # @param from The lower bound of the allowed file size # @param to The upper bound of the allowed file size { search_size => irange("$(from)","$(to)"); file_result => "size"; } ## body file_select bigger_than(size) # @brief Select files that are above a given size # @param size The number of bytes files have { search_size => irange("0","$(size)"); file_result => "!size"; } ## body file_select exclude(name) # @brief Select all files except those that match `name` # @param name A regular expression { leaf_name => { "$(name)"}; file_result => "!leaf_name"; } ## body file_select plain # @brief Select plain, regular files { file_types => { "plain" }; file_result => "file_types"; } body file_select dirs # @brief Select directories { file_types => { "dir" }; file_result => "file_types"; } ## body file_select by_name(names) # @brief Select files that match `names` # @param names A regular expression { leaf_name => { @(names)}; file_result => "leaf_name"; } ## body file_select ex_list(names) # @brief Select all files except those that match `names` # @param names A list of regular expressions { leaf_name => { @(names)}; file_result => "!leaf_name"; } ## body file_select all # @brief Select all file system entries { leaf_name => { ".*" }; file_result => "leaf_name"; } ## body file_select older_than(years, months, days, hours, minutes, seconds) # @brief Select files older than the date-time specified # @param years Number of years # @param months Number of months # @param days Number of days # @param hours Number of hours # @param minutes Number of minutes # @param seconds Number of seconds # # Generic older_than selection body, aimed to have a common definition handy # for every case possible. { mtime => irange(0,ago("$(years)","$(months)","$(days)","$(hours)","$(minutes)","$(seconds)")); file_result => "mtime"; } ## body file_select filetype_older_than(filetype, days) # @brief Select files of specified type older than specified number of days # # @param filetype File type to select # @param days Number of days # # This body only takes a single filetype, see `filetypes_older_than()` # if you want to select more than one type of file. { file_types => { "$(filetype)" }; mtime => irange(0,ago(0,0,"$(days)",0,0,0)); file_result => "file_types.mtime"; } ## body file_select filetypes_older_than(filetypes, days) # @brief Select files of specified types older than specified number of days # # This body only takes a list of filetypes # # @param filetypes A list of file types # @param days Number of days # # **See also:** `filetype_older_than()` { file_types => { @(filetypes) }; mtime => irange(0,ago(0,0,"$(days)",0,0,0)); file_result => "file_types.mtime"; } ##------------------------------------------------------- ## changes ##------------------------------------------------------- body changes detect_all_change # @brief Detect all file changes using the best hash method # # This is fierce, and will cost disk cycles # { hash => "best"; report_changes => "all"; update_hashes => "yes"; } ## body changes detect_all_change_using(hash) # @brief Detect all file changes using a given hash method # # Detect all changes using a configurable hashing algorithm # for times when you care about both content and file stats e.g. mtime # # @param hash supported hashing algorithm (md5, sha1, sha224, sha256, sha384, sha512, best) { hash => "$(hash)"; report_changes => "all"; update_hashes => "yes"; } ## body changes detect_content # @brief Detect file content changes using md5 # # This is a cheaper alternative { hash => "md5"; report_changes => "content"; update_hashes => "yes"; } ## body changes detect_content_using(hash) # @brief Detect file content changes using a given hash algorithm. # # For times when you only care about content, not file stats e.g. mtime # @param hash - supported hashing algorithm (md5, sha1, sha224, sha256, sha384, # sha512, best) { hash => "$(hash)"; report_changes => "content"; update_hashes => "yes"; } ## body changes noupdate # @brief Detect content changes in (small) files that should never change { hash => "sha256"; report_changes => "content"; update_hashes => "no"; } ## body changes diff # @brief Detect file content changes using sha256 # and report the diff to CFEngine Enterprise { hash => "sha256"; report_changes => "content"; report_diffs => "true"; update_hashes => "yes"; } ## body changes all_changes # @brief Detect all file changes using sha256 # and report the diff to CFEngine Enterprise { hash => "sha256"; report_changes => "all"; report_diffs => "true"; update_hashes => "yes"; } ## body changes diff_noupdate # @brief Detect content changes in (small) files # and report the diff to CFEngine Enterprise { hash => "sha256"; report_changes => "content"; report_diffs => "true"; update_hashes => "no"; } # template bundles bundle agent file_mustache(mustache_file, json_file, target_file) # @brief Make a file from a Mustache template and a JSON file # @param mustache_file the file with the Mustache template # @param json_file a file with JSON data # @param target_file the target file to write # # **Example:** # # ```cf3 # methods: # "m" usebundle => file_mustache("x.mustache", "y.json", "z.txt"); # ``` { files: "$(target_file)" create => "true", edit_template => $(mustache_file), template_data => readjson($(json_file), "100k"), template_method => "mustache"; } bundle agent file_mustache_jsonstring(mustache_file, json_string, target_file) # @brief Make a file from a Mustache template and a JSON string # @param mustache_file the file with the Mustache template # @param json_string a string with JSON data # @param target_file the target file to write # # **Example:** # # ```cf3 # methods: # "m" usebundle => file_mustache_jsonstring("x.mustache", '{ "x": "y" }', "z.txt"); # ``` { files: "$(target_file)" create => "true", edit_template => $(mustache_file), template_data => parsejson($(json_string)), template_method => "mustache"; } bundle agent file_tidy(file) # @brief Remove a file # @param file to remove # # **Example:** # # ```cf3 # methods: # "" usebundle => file_tidy("/tmp/z.txt"); # ``` { files: "$(file)" delete => tidy; reports: inform_mode|EXTRA:: "$(this.bundle): deleting $(file) with delete => tidy"; } bundle agent dir_sync(from, to) # @brief Synchronize a directory entire, deleting unknown files # @param from source directory # @param to destination directory # # **Example:** # # ```cf3 # methods: # "" usebundle => dir_sync("/tmp", "/var/tmp"); # ``` { files: "$(to)/." create => "true", depth_search => recurse("inf"), copy_from => copyfrom_sync($(from)); reports: inform_mode|EXTRA:: "$(this.bundle): copying directory $(from) to $(to)"; } bundle agent file_copy(from, to) # @brief Copy a file # @param from source file # @param to destination file # # **Example:** # # ```cf3 # methods: # "" usebundle => file_copy("/tmp/z.txt", "/var/tmp/y.txt"); # ``` { files: "$(to)" copy_from => copyfrom_sync($(from)); reports: inform_mode|EXTRA:: "$(this.bundle): copying file $(from) to $(to)"; } body copy_from copyfrom_sync(f) # @brief Copy a directory or file with digest checksums, preserving attributes and purging leftovers # @param f the file or directory { source => "$(f)"; purge => "true"; preserve => "true"; type_check => "false"; compare => "digest"; } bundle agent file_make(file, str) # @brief Make a file from a string # @param file target # @param str the string data # # **Example:** # # ```cf3 # methods: # "" usebundle => file_make("/tmp/z.txt", "Some text # and some more text here"); # ``` { files: "$(file)" create => "true", edit_line => insert_lines($(str)), edit_defaults => empty; reports: inform_mode|EXTRA:: "$(this.bundle): creating $(file) with contents '$(str)'"; } bundle agent file_empty(file) # @brief Make an empty file # @param file target # # **Example:** # # ```cf3 # methods: # "" usebundle => file_empty("/tmp/z.txt"); # ``` { files: "$(file)" create => "true", edit_defaults => empty; reports: inform_mode|EXTRA:: "$(this.bundle): creating empty $(file) with 0 size"; } bundle agent file_hardlink(target, link) # @brief Make a hard link to a file # @param target of link # @param link the hard link's location # # **Example:** # # ```cf3 # methods: # "" usebundle => file_hardlink("/tmp/z.txt", "/tmp/z.link"); # ``` { files: "$(link)" move_obstructions => "true", link_from => linkfrom($(target), "hardlink"); reports: inform_mode|EXTRA:: "$(this.bundle): $(link) will be a hard link to $(target)"; } bundle agent file_link(target, link) # @brief Make a symlink to a file # @param target of symlink # @param link the symlink's location # # **Example:** # # ```cf3 # methods: # "" usebundle => file_link("/tmp/z.txt", "/tmp/z.link"); # ``` { files: "$(link)" move_obstructions => "true", link_from => linkfrom($(target), "symlink"); reports: inform_mode|EXTRA:: "$(this.bundle): $(link) will be a symlink to $(target)"; } masterfiles-3.6.2/lib/3.6/guest_environments.cf000066400000000000000000000071331241300473300213650ustar00rootroot00000000000000############################################################################ # Copyright (C) CFEngine AS # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License LGPL 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. # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ########################################################################### # # CFEngine Community Open Promise-Body Library # # This initiative started by CFEngine promotes a # standardized set of names and promise specifications # for template functionality within CFEngine 3. # # The aim is to promote an industry standard for # naming of configuration patterns, leading to a # de facto middleware of standardized syntax. # # Names should be intuitive and parameters should be # minimal to assist readability and comprehensibility. # Contributions to this file are voluntarily given to # the cfengine community, and are moderated by CFEngine. # No liability or warranty for misuse is implied. # # If you add to this file, please try to make the # contributions "self-documenting". Comments made # after the bundle/body statement are retained in # the online docs # # For CFEngine Core: 3.6.0 to 3.6.x # Guest environments bodies ################################################### # If you find CFEngine useful, please consider # # purchasing a commercial version of the software.# ################################################### ##------------------------------------------------------- ## guest_environment promises ##------------------------------------------------------- body environment_resources kvm(name, arch, cpu_count, mem_kb, disk_file) # @brief An `environment_resources` body for a KVM virtual machine. # # The `env_spec` attribute is set to a KVM XML specification. # # @param name The name of the virtual machine # @param arch The architecture # @param cpu_count The number of CPUs the virtual machine should have # @param mem_kb The amount of RAM in kilobyte # @param disk_file The file on the host system for the virtual machine's harddrive # # **Example:** # # ```cf3 # bundle agent manage_vm # { # guest_environments: # am_vm_host:: # "db_server" # environment_host => atlas, # environment_type => "kvm", # environment_state => "create", # environment_resources => kvm("PSQL1, "x86_64", "4", "4096", "/var/lib/libvirt/images/psql1.iso") # } # ``` { env_spec => " $(name) $(mem_kb) $(mem_kb) $(cpu_count) hvm destroy restart restart /usr/bin/kvm "; } masterfiles-3.6.2/lib/3.6/monitor.cf000066400000000000000000000100751241300473300171150ustar00rootroot00000000000000############################################################################ # Copyright (C) CFEngine AS # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License LGPL 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. # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ########################################################################### # # CFEngine Community Open Promise-Body Library # # This initiative started by CFEngine promotes a # standardized set of names and promise specifications # for template functionality within CFEngine 3. # # The aim is to promote an industry standard for # naming of configuration patterns, leading to a # de facto middleware of standardized syntax. # # Names should be intuitive and parameters should be # minimal to assist readability and comprehensibility. # Contributions to this file are voluntarily given to # the cfengine community, and are moderated by CFEngine. # No liability or warranty for misuse is implied. # # If you add to this file, please try to make the # contributions "self-documenting". Comments made # after the bundle/body statement are retained in # the online docs # # For CFEngine Core: 3.6.0 to 3.6.x # Monitor bodies ################################################### # If you find CFEngine useful, please consider # # purchasing a commercial version of the software.# ################################################### #################################################### ## monitor bodyparts #################################################### body match_value scan_log(line) # @brief Selects lines matching `line` in a growing file # @param line Regular expression for matching lines. # # **See also:** [`select_line_matching`][measurements#select_line_matching], `track_growing_file` { select_line_matching => "$(line)"; track_growing_file => "true"; } ## body match_value scan_changing_file(line) # @brief Selects lines matching `line` in a changing file # @param line Regular expression for matching lines. # # **See also:** [`select_line_matching`][measurements#select_line_matching], `track_growing_file` { select_line_matching => "$(line)"; track_growing_file => "false"; } ## body match_value single_value(regex) # @brief Extract lines matching `regex` as values # @param regex Regular expression matching lines and values # # **See also:** [`select_line_matching`][measurements#select_line_matching], `extraction_regex` { select_line_matching => "$(regex)"; extraction_regex => "($(regex))"; } ## body match_value line_match_value(line_match, extract_regex) # @brief Find lines matching line_match and extract a value matching extract_regex # @param line_match Regular expression matching line where value is found # @param extract_regex Regular expression matching value to extract # # **See also:** [`select_line_matching`][measurements#select_line_matching], `extraction_regex` # # **Example:** # # ```cf3 # bundle monitor example # { # vars: # "regex_vsz" string => "root\s+[0-9]+\s+[0-9]+\s+[0-9]+\s+[0-9.]+\s+[0-9.]+\s+([0-9]+).*"; # measurements: # "/var/cfengine/state/cf_procs" # handle => "cf_serverd_vsz", # comment => "Tracking the memory consumption of a process can help us identify possible memory leaks", # stream_type => "file", # data_type => "int", # history_type => "weekly", # units => "kB", # match_value => line_match_value(".*cf-serverd.*", "$(regex_vsz)"); # } # ``` { select_line_matching => "$(line_match)"; extraction_regex => "$(extract_regex)"; } masterfiles-3.6.2/lib/3.6/packages.cf000066400000000000000000002422301241300473300172040ustar00rootroot00000000000000############################################################################ # Copyright (C) CFEngine AS # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License LGPL 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. # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ########################################################################### # # CFEngine Community Open Promise-Body Library # # This initiative started by CFEngine promotes a # standardized set of names and promise specifications # for template functionality within CFEngine 3. # # The aim is to promote an industry standard for # naming of configuration patterns, leading to a # de facto middleware of standardized syntax. # # Names should be intuitive and parameters should be # minimal to assist readability and comprehensibility. # Contributions to this file are voluntarily given to # the cfengine community, and are moderated by CFEngine. # No liability or warranty for misuse is implied. # # If you add to this file, please try to make the # contributions "self-documenting". Comments made # after the bundle/body statement are retained in # the online docs # # For CFEngine Core: 3.6.0 to 3.6.x # Packages bodies ################################################### # If you find CFEngine useful, please consider # # purchasing a commercial version of the software.# ################################################### bundle common packages_common # @ignore { vars: "inputs" slist => { "$(this.promise_dirname)/paths.cf", "$(this.promise_dirname)/files.cf", "$(this.promise_dirname)/common.cf" }; } body file control # @ignore { inputs => { @(packages_common.inputs) }; } ##-------------------------------------------------------------- ## Packages promises ##-------------------------------------------------------------- bundle common common_knowledge # @brief common packages knowledge bundle # # This common bundle defines general things about platforms. { vars: "list_update_ifelapsed" string => "240"; } bundle common debian_knowledge # @depends paths # @brief common Debian knowledge bundle # # This common bundle has useful information about Debian. { 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+.*"; } bundle common rpm_knowledge # @depends paths # @brief common RPM knowledge bundle # # This common bundle has useful information about platforms using RPM { 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+).*"; } bundle common redhat_knowledge # @depends paths # @brief common Red Hat knowledge bundle # # This common bundle has useful information about Red Hat and its # derivatives { vars: # Red Hat default package architecture "default_arch" string => $(sys.arch); "call_yum" string => "$(paths.path[yum])"; # on RHEL 4, Yum doesn't know how to be --quiet "yum_options" string => ifelse("redhat_4", "", "--quiet"); # yum check-update prints a lot of extra useless lines, but the format of # the actual package lines is: # # . # # 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.'"; } bundle common suse_knowledge # @depends paths # @brief common SUSE knowledge bundle { vars: # SUSE default package architecture "default_arch" string => $(sys.arch); "call_zypper" string => "$(paths.zypper)"; } bundle common darwin_knowledge # @depends paths # @brief common Darwin / Mac OS X knowledge bundle # # This common bundle has useful information about Darwin / Mac OS X. { 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]+)"; } bundle common npm_knowledge # @depends paths # @brief Node.js `npm' knowledge bundle # # This common bundle has useful information about the Node.js `npm' package manager. { 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.]+)"; } bundle common pip_knowledge # @depends paths # @brief Python `pip' knowledge bundle # # This common bundle has useful information about the Python `pip' package manager. { 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.]+\))"; } bundle common solaris_knowledge # @depends paths # @brief Solaris knowledge bundle # # This common bundle has useful information about the Solaris packages. { 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"; } body package_method pip(flags) # @depends common_knowledge pip_knowledge # @brief 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 # # @param flags The command line parameter passed to `pip` # # Note: "update" command preforms recursive upgrade (of dependencies) by # default. Set $flags to "--no-deps" to preform non-recursive upgrade. # http://www.pip-installer.org/en/latest/cookbook.html#non-recursive-upgrades # # **Example:** # # ```cf3 # 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! # # ```console # $ pip search django | egrep "^Django\s+-" # Django - A high-level Python Web framework [..output trimmed..] # ``` { 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)"; } body package_method npm(dir) # @depends common_knowledge npm_knowledge # @brief 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 # # @param dir The prefix path to ./node_modules/ # # **Example:** # # ```cf3 # 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"; # ``` { 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)"; } body package_method npm_g # @depends common_knowledge npm_knowledge # @brief 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:** # # ```cf3 # packages: # "express" package_method => npm_g, package_policy => "add"; # "redis" package_method => npm_g, package_policy => "delete"; # ``` { 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"; } body package_method brew(user) # @depends common_knowledge darwin_knowledge # @brief 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). # # @param 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:** # # ```cf3 # packages: # "mypackage" package_method => brew("adminuser"), package_policy => "add"; # "uppackage" package_method => brew("adminuser"), package_policy => "update", package_version => "3.5.2"; # ``` { 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"; } body package_method apt # @depends common_knowledge debian_knowledge # @brief APT installation package method # # This package method interacts with the APT package manager through `aptitude`. # # **Example:** # # ```cf3 # packages: # "mypackage" package_method => apt, package_policy => "add"; # ``` { 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)"; } # Ignore aptitude because: # 1) aptitude will remove "unneeded" packages unexpectly # 2) aptitude return codes are useless # 3) aptitude is a high level interface # 4) aptitude provides little benefit # 5) have_aptitude is a hard class and thus cannot be unset body package_method apt_get # @depends common_knowledge debian_knowledge # @brief APT installation package method # # This package method interacts with the APT package manager through `apt-get`. # # **Example:** # # ```cf3 # packages: # "mypackage" package_method => apt_get, package_policy => "add"; # ``` { 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)"; } body package_method apt_get_permissive # @depends common_knowledge debian_knowledge # @brief APT permissive (just by name) package method # # This package method interacts with the APT package manager through # `apt-get`. # # **Example:** # # ```cf3 # packages: # "mypackage" package_method => apt_get_permissive, package_policy => "add"; # ``` { 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)"; } body package_method apt_get_release(release) # @depends common_knowledge debian_knowledge # @brief APT installation package method # @param release specific release to use # # This package method interacts with the APT package manager through `apt-get` but sets a specific target release. # # **Example:** # # ```cf3 # packages: # "mypackage" package_method => apt_get_release("xyz"), package_policy => "add"; # ``` { 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)"; } ## body package_method dpkg_version(repo) # @depends common_knowledge debian_knowledge # @brief dpkg installation package method # @param repo specific repo to use # # This package method interacts with `dpkg`. # # **Example:** # # ```cf3 # packages: # "mypackage" package_method => dpkg_version("xyz"), package_policy => "add"; # ``` { 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)"; } ## body package_method rpm_version(repo) # @depends common_knowledge rpm_knowledge redhat_knowledge # @brief RPM direct installation method # @param repo the specific repository for `package_file_repositories` # # This package method interacts with the RPM package manager for a specific repo. # # **Example:** # # ```cf3 # packages: # "mypackage" package_method => rpm_version("myrepo"), package_policy => "add"; # ``` { 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].*"; } ## body package_method windows_feature # @brief Method for managing Windows features { 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}\""; } ## body package_method msi_implicit(repo) # @brief Windows MSI method # @param 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()` { 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"; } ## body package_method msi_explicit(repo) # @brief Windows MSI method # @param 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()` { 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"; } ## body package_method yum # @depends common_knowledge rpm_knowledge redhat_knowledge # @brief 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:** # # ```cf3 # packages: # "mypackage" package_method => yum, package_policy => "add"; # ``` { 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_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"; } ## body package_method yum_rpm # @depends common_knowledge rpm_knowledge redhat_knowledge # @brief 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:** # # ```cf3 # packages: # "mypackage" package_method => yum_rpm, package_policy => "add"; # ``` { 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_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"; } body package_method yum_rpm_permissive # @depends common_knowledge rpm_knowledge redhat_knowledge # @brief 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. # # **Example:** # # ```cf3 # packages: # "mypackage" package_method => yum_rpm_permissive, package_policy => "add"; # ``` { 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_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"; } ## body package_method yum_rpm_enable_repo(repoid) # @depends common_knowledge rpm_knowledge redhat_knowledge # @brief Yum+RPM repo-specific installation method # @param 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:** # # ```cf3 # packages: # "mypackage" package_method => yum_rpm_enable_repo("myrepo"), package_policy => "add"; # ``` { 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_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"; } ## body package_method yum_group # @depends common_knowledge redhat_knowledge # @brief 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. # # ```console # $ yum grouplist -v|grep Networking|head -n 1 # Networking Tools (network-tools) # ``` # # **Example:** # # ```cf3 # 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; # ``` { 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"; } ## body package_method rpm_filebased(path) # @depends common_knowledge rpm_knowledge redhat_knowledge # @brief install packages from local filesystem-based RPM repository. # @param 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:** # # ```cf3 # packages: # "epel-release" # package_policy => "add", # package_version => "5-4", # package_architectures => { "noarch" }, # package_method => rpm_filebased("/repo/RPMs"); # ``` { 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"; } ## body package_method ips # @depends paths # @depends common_knowledge # @brief 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: # # ```cf3 # "shell/zsh" # package_policy => "addupdate", # package_method => ips, # package_select => ">=", # package_version => "4.3.17_5.11-0.175.1.0.0.24.0"; # ``` { 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)"; } ## body package_method smartos # @depends common_knowledge # @brief pkgin method for SmartOS (solaris 10 fork by Joyent) { package_changes => "bulk"; package_list_command => "/opt/local/bin/pkgin list"; 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_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"; } body package_method opencsw # @depends common_knowledge # @brief OpenCSW (Solaris software packages) method { 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"; } body package_method solaris(pkgname, spoolfile, adminfile) # @depends paths # @brief Package method for old Solaris package system # # @param pkgname Not used # @param spoolfile The spool file, located in `/tmp` # @param 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. { 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)"; } ## body package_method solaris_install(adminfile) # @depends paths # @brief Package method for old Solaris package system # # @param adminfile The admin file created by `create_solaris_admin_file` { 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)"; } ## bundle edit_line create_solaris_admin_file # @brief The following bundle is part of a package setup for solaris # # See unit examples. { insert_lines: "$(solaris_knowledge.admin_nocheck)" comment => "Insert contents of Solaris admin file (automatically install packages)"; } ## body package_method freebsd # @depends common_knowledge # @brief 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: # # ```cf3 # ---------------------------- # # vars: # environment => { "PACKAGESITE=http://repo.example.com/private/8_STABLE/" }; # packages: # "perl5" # package_policy => "add", # 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_add -r"; package_delete_command => "/usr/sbin/pkg_delete"; } body package_method freebsd_portmaster # @depends common_knowledge # @brief 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:** # # ```cf3 # # packages: # "perl5.14" # package_policy => "add", # 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"; } ## body package_method alpinelinux # @brief Alpine Linux apk package installation method # # This package method interacts with apk to manage packages. # # **Example:** # # ```cf3 # # packages: # "vim" # package_policy => "add", # 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"; } ## body package_method emerge # @depends common_knowledge # @brief Gentoo emerge package installation method # # This package method interacts with emerge to build and install packages. # # **Example:** # # ```cf3 # # packages: # "zsh" # package_policy => "add", # 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).*"; } ## body package_method pacman # @depends common_knowledge # @brief Arch Linux pacman package management method { 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"; } body package_method zypper # @depends paths # @depends common_knowledge rpm_knowledge suse_knowledge # @brief SUSE installation method # # This package method interacts with the SUSE Zypper package manager # # **Example:** # # ```cf3 # packages: # "mypackage" package_method => zypper, package_policy => "add"; # ``` { 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$"; } body package_method generic # @depends paths common_knowledge debian_knowledge rpm_knowledge redhat_knowledge # @brief 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:** # # ```cf3 # packages: # "mypackage" package_method => generic, package_policy => "add"; # ``` { suse:: 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 => "0"; 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_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"; 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_add -r"; 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 => ".*/([^\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).*"; 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"; } ## Useful bundles ## bundle agent package_absent(package) # @brief Ensure package is absent # @param package the packages to remove # # This package method will remove `package`, using # `package_ensure`. # # **Example:** # # ```cf3 # methods: # "nozip" usebundle => package_absent("zip"); # ``` { packages: debian:: "$(package)" package_policy => "delete", package_method => apt_get_permissive; redhat:: "$(package)" package_policy => "delete", package_method => yum_rpm_permissive; suse:: "$(package)" package_policy => "delete", package_method => zypper; !debian.!redhat.!suse:: "$(package)" package_policy => "delete", package_method => generic; } bundle agent package_present(package) # @brief Ensure package is present # @param 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:** # # ```cf3 # methods: # "pleasezip" usebundle => package_present("zip"); # ``` { packages: debian:: "$(package)" package_policy => "add", package_method => apt_get_permissive; redhat:: "$(package)" package_policy => "add", package_method => yum_rpm_permissive; suse:: "$(package)" package_policy => "add", package_method => zypper; !debian.!redhat.!suse:: "$(package)" package_policy => "add", package_method => generic; } bundle agent package_latest(package) # @brief Ensure package is present and updated # @param 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:** # # ```cf3 # methods: # "latestzip" usebundle => package_latest("zip"); # ``` { packages: debian:: "$(package)" package_policy => "addupdate", package_version => "999999999", package_method => apt_get_permissive; redhat:: "$(package)" package_policy => "addupdate", package_version => "999999999", package_method => yum_rpm_permissive; suse:: "$(package)" package_policy => "addupdate", package_version => "999999999", package_method => zypper; !debian.!redhat.!suse:: "$(package)" package_policy => "addupdate", package_method => generic; } bundle agent package_specific_present(packageorfile, package_version, package_arch) # @depends package_specific # @brief Ensure package is present # @param packageorfile the package or full filename to add # @param package_version the `package_version` desired # @param package_arch a string determining the `package_architectures` desired # # This package method will add `packageorfile` as a package or file, # using `package_specific`. # # **Example:** # # ```cf3 # methods: # "addfilezip" # usebundle => package_specific_present("/mydir/zip", # "3.0-7", # $(debian_knowledge.default_arch)); # ``` { methods: "ensure" usebundle => package_specific($(packageorfile), "add", $(package_version), $(package_arch)); } bundle agent package_specific_absent(packageorfile, package_version, package_arch) # @depends package_specific # @brief Ensure package is absent # @param packageorfile the package or full filename to delete # @param package_version the `package_version` desired # @param package_arch a string determining the `package_architectures` desired # # This package method will remove `packageorfile` as a package or file, # using `package_specific`. # # **Example:** # # ```cf3 # methods: # "addfilezip" # usebundle => package_specific_absent("/mydir/zip", # "3.0-7", # $(debian_knowledge.default_arch)); # ``` { methods: "ensure" usebundle => package_specific($(packageorfile), "delete", $(package_version), $(package_arch)); } bundle agent package_specific_latest(packageorfile, package_version, package_arch) # @depends package_specific # @brief Ensure package is added or updated # @param packageorfile the package or full filename to add or update # @param package_version the `package_version` desired # @param package_arch a string determining the `package_architectures` desired # # This package method will add or update `packageorfile` as a package # or file, using `package_specific`. # # **Example:** # # ```cf3 # 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)); # ``` { methods: "ensure" usebundle => package_specific($(packageorfile), "addupdate", $(package_version), $(package_arch)); } bundle agent package_specific(package_name, desired, package_version, package_arch) # @depends apt_get yum_rpm generic dpkg_version rpm_version zypper # @brief Ensure `package_name` has the `desired` state # @param package_name the packages to ensure (can be files) # @param desired the desired `package_policy`, add or delete or addupdate # @param package_version the desired `package_version` # @param 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:** # # ```cf3 # 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"); # ``` { 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:: "$(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:: "$(package_name)" package_policy => $(desired), package_method => generic; reports: (inform_mode||verbose_mode).filebased.!suse.!debian.!redhat.!aix.!solaris_pkgadd:: "$(this.bundle): sorry, can't do file-based installs on $(sys.os)"; } masterfiles-3.6.2/lib/3.6/paths.cf000066400000000000000000000520071241300473300165460ustar00rootroot00000000000000############################################################################ # Copyright (C) CFEngine AS # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License LGPL 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. # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ########################################################################### # # CFEngine Community Open Promise-Body Library # # This initiative started by CFEngine promotes a # standardized set of names and promise specifications # for template functionality within CFEngine 3. # # The aim is to promote an industry standard for # naming of configuration patterns, leading to a # de facto middleware of standardized syntax. # # Names should be intuitive and parameters should be # minimal to assist readability and comprehensibility. # Contributions to this file are voluntarily given to # the cfengine community, and are moderated by CFEngine. # No liability or warranty for misuse is implied. # # If you add to this file, please try to make the # contributions "self-documenting". Comments made # after the bundle/body statement are retained in # the online docs # # For CFEngine Core: 3.6.0 to 3.6.x # Paths bundle (used by other bodies) ################################################### # If you find CFEngine useful, please consider # # purchasing a commercial version of the software.# ################################################### bundle common paths # @brief Defines an array `path` with common paths to standard binaries, # and classes for defined and existing paths. # # If the current platform knows that binary XYZ should be present, # `_stdlib_has_path_XYZ` is defined. Furthermore, if XYZ is actually present # (i.e. the binary exists) in the expected location, `_stdlib_path_exists_XYZ` is # defined. # # **Example:** # # ```cf3 # bundle agent repair_newlines(filename) # { # commands: # _stdlib_path_exists_sed:: # “$(path[sed])” # args => “-i 's/^M//' $(filename)” # } # ``` { vars: # # Common full pathname of commands for OS # enterprise.(am_policy_hub|policy_server):: "path[git]" string => "$(sys.workdir)/bin/git", comment => "CFEngine Enterprise Hub ships with its own git which is used internally"; !(enterprise.(am_policy_hub|policy_server)):: "path[git]" string => "/usr/bin/git"; any:: "path[getfacl]" string => "/usr/bin/getfacl"; "path[npm]" string => "/usr/bin/npm"; "path[pip]" string => "/usr/bin/pip"; _have_bin_env:: "path[env]" string => "/bin/env"; !_have_bin_env:: "path[env]" string => "/usr/bin/env"; _have_bin_systemctl:: "path[systemctl]" string => "/bin/systemctl"; !_have_bin_systemctl:: "path[systemctl]" string => "/usr/bin/systemctl"; linux:: "path[lsattr]" string => "/usr/bin/lsattr"; "path[tar]" string => "/bin/tar"; aix:: "path[awk]" string => "/usr/bin/awk"; "path[bc]" string => "/usr/bin/bc"; "path[cat]" string => "/bin/cat"; "path[cksum]" string => "/usr/bin/cksum"; "path[crontabs]" string => "/var/spool/cron/crontabs"; "path[cut]" string => "/usr/bin/cut"; "path[dc]" string => "/usr/bin/dc"; "path[df]" string => "/usr/bin/df"; "path[diff]" string => "/usr/bin/diff"; "path[dig]" string => "/usr/bin/dig"; "path[echo]" string => "/usr/bin/echo"; "path[egrep]" string => "/usr/bin/egrep"; "path[find]" string => "/usr/bin/find"; "path[grep]" string => "/usr/bin/grep"; "path[ls]" string => "/usr/bin/ls"; "path[netstat]" string => "/usr/bin/netstat"; "path[ping]" string => "/usr/bin/ping"; "path[perl]" string => "/usr/bin/perl"; "path[printf]" string => "/usr/bin/printf"; "path[sed]" string => "/usr/bin/sed"; "path[sort]" string => "/usr/bin/sort"; "path[tr]" string => "/usr/bin/tr"; archlinux:: "path[awk]" string => "/usr/bin/awk"; "path[bc]" string => "/usr/bin/bc"; "path[cat]" string => "/usr/bin/cat"; "path[cksum]" string => "/usr/bin/cksum"; "path[crontab]" string => "/usr/bin/crontab"; "path[cut]" string => "/usr/bin/cut"; "path[dc]" string => "/usr/bin/dc"; "path[df]" string => "/usr/bin/df"; "path[diff]" string => "/usr/bin/diff"; "path[dig]" string => "/usr/bin/dig"; "path[dmidecode]" string => "/usr/bin/dmidecode"; "path[echo]" string => "/usr/bin/echo"; "path[egrep]" string => "/usr/bin/egrep"; "path[ethtool]" string => "/usr/bin/ethtool"; "path[find]" string => "/usr/bin/find"; "path[free]" string => "/usr/bin/free"; "path[grep]" string => "/usr/bin/grep"; "path[hostname]" string => "/usr/bin/hostname"; "path[init]" string => "/usr/bin/init"; "path[iptables]" string => "/usr/bin/iptables"; "path[iptables_save]" string => "/usr/bin/iptables-save"; "path[iptables_restore]" string => "/usr/bin/iptables-restore"; "path[ls]" string => "/usr/bin/ls"; "path[lsof]" string => "/usr/bin/lsof"; "path[netstat]" string => "/usr/bin/netstat"; "path[ping]" string => "/usr/bin/ping"; "path[perl]" string => "/usr/bin/perl"; "path[printf]" string => "/usr/bin/printf"; "path[sed]" string => "/usr/bin/sed"; "path[sort]" string => "/usr/bin/sort"; "path[test]" string => "/usr/bin/test"; "path[top]" string => "/usr/bin/top"; "path[tr]" string => "/usr/bin/tr"; # "path[pacman]" string => "/usr/bin/pacman"; "path[yaourt]" string => "/usr/bin/yaourt"; "path[useradd]" string => "/usr/bin/useradd"; "path[groupadd]" string => "/usr/bin/groupadd"; "path[ip]" string => "/usr/bin/ip"; "path[ifconfig]" string => "/usr/bin/ifconfig"; "path[journalctl]" string => "/usr/bin/journalctl"; "path[netctl]" string => "/usr/bin/netctl"; freebsd|netbsd|openbsd:: "path[awk]" string => "/usr/bin/awk"; "path[bc]" string => "/usr/bin/bc"; "path[cat]" string => "/bin/cat"; "path[crontabs]" string => "/var/cron/tabs"; "path[cut]" string => "/usr/bin/cut"; "path[dc]" string => "/usr/bin/dc"; "path[df]" string => "/bin/df"; "path[diff]" string => "/usr/bin/diff"; "path[dig]" string => "/usr/bin/dig"; "path[echo]" string => "/bin/echo"; "path[egrep]" string => "/usr/bin/egrep"; "path[find]" string => "/usr/bin/find"; "path[grep]" string => "/usr/bin/grep"; "path[ls]" string => "/bin/ls"; "path[netstat]" string => "/usr/bin/netstat"; "path[ping]" string => "/usr/bin/ping"; "path[perl]" string => "/usr/bin/perl"; "path[printf]" string => "/usr/bin/printf"; "path[sed]" string => "/usr/bin/sed"; "path[sort]" string => "/usr/bin/sort"; "path[tr]" string => "/usr/bin/tr"; freebsd|netbsd:: "path[cksum]" string => "/usr/bin/cksum"; "path[realpath]" string => "/bin/realpath"; openbsd:: "path[cksum]" string => "/bin/cksum"; smartos:: "path[npm]" string => "/opt/local/bin/npm"; "path[pip]" string => "/opt/local/bin/pip"; solaris:: "path[awk]" string => "/usr/bin/awk"; "path[bc]" string => "/usr/bin/bc"; "path[cat]" string => "/usr/bin/cat"; "path[cksum]" string => "/usr/bin/cksum"; "path[crontab]" string => "/usr/bin/crontab"; "path[crontabs]" string => "/var/spool/cron/crontabs"; "path[curl]" string => "/usr/bin/curl"; "path[cut]" string => "/usr/bin/cut"; "path[dc]" string => "/usr/bin/dc"; "path[df]" string => "/usr/bin/df"; "path[diff]" string => "/usr/bin/diff"; "path[dig]" string => "/usr/sbin/dig"; "path[echo]" string => "/usr/bin/echo"; "path[egrep]" string => "/usr/bin/egrep"; "path[find]" string => "/usr/bin/find"; "path[grep]" string => "/usr/bin/grep"; "path[ls]" string => "/usr/bin/ls"; "path[netstat]" string => "/usr/bin/netstat"; "path[ping]" string => "/usr/bin/ping"; "path[perl]" string => "/usr/bin/perl"; "path[printf]" string => "/usr/bin/printf"; "path[sed]" string => "/usr/bin/sed"; "path[sort]" string => "/usr/bin/sort"; "path[tr]" string => "/usr/bin/tr"; "path[wget]" string => "/usr/bin/wget"; # "path[svcs]" string => "/usr/bin/svcs"; "path[svcadm]" string => "/usr/sbin/svcadm"; "path[svccfg]" string => "/usr/sbin/svccfg"; "path[netadm]" string => "/usr/sbin/netadm"; "path[dladm]" string => "/usr/sbin/dladm"; "path[ipadm]" string => "/usr/sbin/ipadm"; "path[pkg]" string => "/usr/bin/pkg"; "path[pkginfo]" string => "/usr/bin/pkginfo"; "path[pkgadd]" string => "/usr/sbin/pkgadd"; "path[pkgrm]" string => "/usr/sbin/pkgrm"; "path[zoneadm]" string => "/usr/sbin/zoneadm"; "path[zonecfg]" string => "/usr/sbin/zonecfg"; redhat:: "path[awk]" string => "/bin/awk"; "path[bc]" string => "/usr/bin/bc"; "path[cat]" string => "/bin/cat"; "path[cksum]" string => "/usr/bin/cksum"; "path[createrepo]" string => "/usr/bin/createrepo"; "path[crontab]" string => "/usr/bin/crontab"; "path[crontabs]" string => "/var/spool/cron"; "path[curl]" string => "/usr/bin/curl"; "path[cut]" string => "/bin/cut"; "path[dc]" string => "/usr/bin/dc"; "path[df]" string => "/bin/df"; "path[diff]" string => "/usr/bin/diff"; "path[dig]" string => "/usr/bin/dig"; "path[domainname]" string => "/bin/domainname"; "path[echo]" string => "/bin/echo"; "path[egrep]" string => "/bin/egrep"; "path[ethtool]" string => "/usr/sbin/ethtool"; "path[find]" string => "/usr/bin/find"; "path[grep]" string => "/bin/grep"; "path[hostname]" string => "/bin/hostname"; "path[init]" string => "/sbin/init"; "path[iptables]" string => "/sbin/iptables"; "path[iptables_save]" string => "/sbin/iptables-save"; "path[ls]" string => "/bin/ls"; "path[lsof]" string => "/usr/sbin/lsof"; "path[netstat]" string => "/bin/netstat"; "path[nologin]" string => "/sbin/nologin"; "path[ping]" string => "/usr/bin/ping"; "path[perl]" string => "/usr/bin/perl"; "path[printf]" string => "/usr/bin/printf"; "path[sed]" string => "/bin/sed"; "path[sort]" string => "/bin/sort"; "path[test]" string => "/usr/bin/test"; "path[tr]" string => "/usr/bin/tr"; "path[wget]" string => "/usr/bin/wget"; "path[realpath]" string => "/usr/bin/realpath"; # "path[chkconfig]" string => "/sbin/chkconfig"; "path[groupadd]" string => "/usr/sbin/groupadd"; "path[groupdel]" string => "/usr/sbin/groupdel"; "path[ifconfig]" string => "/sbin/ifconfig"; "path[ip]" string => "/sbin/ip"; "path[rpm]" string => "/bin/rpm"; "path[service]" string => "/sbin/service"; "path[svc]" string => "/sbin/service"; "path[useradd]" string => "/usr/sbin/useradd"; "path[userdel]" string => "/usr/sbin/userdel"; "path[yum]" string => "/usr/bin/yum"; darwin:: "path[awk]" string => "/usr/bin/awk"; "path[bc]" string => "/usr/bin/bc"; "path[cat]" string => "/bin/cat"; "path[cksum]" string => "/usr/bin/cksum"; "path[createrepo]" string => "/usr/bin/createrepo"; "path[crontab]" string => "/usr/bin/crontab"; "path[crontabs]" string => "/usr/lib/cron/tabs"; "path[cut]" string => "/usr/bin/cut"; "path[dc]" string => "/usr/bin/dc"; "path[df]" string => "/bin/df"; "path[diff]" string => "/usr/bin/diff"; "path[dig]" string => "/usr/bin/dig"; "path[domainname]" string => "/bin/domainname"; "path[echo]" string => "/bin/echo"; "path[egrep]" string => "/usr/bin/egrep"; "path[find]" string => "/usr/bin/find"; "path[grep]" string => "/usr/bin/grep"; "path[hostname]" string => "/bin/hostname"; "path[ls]" string => "/bin/ls"; "path[lsof]" string => "/usr/sbin/lsof"; "path[netstat]" string => "/usr/sbin/netstat"; "path[ping]" string => "/sbin/ping"; "path[perl]" string => "/usr/bin/perl"; "path[printf]" string => "/usr/bin/printf"; "path[sed]" string => "/usr/bin/sed"; "path[sort]" string => "/usr/bin/sort"; "path[test]" string => "/bin/test"; "path[tr]" string => "/usr/bin/tr"; # "path[brew]" string => "/usr/local/bin/brew"; "path[sudo]" string => "/usr/bin/sudo"; debian:: "path[awk]" string => "/usr/bin/awk"; "path[bc]" string => "/usr/bin/bc"; "path[cat]" string => "/bin/cat"; "path[chkconfig]" string => "/sbin/chkconfig"; "path[cksum]" string => "/usr/bin/cksum"; "path[createrepo]" string => "/usr/bin/createrepo"; "path[crontab]" string => "/usr/bin/crontab"; "path[crontabs]" string => "/var/spool/cron/crontabs"; "path[curl]" string => "/usr/bin/curl"; "path[cut]" string => "/usr/bin/cut"; "path[dc]" string => "/usr/bin/dc"; "path[df]" string => "/bin/df"; "path[diff]" string => "/usr/bin/diff"; "path[dig]" string => "/usr/bin/dig"; "path[dmidecode]" string => "/usr/sbin/dmidecode"; "path[domainname]" string => "/bin/domainname"; "path[echo]" string => "/bin/echo"; "path[egrep]" string => "/bin/egrep"; "path[ethtool]" string => "/sbin/ethtool"; "path[find]" string => "/usr/bin/find"; "path[grep]" string => "/bin/grep"; "path[hostname]" string => "/bin/hostname"; "path[init]" string => "/sbin/init"; "path[iptables]" string => "/sbin/iptables"; "path[iptables_save]" string => "/sbin/iptables-save"; "path[ls]" string => "/bin/ls"; "path[lsof]" string => "/usr/bin/lsof"; "path[netstat]" string => "/bin/netstat"; "path[nologin]" string => "/usr/sbin/nologin"; "path[ping]" string => "/bin/ping"; "path[perl]" string => "/usr/bin/perl"; "path[printf]" string => "/usr/bin/printf"; "path[sed]" string => "/bin/sed"; "path[sort]" string => "/usr/bin/sort"; "path[test]" string => "/usr/bin/test"; "path[tr]" string => "/usr/bin/tr"; "path[wget]" string => "/usr/bin/wget"; "path[realpath]" string => "/usr/bin/realpath"; # "path[apt_cache]" string => "/usr/bin/apt-cache"; "path[apt_config]" string => "/usr/bin/apt-config"; "path[apt_get]" string => "/usr/bin/apt-get"; "path[apt_key]" string => "/usr/bin/apt-key"; "path[aptitude]" string => "/usr/bin/aptitude"; "path[dpkg]" string => "/usr/bin/dpkg"; "path[groupadd]" string => "/usr/sbin/groupadd"; "path[ifconfig]" string => "/sbin/ifconfig"; "path[ip]" string => "/sbin/ip"; "path[service]" string => "/usr/sbin/service"; "path[svc]" string => "/usr/sbin/service"; "path[update_alternatives]" string => "/usr/bin/update-alternatives"; "path[update_rc_d]" string => "/usr/sbin/update-rc.d"; "path[useradd]" string => "/usr/sbin/useradd"; archlinux||darwin:: "path[sysctl]" string => "/usr/bin/sysctl"; !(archlinux||darwin):: "path[sysctl]" string => "/sbin/sysctl"; !suse:: "path[logger]" string => "/usr/bin/logger"; suse:: "path[awk]" string => "/usr/bin/awk"; "path[bc]" string => "/usr/bin/bc"; "path[cat]" string => "/bin/cat"; "path[cksum]" string => "/usr/bin/cksum"; "path[createrepo]" string => "/usr/bin/createrepo"; "path[crontab]" string => "/usr/bin/crontab"; "path[crontabs]" string => "/var/spool/cron/tabs"; "path[curl]" string => "/usr/bin/curl"; "path[cut]" string => "/usr/bin/cut"; "path[dc]" string => "/usr/bin/dc"; "path[df]" string => "/bin/df"; "path[diff]" string => "/usr/bin/diff"; "path[dig]" string => "/usr/bin/dig"; "path[dmidecode]" string => "/usr/sbin/dmidecode"; "path[domainname]" string => "/bin/domainname"; "path[echo]" string => "/bin/echo"; "path[egrep]" string => "/usr/bin/egrep"; "path[ethtool]" string => "/usr/sbin/ethtool"; "path[find]" string => "/usr/bin/find"; "path[free]" string => "/usr/bin/free"; "path[grep]" string => "/usr/bin/grep"; "path[hostname]" string => "/bin/hostname"; "path[init]" string => "/sbin/init"; "path[iptables]" string => "/usr/sbin/iptables"; "path[iptables_save]" string => "/usr/sbin/iptables-save"; "path[ls]" string => "/bin/ls"; "path[lsof]" string => "/usr/bin/lsof"; "path[netstat]" string => "/bin/netstat"; "path[nologin]" string => "/sbin/nologin"; "path[ping]" string => "/bin/ping"; "path[perl]" string => "/usr/bin/perl"; "path[printf]" string => "/usr/bin/printf"; "path[sed]" string => "/bin/sed"; "path[sort]" string => "/usr/bin/sort"; "path[test]" string => "/usr/bin/test"; "path[tr]" string => "/usr/bin/tr"; "path[logger]" string => "/bin/logger"; "path[wget]" string => "/usr/bin/wget"; # "path[chkconfig]" string => "/sbin/chkconfig"; "path[groupadd]" string => "/usr/sbin/groupadd"; "path[groupdel]" string => "/usr/sbin/groupdel"; "path[groupmod]" string => "/usr/sbin/groupmod"; "path[ifconfig]" string => "/sbin/ifconfig"; "path[ip]" string => "/sbin/ip"; "path[rpm]" string => "/bin/rpm"; "path[service]" string => "/sbin/service"; "path[useradd]" string => "/usr/sbin/useradd"; "path[userdel]" string => "/usr/sbin/userdel"; "path[usermod]" string => "/usr/sbin/usermod"; "path[zypper]" string => "/usr/bin/zypper"; linux|solaris:: "path[shadow]" string => "/etc/shadow"; freebsd|openbsd|netbsd|darwin:: "path[shadow]" string => "/etc/master.passwd"; aix:: "path[shadow]" string => "/etc/security/passwd"; any:: "all_paths" slist => getindices("path"); "$(all_paths)" string => "$(path[$(all_paths)])"; classes: "_have_bin_env" expression => fileexists("/bin/env"); "_have_bin_systemctl" expression => fileexists("/bin/systemctl"); "_stdlib_has_path_$(all_paths)" expression => isvariable("$(all_paths)"), comment => "It's useful to know if a given path is defined"; "_stdlib_path_exists_$(all_paths)" expression => fileexists("$(path[$(all_paths)])"), comment => "It's useful to know if $(all_paths) exists on the filesystem as defined"; } masterfiles-3.6.2/lib/3.6/processes.cf000066400000000000000000000102671241300473300174370ustar00rootroot00000000000000############################################################################ # Copyright (C) CFEngine AS # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License LGPL 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. # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ########################################################################### # # CFEngine Community Open Promise-Body Library # # This initiative started by CFEngine promotes a # standardized set of names and promise specifications # for template functionality within CFEngine 3. # # The aim is to promote an industry standard for # naming of configuration patterns, leading to a # de facto middleware of standardized syntax. # # Names should be intuitive and parameters should be # minimal to assist readability and comprehensibility. # Contributions to this file are voluntarily given to # the cfengine community, and are moderated by CFEngine. # No liability or warranty for misuse is implied. # # If you add to this file, please try to make the # contributions "self-documenting". Comments made # after the bundle/body statement are retained in # the online docs # # For CFEngine Core: 3.6.0 to 3.6.x # Processes bodies ################################################### # If you find CFEngine useful, please consider # # purchasing a commercial version of the software.# ################################################### ##------------------------------------------------------- ## process promises ##------------------------------------------------------- body process_select exclude_procs(x) # @brief Select all processes excluding those matching `x` # @param x Regular expression matching the command/cmd field # of the processes that should be excluded { command => "$(x)"; process_result => "!command"; } ## body process_select days_older_than(d) # @brief Select all processes that are older than `d` days # @param d Days that processes need to be old to be selected { stime_range => irange(ago(0,0,"$(d)",0,0,0),now); process_result => "stime"; } ## body process_select by_owner(u) # @brief Select processes owned by user `u` # @param u The name of the user # # Matches processes against the given username and the given username's uid # in case only uid is visible in process list. { process_owner => { "$(u)", canonify(getuid("$(u)")) }; process_result => "process_owner"; } body process_select by_pid(pid) # @brief Select a process matching the given PID # @param pid PID of the process to be matched { pid => irange("$(pid)","$(pid)"); process_result => "pid"; } ## body process_count any_count(cl) # @brief Define class `cl` if the process is running # @param cl Name of the class to be defined { match_range => "0,0"; out_of_range_define => { "$(cl)" }; } ## body process_count check_range(name,lower,upper) # @brief Define a class if the number of processes is not # within the specified range. # @param name The name part of the class `$(name)_out_of_range` # @param lower The lower bound of the range # @param upper The upper bound of the range { match_range => irange("$(lower)","$(upper)"); out_of_range_define => { "$(name)_out_of_range" }; } bundle agent process_kill(name) # @brief Kill a process by name (can be a regular expression) # @param name the regular expression or string # # **Example:** # # ```cf3 # methods: # "kill" usebundle => process_kill("badprocess"); # ``` { processes: !windows:: # Signals are presented as an ordered list to the process. "$(name)" signals => { "term", "kill" }; windows:: # On Windows, only the kill signal is supported, which terminates the process. "$(name)" signals => { "kill" }; } masterfiles-3.6.2/lib/3.6/reports.cf000066400000000000000000000054721241300473300171310ustar00rootroot00000000000000############################################################################ # Copyright (C) CFEngine AS # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License LGPL 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. # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ########################################################################### # # CFEngine Community Open Promise-Body Library # # This initiative started by CFEngine promotes a # standardized set of names and promise specifications # for template functionality within CFEngine 3. # # The aim is to promote an industry standard for # naming of configuration patterns, leading to a # de facto middleware of standardized syntax. # # Names should be intuitive and parameters should be # minimal to assist readability and comprehensibility. # Contributions to this file are voluntarily given to # the cfengine community, and are moderated by CFEngine. # No liability or warranty for misuse is implied. # # If you add to this file, please try to make the # contributions "self-documenting". Comments made # after the bundle/body statement are retained in # the online docs # # For CFEngine Core: 3.6.0 to 3.6.x # Reporting bodies ################################################### # If you find CFEngine useful, please consider # # purchasing a commercial version of the software.# ################################################### body report_data_select default_data_select_host # @brief Data to collect from remote hosts by default # # By convention variables and classes known to be internal, (having no # reporting value) should be prefixed with an underscore. By default the policy # framework explicitly excludes these variables and classes from collection. { metatags_include => { "inventory", "report" }; metatags_exclude => { "noreport" }; monitoring_include => { "" }; } body report_data_select default_data_select_policy_hub # @brief Data to collect from policy servers by default # # By convention variables and classes known to be internal, (having no # reporting value) should be prefixed with an underscore. By default the policy # framework explicitly excludes these variables and classes from collection. { metatags_include => { "inventory", "report" }; metatags_exclude => { "noreport" }; monitoring_include => { "" }; } masterfiles-3.6.2/lib/3.6/services.cf000066400000000000000000001070671241300473300172610ustar00rootroot00000000000000############################################################################ # Copyright (C) CFEngine AS # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License LGPL 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. # # To the extent this program is licensed as part of the Enterprise # versions of CFEngine, the applicable Commercial Open Source License # (COSL) may apply to this file if you as a licensee so wish it. See # included file COSL.txt. ########################################################################### # # CFEngine Community Open Promise-Body Library # # This initiative started by CFEngine promotes a # standardized set of names and promise specifications # for template functionality within CFEngine 3. # # The aim is to promote an industry standard for # naming of configuration patterns, leading to a # de facto middleware of standardized syntax. # # Names should be intuitive and parameters should be # minimal to assist readability and comprehensibility. # Contributions to this file are voluntarily given to # the cfengine community, and are moderated by CFEngine. # No liability or warranty for misuse is implied. # # If you add to this file, please try to make the # contributions "self-documenting". Comments made # after the bundle/body statement are retained in # the online docs # # For CFEngine Core: 3.6.0 to 3.6.x # Services bodies ################################################### # If you find CFEngine useful, please consider # # purchasing a commercial version of the software.# ################################################### bundle common services_common # @ignore { vars: "inputs" slist => { "$(this.promise_dirname)/common.cf", "$(this.promise_dirname)/paths.cf" }; } body file control # @ignore { inputs => { @(services_common.inputs) }; } ##------------------------------------------------------- ## service promises ##------------------------------------------------------- body service_method bootstart # @brief Start the service and all its dependencies at boot time # # **See also:** `service_autostart_policy`, `service_dependence_chain` { service_autostart_policy => "boot_time"; service_dependence_chain => "start_parent_services"; windows:: service_type => "windows"; } ## body service_method force_deps # @brief Start all dependendencies when this service starts, and stop all # dependent services when this service stops. # # The service does not get automatically started. # # **See also:** `service_autostart_policy`, `service_dependence_chain` { service_dependence_chain => "all_related"; windows:: service_type => "windows"; } ## bundle agent standard_services(service,state) # @brief Standard services bundle, used by CFEngine by default # @author CFEngine AS # @param service Name of service to control # @param state The desired state for that service: "start", "restart", "reload", "stop", or "disable" # # This bundle is used by CFEngine if you don't specify a services # handler explicitly, and will work with systemd or chkconfig or other # non-sysvinit service managers. It will try to automate service # discovery, unlike `classic_services` which requires known service # names. If it can't do the automatic management, it will pass control # to `classic_services`. # # This bundle receives the service name and the desired service state, # then does the needful to reach the desired state. # # If you're running systemd, systemctl will be used. # # Else, if chkconfig is present, it will be used. # # Else, if the service command is available, if will be used. # # Else, if the svcadm command is available, if will be used. Note you # have to supply the full SMF service identifier. # # Else, control is passed to `classic_services`. # # Note you do **not** have to call this bundle from `services` # promises. You can simply make a `methods` call to it. That would # enable you to use systemd states like `try-restart` for instance. # # **Example:** # # ```cf3 # services: # "sshd" service_policy => "start"; # uses `standard_services` # # methods: # "" usebundle => standard_services("sshd", "start"); # direct # ``` { vars: "call_systemctl" string => "$(paths.systemctl) --no-ask-password --global --system"; "init" string => "/etc/init.d/$(service)"; start|restart|reload:: "chkconfig_mode" string => "on"; "svcadm_mode" string => "enable"; stop|disable:: "chkconfig_mode" string => "off"; "svcadm_mode" string => "disable"; classes: # define a class named after the desired state "$(state)" expression => "any"; "non_disabling" or => { "start", "stop", "restart", "reload" }; "chkconfig" expression => "!systemd._stdlib_path_exists_chkconfig"; "sysvservice" expression => "!systemd.!chkconfig._stdlib_path_exists_service"; "smf" expression => "!systemd.!chkconfig.!sysvservice._stdlib_path_exists_svcadm"; "fallback" expression => "!systemd.!chkconfig.!sysvservice.!smf"; "have_init" expression => fileexists($(init)); chkconfig.have_init:: "running" expression => returnszero("$(init) status > /dev/null", "useshell"); chkconfig:: "onboot" expression => returnszero("$(paths.chkconfig) $(service)", "noshell"), comment => "We need to know if the service is configured to start at boot or not"; commands: systemd:: # note this class is defined in `inventory/linux.cf` # conveniently, systemd states map to `services` states, except # for `enable` "$(call_systemctl) $(state) $(service)" classes => kept_successful_command; systemd.start:: # so for `start` we explicitly enable the service, but for # `stop` we do NOT disable it "$(call_systemctl) enable $(service)" classes => kept_successful_command; chkconfig.stop.onboot:: # Only chkconfig disable if it's currently set to start on boot "$(paths.chkconfig) $(service) $(chkconfig_mode)" classes => kept_successful_command, contain => silent; chkconfig.start.!onboot:: # Only chkconfig enable service if it's not already set to start on boot "$(paths.chkconfig) $(service) $(chkconfig_mode)" classes => kept_successful_command, contain => silent; chkconfig.have_init.((start.!running)|(stop.running)).non_disabling:: "$(init) $(state)" classes => kept_successful_command, contain => silent; sysvservice.non_disabling:: "$(paths.service) $(service) $(state)" classes => kept_successful_command; sysvservice.disable:: "$(paths.service) $(service) stop" classes => kept_successful_command; smf:: "$(paths.svcadm) $(svcadm_mode) $(service)" classes => kept_successful_command; methods: fallback:: "classic" usebundle => classic_services($(service), $(state)); reports: inform_mode.systemd:: "$(this.bundle): using systemd layer to $(state) $(service)"; inform_mode.chkconfig:: "$(this.bundle): using chkconfig layer to $(state) $(service) (chkconfig mode $(chkconfig_mode))" ifvarclass => canonify("chkconfig_$(service)_registered"); inform_mode.chkconfig:: "$(this.bundle): skipping chkconfig layer to $(state) $(service) because $(service) is not registered with chkconfig (chkconfig mode $(chkconfig_mode))" ifvarclass => not(canonify("!chkconfig_$(service)_registered")); inform_mode.sysvservice:: "$(this.bundle): using System V service / Upstart layer to $(state) $(service)"; inform_mode.smf:: "$(this.bundle): using Solaris SMF to $(state) $(service) (svcadm mode $(svcadm_mode))"; inform_mode.fallback:: "$(this.bundle): falling back to classic_services to $(state) $(service)"; } bundle agent classic_services(service,state) # @brief Standard services bundle, used by CFEngine by default # @author CFEngine AS # @author Tero Kantonen # @param service specific service to control # @param state desired state for that service # # This bundle is used by CFEngine if you don't specify a services # handler explicitly. # # It receives the service name and the desired service state, then # does the needful to reach the desired state.. # # **Example:** # # ```cf3 # services: # "ntp" service_policy => "start"; # "ssh" service_policy => "stop"; # ``` # # There's multiple ways you can add new services to this list. # Here's few examples: # # a) The zeroconf mode; If the new service matches these rules, # you don't need to add anything to the standard_services: # # 1. Your init script basename = `$(service)` # 2. Your init script argument = `$(state)` # 3. Your init script lives in `/etc/init.d/` (for non-*bsd), # or `/etc/rc.d/` (for *bsd) # 4. Your process regex pattern = `\b$(service)\b` # 5. You call the init as `/etc/init.d/