./PaxHeaders/cfengine-masterfiles-3.27.30000644000000000000000000000003615266337437015061 xustar0030 mtime=1792655135.297801973 cfengine-masterfiles-3.27.3/0000755000000000000000000000000015266337437014106 5ustar0000000000000000cfengine-masterfiles-3.27.3/CFVERSION0000644000000000000000000000002214735102600015337 0ustar00000000000000003.27.3a.d15a8e749 cfengine-masterfiles-3.27.3/CONTRIBUTING.md0000644000000000000000000000145114735102600016316 0ustar0000000000000000# Contributing to the CFEngine masterfiles * Follow the [Core contribution guidelines](https://github.com/cfengine/core/blob/master/CONTRIBUTING.md#how-to-contribute-to-cfengine) * * Prefix commit subjects with the issue identifier * * Don't forget to include a [ChangeLog Entry](https://github.com/cfengine/core/blob/master/CONTRIBUTING.md#changelog) * Follow the [policy style guide](https://docs.cfengine.com/docs/latest/guide-writing-and-serving-policy-policy-style.html) * Test thoroughly, provide [acceptance tests](https://github.com/cfengine/core/blob/master/tests/acceptance/README) to run in core or masterfiles using the [DCS framework](https://github.com/cfengine/core/blob/master/tests/acceptance/DCS.org) * Document well See [MPF.md](MPF.md) * lurk for a bit * don't be afraid to ask questions cfengine-masterfiles-3.27.3/LICENSE0000644000000000000000000000230514735102600015071 0ustar0000000000000000All software in this repository except where explicitly marked otherwise is under the following license. MIT Public License http://www.opensource.org/licenses/MIT Copyright 2024 Northern.tech 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. cfengine-masterfiles-3.27.3/Makefile.am0000644000000000000000000000611014735102600016116 0ustar0000000000000000ACLOCAL_AMFLAGS = -I m4 SUBDIRS = \ tests/ # See configure.ac for MASTERFILES_INSTALL_TARGETS. nobase_dist_masterfiles_DATA = @MASTERFILES_INSTALL_TARGETS@ masterfilesdir=$(prefix)/masterfiles EXTRA_DIST = README.md inventory/README.md lib/README.md CONTRIBUTING.md LICENSE CFVERSION modules/promises # Normalize tar header fields so two builds of the same source tree produce a # byte-identical tarball, following the GNU tar reproducibility guidance: # https://www.gnu.org/software/tar/manual/html_section/Reproducibility.html # --format=posix stable, version-independent header encoding (configure.ac # selects tar-pax so $(am__tar) emits posix) # --pax-option=... keep tar's PID out of extended-header names and omit # atime/ctime, leaving the archive in the ustar subset # --sort=name stable member order # --numeric-owner do not record buildslave user/group names # --owner=0 --group=0 deterministic ownership # --mode=go+u,go-w deterministic permissions # mtime clamping (the manual's --clamp-mtime --mtime) is handled by the # touch -d @$$SOURCE_DATE_EPOCH calls in dist-hook and tar-package below. TAR_OPTIONS = \ --format=posix \ --pax-option=exthdr.name=%d/PaxHeaders/%f \ --pax-option=delete=atime,delete=ctime \ --sort=name \ --numeric-owner --owner=0 --group=0 \ --mode=go+u,go-w export TAR_OPTIONS # The same guidance says to "run GNU tar in the C locale" alongside the options # above; its example invokes "LC_ALL=C tar ...". Exporting LC_ALL=C covers both # "make dist" and "make tar-package", which invoke $(am__tar). LC_ALL = C export LC_ALL # Store the permissions properly in the tarball for acceptance tests to succeed. # Also normalize directory permissions (which would otherwise be affected by the # builder's umask). When SOURCE_DATE_EPOCH is set, clamp every mtime to it so # the "make dist" source tarball is reproducible. dist-hook: find $(distdir) -name '*.cf*' | xargs chmod go-w find $(distdir) -type d -exec chmod 755 {} + if [ -n "$$SOURCE_DATE_EPOCH" ]; then \ find $(distdir) -exec touch -d @$$SOURCE_DATE_EPOCH {} + ; \ fi tar-package: pkgdir=`mktemp -d` && export pkgdir && \ origdir=`pwd` && export origdir && \ umask 0022 && chmod 755 $$pkgdir && \ $(MAKE) prefix=$$pkgdir install && \ ( cd $$pkgdir && \ find . -name '*.cf*' | xargs -n1 chmod go-w && \ if [ -n "$$SOURCE_DATE_EPOCH" ]; then \ find . -exec touch -d @$$SOURCE_DATE_EPOCH {} + ; \ fi && \ tardir=. && $(am__tar) | \ GZIP=$(GZIP_ENV) gzip --no-name --stdout \ > "$$origdir"/$(PACKAGE)-$(VERSION)-$(RELEASE).pkg.tar.gz \ ) ; \ [ x$$pkgdir != x ] && rm -rf $$pkgdir clean-local: rm -rf build non-priv-install: mkdir -p "$$HOME/.cfagent/bin" ln -sf $$(command -v cf-promises) "$$HOME/.cfagent/bin" mkdir -p "$$HOME/.cfagent/inputs/lib" rsync -avz ./lib/ "$$HOME/.cfagent/inputs/lib/" [ ! -s "$$HOME/.cfagent/inputs/promises.cf" ] && echo "bundle agent main { reports: 'Hello, CFEngine!'; }" > "$$HOME/.cfagent/inputs/promises.cf" cfengine-masterfiles-3.27.3/Makefile.in0000644000000000000000000007432014735102600016137 0ustar0000000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/adl_recursive_eval.m4 \ $(top_srcdir)/m4/tar.m4 $(top_srcdir)/m4/cf3_platforms.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ $(am__configure_deps) $(nobase_dist_masterfiles_DATA) \ $(am__DIST_COMMON) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = controls/update_def.cf update.cf promises.cf \ standalone_self_upgrade.cf CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(masterfilesdir)" DATA = $(nobase_dist_masterfiles_DATA) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ cscope distdir dist dist-all distcheck am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags CSCOPE = cscope DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/promises.cf.in \ $(srcdir)/standalone_self_upgrade.cf.in $(srcdir)/update.cf.in \ $(top_srcdir)/controls/update_def.cf.in config.guess \ config.sub install-sh missing DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ if test -d "$(distdir)"; then \ find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -rf "$(distdir)" \ || { sleep 5 && rm -rf "$(distdir)"; }; \ else :; fi am__post_remove_distdir = $(am__remove_distdir) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best DIST_TARGETS = dist-gzip distuninstallcheck_listfiles = find . -type f -print am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MASTERFILES_INSTALL_TARGETS = @MASTERFILES_INSTALL_TARGETS@ MASTERFILES_TESTS = @MASTERFILES_TESTS@ MKDIR_P = @MKDIR_P@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RELEASE = @RELEASE@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_cv_pkg_install = @ac_cv_pkg_install@ ac_cv_shunit2 = @ac_cv_shunit2@ am__leading_dot = @am__leading_dot@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ core_dir = @core_dir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ enterprise_dir = @enterprise_dir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ ACLOCAL_AMFLAGS = -I m4 SUBDIRS = \ tests/ # See configure.ac for MASTERFILES_INSTALL_TARGETS. nobase_dist_masterfiles_DATA = @MASTERFILES_INSTALL_TARGETS@ masterfilesdir = $(prefix)/masterfiles EXTRA_DIST = README.md inventory/README.md lib/README.md CONTRIBUTING.md LICENSE CFVERSION modules/promises # Normalize tar header fields so two builds of the same source tree produce a # byte-identical tarball, following the GNU tar reproducibility guidance: # https://www.gnu.org/software/tar/manual/html_section/Reproducibility.html # --format=posix stable, version-independent header encoding (configure.ac # selects tar-pax so $(am__tar) emits posix) # --pax-option=... keep tar's PID out of extended-header names and omit # atime/ctime, leaving the archive in the ustar subset # --sort=name stable member order # --numeric-owner do not record buildslave user/group names # --owner=0 --group=0 deterministic ownership # --mode=go+u,go-w deterministic permissions # mtime clamping (the manual's --clamp-mtime --mtime) is handled by the # touch -d @$$SOURCE_DATE_EPOCH calls in dist-hook and tar-package below. TAR_OPTIONS = \ --format=posix \ --pax-option=exthdr.name=%d/PaxHeaders/%f \ --pax-option=delete=atime,delete=ctime \ --sort=name \ --numeric-owner --owner=0 --group=0 \ --mode=go+u,go-w # The same guidance says to "run GNU tar in the C locale" alongside the options # above; its example invokes "LC_ALL=C tar ...". Exporting LC_ALL=C covers both # "make dist" and "make tar-package", which invoke $(am__tar). LC_ALL = C all: all-recursive .SUFFIXES: am--refresh: Makefile @: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) $(am__cd) $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) $(am__aclocal_m4_deps): controls/update_def.cf: $(top_builddir)/config.status $(top_srcdir)/controls/update_def.cf.in cd $(top_builddir) && $(SHELL) ./config.status $@ update.cf: $(top_builddir)/config.status $(srcdir)/update.cf.in cd $(top_builddir) && $(SHELL) ./config.status $@ promises.cf: $(top_builddir)/config.status $(srcdir)/promises.cf.in cd $(top_builddir) && $(SHELL) ./config.status $@ standalone_self_upgrade.cf: $(top_builddir)/config.status $(srcdir)/standalone_self_upgrade.cf.in cd $(top_builddir) && $(SHELL) ./config.status $@ install-nobase_dist_masterfilesDATA: $(nobase_dist_masterfiles_DATA) @$(NORMAL_INSTALL) @list='$(nobase_dist_masterfiles_DATA)'; test -n "$(masterfilesdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(masterfilesdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(masterfilesdir)" || exit 1; \ fi; \ $(am__nobase_list) | while read dir files; do \ xfiles=; for file in $$files; do \ if test -f "$$file"; then xfiles="$$xfiles $$file"; \ else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \ test -z "$$xfiles" || { \ test "x$$dir" = x. || { \ echo " $(MKDIR_P) '$(DESTDIR)$(masterfilesdir)/$$dir'"; \ $(MKDIR_P) "$(DESTDIR)$(masterfilesdir)/$$dir"; }; \ echo " $(INSTALL_DATA) $$xfiles '$(DESTDIR)$(masterfilesdir)/$$dir'"; \ $(INSTALL_DATA) $$xfiles "$(DESTDIR)$(masterfilesdir)/$$dir" || exit $$?; }; \ done uninstall-nobase_dist_masterfilesDATA: @$(NORMAL_UNINSTALL) @list='$(nobase_dist_masterfiles_DATA)'; test -n "$(masterfilesdir)" || list=; \ $(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \ dir='$(DESTDIR)$(masterfilesdir)'; $(am__uninstall_files_from_dir) # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscope: cscope.files test ! -s cscope.files \ || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) clean-cscope: -rm -f cscope.files cscope.files: clean-cscope cscopelist cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -rm -f cscope.out cscope.in.out cscope.po.out cscope.files distdir: $(DISTFILES) $(am__remove_distdir) test -d "$(distdir)" || mkdir "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" distdir="$(distdir)" \ dist-hook -test -n "$(am__skip_mode_fix)" \ || find "$(distdir)" -type d ! -perm -755 \ -exec chmod u+rwx,go+rx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__post_remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 $(am__post_remove_distdir) dist-lzip: distdir tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz $(am__post_remove_distdir) dist-xz: distdir tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz $(am__post_remove_distdir) dist-tarZ: distdir @echo WARNING: "Support for distribution archives compressed with" \ "legacy program 'compress' is deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__post_remove_distdir) dist-shar: distdir @echo WARNING: "Support for shar distribution archives is" \ "deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz $(am__post_remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__post_remove_distdir) dist dist-all: $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' $(am__post_remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lz*) \ lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ *.tar.xz*) \ xz -dc $(distdir).tar.xz | $(am__untar) ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac chmod -R a-w $(distdir) chmod u+w $(distdir) mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst chmod a-w $(distdir) test -d $(distdir)/_build || exit 0; \ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && am__cwd=`pwd` \ && $(am__cd) $(distdir)/_build/sub \ && ../../configure \ $(AM_DISTCHECK_CONFIGURE_FLAGS) \ $(DISTCHECK_CONFIGURE_FLAGS) \ --srcdir=../.. --prefix="$$dc_install_base" \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ distuninstallcheck \ && chmod -R a-w "$$dc_install_base" \ && ({ \ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ } || { rm -rf "$$dc_destdir"; exit 1; }) \ && rm -rf "$$dc_destdir" \ && $(MAKE) $(AM_MAKEFLAGS) dist \ && rm -rf $(DIST_ARCHIVES) \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ && cd "$$am__cwd" \ || exit 1 $(am__post_remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' distuninstallcheck: @test -n '$(distuninstallcheck_dir)' || { \ echo 'ERROR: trying to run $@ with an empty' \ '$$(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ $(am__cd) '$(distuninstallcheck_dir)' || { \ echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ fi ; \ $(distuninstallcheck_listfiles) ; \ exit 1; } >&2 distcleancheck: distclean @if test '$(srcdir)' = . ; then \ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ exit 1 ; \ fi @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left in build directory after distclean:" ; \ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am check: check-recursive all-am: Makefile $(DATA) installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(masterfilesdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-local mostlyclean-am distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-nobase_dist_masterfilesDATA install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-nobase_dist_masterfilesDATA .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ am--refresh check check-am clean clean-cscope clean-generic \ clean-local cscope cscopelist-am ctags ctags-am dist dist-all \ dist-bzip2 dist-gzip dist-hook dist-lzip dist-shar dist-tarZ \ dist-xz dist-zip distcheck distclean distclean-generic \ distclean-tags distcleancheck distdir distuninstallcheck dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man \ install-nobase_dist_masterfilesDATA install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ pdf-am ps ps-am tags tags-am uninstall uninstall-am \ uninstall-nobase_dist_masterfilesDATA .PRECIOUS: Makefile export TAR_OPTIONS export LC_ALL # Store the permissions properly in the tarball for acceptance tests to succeed. # Also normalize directory permissions (which would otherwise be affected by the # builder's umask). When SOURCE_DATE_EPOCH is set, clamp every mtime to it so # the "make dist" source tarball is reproducible. dist-hook: find $(distdir) -name '*.cf*' | xargs chmod go-w find $(distdir) -type d -exec chmod 755 {} + if [ -n "$$SOURCE_DATE_EPOCH" ]; then \ find $(distdir) -exec touch -d @$$SOURCE_DATE_EPOCH {} + ; \ fi tar-package: pkgdir=`mktemp -d` && export pkgdir && \ origdir=`pwd` && export origdir && \ umask 0022 && chmod 755 $$pkgdir && \ $(MAKE) prefix=$$pkgdir install && \ ( cd $$pkgdir && \ find . -name '*.cf*' | xargs -n1 chmod go-w && \ if [ -n "$$SOURCE_DATE_EPOCH" ]; then \ find . -exec touch -d @$$SOURCE_DATE_EPOCH {} + ; \ fi && \ tardir=. && $(am__tar) | \ GZIP=$(GZIP_ENV) gzip --no-name --stdout \ > "$$origdir"/$(PACKAGE)-$(VERSION)-$(RELEASE).pkg.tar.gz \ ) ; \ [ x$$pkgdir != x ] && rm -rf $$pkgdir clean-local: rm -rf build non-priv-install: mkdir -p "$$HOME/.cfagent/bin" ln -sf $$(command -v cf-promises) "$$HOME/.cfagent/bin" mkdir -p "$$HOME/.cfagent/inputs/lib" rsync -avz ./lib/ "$$HOME/.cfagent/inputs/lib/" [ ! -s "$$HOME/.cfagent/inputs/promises.cf" ] && echo "bundle agent main { reports: 'Hello, CFEngine!'; }" > "$$HOME/.cfagent/inputs/promises.cf" # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: cfengine-masterfiles-3.27.3/README.md0000644000000000000000000000606014735102600015345 0ustar0000000000000000Looking for help? * [Chat with us in #CFEngine:matrix.org](https://matrix.to/#/#CFEngine:matrix.org). * Ask questions on [Github Discussions](https://github.com/cfengine/core/discussions/) or the mailing list [help-cfengine@googlegroups.com](https://groups.google.com/g/help-cfengine). # 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. The MPF or Masterfiles Policy Framework is intended to provide a stable base policy for installations and upgrades, and is used by both CFEngine Enterprise and CFEngine community in versions 3.6 and newer. The [documentation for the MPF](https://docs.cfengine.com/docs/master/reference-masterfiles-policy-framework.html) is highly recommended. ## Installation There are several methods available for installing the CFEngine Masterfiles Policy Framework. * From pkg tarball * From git * From source tarball ### From pkg tarball If you have downloaded a [package tarball from our website](https://cfengine.com/product/community/) (not from github), you don't need to `autogen`, `configure` or `make` anything. Instead simply unpack the tarball to the desired location using `tar`. For example: ``` tar zxvf cfengine-masterfiles-MAJOR.MINOR.PATCH.pkg.tar.gz /var/cfengine/masterfiles ``` ### From git Clone this repository ``` git clone https://github.com/cfengine/masterfiles ``` If you have cloned the repository from github: Run autogen and make to build masterfiles. ``` ./autogen.sh make ``` Optionally configure masterfiles to install to a different location (perhaps your own version control checkout) ``` ./configure --prefix=/tmp/cfengine/ make ``` ``` make install ``` ### From source tarball If you have downloaded a [release tarball from our website](https://cfengine.com/product/community/) (not from github), you don't need to run `autogen.sh`. By default it installs in `/var/cfengine/masterfiles` but you can override that easily: ``` ./configure --prefix=/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 available 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) # Authors CFEngine was originally created by Mark Burgess with many contributions from around the world. Thanks [everyone](https://github.com/cfengine/core/blob/master/AUTHORS)! [CFEngine](https://cfengine.com) is sponsored by [Northern.tech AS](https://northern.tech) cfengine-masterfiles-3.27.3/aclocal.m40000644000000000000000000006520114735102600015730 0ustar0000000000000000# generated automatically by aclocal 1.15 -*- Autoconf -*- # Copyright (C) 1996-2014 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, [m4_warning([this file was generated for autoconf 2.69. You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) # Copyright (C) 2002-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.15' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. m4_if([$1], [1.15], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) # _AM_AUTOCONF_VERSION(VERSION) # ----------------------------- # aclocal traces this macro to find the Autoconf version. # This is a private macro too. Using m4_define simplifies # the logic in aclocal, which can simply ignore this definition. m4_define([_AM_AUTOCONF_VERSION], []) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.15])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- # Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to # '$srcdir', '$srcdir/..', or '$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and # therefore $ac_aux_dir as well) can be either absolute or relative, # depending on how configure is run. This is pretty annoying, since # it makes $ac_aux_dir quite unusable in subdirectories: in the top # source directory, any form will work fine, but in subdirectories a # relative path needs to be adjusted first. # # $ac_aux_dir/missing # fails when called from a subdirectory if $ac_aux_dir is relative # $top_srcdir/$ac_aux_dir/missing # fails if $ac_aux_dir is absolute, # fails when called from a subdirectory in a VPATH build with # a relative $ac_aux_dir # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually # harmless because $srcdir is '.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, # iff we strip the leading $srcdir from $ac_aux_dir. That would be: # am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` # and then we would define $MISSING as # MISSING="\${SHELL} $am_aux_dir/missing" # This will work as long as MISSING is not called from configure, because # unfortunately $(top_srcdir) has no meaning in configure. # However there are other variables, like CC, which are often used in # configure, and could therefore not use this "fixed" $ac_aux_dir. # # Another solution, used here, is to always expand $ac_aux_dir to an # absolute PATH. The drawback is that using absolute paths prevent a # configured tree to be moved without reconfiguration. AC_DEFUN([AM_AUX_DIR_EXPAND], [AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl # Expand $ac_aux_dir to an absolute path. am_aux_dir=`cd "$ac_aux_dir" && pwd` ]) # AM_COND_IF -*- Autoconf -*- # Copyright (C) 2008-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_COND_IF # _AM_COND_ELSE # _AM_COND_ENDIF # -------------- # These macros are only used for tracing. m4_define([_AM_COND_IF]) m4_define([_AM_COND_ELSE]) m4_define([_AM_COND_ENDIF]) # AM_COND_IF(COND, [IF-TRUE], [IF-FALSE]) # --------------------------------------- # If the shell condition COND is true, execute IF-TRUE, otherwise execute # IF-FALSE. Allow automake to learn about conditional instantiating macros # (the AC_CONFIG_FOOS). AC_DEFUN([AM_COND_IF], [m4_ifndef([_AM_COND_VALUE_$1], [m4_fatal([$0: no such condition "$1"])])dnl _AM_COND_IF([$1])dnl if test -z "$$1_TRUE"; then : m4_n([$2])[]dnl m4_ifval([$3], [_AM_COND_ELSE([$1])dnl else $3 ])dnl _AM_COND_ENDIF([$1])dnl fi[]dnl ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright (C) 1997-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [AC_PREREQ([2.52])dnl m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE])dnl AC_SUBST([$1_FALSE])dnl _AM_SUBST_NOTMAKE([$1_TRUE])dnl _AM_SUBST_NOTMAKE([$1_FALSE])dnl m4_define([_AM_COND_VALUE_$1], [$2])dnl if $2; then $1_TRUE= $1_FALSE='#' else $1_TRUE='#' $1_FALSE= fi AC_CONFIG_COMMANDS_PRE( [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then AC_MSG_ERROR([[conditional "$1" was never defined. Usually this means the macro was only invoked conditionally.]]) fi])]) # Do all the work for Automake. -*- Autoconf -*- # Copyright (C) 1996-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC]) [_AM_PROG_CC_C_O ]) # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- # The call with PACKAGE and VERSION arguments is the old style # call (pre autoconf-2.50), which is being phased out. PACKAGE # and VERSION should now be passed to AC_INIT and removed from # the call to AM_INIT_AUTOMAKE. # We support both call styles for the transition. After # the next Automake release, Autoconf can make the AC_INIT # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], [AC_PREREQ([2.65])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl # test to see if srcdir already configured if test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [AC_DIAGNOSE([obsolete], [$0: two- and three-arguments forms are deprecated.]) m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. m4_if( m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), [ok:ok],, [m4_fatal([AC_INIT should be called with package and version arguments])])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, [AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) AM_MISSING_PROG([AUTOCONF], [autoconf]) AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) AM_MISSING_PROG([AUTOHEADER], [autoheader]) AM_MISSING_PROG([MAKEINFO], [makeinfo]) AC_REQUIRE([AM_PROG_INSTALL_SH])dnl AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # AC_SUBST([mkdir_p], ['$(MKDIR_P)']) # We need awk for the "check" target (and possibly the TAP driver). The # system "awk" is bad on some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES([CC])], [m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES([CXX])], [m4_define([AC_PROG_CXX], m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], [_AM_DEPENDENCIES([OBJC])], [m4_define([AC_PROG_OBJC], m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], [_AM_DEPENDENCIES([OBJCXX])], [m4_define([AC_PROG_OBJCXX], m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl ]) AC_REQUIRE([AM_SILENT_RULES])dnl dnl The testsuite driver may need to know about EXEEXT, so add the dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl # POSIX will say in a future version that running "rm -f" with no argument # is OK; and we want to be able to make that assumption in our Makefile # recipes. So use an aggressive probe to check that the usage we want is # actually supported "in the wild" to an acceptable degree. # See automake bug#10828. # To make any issue more visible, cause the running configure to be aborted # by default if the 'rm' program in use doesn't match our expectations; the # user can still override this though. if rm -f && rm -fr && rm -rf; then : OK; else cat >&2 <<'END' Oops! Your 'rm' program seems unable to run without file operands specified on the command line, even when the '-f' option is present. This is contrary to the behaviour of most rm programs out there, and not conforming with the upcoming POSIX standard: Please tell bug-automake@gnu.org about your system, including the value of your $PATH and any error possibly output before this message. This can help us improve future automake versions. END if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then echo 'Configuration will proceed anyway, since you have set the' >&2 echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 echo >&2 else cat >&2 <<'END' Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM to "yes", and re-run configure. END AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) fi fi dnl The trailing newline in this macro's definition is deliberate, for dnl backward compatibility and to allow trailing 'dnl'-style comments dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841. ]) dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further dnl mangled by Autoconf and run in a shell conditional statement. m4_define([_AC_COMPILER_EXEEXT], m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. # Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the # loop where config.status creates the headers, so we can generate # our stamp files there. AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. _am_arg=$1 _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) # Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl if test x"${install_sh+set}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi AC_SUBST([install_sh])]) # Copyright (C) 2003-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], [rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) # Add --enable-maintainer-mode option to configure. -*- Autoconf -*- # From Jim Meyering # Copyright (C) 1996-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MAINTAINER_MODE([DEFAULT-MODE]) # ---------------------------------- # Control maintainer-specific portions of Makefiles. # Default is to disable them, unless 'enable' is passed literally. # For symmetry, 'disable' may be passed as well. Anyway, the user # can override the default with the --enable/--disable switch. AC_DEFUN([AM_MAINTAINER_MODE], [m4_case(m4_default([$1], [disable]), [enable], [m4_define([am_maintainer_other], [disable])], [disable], [m4_define([am_maintainer_other], [enable])], [m4_define([am_maintainer_other], [enable]) m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])]) AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) dnl maintainer-mode's default is 'disable' unless 'enable' is passed AC_ARG_ENABLE([maintainer-mode], [AS_HELP_STRING([--]am_maintainer_other[-maintainer-mode], am_maintainer_other[ make rules and dependencies not useful (and sometimes confusing) to the casual installer])], [USE_MAINTAINER_MODE=$enableval], [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes])) AC_MSG_RESULT([$USE_MAINTAINER_MODE]) AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes]) MAINT=$MAINTAINER_MODE_TRUE AC_SUBST([MAINT])dnl ] ) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- # Copyright (C) 1997-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) # AM_MISSING_HAS_RUN # ------------------ # Define MISSING if not defined so far and test if it is modern enough. # If it is, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= AC_MSG_WARN(['missing' script is too old or missing]) fi ]) # Helper functions for option handling. -*- Autoconf -*- # Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) # _AM_SET_OPTION(NAME) # -------------------- # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), [1])]) # _AM_SET_OPTIONS(OPTIONS) # ------------------------ # OPTIONS is a space-separated list of Automake options. AC_DEFUN([_AM_SET_OPTIONS], [m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) # _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) # ------------------------------------------- # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) # Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_RUN_LOG(COMMAND) # ------------------- # Run COMMAND, save the exit status in ac_status, and log it. # (This has been adapted from Autoconf's _AC_RUN_LOG macro.) AC_DEFUN([AM_RUN_LOG], [{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD (exit $ac_status); }]) # Check to make sure that the build environment is sane. -*- Autoconf -*- # Copyright (C) 1996-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[[\\\"\#\$\&\'\`$am_lf]]*) AC_MSG_ERROR([unsafe absolute working directory name]);; esac case $srcdir in *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$[*]" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$[*]" != "X $srcdir/configure conftest.file" \ && test "$[*]" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken alias in your environment]) fi if test "$[2]" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$[2]" = conftest.file ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi AC_MSG_RESULT([yes]) # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi AC_CONFIG_COMMANDS_PRE( [AC_MSG_CHECKING([that generated files are newer than configure]) if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi AC_MSG_RESULT([done])]) rm -f conftest.file ]) # Copyright (C) 2009-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_SILENT_RULES([DEFAULT]) # -------------------------- # Enable less verbose build rules; with the default set to DEFAULT # ("yes" being less verbose, "no" or empty being verbose). AC_DEFUN([AM_SILENT_RULES], [AC_ARG_ENABLE([silent-rules], [dnl AS_HELP_STRING( [--enable-silent-rules], [less verbose build output (undo: "make V=1")]) AS_HELP_STRING( [--disable-silent-rules], [verbose build output (undo: "make V=0")])dnl ]) case $enable_silent_rules in @%:@ ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; esac dnl dnl A few 'make' implementations (e.g., NonStop OS and NextStep) dnl do not support nested variable expansions. dnl See automake bug#9928 and bug#10237. am_make=${MAKE-make} AC_CACHE_CHECK([whether $am_make supports nested variables], [am_cv_make_support_nested_variables], [if AS_ECHO([['TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi]) if test $am_cv_make_support_nested_variables = yes; then dnl Using '$V' instead of '$(V)' breaks IRIX make. AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AC_SUBST([AM_V])dnl AM_SUBST_NOTMAKE([AM_V])dnl AC_SUBST([AM_DEFAULT_V])dnl AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl AC_SUBST([AM_DEFAULT_VERBOSITY])dnl AM_BACKSLASH='\' AC_SUBST([AM_BACKSLASH])dnl _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) # Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_STRIP # --------------------- # One issue with vendor 'install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we # always use install-sh in "make install-strip", and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) # Copyright (C) 2006-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. # This macro is traced by Automake. AC_DEFUN([_AM_SUBST_NOTMAKE]) # AM_SUBST_NOTMAKE(VARIABLE) # -------------------------- # Public sister of _AM_SUBST_NOTMAKE. AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) m4_include([m4/adl_recursive_eval.m4]) m4_include([m4/tar.m4]) cfengine-masterfiles-3.27.3/PaxHeaders/cfe_internal0000644000000000000000000000003515266337437017354 xustar0029 mtime=1792655135.13379644 cfengine-masterfiles-3.27.3/cfe_internal/0000755000000000000000000000000015266337437016537 5ustar0000000000000000cfengine-masterfiles-3.27.3/cfe_internal/CFE_cfengine.cf0000644000000000000000000000510714735102600021265 0ustar0000000000000000################################################################## # # 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 common cfe_internal_management_file_control # @brief Define policy input dependancies { vars: "inputs" slist => {}; cfengine_recommendations_enabled:: "input[cfengine_recommendations]" string => "$(this.promise_dirname)/recommendations.cf"; any:: "inputs" slist => getvalues(input); } body file control # @brief Include policy input dependancies { cfengine_recommendations_enabled:: inputs => { @(cfe_internal_management_file_control.inputs) }; } bundle agent cfe_internal_management # @brief Actuate the appropriate set(s) of internal management policies { vars: any:: "policy[cfe_internal_core_main]" string => "cfe_internal_core_main", comment => "Activate policies related to basic CFEngine operations"; enterprise_edition:: "policy[cfe_internal_enterprise_main]" string => "cfe_internal_enterprise_main", comment => "Activate policies related to CFEngine Enterprise operations"; # TODO: Scope this more tightly to mission portal role enterprise_edition.policy_server:: "policy[cfe_internal_enterprise_mission_portal]" string => "Activate policies related to CFEngine Enterprise Mission Portal"; any:: "bundles" slist => getindices(policy); "recommendation_bundles" slist => sort(bundlesmatching(".*", "cfengine_recommends"), lex); methods: # CFEngine internals "CFEngine_Internals" usebundle => "$(bundles)"; "CFEngine Recommendations" usebundle => $(recommendation_bundles), if => isvariable(recommendation_bundles); reports: DEBUG|DEBUG_cfe_internal_management:: "DEBUG $(this.bundle): Should actuate $(bundles)"; cfengine_recommendation_instruct_disablement:: "Note: All recommendations can be disabled by defining 'default:cfengine_recommendations_disabled'"; } cfengine-masterfiles-3.27.3/cfe_internal/PaxHeaders/core0000644000000000000000000000003615266337437020305 xustar0030 mtime=1792655135.121796035 cfengine-masterfiles-3.27.3/cfe_internal/core/0000755000000000000000000000000015266337437017467 5ustar0000000000000000cfengine-masterfiles-3.27.3/cfe_internal/core/PaxHeaders/deprecated0000644000000000000000000000003615266337437022405 xustar0030 mtime=1792655135.121796035 cfengine-masterfiles-3.27.3/cfe_internal/core/deprecated/0000755000000000000000000000000015266337437021567 5ustar0000000000000000cfengine-masterfiles-3.27.3/cfe_internal/core/deprecated/cfengine_processes.cf0000644000000000000000000001404414735102600025726 0ustar0000000000000000################################################################## # # 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 $(sys.workdir)/lib ] && /sbin/ldconfig -m $(sys.workdir)/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; } cfengine-masterfiles-3.27.3/cfe_internal/core/host_info_report.cf0000644000000000000000000001344314735102600023347 0ustar0000000000000000bundle 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("packages[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_inventory # @brief Collect information about policy { vars: @if minimum_version(3.10) "inventory_vars" data => variablesmatching_as_data(".*", "inventory"); @endif } 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)'"; } cfengine-masterfiles-3.27.3/cfe_internal/core/limit_robot_agents.cf0000644000000000000000000000744214735102600023652 0ustar0000000000000000############################################################################### # # cfe_internal_limit_robot_agents # - Kill and restart CFE processes for a given component if there are too many # ############################################################################### bundle agent cfe_internal_limit_robot_agents # @brief Remediate pathological case of duplicate cfengine daemons running concurrently { methods: any:: "Ensure there are not more than expected cfengine daemons" -> { "CFE-3150" } usebundle => "cfe_internal_limit_robot_agents_reap"; more_cf_execd_processes_than_expected|more_cf_monitord_process_than_expected:: # We only look to re-launch daemons if we found a pathological case. It's # important that these promises are in a separate bundle as we want to # refresh our observation of the process table to ensure they are indeed # not running. "Ensure expected cfengine daemons are running" -> { "CFE-3150" } usebundle => "cfe_internal_limit_robot_agents_spawn"; } bundle agent cfe_internal_limit_robot_agents_reap # @brief Ensure that there are not more cfengine daemons running than there should be { processes: !windows:: "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-execd because it forks child processes to handle requests. # Do not do this for cf-hub because cf-hub may have unlimited processes # Do not do this for cf-agent because it is not unexpected to have # concurrent agent runs, and the lifetime of an individual agent run can be controlled with # [agent_expireafter][cf-execd#agent_expireafter] as defined in body executor control more_cf_monitord_processes_than_expected:: "bin/cf-monitord" signals => { "term", "kill" }, comment => "When cf-monitord comes undone then kill all matching process", handle => "cfe_internal_limit_robot_agents_processes_kill_cf_monitord"; } bundle agent cfe_internal_limit_robot_agents_spawn # @brief Ensure that daemons are running after we have possibly reaped a pathological condition where more than the expected number of cfengine daemons was running { processes: !windows:: "bin/cf-execd" -> { "CFE-2974" } restart_class => "cf_execd_not_running", comment => "If cf-execd isn't running, define a class so that it will be started", handle => "cfe_internal_limit_robot_agents_processes_cf_execd_not_running"; "bin/cf-monitord" -> { "CFE-2963" } restart_class => "cf_monitord_not_running", handle => "cfe_internal_limit_robot_agents_classify_cf_monitord_not_running", comment => "We want cf-monitord to be running, but in order to avoid non-convergent promises, this must be separated from the promise to terminate misbehaving daemons"; commands: cf_execd_not_running:: "$(sys.cf_execd)" comment => "Restart cf-execd process", handle => "cfe_internal_limit_robot_agents_commands_restart_cf_execd"; cf_monitord_not_running:: "$(sys.cf_monitord)" comment => "Restart cf-monitord process", handle => "cfe_internal_limit_robot_agents_commands_restart_cf_monitord"; } body process_count check_execd(n) { match_range => "0,$(n)"; # Note this class is namespace scoped. Other bundles do use it out_of_range_define => { "more_cf_execd_processes_than_expected" }; } body process_count check_monitord(n) { match_range => "0,$(n)"; # Note this class is namespace scoped. Other bundles do use it out_of_range_define => { "more_cf_monitord_processes_than_expected" }; } cfengine-masterfiles-3.27.3/cfe_internal/core/log_rotation.cf0000644000000000000000000000361614735102600022465 0ustar0000000000000000################################################################## # # cfe_internal_log_rotation # - Rotate logs and clean up old files so the disk doesn't get full # ################################################################## bundle agent cfe_internal_log_rotation # @brief Manage CFEngine log files so they don't 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 CFEngine log files" handle => "cfe_internal_log_rotation_rotate_log_files", usebundle => logrotate( @(def.cfe_log_files), $(def.mpf_log_file_max_size), $(def.mpf_log_file_retention) ), comment => "To keep the disk from getting to full we want to rotate log files when they reach $(def.mpf_log_file_max_size) in size. So that we have some history , we keep $(def.mpf_log_file_retention) versions."; "Prune old log files" handle => "cfe_internal_log_rotation_prune_log_dirs", usebundle => prunedir( @(def.cfe_log_dirs), $(def.mpf_log_dir_retention) ), comment => "Scheduled activities like agent runs and reports can create log files or reports that stack up over time. So that we don't fill the disk, but have some historical information available locally we purge log files older than $(def.mpf_log_dir_retention) days."; reports: DEBUG|DEBUG_cfe_internal_log_rotation:: "DEBUG $(this.bundle): Check CFEngine log file for rotation '$(def.cfe_log_files)'"; "DEBUG $(this.bundle): Check CFEngine log directory for old logs in '$(def.cfe_log_dirs)' older than '$(def.mpf_log_dir_retention)' days"; } cfengine-masterfiles-3.27.3/cfe_internal/core/main.cf0000644000000000000000000001526014735102600020707 0ustar0000000000000000bundle agent cfe_internal_core_main { methods: !mpf_auto_am_policy_hub_state_disabled:: "Verify policy hub state" -> { "CFE-3073" } usebundle => mpf_auto_am_policy_hub_state, if => not(fileexists("$(sys.statedir)/am_policy_hub")); any:: # NB! On a container host this may kill CFEngine processes inside containers. # See https://dev.cfengine.com/issues/6906 !mpf_disable_cfe_internal_limit_robot_agents:: "Limit concurrent agents" -> { "CFE-1799" } usebundle => cfe_internal_limit_robot_agents, handle => "cfe_internal_management_limit_cfe_agents", comment => "Manage CFE processes"; any:: "any" usebundle => cfe_internal_log_rotation, handle => "cfe_internal_management_log_rotation", comment => "Rotate CFEngine logs so we don't fill the disk"; cfe_internal_core_watchdog_disabled:: "Disable Core Watchdog" usebundle => cfe_internal_core_watchdog("disabled"); cfe_internal_core_watchdog_enabled:: "Enable Core Watchdog" usebundle => cfe_internal_core_watchdog("enabled"); mpf_augments_control_enabled:: "mpf_augments_control" usebundle => mpf_augments_control; } bundle agent mpf_auto_am_policy_hub_state # @brief Ensure that `$(sys.statedir)/am_policy_hub` file is present when expected { files: # We think we are a policy hub if the policy server (the host you # bootstrapped to) resolves to an IP found on the host. This is intended # to prevent accidental removal of the am_policy_hub state file. "$(sys.statedir)/am_policy_hub" create => "true", if => some(escape($(sys.policy_server)), @(sys.ipaddresses)); } bundle agent mpf_augments_control # @brief Restart cfenigne components when one of the control variables has changed. # # While the agent itsef will reload its config upon notice of policy change # this bundle specifically handles changes to variables used in the MPF which may # come from external data sources which are unknown to the components themselves. { @if minimum_version(3.10) # This policy leverages variablesmatching_as_data() (available since # 3.10.0) and the -top- mustache extension (available since 3.9.0). vars: # Variables and their data which might necessitate a component restart "server_controls" data => variablesmatching_as_data("default:def.control_server_.*"); "executor_controls" data => variablesmatching_as_data("default:def.control_executor_.*"); "monitor_controls" data => variablesmatching_as_data("default:def.control_monitor_.*"); "hub_controls" data => variablesmatching_as_data("default:def.control_hub_.*"); "runagent_controls" data => variablesmatching_as_data("default:def.control_runagent_.*"); "common_controls" data => variablesmatching_as_data("default:def.control_common_.*"); "agent_controls" data => variablesmatching_as_data("default:def.control_agent_.*"); # Serialized data for tracking state "server_controls_state" string => string_mustache("{{$-top-}}", server_controls); "executor_controls_state" string => string_mustache("{{$-top-}}", executor_controls); "monitor_controls_state" string => string_mustache("{{$-top-}}", monitor_controls); "hub_controls_state" string => string_mustache("{{$-top-}}", hub_controls); "runagent_controls_state" string => string_mustache("{{$-top-}}", runagent_controls); "common_controls_state" string => string_mustache("{{$-top-}}", common_controls); "agent_controls_state" string => string_mustache("{{$-top-}}", agent_controls); files: "$(sys.workdir)$(const.dirsep)state$(const.dirsep)mpf_hub_controls" create => "true", edit_line => insert_lines($(hub_controls_state)), edit_defaults => empty, classes => results("bundle", "hub_controls"); "$(sys.workdir)$(const.dirsep)state$(const.dirsep)mpf_server_controls" create => "true", edit_line => insert_lines($(server_controls_state)), edit_defaults => empty, classes => results("bundle", "server_controls"); "$(sys.workdir)$(const.dirsep)state$(const.dirsep)mpf_monitor_controls" create => "true", edit_line => insert_lines($(monitor_controls_state)), edit_defaults => empty, classes => results("bundle", "monitor_controls"); "$(sys.workdir)$(const.dirsep)state$(const.dirsep)mpf_executor_controls" create => "true", edit_line => insert_lines($(executor_controls_state)), edit_defaults => empty, classes => results("bundle", "executor_controls"); "$(sys.workdir)$(const.dirsep)state$(const.dirsep)mpf_runagent_controls" create => "true", edit_line => insert_lines($(runagent_controls_state)), edit_defaults => empty, classes => results("bundle", "runagent_controls"); # Note a change in common controls is not expected to trigger any # component restart, its simply tracked for completeness. "$(sys.workdir)$(const.dirsep)state$(const.dirsep)mpf_common_controls" create => "true", edit_line => insert_lines($(common_controls_state)), edit_defaults => empty, classes => results("bundle", "common_controls"); # No need to restart cf-agent it as its not long running. We simply track the details for completeness. "$(sys.workdir)$(const.dirsep)state$(const.dirsep)mpf_agent_controls" create => "true", edit_line => insert_lines($(agent_controls_state)), edit_defaults => empty, classes => results("bundle", "agent_controls"); services: systemd:: "cf-serverd" service_policy => "restart", if => "(server_controls_repaired|runagent_controls_repaired)"; "cf-monitord" service_policy => "restart", if => "monitor_controls_repaired"; systemd.enterprise_edition.(am_policy_hub|policy_server):: "cf-hub" service_policy => "restart", if => "hub_controls_repaired"; # Well, this is dangerous we might kill our own agent # "cf-execd" # service_policy => "restart", # if => "(execd_controls_repaired|runagent_controls_repaired)"; processes: !systemd:: "cf-serverd" signals => { "term" }, if => "(server_controls_repaired|runagent_controls_repaired)"; "cf-monitord" signals => { "term" }, if => "monitor_controls_repaired"; systemd.enterprise_edition.(am_policy_hub|policy_server):: "cf-hub" signals => { "term" }, if => "hub_controls_repaired"; # Well, this is dangerous we might kill our own agent # "cf-execd" # signals => { "term" }, # if => "(execd_controls_repaired|runagent_controls_repaired)"; @endif } cfengine-masterfiles-3.27.3/cfe_internal/core/PaxHeaders/watchdog0000644000000000000000000000003615266337437022105 xustar0030 mtime=1792655135.121796035 cfengine-masterfiles-3.27.3/cfe_internal/core/watchdog/0000755000000000000000000000000015266337437021267 5ustar0000000000000000cfengine-masterfiles-3.27.3/cfe_internal/core/watchdog/PaxHeaders/templates0000644000000000000000000000003615266337437024103 xustar0030 mtime=1792655135.213799139 cfengine-masterfiles-3.27.3/cfe_internal/core/watchdog/templates/0000755000000000000000000000000015266337437023265 5ustar0000000000000000cfengine-masterfiles-3.27.3/cfe_internal/core/watchdog/templates/watchdog-windows.ps1.mustache0000644000000000000000000000344514735102600030776 0ustar0000000000000000$LOGFILE="{{{logfile}}}" $long_running_cf_agent_threshold_min = 5 $long_running_cf_agent_count = @(Get-Process cf-agent -erroraction "silentlycontinue" | Where { $_.StartTime -lt (Get-Date).AddMinutes(-$long_running_cf_agent_threshold_min) }).count $long_running_cf_agent_count_threshold = 1 If ($long_running_cf_agent_count -ge $long_running_cf_agent_count_threshold) { $DATESTAMP=Get-Date -Format "yyyy-MM-dd HH:mm" Write-Output "${DATESTAMP}: Count of long running cf-agent ($long_running_cf_agent_count) has met the threshold ($long_running_cf_agent_count_threshold) of long running agents, remediation triggered." | Tee-Object -FilePath "$LOGFILE" -Append Write-Output "${DATESTAMP}: Before remediation" | Tee-Object -FilePath "$LOGFILE" -Append Get-Process cf-agent -erroraction "silentlycontinue" | ft -erroraction "silentlycontinue" Name,CommandLine,StartTime,@{label="Elapsed Minutes";expression={[System.Math]::Round(((Get-Date)-$_.StartTime).totalminutes)}} | Tee-Object -FilePath "$LOGFILE" -Append Get-Process cf-agent -erroraction "silentlycontinue" | Where { $_.StartTime -lt (Get-Date).AddMinutes(-$long_running_cf_agent_threshold_min) } | Stop-Process -Force # Give the system a bit of time to kill all the processes sleep 1 $DATESTAMP=Get-Date -Format "yyyy-MM-dd HH:mm" $running_cf_agent_count = @(Get-Process cf-agent -erroraction "silentlycontinue").count Write-Output "${DATESTAMP}: Observed $running_cf_agent_count cf-agent processes after remediation" | Tee-Object -FilePath "$LOGFILE" -Append Get-Process cf-agent -erroraction "silentlycontinue" | ft -erroraction "silentlycontinue" Name,CommandLine,StartTime,@{label="Elapsed Minutes";expression={[System.Math]::Round(((Get-Date)-$_.StartTime).totalminutes)}} | Tee-Object -FilePath "$LOGFILE" -Append } cfengine-masterfiles-3.27.3/cfe_internal/core/watchdog/templates/watchdog.mustache0000644000000000000000000003610414735102600026602 0ustar0000000000000000#!/usr/bin/sh # Watchdog events are logged here. PIDFILE="/var/cfengine/watchdog.pid" trap cleanup SIGHUP SIGINT SIGQUIT SIGABRT SIGTERM cleanup() { # Don't leave behind junk if the script is killed if [ -d "${COLLECTION_DIR}" ]; then rm -rf "${COLLECTION_DIR}" fi } all_cfengine_daemons_running() { /etc/rc.d/init.d/cfengine3 restart > ${COLLECTION_DIR}/etc_rc_d_init_d_cfengine3_restart.$(date +%s).log 2>&1 sleep 3 # Log if any expected daemon is not running if [ $(ps -ef -o args | grep -c ^\/var\/cfengine\/bin\/[c]f-execd) -lt 1 ]; then echo "- *cf-execd is not running after service restart*" >> ${COLLECTION_REPORT} echo "$(date) cf-execd is not running after service restart" | tee -a ${LOGFILE} fi if [ $(ps -ef -o args | grep -c ^\/var\/cfengine\/bin\/[c]f-serverd) -lt 1 ]; then echo "- *cf-serverd is not running after service restart*" >> ${COLLECTION_REPORT} echo "$(date) cf-serverd is not running after service restart" | tee -a ${LOGFILE} fi if [ $(ps -ef -o args | grep -c ^\/var\/cfengine\/bin\/[c]f-monitord) -lt 1 ]; then echo "- *cf-monitord is not running after service restart*" >> ${COLLECTION_REPORT} echo "$(date) cf-monitord is not running after service restart" | tee -a ${LOGFILE} fi if [ $(ps -ef -o args | grep -c ^\/var\/cfengine\/bin\/[c]f-) -lt 1 ]; then echo "- *No cf- processes running after service restart*" >> ${COLLECTION_REPORT} echo "$(date) No cf- processes running after service restart" | tee -a ${LOGFILE} fi for each in execd serverd monitord; do if [ $(ps -ef -o args | grep -c ^\/var\/cfengine\/bin\/[c]f-${each}) -lt 1 ]; then /etc/rc.d/init.d/cfengine3 stop > ${COLLECTION_DIR}/etc_rc_d_init_d_cfengine3_stop.$(date +%s).log 2>&1 return 1 fi done return 0 } LOGFILE="/var/cfengine/watchdog.log" echo "$(date) Initiating watchdog $$" >> ${LOGFILE} if [ -s $PIDFILE ]; then # We have a pidfile if ps -p $(cat $PIDFILE) > /dev/null 2>&1 ; then # There is a process with the PID in the file, but is it stale? if [ -d /proc ]; then # We can know for sure if it's stale actual_process="/proc/$(cat "$PIDFILE")" newer="$(ls -1dt "$PIDFILE" "$actual_process" | head -n 1)" if [ "$actual_process" = "$newer" ]; then # Pidfile is stale, ignore it echo $$ > $PIDFILE else # Pidfile is definitely correct echo "$(date) Aborting execution of watchdog $$, existing watchdog process $(cat $PIDFILE) running" >> ${LOGFILE} exit 1 fi else # No /proc, pidfile shows a running process, we'll assume it's valid echo "$(date) Aborting execution of watchdog $$, existing watchdog process $(cat $PIDFILE) running" >> ${LOGFILE} exit 1 fi else # No current process matching pid in file echo $$ > $PIDFILE fi else # No pidfile at all echo $$ > $PIDFILE fi TMPDIR="/tmp" mkdir -p $TMPDIR CFENGINE_WORKDIR="/var/cfengine" CFENGINE_WORKDIR_COLLECTION="" OUTPUTS_DIR="${CFENGINE_WORKDIR}/outputs" ARCHIVE_DIR="/var/cfengine/watchdog-archives" mkdir -p "${ARCHIVE_DIR}" PATHOLOGY_COUNT=0 PATHOLOGY_THRESHOLD=0 # Collection Dir # - We create a directory in order to collect artifacts about our observations # - If there are enough pathology indicators found to warrant a report, the # directory will be packaged for sending # Portable mktemp: https://stackoverflow.com/questions/10224921/how-to-create-a-temporary-file-with-portable-shell-in-a-secure-way#comment86787877_10235393 # Adjusted, known to work on aix 7.1.0.0 if [ -r "/dev/urandom" ]; then RNDM="/dev/urandom" else RNDM="/dev/random" fi length=7; safetemp=$(od -An -N${length} -tx1 ${RNDM} | tr -d ' \t').cfengine-watchdog COLLECTION_DIR="${TMPDIR}/${safetemp}" mkdir -p "${COLLECTION_DIR}" COLLECTION_REPORT="${COLLECTION_DIR}/README.org" echo "#+Title: CFEngine Watchdog Engineering Summary [$(date '+%Y-%m-%d %a')]" >> ${COLLECTION_REPORT} echo "* Pathologies" >> ${COLLECTION_REPORT} ARCHIVE_DIR_FREEk=$(df -k ${ARCHIVE_DIR} | tail -n 1 | awk '{print $3}') if [ "${ARCHIVE_DIR_FREEk}" -lt 500000 ]; then echo "$(date) ${ARCHIVE_DIR} has less than 500MB free space, initiating watchdog archive cleanup" | tee -a ${LOGFILE} # Archive dir has less than 500MB, cleanup leaving oldest and newest archives files=$(ls ${ARCHIVE_DIR}) count=$(echo $files | wc -w) _counter=0 for i in $files; do if [ "${_counter}" -eq 0 ]; then echo "Not deleting $i it's the oldest and may contain valuable information about the first event" elif [ "${_counter}" -eq "$(( $count - 1))" ]; then echo "Not deleting $i it's the most recent" else echo "Delete $i" rm "${ARCHIVE_DIR}/$i" fi _counter=$((1 + ${_counter})) done ARCHIVE_DIR_FREEk=$(df -k ${ARCHIVE_DIR} | tail -n 1 | awk '{print $3}') if [ "${ARCHIVE_DIR_FREEk}" -lt 500000 ]; then echo "$(date) ${ARCHIVE_DIR} still has less than 500MB free space after cleaning up archives." | tee -a ${LOGFILE} echo "$(date) Aborting watchdog $$" | tee -a ${LOGFILE} cleanup exit 1 fi fi # We check free space in tmp second (in case tmp is on same filesystem as archives, and archives get cleaned up) TMPDIR_FREEk=$(df -k ${TMPDIR} | tail -n 1 | awk '{print $3}') if [ "${TMPDIR_FREEk}" -lt 500000 ]; then echo "$(date) ${TMPDIR} has less than 500MB free space" | tee -a ${LOGFILE} echo "$(date) Aborting watchdog $$" | tee -a ${LOGFILE} cleanup exit 1 fi # Pathology #1: cf-execd is not running. # While not strictly a pathology, it is non-standard to run cf-agent without cf-execd. ps -ef -o args | grep ^\/var\/cfengine\/bin\/[c]f-execd > "${COLLECTION_DIR}/ps_grep_cf-execd.txt" _COUNT_CF_EXECD_PROCS="$(cat ${COLLECTION_DIR}/ps_grep_cf-execd.txt | wc -l)" if [ "${_COUNT_CF_EXECD_PROCS}" -lt "1" ]; then echo "$(date) Found cf-execd not running" >> ${LOGFILE} echo "- cf-execd not running" >> ${COLLECTION_REPORT} PATHOLOGY_COUNT=$((${PATHOLOGY_COUNT}+1)) fi # Pathology #1.5: More than one cf-execd is running. /var/cfengine/bin/cf-promises --show-vars=default:sys.cf > "${COLLECTION_DIR}/cf-promises_--show-vars=default:sys.cf.txt" CF_VERSION_MINOR_RUNNING="$(awk '/cf_version_minor / {print $2}' ${COLLECTION_DIR}/cf-promises_--show-vars=default:sys.cf.txt)" # At 3.18.0 cf-execd began running cf-agent from a child process instead of a thread on POSIX systems (ENT-6182) _COUNT_CF_EXECD_PROCS_THRESHOLD=1 if [ "${CF_VERSION_MINOR_RUNNING}" -ge "18" ]; then _COUNT_CF_EXECD_PROCS_THRESHOLD=2 fi if [ "${_COUNT_CF_EXECD_PROCS}" -gt "${_COUNT_CF_EXECD_PROCS_THRESHOLD}" ]; then echo "$(date) Found ${_COUNT_CF_EXECD_PROCS} cf-execd processes running" >> ${LOGFILE} echo "- Found ${_COUNT_CF_EXECD_PROCS} cf-execd running" >> ${COLLECTION_REPORT} PATHOLOGY_COUNT=$((${PATHOLOGY_COUNT}+1)) fi # Pathology #2: cf-agent execution times exceed body executor control agent_expireafter # cf-agent processes launched by cf-execd have not communicated back to cf-execd # within $(agent_expireafter). This may be OK, but may also indicate that # cf-agent is hung. # Outputs could be empty because: # - cf-execd hasn't executed cf-agent since purging outputs # - cf-agent is not producing output (the expected normal state) if [ "$(ls -A ${OUTPUTS_DIR})" ]; then observation=$(find "${OUTPUTS_DIR}" ! -name previous | xargs grep "cf-execd: timeout waiting for output from agent") if [ -n "$observation" ]; then count=$(expr 0 + $(echo -n "${observation}" | wc -l)) echo "$(date) Found ${count} occurrences of cf-execd terminating unresponsive cf-agent" >> ${LOGFILE} echo "- ${count} cf-agent terminations" >> ${COLLECTION_REPORT} PATHOLOGY_COUNT=$((${PATHOLOGY_COUNT}+1)) fi fi # Pathology #3: cf-agent process(s) running longer than expected # While not strictly a pathology, this may indicate a hung agent # On AIX, etime (and etimes) is displayed in human readable form # e.g: # USER PID ELAPSED COMMAND # root 10551366 5-00:35:58 /var/cfengine/bin/cf-agent # We have to convert that into seconds so that we can determine if it's been # running longer than we expect, that's what the second awk command is for. observation=$(ps -e -o user,pid,etime,args | awk 'FNR == 1 {next} /\/var\/cfengine\/bin\/cf-agent/ {print $3}' | awk 'BEGIN { FS = ":" } \ { if (NF == 2) { etimes = $1*60 + $2 } else if (NF == 3) { split($1, a, "-"); if (a[2] != "" ) { etimes = ((a[1]*24+a[2])*60 + $2) * 60 + $3; } else { etimes = ($1*60 + $2) * 60 + $3; } } if (etimes > 300) { print } }') if [ ${#observation} -gt 0 ]; then count=$(expr 1 + $(echo -n "${observation}" | wc -l)) echo "$(date) Found ${count} cf-agent processes running longer than 300s" >> ${LOGFILE} echo "- ${count} cf-agent processes running longer than 300s" >> ${COLLECTION_REPORT} PATHOLOGY_COUNT=$((${PATHOLOGY_COUNT}+1)) fi # Pathology #4: High number of concurrent cf-agent processes # While cf-agent is designed to be able to run concurrently, having many # concurrent cf-agent processes may indicate an an issue like an agent pile up observation=$(ps -e -o pid,etime,args | awk '/\/var\/cfengine\/bin\/cf-agent/ {print}') if [ ${#observation} -gt 0 ]; then count=$(expr 1 + $(echo -n "${observation}" | wc -l)) if [ ${count} -gt 3 ]; then echo "$(date) Found ${count} concurrently running agents" >> ${LOGFILE} echo "- ${count} concurrently running cf-agent processes" >> ${COLLECTION_REPORT} PATHOLOGY_COUNT=$((${PATHOLOGY_COUNT}+1)) fi fi # Pathology #5: cf-check has encountered a critical issue # This indicates that there are one or more integrity issues if [ -x /var/cfengine/bin/cf-check ]; then observation=$(/var/cfengine/bin/cf-check diagnose /var/cfengine/state/*.lmdb) if [ $? -ne 0 ]; then echo "$(date) cf-check observed critical integrity issues" >> ${LOGFILE} echo "- cf-check observed critical integrity issues" >> ${COLLECTION_REPORT} echo " #+begin_example\n${observation}\n#+end_example" >> ${COLLECTION_REPORT} fi fi if [ "${PATHOLOGY_COUNT}" -gt "${PATHOLOGY_THRESHOLD}" ]; then echo "$(date) Found ${PATHOLOGY_COUNT} symptoms, threshold (${PATHOLOGY_THRESHOLD}) breached." | tee -a ${LOGFILE} echo "* Observations" >> ${COLLECTION_REPORT} ps auxwww > "${COLLECTION_DIR}/ps_auxwww.txt" echo "- [[./ps_auxwww.txt][~ps auxwww~]]" >> ${COLLECTION_REPORT} ps -elf > "${COLLECTION_DIR}/ps_-elf.txt" echo "- [[./ps_-elf.txt][~ps -elf~]]" >> ${COLLECTION_REPORT} find "${CFENGINE_WORKDIR}" >> "${COLLECTION_DIR}/find__var_cfengine.txt" echo "- [[./find__var_cfengine.txt][=/var/cfengine= file list]] - Before remediation" >> ${COLLECTION_REPORT} tar -c -f "${COLLECTION_DIR}/sys.workdir-before-remediation.tar" -C "${CFENGINE_WORKDIR}" state outputs echo "- [[./sys.workdir-before-remediation.tar][=sys.workdir-before-remediation.tar=]] - CFEngine WORKDIR artifacts before remediation" >> ${COLLECTION_REPORT} ps -efl | grep cf- > "${COLLECTION_DIR}/cf-procs.txt" echo "- [[./cf-procs.txt][~ps -efl | grep cf-~]]" >> ${COLLECTION_REPORT} echo "$(date) Initiating apoptosis" | tee -a ${LOGFILE} while IFS= read -r proc; do _PID=$(echo $proc | awk '{print $4}') _PROC=$(echo $proc | awk '{print $15}') _PROCFILE=$(echo "$_PROC" | sed 's./._.g') _COREFILE=$(printf "%s_%s.core" "$_PID" "$_PROCFILE") _COREPATH=$(printf "%s/%s" "${COLLECTION_DIR}" "$_COREFILE") _DBX_ERR_LOG=$(printf "%s/%s.dbx.err" "${COLLECTION_DIR}" "$_COREFILE") gencore "$_PID" "$_COREPATH" > "${COLLECTION_DIR}/gencore-$_PID.output" 2>&1 echo "- [[./gencore-$_PID.output][output from gencore $_PID $_COREPATH]]" >> ${COLLECTION_REPORT} echo "- [[./$_COREFILE][core from $_PID]]" >> ${COLLECTION_REPORT} observation=$(echo "where" | dbx "$_PROC" "$_COREPATH" 2> "$_DBX_ERR_LOG") echo " - backtrace:" >> ${COLLECTION_REPORT} echo " #+begin_example\n${observation}\n#+end_example" >> ${COLLECTION_REPORT} echo " - dbx stderr: [[./$(basename $_DBX_ERR_LOG)][dbx $_PROC $_COREPATH]]" >> ${COLLECTION_REPORT} kill -s SIGKILL "$_PID" > "${COLLECTION_DIR}/kill_$_PID.txt" 2>&1 echo " - [[./kill_$_PID.txt][~kill -s SIGKILL $_PID~]]" >> ${COLLECTION_REPORT} done < "${COLLECTION_DIR}/cf-procs.txt" echo "- Purged outputs (don't want them to trigger pathology remediation more than once)" >> ${COLLECTION_REPORT} for each in $(ls -A "${CFENGINE_WORKDIR}/outputs/"); do rm "${CFENGINE_WORKDIR}/outputs/${each}" done # Switch to more intelligent cf-check repair in 3.12.3 echo "- Purged LMDBs" >> ${COLLECTION_REPORT} for each in ${CFENGINE_WORKDIR}/state/*.lmdb*; do rm "${each}" done tar -c -f "${COLLECTION_DIR}/sys.workdir-after-remediation.tar" -C "${CFENGINE_WORKDIR}" state outputs echo "- [[./sys.workdir-after-remediation.tar][=sys.workdir-after-remediation.tar=]] - CFEngine WORKDIR artifacts after remediation" >> ${COLLECTION_REPORT} ####+begin_critical # We will re-try up to 10 times to get all the daemons running echo "$(date) Initiating anastasis" | tee -a ${LOGFILE} for try in 1 2 3 4 5 6 7 8 9 10; do echo "- Anastasis [[./remediation-re-start-try-${try}.log][try ${try}]]" >> ${COLLECTION_REPORT} if all_cfengine_daemons_running > "${COLLECTION_DIR}/remediation-re-start-try-${try}.log"; then break; fi if [ "${try}" -ne 10 ]; then echo "Attempt $((1 + ${try})) of 10 in 10 seconds ..." >> ${LOGFILE} sleep 10 else echo "$(date) Failed to bring all services online after 10 retries, giving up" | tee -a ${LOGFILE} echo "- Failed to bring all services online after 10 retries, giving up" >> ${COLLECTION_REPORT} fi done ####+end_critical tar -c -f "${COLLECTION_DIR}/sys.workdir-after-restarting.tar" -C "${CFENGINE_WORKDIR}" state outputs echo "- [[./sys.workdir-after-restarting.tar][=sys.workdir-after-restarting.tar=]] - CFEngine WORKDIR artifacts after restarting" >> ${COLLECTION_REPORT} cp $0 ${COLLECTION_DIR}/watchdog echo "- [[./watchdog][=watchdog=]] - The watchdog that generated this report" >> ${COLLECTION_REPORT} # Package the artifacts together tar -c -f "${COLLECTION_DIR}.tar" -C "${COLLECTION_DIR}" . gzip "${COLLECTION_DIR}.tar" mv "${COLLECTION_DIR}.tar.gz" "${ARCHIVE_DIR}/$(date +%Y-%m-%d_%s).tar.gz" echo "$(date) Collected artifacts stored in ${ARCHIVE_DIR}/$(date +%Y-%m-%d_%s).tar.gz" | tee -a ${LOGFILE} elif [ "${PATHOLOGY_COUNT}" -gt 0 ]; then echo "$(date) Found ${PATHOLOGY_COUNT} symptoms, threshold (${PATHOLOGY_THRESHOLD}) not breached." | tee -a ${LOGFILE} else echo "$(date) Found ${PATHOLOGY_COUNT} symptoms, threshold (${PATHOLOGY_THRESHOLD}) not breached, no remediation or collection performed" >> ${LOGFILE} fi echo "$(date) DONE watchdog $$" >> ${LOGFILE} cleanup cfengine-masterfiles-3.27.3/cfe_internal/core/watchdog/watchdog.cf0000644000000000000000000002035414735102600023363 0ustar0000000000000000bundle agent cfe_internal_core_watchdog(state) # @brief Configure external watchdog processes to keep cf-execd running # @param state (enabled|disabled) The state to keep the watchdog configuration in { meta: "description" string => "Configure external watchdog processes (like cron, or monit) to make sure that cf-execd is always running"; vars: "_logfile" string => "$(sys.workdir)/watchdog.log"; classes: "invalid_state" not => regcmp("(enabled|disabled)", "$(state)"); "have_cron_d" expression => isdir("/etc/cron.d"); "use_cfe_internal_core_watchdog_cron_d" expression => "have_cron_d._stdlib_path_exists_pgrep"; # We use the aix specific watchdog implementation when it's aix and we are # not using the cron.d implementation. "use_cfe_internal_core_watchdog_aix" expression => "!use_cfe_internal_core_watchdog_cron_d.aix"; "use_cfe_internal_core_watchdog_windows" expression => "windows"; methods: use_cfe_internal_core_watchdog_cron_d:: "any" usebundle => cfe_internal_core_watchdog_cron_d($(state)); use_cfe_internal_core_watchdog_aix:: "any" usebundle => cfe_internal_core_watchdog_aix($(state)); use_cfe_internal_core_watchdog_windows:: "any" usebundle => cfe_internal_core_watchdog_windows($(state)); reports: DEBUG|DEBUG_cfe_internal_core_watchdog:: "DEBUG $(this.bundle): Watchdog '$(state)'"; "DEBUG $(this.bundle): Invalid state '$(state)' only enabled|disabled allowed" if => "invalid_state"; !(use_cfe_internal_core_watchdog_cron_d|use_cfe_internal_core_watchdog_aix|use_cfe_internal_core_watchdog_windows):: "WARNING $(this.bundle): Currently only supports /etc/cron.d on systems that have pgrep in the the stdlib paths bundle, AIX and Windows hosts."; } bundle agent cfe_internal_core_watchdog_windows(state) # @brief Manage watchdog state on windows # @param state enabled|disabled # - When enabled a scheduled task "CFEngine-watchdog" will be present and enabled # - When disabled a scheduled task named "CFEngine-watchdog" will be absent. { vars: windows:: "_requested_state" string => ifelse( regcmp("enabled|disabled", $(state)), "$(state)", "invalid" ); "_taskname" string => "CFEngine-watchdog"; "_taskfreq" string => "1"; "_taskscript" string => "$(sys.bindir)$(const.dirsep)watchdog.ps1"; "_taskrun" string => "PowerShell"; "_taskrun_args" string => "-NoProfile -ExecutionPolicy bypass -File"; "_logfile" string => "$(cfe_internal_core_watchdog._logfile)"; # -NonInteractive? "_cmd_task_schedule" string => `$(sys.winsysdir)$(const.dirsep)schtasks.exe /create /tn "$(_taskname)" /tr "$(_taskrun) $(_taskrun_args) '$(_taskscript)'" /ru "System" /sc minute /mo $(_taskfreq) /rl highest /f`; # We use XML output because it's the most portable output considering localization etc ... "_cmd_task_query" string => `schtasks /QUERY /TN "$(_taskname)" /XML 2> $(const.dollar)null`; "_cmd_task_query_result" string => execresult($(_cmd_task_query), powershell); # This regular expression is used to match against the XML output querying the task # We escape _taskscript with \Q \E since it contains backslashes which we don't want to be expanded "_scheduled_task_regex" string => concat( ".*Interval.PT$(_taskfreq)M..Interval", ".*Command.$(_taskrun)..Command", ".*Arguments.$(_taskrun_args) .\Q$(_taskscript)\E...Arguments", ".*" ); classes: windows:: "_requested_state_$(_requested_state)"; _requested_state_enabled:: "_watchdog_present_correct" expression => regcmp( $(_scheduled_task_regex), $(_cmd_task_query_result) ); _requested_state_disabled:: "_watchdog_absent_correct" expression => not( returnszero( 'schtasks /QUERY /TN "$(_taskname)" 2> $(const.dollar)null', powershell ) ); files: "$(_taskscript)" create => "true", template_method => "mustache", edit_template => "$(this.promise_dirname)/templates/watchdog-windows.ps1.mustache", template_data => parsejson('{"logfile": "$(_logfile)" }'); commands: _requested_state_disabled.!_watchdog_absent_correct:: `schtasks /DELETE /TN "$(_taskname)" /F` action => immediate, contain => powershell, classes => results("bundle", "win_watchdog_script"); _requested_state_enabled.!_watchdog_present_correct:: `$(_cmd_task_schedule)` action => immediate, contain => in_shell, classes => results("bundle", "win_watchdog_script"); reports: verbose_mode:: "CFEngine-watchdog desired state '$(_requested_state)'"; "CFEngine-watchdog scheduled task state '$(_requested_state)' correct" if => "_watchdog_present_correct|_watchdog_absent_correct"; verbose_mode.(!_watchdog_present_correct._requested_state_enabled):: "CFEngine-watchdog scheduled task state incorrect"; `Should: $(_cmd_task_schedule)`; (inform_mode|verbose_mode).win_watchdog_script_repaired:: "CFEngine-watchdog scheduled task repaired"; } bundle agent cfe_internal_core_watchdog_aix(state) # @brief Manage watchdog state on aix # @param state enabled|disabled # - When enabled a cron job will be present to start cf-execd if it's not running. # - When disabled cron jobs ending with `# CFEngine watchdog` will not be present. { classes: any:: # Define a class for whatever the desired state is "$(state)" expression => "any"; vars: "my_statedir" string => "$(sys.statedir)/MPF/$(this.bundle)"; commands: # We need to know about the current crontab before making any changes "/usr/bin/crontab -l > $(my_statedir)/root-crontab" handle => "aix_crontab_get_state", if => isdir("$(my_statedir)"), contain => in_shell_and_silent; files: enabled:: # We need a place to track state for processing changes to cron entries # with proper signaling. "$(my_statedir)/." create => "true"; # The watchdog script takes care of detecting conditions and launching # necessary components. "$(sys.bindir)/watchdog" create => "true", template_method => "mustache", perms => mog("700", "root", "system"), edit_template => "$(this.promise_dirname)/templates/watchdog.mustache"; # When enabled we make sure there is a cron entry to execute the watchdog # script. # NOTE The text `# CFEngine watchdog` is used to locate the specific entry in cron when disabling "$(my_statedir)/root-crontab" create => "true", edit_line => lines_present( "* * * * * $(sys.bindir)/watchdog >/dev/null 2>&1 # CFEngine watchdog" ), classes => results("bundle", "root_crontab"), depends_on => { "aix_crontab_get_state" }; disabled:: "$(my_statedir)/root-crontab" edit_line => delete_lines_matching(".*# CFEngine watchdog"), classes => results("bundle", "root_crontab"), depends_on => { "aix_crontab_get_state" }; commands: root_crontab_repaired:: # We use crontab to load the desired entries so that crond will be # signaled and the changes will be respected. "/usr/bin/crontab $(my_statedir)/root-crontab"; } bundle agent cfe_internal_core_watchdog_cron_d(state) # @brief Use a cron job installed in /etc/cron.d to watch and make sure that # cf-execd is always running. # @param state (enabled|disabled) The state to keep the watchdog configuration # in. Enabled manages the cron job, disabled removes it. { classes: any:: # Define a class for whatever the desired state is "$(state)" expression => "any"; vars: any:: "template" string => "$(this.promise_dirname)/../../../templates/cfengine_watchdog.mustache"; "cron_d_watchdog" string => "/etc/cron.d/cfengine_watchdog"; files: enabled:: "$(cron_d_watchdog)" create => "true"; "$(cron_d_watchdog)" edit_template => "$(template)", handle => "cfe_internal_core_watchdog_enable_cron_d_file_content", template_method => "mustache"; disabled:: "$(cron_d_watchdog)" delete => tidy; } cfengine-masterfiles-3.27.3/cfe_internal/PaxHeaders/enterprise0000644000000000000000000000003515266337437021534 xustar0029 mtime=1792655135.13379644 cfengine-masterfiles-3.27.3/cfe_internal/enterprise/0000755000000000000000000000000015266337437020717 5ustar0000000000000000cfengine-masterfiles-3.27.3/cfe_internal/enterprise/CFE_hub_specific.cf0000644000000000000000000010271614735102600024316 0ustar0000000000000000################################################################## # # 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 # ################################################################## @if minimum_version(3.12.0) bundle common cfe_hub_specific_file_control { vars: "inputs" slist => { "$(this.promise_dirname)/federation/federation.cf" }; } body file control { inputs => { @(cfe_hub_specific_file_control.inputs) }; } @endif bundle common cfe_internal_hub_vars # @brief Set hub specific variables { classes: "cfe_enterprise_have_SSLCACertificateFile_defined" -> { "ENT-11421" } scope => "namespace", expression => isvariable("SSLCACertificateFile"); vars: policy_server:: "http_port" -> { "ENT-12151" } string => ifelse( isvariable("cfe_internal_hub_vars.http_port"), "$(cfe_internal_hub_vars.http_port)", "80" ), comment => "Mission portal's webserver HTTP port. Default 80"; "https_port" -> { "ENT-12151" } string => ifelse( isvariable("cfe_internal_hub_vars.https_port"), "$(cfe_internal_hub_vars.https_port)", "443" ), comment => "Mission portal's webserver HTTPS port. Default 443"; "docroot" string => "$(sys.workdir)/httpd/htdocs", comment => "Root directory of Enterprise Web interface", handle => "cfe_internal_hub_vars_docroot"; "public_docroot" string => ifelse( isdir("$(cfe_internal_hub_vars.docroot)/public"), "$(cfe_internal_hub_vars.docroot)/public", $(cfe_internal_hub_vars.docroot) ), comment => "Public root directory of Enterprise Web interface"; # TODO Consider tagging these files for file integrity monitoring. "SSLCertificateFile" string => "$(sys.workdir)/httpd/ssl/certs/$(sys.fqhost).cert"; "SSLCertificateKeyFile" string => "$(sys.workdir)/httpd/ssl/private/$(sys.fqhost).key"; "SSLCertificatePasswdKeyFile" string => "$(sys.workdir)/httpd/ssl/private/$(sys.fqhost).pass.key"; "SSLCertificateSigningRequest" string => "$(sys.workdir)/httpd/ssl/private/$(sys.fqhost).csr"; "SSLCnf" string => "$(sys.workdir)/ssl/openssl.cnf"; "access_log" string => "$(sys.workdir)/httpd/logs/access_log"; "error_log" string => "$(sys.workdir)/httpd/logs/error_log"; "ssl_request_log" string => "$(sys.workdir)/httpd/logs/ssl_request_log"; "SSLCertificateKeySize" string => "4096"; "SSLCertificateDaysValid" string => "3650"; # Determine the version of PHP that is used # TODO Drop this after 3.18 is no longer supported. It's used for Mission Portals httpd configuration. # ENT-11440 enabled http/2 which switched from libphp.so apache module to php-fpm. # httpd.conf doesn't use php_version when http/2 is enabled. "php_version" -> { "ENT-7039" } string => ifelse( fileexists("$(sys.workdir)/httpd/php/sbin/php-fpm"), "", # ENT-11440, http/2 in httpd.conf doesn't need php_version fileexists("$(sys.workdir)/httpd/modules/libphp.so"), "", # ENT-7039 php 8+ fileexists("$(sys.workdir)/httpd/modules/libphp7.so"), "7", fileexists("$(sys.workdir)/httpd/modules/libphp5.so"), "5", "UNKNOWN" ); reports: policy_server:: "ERROR: $(this.bundle): Unable to determine correct PHP version." if => strcmp($(php_version), "UNKNOWN"); } ################################################################## # # update_cli_rest_server_url_config # - updates REST server URL port of Mission Portal WebGUI when # cfe_internal_hub_vars.https_port is changed # ################################################################## bundle agent update_cli_rest_server_url_config { vars: # Both share and live versions must be changed at once since httpd will be restarted later in the same agent run. "mp_config_files" slist => { "application/config/config.php" }; "api_config_files" slist => { "api/config/config.php", "api/modules/inventory/config/config.php" }; "share" string => "$(sys.workdir)/share/GUI"; "docroot" string => "$(cfe_internal_hub_vars.docroot)"; "mp_test_pattern" string => ".*localhost:$(cfe_internal_hub_vars.https_port).*"; "api_test_pattern" string => ".*127\.0\.0\.1:$(cfe_internal_hub_vars.https_port).*"; files: mpf_enable_mission_portal_docroot_sync_from_share_gui:: "$(share)/$(mp_config_files)" handle => canonify( concat("cfe_internal_edit_share_", "$(mp_config_files)") ), edit_line => change_mp_server_url_port, if => and( fileexists("$(share)/$(mp_config_files)"), islessthan( countlinesmatching( "$(mp_test_pattern)", "$(share)/$(mp_config_files)" ), 1 ) ); "$(share)/$(api_config_files)" handle => canonify( concat("cfe_internal_edit_share_", "$(api_config_files)") ), edit_line => change_api_server_url_port, if => and( fileexists("$(share)/$(api_config_files)"), islessthan( countlinesmatching( "$(api_test_pattern)", "$(share)/$(api_config_files)" ), 1 ) ); any:: "$(docroot)/$(mp_config_files)" handle => canonify(concat("cfe_internal_edit_", "$(mp_config_files)")), edit_line => change_mp_server_url_port, if => and( fileexists("$(docroot)/$(mp_config_files)"), islessthan( countlinesmatching( "$(mp_test_pattern)", "$(docroot)/$(mp_config_files)" ), 1 ) ); "$(docroot)/$(api_config_files)" handle => canonify(concat("cfe_internal_edit_", "$(api_config_files)")), edit_line => change_api_server_url_port, if => and( fileexists("$(docroot)/$(api_config_files)"), islessthan( countlinesmatching( "$(api_test_pattern)", "$(docroot)/$(api_config_files)" ), 1 ) ); } bundle edit_line change_mp_server_url_port { replace_patterns: "^\s*\$config\['cli_rest_server_url'\]\s*=\s*\"https:\/\/localhost(?::(?!$(cfe_internal_hub_vars.https_port))\d{1,5})?\/api\/\";\s*$" replace_with => value( " $config['cli_rest_server_url'] = \"https://localhost:$(cfe_internal_hub_vars.https_port)/api/\";" ), comment => "Change port MP REST server URL port"; } bundle edit_line change_api_server_url_port { replace_patterns: "https:\/\/127\.0\.0\.1(?::(?!$(cfe_internal_hub_vars.https_port))\d{1,5})?\/" replace_with => value( "https://127.0.0.1:$(cfe_internal_hub_vars.https_port)/" ), comment => "Change port API REST server URL port"; } ################################################################## # # cfe_internal_update_folders # - create temp directories to make CFE silent (self-upgrading) # ################################################################## bundle agent cfe_internal_update_folders # @brief Ensure that the directory structure exists on the hub for storing packages used in self upgrade { vars: "dirs" slist => { "aix_5_powerpc", "aix_6_powerpc", "aix_6.1_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", "ubuntu_16_i686", "ubuntu_16_x86_64", "centos_5_i686", "centos_5_x86_64", "centos_6_i686", "centos_6_x86_64", "centos_7_i686", "centos_7_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", "hpux_ia64", }, comment => "Define a list for $(sys.flavour)_$(sys.arch) directories", handle => "cfe_internal_update_folders_vars_dirs"; files: "$(sys.workdir)/master_software_updates/$(dirs)/." comment => "Prepare binary upgrade folders for all distributions in our environment", handle => "cfe_internal_update_folders_files_create_dirs", create => "true"; } bundle agent cfe_internal_php_runalerts # @brief Manage the runalerts service. # # - Bundle status need to be updated and displayed on MP. This bundle manages a # small script which runs in a loop. { vars: any:: "runalerts_types" comment => "Runalerts is run for different types of alerts", slist => { "all" }; "runalerts_script" string => "$(sys.bindir)/runalerts.php", comment => "location of php runalerts script", handle => "cfe_internal_php_runalerts_vars_runalerts_script"; # TODO Move runalerts stamp files into $(sys.statedir) "runalerts_stampfiles_dir" string => "$(sys.workdir)/httpd/php/runalerts-stamp", 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"; "all[name]" string => "all", comment => "name of query type - all", handle => "cfe_internal_php_runalerts_vars_all_name"; "all[limit]" string => "300", comment => "query limit of sql", handle => "cfe_internal_php_runalerts_vars_all_limit"; "all[running]" string => "20", comment => "how many query at a time of sql", handle => "cfe_internal_php_runalerts_vars_all_running"; classes: "systemd_supervised" scope => "bundle", expression => "systemd", comment => "As of 3.10 the runalerts service is supervised by systemd when available. Prior to 3.10 the service is supervised directly by CFEngine policy."; files: any:: "$(runalerts_script)" comment => "The runalerts script is necessary for the proper functioning of the CFEngine Enterprise alerts.", handle => "cfe_internal_php_runalerts_files_php_runalerts_script", create => "true", perms => mog("0755", "root", "root"), edit_template => "$(this.promise_dirname)/templates/runalerts.php.mustache", classes => results("bundle", "runalerts_script"), template_method => "mustache"; "$(runalerts_stampfiles_dir)/." create => "true", comment => "We provide a single directory where the runalerts process should maintain its timestamp tracking."; # This promise uses the side effect of cleaning up the timestamp files to # realize when it's time to kill the runalerts script. However, in order # to make sure that runalerts can write to the state files, we will also # make sure they exist with specific perms. This extra churn is probably # unnecessary. "$(runalerts_stampfiles_dir)/runalerts_.*" comment => "The runalerts process updates a timestamp for each type of alert each time alerts are checked. Here we check for the state files not being updated and kill off the runalerts process so that it can be refreshed. ", handle => "cfe_internal_php_runalerts_files_status_check", delete => tidy, file_select => mins_old("$(stale_time)"), classes => results("bundle", "stale_runalerts_timestamp"); "$(runalerts_stampfiles_dir)/runalerts_$(runalerts_types)" create => "true", handle => "cfe_internal_php_runalerts_state_file_perms", comment => "The runalerts timestamp files need to be owned by the apache user or we won't be able to update the timestamps from the runalerts service which is expected to be running as $(def.cf_apache_user)", perms => mog("600", $(def.cf_apache_user), $(def.cf_apache_group)); # Cleanup old runalerts script if it's still present "$(sys.bindir)/runalerts.sh" delete => tidy, comment => "The runalerts loop was re-written in php to better work with systemd service Type=simple."; processes: "$(sys.bindir)/runalerts.sh" comment => "The old runalerts process should be killed if it's running and replaced with the php version of the loop.", signals => { "kill" }; # Make sure to kill script on non active hub(s), when the tracking timestamp # is stale, or when the script has been repaired. stale_runalerts_timestamp_repaired|passive_ha_hub|runalerts_script_repaired:: "$(runalerts_script)" comment => "The runalerts process should be killed if it has failed to update the timestamp files in $(stale_time) minutes or if it is running on an standby HA hub.", handle => "cfe_internal_php_runalerts_process_kill_php_runalerts_script", signals => { "term" }, classes => if_repaired("run_script"); # We don't try to supervise the runalerts process on systemd hosts because # there is a unit for that. !systemd_supervised.active_hub:: "$(runalerts_script)" comment => "When the runalerts service is not supervised by systemd we need to check to see if the service is running so that we can restart it when necessary.", handle => "cfe_internal_php_runalerts_process_check_php_runalerts_script", restart_class => "runalerts_process_not_running"; commands: # Don't run the script on systemd hosts !systemd_supervised.runalerts_process_not_running.active_hub:: "$(runalerts_script) > /dev/null < /dev/null 2>&1 &" comment => "Runalerts is needed for proper functioning of Enterprise dashboard alerts. It should only be run on the active hub to avoid duplicate alerts. On systemd hosts the service is supervised by it's own unit and the CFEngine policy does not need to ensure it is running.", handle => "cfe_internal_php_runalerts_commands_run_php_runalerts_script", classes => kept_successful_command, contain => run_as_cfapache, action => cfe_internal_bg; } body contain run_as_cfapache { useshell => "true"; exec_owner => "$(def.cf_apache_user)"; exec_group => "$(def.cf_apache_group)"; } body action cfe_internal_bg { background => "true"; } body file_select mins_old(mins) # @brief Select files that are older than `mins` minutes old { mtime => irange(0, ago(0, 0, 0, 0, "$(mins)", 0)); file_result => "mtime"; } 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.public_docroot)/index.php cli_tasks truncate_events" contain => silent, comment => "Truncate all the pending notifications if there is any", handle => "cfe_internal_truncate_event_mp"; } bundle agent cfe_internal_purge_scheduled_reports_older_than_days(days) # @brief Clean up scheduled reports older than `days` days old { vars: "tmp_directories_list" slist => { "$(cfe_internal_hub_vars.public_docroot)/tmp/.", "$(cfe_internal_hub_vars.docroot)/static/.", }; files: "$(tmp_directories_list)" handle => "cfe_internal_purge_scheduled_reports_files_docroot_tmp", delete => tidy, depth_search => recurse("inf"), file_select => filetype_older_than("plain", $(days)), if => isdir($(tmp_directories_list)), comment => "Mission Portals scheduled reports are written here. They need to be purged after some time so that they do not fill the disk."; "$(cfe_internal_hub_vars.docroot)/api/static/." -> { "ENT-3558" } handle => "cfe_internal_purge_scheduled_reports_files_docroot_api_static", delete => tidy, depth_search => recurse("inf"), file_select => filetype_older_than("plain", $(days)), comment => "In some versions of Enterprise the async query api and scheduled reports assets are deposited in this directory. They need to be cleaned up as to not fill the disk."; } bundle agent inventory_cfengine_enterprise_license_utilization # @brief Inventory CFEngine Enterprise License Utilization { @if minimum_version(3.15.0) classes: enterprise_edition:: "have_cf_hub" expression => fileexists($(cf_hub)); vars: "cf_hub" string => "/var/cfengine/bin/cf-hub"; have_cf_hub:: "cf_hub_show_license_output" string => '$(sys.statedir)/cf-hub-show-license.txt'; "parsed_license" data => data_readstringarray( $(cf_hub_show_license_output), "", ":\s+", 10, 500 ), if => fileexists($(cf_hub_show_license_output)); "license_file" string => "$(parsed_license[License file])", meta => { "inventory", "attribute_name=CFEngine Enterprise license file" }; "license_owner" -> { "ENT-5337" } string => "$(with)", meta => { "inventory", "attribute_name=CFEngine Enterprise license owner" }, with => nth( string_split("$(parsed_license[Company name])", "\W", inf), 0 ), if => isvariable("parsed_license[Company Name]"); "license_utilization" string => "$(with)", meta => { "inventory", "attribute_name=CFEngine Enterprise license utilization" }, with => nth( string_split("$(parsed_license[Utilization])", "\W", inf), 0 ), if => isvariable("parsed_license[Utilization]"); "license_expiration" string => "$(parsed_license[Expiration date])", meta => { "inventory", "attribute_name=CFEngine Enterprise license expiration date", }, if => isvariable("parsed_license[Expiration date]"); "license_count" string => "$(with)", with => nth( string_split("$(parsed_license[Utilization])", "\W", inf), 1 ), meta => { "inventory", "attribute_name=CFEngine Enterprise licenses allocated" }, if => isvariable("parsed_license[Utilization]"); "license_status" string => "$(parsed_license[License status])", meta => { "inventory", "attribute_name=CFEngine Enterprise license status" }, if => isvariable("parsed_license[License status]"); commands: have_cf_hub:: "$(sys.cf_hub) --show-license" arglist => { ">", $(cf_hub_show_license_output) }, handle => "enterprise_hub_license_info_cache", contain => in_shell, inform => "false", classes => ENT_5279; @endif } body classes ENT_5279 # @brief Work around ENT-5279, cf-hub --show-license returns 1 when no license is installed { kept_returncodes => { "0" }; # TODO: Redact when 3.15.x is no longer supported # considered kept on affected versions. cfengine_3_15_0:: kept_returncodes => { "0", "1" }; } bundle agent log_cfengine_enterprise_license_utilization # @brief Log the number of hosts seen within the last 24 hours and the number of # hosts reported to have the "cfengine" class. Note any hosts that has been # successfully collected from is expected to have the "cfengine" class. This # bundle will not be called unless the class # `enable_log_cfengine_enterprise_license_utilization` is defined. { reports: policy_server.enterprise_edition.DEBUG_log_cfengine_enterprise_license_utilization:: "Hosts reported: $(count_reporting)"; vars: policy_server.enterprise_edition:: "log_dir" string => "$(sys.workdir)/log"; policy_server.enterprise_edition.enable_log_cfengine_enterprise_license_utilization.(DEBUG_log_cfengine_enterprise_license_utilization|!cfe_internal_logged_utilization):: "log_frequency" int => "720"; # Using address for reporting hosts because hostseen() will incur # undesirable reverse dns lookups if name is used # The cfengine class is always reported, and a reliable way to find hosts # that have reported. "hosts_reporting" slist => hostswithclass("cfengine", "address"); "count_reporting" int => length(hosts_reporting); # We are counting hosts seen within the last day. "hosts_seen" slist => hostsseen("24", "lastseen", "address"); "count_seen" int => length(hosts_seen); files: policy_server.enterprise_edition:: "$(log_dir)/." create => "true", comment => "The log dir must exist in order to write to a file."; reports: policy_server.enterprise_edition.!cfe_internal_logged_utilization:: "$(sys.date), hosts_reporting=$(count_reporting), hosts_seen=$(count_seen)" report_to_file => "$(sys.workdir)/log/license_utilization.log", classes => cfe_internal_log_utilization($(log_frequency)); } bundle agent cfe_internal_enterprise_ha_classes { classes: # NOTE The `hub_active` class is a hard class defined by the ha_plugin in # the enterprise agent. "active_hub" expression => "policy_server.(!enable_cfengine_enterprise_hub_ha|(enable_cfengine_enterprise_hub_ha.hub_active))", scope => "namespace", comment => "This means this is a hub that is not in an HA setup or the active one in a HA setup"; # TODO Consider using `hub_passive` instead of `!hub_active` "passive_ha_hub" expression => "policy_server.(enable_cfengine_enterprise_hub_ha.!hub_active)", scope => "namespace", comment => "This means this is a passive hub in an HA setup"; } bundle agent cfe_internal_enterprise_maintenance # @brief Actuate bundles tagged with `enterprise_maintenance` in lexically sorted order { vars: enterprise_edition:: "enterprise_maintenance_bundles_unsorted" slist => bundlesmatching(".*", "enterprise_maintenance"); "enterprise_maintenance_bundles" slist => sort(enterprise_maintenance_bundles_unsorted, lex); "enterprise_maintenance_bundle_count" int => length(enterprise_maintenance_bundles); methods: enterprise_edition:: "HA classes" usebundle => "cfe_internal_enterprise_ha_classes", comment => "Set the HA-related classes for the maintenance bundles"; "Enterprise Maintenance" usebundle => $(enterprise_maintenance_bundles), if => isgreaterthan($(enterprise_maintenance_bundle_count), 0); reports: "DEBUG|DEBUG_$(this.bundle)":: "DEBUG $(this.bundle): $(enterprise_maintenance_bundle_count) CFEngine Enterprise Maintenance Bundles" if => isgreaterthan($(enterprise_maintenance_bundle_count), 0); "DEBUG $(this.bundle): $(enterprise_maintenance_bundles) CFEngine Enterprise Maintenance Bundles" if => isgreaterthan($(enterprise_maintenance_bundle_count), 0); } bundle agent cfe_internal_exported_report_location # @brief Ensure that exported reports are in the correct directory { meta: am_policy_hub.enterprise_edition:: "tags" slist => { "enterprise_maintenance" }; files: am_policy_hub.enterprise_edition:: "$(cfe_internal_hub_vars.public_docroot)/tmp/." -> { "ENT-7465" } depth_search => recurse(inf), file_select => by_name('.*\.(csv|pdf)'), transformer => "/bin/mv $(this.promiser) $(cfe_internal_hub_vars.docroot)/static/", if => isdir("$(cfe_internal_hub_vars.docroot)/static/."), comment => "Generated reports (CSV and PDF) should be in the static directory if it exists."; } bundle agent cfe_internal_refresh_inventory_view # @brief Refresh list of inventory variables every 5 minutes # @note Beginning with 3.24.0 the inventory view refresh is handled by cf-reactor. { @if before_version(3.24.0) meta: (policy_server|am_policy_hub).enterprise_edition:: "tags" slist => { "enterprise_maintenance" }; commands: (policy_server|am_policy_hub).enterprise_edition.active_hub:: "$(sys.workdir)/httpd/php/bin/php" args => "$(cfe_internal_hub_vars.public_docroot)/index.php cli_tasks inventory_refresh", contain => silent, inform => "false", comment => "This refreshes the variables shown in the Mission Portal Inventory.", handle => "mpf_fresh_inventory_view", if => isdir("$(cfe_internal_hub_vars.docroot)/api/modules/inventory"); @endif } bundle agent cfe_internal_refresh_hosts_view # @brief Refresh hosts materialized view every 5 minutes { meta: (policy_server|am_policy_hub).enterprise_edition:: "tags" slist => { "enterprise_maintenance" }; commands: (policy_server|am_policy_hub).enterprise_edition.active_hub:: "$(sys.workdir)/httpd/php/bin/php" -> { "ENT-3482" } args => "$(cfe_internal_hub_vars.public_docroot)/index.php cli_tasks materialized_hosts_view_refresh", contain => silent, @if minimum_version(3.15.0) inform => "false", @endif comment => "This refreshes the hosts view. If the hosts view is not refreshed then it will contain stale data.", handle => "mpf_fresh_hosts_view", if => isgreaterthan( countlinesmatching( ".*materialized_hosts_view_refresh.*", "$(cfe_internal_hub_vars.docroot)/application/controllers/Cli_tasks.php" ), 0 ); } bundle agent cfe_internal_clear_last_seen_hosts_logs # @brief Clear last seen hosts log every 5 minutes # TODO Redact this bundle when 3.15 is no longer under standard support # (December 31st 2022). The commands in the policy are scoped to run only on # active enterprise hubs with =(cfengine_3_12|cfengine_3_13|cfengine_3_14)=. # 3.15.0 was released while 3.12.x was still supported and this bundle should # remain until 3.15.0 becomes EOL so that someone running 3.12.x could upgrade # to 3.15.x policy while still running 3.12.x binaries and this bundle will # continue to function as expected. { meta: (policy_server|am_policy_hub).enterprise_edition:: "tags" slist => { "enterprise_maintenance" }; commands: (policy_server|am_policy_hub).enterprise_edition.active_hub.(cfengine_3_12|cfengine_3_13|cfengine_3_14):: "$(sys.workdir)/httpd/php/bin/php" -> { "ENT-3550" } args => "$(cfe_internal_hub_vars.public_docroot)/index.php cli_tasks clearLastSeenHostsLogs", contain => silent, comment => "This clears the __lastseenhostslogs table. If the __lastseenhostslogs table is not cleared then it will contain unnecessary data.", handle => "mpf_clear_lastseenhostslogs", if => isgreaterthan( countlinesmatching( ".*clearLastSeenHostsLogs.*", "$(cfe_internal_hub_vars.docroot)/application/controllers/Cli_tasks.php" ), 0 ); } bundle agent cfe_internal_refresh_events_table # @brief Refresh materialized view every 5 minutes { meta: (policy_server|am_policy_hub).enterprise_edition:: "tags" slist => { "enterprise_maintenance" }; commands: (policy_server|am_policy_hub).enterprise_edition.active_hub:: "$(sys.workdir)/httpd/php/bin/php" args => "$(cfe_internal_hub_vars.public_docroot)/index.php cli_tasks process_api_events", contain => silent, @if minimum_version(3.15.0) inform => "false", @endif comment => "This refreshes the events table. If the events table is not refreshed then it will contain stale data.", handle => "mpf_fresh_events_table", if => fileexists( "$(cfe_internal_hub_vars.docroot)/api/resource-v1/Event.php" ); } bundle agent cfe_internal_update_health_failures # @brief Update table that contains health diagnostics failures hosts { meta: (policy_server|am_policy_hub).enterprise_edition:: "tags" slist => { "enterprise_maintenance" }; commands: (policy_server|am_policy_hub).enterprise_edition.active_hub:: "$(sys.workdir)/httpd/php/bin/php" -> { "ENT-6228" } args => "$(cfe_internal_hub_vars.public_docroot)/index.php cli_tasks update_health_failures", contain => silent, @if minimum_version(3.15.0) inform => "false", @endif comment => "This updates health diagnostics failures table. If the table is not updated then it will contain stale data.", handle => "mpf_update_health_failures", if => isgreaterthan( countlinesmatching( ".*update_health_failures.*", "$(cfe_internal_hub_vars.docroot)/application/controllers/Cli_tasks.php" ), 0 ); } body classes cfe_internal_log_utilization(time) # @brief Define persistent class for period of time to control log volume { promise_repaired => { "cfe_internal_logged_utilization" }; promise_kept => { "cfe_internal_logged_utilization" }; scope => "namespace"; persist_time => "$(time)"; } bundle agent cfe_internal_enterprise_policy_analyzer # @brief Ensure published policy is available for use with policy analyzer # @description This bundle runs as part of the enterprise_maintenance bundles. When `analyzer_flagfile` exists, this bundle ensures policy from `analyzer_source` is kept in sync with `analyzer_dir`. { meta: (policy_server|am_policy_hub).enterprise_edition:: "tags" -> { "ENT-4192" } slist => { "enterprise_maintenance" }; vars: enterprise_edition.policy_server:: "analyzer_flagfile" string => "$(cfe_internal_hub_vars.docroot)/analyzer/pa.enabled"; "analyzer_base" string => "/opt/cfengine/analyzer"; "analyzer_dir" string => "$(analyzer_base)/policy/masterfiles"; "analyzer_source" string => "$(sys.masterdir)"; "exclude_files" -> { "ENT-7684" } slist => { "" }, unless => isvariable( "def.cfengine_enterprise_policy_analyzer_exclude_files" ), comment => concat( "By default policy analyzer will get access to all files, ", "that are part of the policy." ); "exclude_files" -> { "ENT-7684" } slist => { "@(def.cfengine_enterprise_policy_analyzer_exclude_files)" }, if => isvariable( "def.cfengine_enterprise_policy_analyzer_exclude_files" ), comment => concat( "A list of regular expressions matching file leaf names ", "that should not be copied for access by policy analyzer." ); classes: enterprise_edition.policy_server:: "policy_analyzer_enabled" expression => fileexists($(analyzer_flagfile)); files: enterprise_edition.policy_server:: "$(cfe_internal_hub_vars.docroot)/analyzer/." -> { "CFE-951" } create => "true", handle => "cfe_internal_setup_knowledge_docroot_analyzer_dir", perms => mog("0470", "root", $(def.cf_apache_group)), comment => concat( "This directory holds the policy analyzer flag file ", "that is written by Mission Portal when someone ", "clicks to enable the feature. Thus, it needs to be ", "readable, writeable and executable for the web ", "server." ); policy_analyzer_enabled:: "$(analyzer_dir)/." create => "true", handle => "policy_analyzer_sync_analyzer_source", copy_from => analyzer_sync($(analyzer_source)), depth_search => recurse_with_base(inf), file_select => default:ex_list(@(exclude_files)); "$(analyzer_base)/." -> { "CFE-951" } file_select => default:dirs, depth_search => recurse_with_base(inf), perms => mog("0450", "root", $(def.cf_apache_group)); "$(analyzer_dir)/." -> { "CFE-951" } file_select => default:not_dir, depth_search => recurse_with_base(inf), perms => mog("0450", "root", $(def.cf_apache_group)); reports: DEBUG|DEBUG_cfe_internal_enterprise_policy_analyzer:: "DEBUG Mission Portal Policy Analyzer enabled. Keeping '$(analyzer_dir)' in sync with '$(analyzer_source)'" if => "policy_analyzer_enabled"; } body copy_from analyzer_sync(path) # @brief Keep promised files in sync with local `path` { source => "$(path)"; purge => "true"; preserve => "false"; compare => "digest"; } cfengine-masterfiles-3.27.3/cfe_internal/enterprise/CFE_knowledge.cf0000644000000000000000000007524414735102600023657 0ustar0000000000000000################################################################## # # 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 # @brief Policy related to enterprise hubs { classes: # check when updates arrive, new compared to the database "ENT_3572" -> { "ENT-3572" } comment => "Hosts with this class need to be sure that the ssl directory is readable and executable by other users", or => { "enterprise_3_7_3", "enterprise_3_7_4", "enterprise_3_7_5", "enterprise_3_10_0", }; vars: "install_logs" -> { "ENT-4564" } slist => findfiles("/var/log/CFEngine*Install.log"), unless => "windows"; # TODO: Remove this once sys.moduledir is always available (3.26+ only) "moduledir" -> { "CFE-1484" } string => ifelse( isvariable("sys.moduledir"), "$(sys.moduledir)", "$(sys.workdir)/modules" ); files: mpf_enable_mission_portal_docroot_sync_from_share_gui:: "$(cfe_internal_hub_vars.docroot)" -> { "ENT-13172" } 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_compare("$(sys.workdir)/share/GUI", "binary"), depth_search => recurse("inf"); "$(cfe_internal_hub_vars.docroot)/.htaccess" comment => "Correct up htaccess file in doc root", handle => "cfe_internal_setup_knowledge_files_doc_root_htaccess", copy_from => no_backup_cp("$(sys.workdir)/share/GUI/Apache-htaccess"); any:: "$(install_logs)" -> { "ENT-4506" } perms => mog("0600", "root", "root"); "$(cfe_internal_hub_vars.docroot)/." -> { "CFE-951" } comment => "The top level docroot needs to be readable and executable by the web server.", handle => "cfe_internal_setup_knowledge_dir_doc_root", perms => mog("0550", "root", $(def.cf_apache_group)); "$(sys.workdir)/httpd/php/." -> { "ENT-9703", "cfe_internal_setup_knowledge_dir_doc_root_runalerts_stamp", } create => "true", comment => "php directory needs to be accessible (execute) to cfapache", handle => "cfe_internal_setup_knowledge_dir_doc_root_php", perms => mog("0550", "root", $(def.cf_apache_group)); "$(sys.workdir)/httpd/php/runalerts-stamp/." -> { "ENT-9703" } create => "true", comment => "runalerts-stamp directory needs to be accessible (execute) to cfapache", handle => "cfe_internal_setup_knowledge_dir_doc_root_runalerts_stamp", perms => mog("0550", "root", $(def.cf_apache_group)); "$(cfe_internal_hub_vars.docroot)/vendor/." -> { "CFE-951" } comment => "The vendor directory and sub-directories contains dependencies from the code ignitor framework and the directories need to be searchable by the web server.", handle => "cfe_internal_setup_knowledge_dir_doc_root_vendor_dirs", depth_search => recurse_with_base("inf"), file_select => dirs, perms => mog("0550", "root", $(def.cf_apache_group)); "$(cfe_internal_hub_vars.docroot)/vendor/." -> { "CFE-951" } comment => "The files in the vendor directory contain dependencies from the code ignitor framework and need to be readable by the web server.", handle => "cfe_internal_setup_knowledge_dir_doc_root_vendor_not_dir", depth_search => recurse_with_base("inf"), file_select => not_dir, perms => mog("0440", "root", $(def.cf_apache_group)); "$(cfe_internal_hub_vars.public_docroot)/themes/." -> { "CFE-951" } comment => "The public docroot themes directory needs to be searchable by the web server so that it can find css and images to make Mission Portal look as expected.", handle => "cfe_internal_setup_knowledge_dir_doc_root_public_themes_dirs", depth_search => recurse_with_base("inf"), file_select => dirs, perms => mog("0550", "root", $(def.cf_apache_group)); "$(cfe_internal_hub_vars.public_docroot)/themes/." -> { "CFE-951" } comment => "The public docroot themes directory needs to be searchable by the web server so that it can find css and images to make Mission Portal look as expected.", handle => "cfe_internal_setup_knowledge_dir_doc_root_public_themes_not_dir", depth_search => recurse_with_base("inf"), file_select => not_dir, perms => mog("0440", "root", $(def.cf_apache_group)); "$(cfe_internal_hub_vars.public_docroot)/." comment => "The public dir in the docroot needs the to be executable by the webserver", handle => "cfe_internal_setup_knowledge_dir_doc_root_public", perms => mog("0550", "root", $(def.cf_apache_group)); "$(cfe_internal_hub_vars.public_docroot)/index.php" comment => "The public dir in the docroot needs the to be executable by the webserver", handle => "cfe_internal_setup_knowledge_dir_doc_root_public_index_php", perms => mog("0440", "root", $(def.cf_apache_group)); "$(cfe_internal_hub_vars.public_docroot)/images/." -> { "CFE-951" } comment => "The public docroot images directory needs to be searchable by the webserver so that Mission Portal can load images and look as expected.", handle => "cfe_internal_setup_knowledge_dir_doc_root_public_images_dirs", depth_search => recurse_with_base("inf"), file_select => dirs, perms => mog("0550", "root", $(def.cf_apache_group)); "$(cfe_internal_hub_vars.public_docroot)/images/." -> { "CFE-951" } comment => "The public docroot images directory needs to be searchable by the webserver so that Mission Portal can load images and look as expected.", handle => "cfe_internal_setup_knowledge_dir_doc_root_public_images_not_dir", depth_search => recurse_with_base("inf"), file_select => not_dir, perms => mog("0440", "root", $(def.cf_apache_group)); "$(sys.workdir)/httpd/." comment => "httpd dir should be 755", handle => "cfe_internal_setup_knowledge_dir_httpd", perms => mog("755", "root", "root"); "$(cfe_internal_hub_vars.public_docroot)/scripts/." -> { "CFE-951" } comment => "Ensure permissions for $(cfe_internal_hub_vars.public_docroot)/scripts", handle => "cfe_internal_setup_knowledge_files_doc_root_scripts_dir", create => "true", perms => mog("0570", "root", $(def.cf_apache_group)); "$(cfe_internal_hub_vars.public_docroot)/scripts/." -> { "CFE-951", "ENT-13243" } comment => "Ensure permissions for $(cfe_internal_hub_vars.public_docroot)/scripts", handle => "cfe_internal_setup_knowledge_files_doc_root_scripts_not_dir", create => "true", file_select => not_dir, depth_search => recurse_basedir("inf"), perms => mog("0440", "root", $(def.cf_apache_group)), if => "mpf_enable_mission_portal_public_docroot_scripts_not_dir_perms"; "$(cfe_internal_hub_vars.docroot)/static/." -> { "CFE-951" } handle => "cfe_internal_setup_knowledge_files_doc_root_static_dir", create => "true", perms => mog("0770", "root", $(def.cf_apache_group)), comment => "Ensure permissions for $(cfe_internal_hub_vars.docroot)/static. This is where exported and scheduled reports generated by Mission Portal (temp files to email)"; "$(cfe_internal_hub_vars.docroot)/static/." -> { "CFE-951", "ENT-11941" } handle => "cfe_internal_setup_knowledge_files_doc_root_static_not_dir", create => "true", depth_search => recurse_basedir("inf"), file_select => not_dir, perms => mog("0600", "$(def.cf_apache_user)", "$(def.cf_apache_group)"), comment => "Ensure permissions for $(cfe_internal_hub_vars.docroot)/static/*. This is where exported and scheduled reports generated by Mission Portal (temp files to download or email)"; "$(cfe_internal_hub_vars.public_docroot)/tmp/." -> { "CFE-951" } handle => "cfe_internal_setup_knowledge_files_public_doc_root_tmp_dir", create => "true", depth_search => recurse_basedir("inf"), file_select => dirs, perms => mog("0770", $(def.cf_apache_user), $(def.cf_apache_group)), comment => "Ensure permissions for $(cfe_internal_hub_vars.public_docroot)/tmp. This is where css and js files generated by Mission Portal"; "$(cfe_internal_hub_vars.public_docroot)/tmp/." -> { "CFE-951" } handle => "cfe_internal_setup_knowledge_files_public_doc_root_tmp_not_dir", create => "true", depth_search => recurse_basedir("inf"), file_select => not_dir, perms => mog("0440", $(def.cf_apache_user), $(def.cf_apache_group)), comment => "Ensure permissions for $(cfe_internal_hub_vars.public_docroot)/tmp. This is where css and js files generated by Mission Portal"; "$(cfe_internal_hub_vars.docroot)/application" -> { "CFE-951" } comment => "No one should be able to write to the application, and only the webserver needs access", handle => "cfe_internal_setup_knowledge_files_all_not_dir_in_application", depth_search => cfe_internal_docroot_application_perms, file_select => not_dir, perms => mog("0440", "root", $(def.cf_apache_group)); "$(cfe_internal_hub_vars.docroot)/application" -> { "CFE-951" } comment => "No one should be able to write to the application, and only the webserver needs access", handle => "cfe_internal_setup_knowledge_files_all_dirs_in_application", depth_search => cfe_internal_docroot_application_perms, file_select => dirs, perms => mog("0550", "root", $(def.cf_apache_group)); "$(cfe_internal_hub_vars.docroot)/application/cache/." -> { "ENT-11442" } handle => "cfe_internal_setup_knowledge_files_doc_root_application_cache", create => "true", perms => mog("0770", $(def.cf_apache_user), $(def.cf_apache_group)), comment => "This is where cache generated by Mission Portal is stored."; "$(cfe_internal_hub_vars.docroot)/api/." -> { "ENT-4250" } comment => "The api directory and it's subdirectories need to be executable by cfapache", perms => mog("0550", "root", $(def.cf_apache_group)); "$(cfe_internal_hub_vars.docroot)/api/." -> { "ENT-4250", "CFE-951" } depth_search => recurse_ignore("inf", "static"), file_select => dirs, comment => "The api subdirectories need to be executable by cfapache, but ignore static here, it needs to be writeable as well, well take care of it separately", perms => mog("0550", "root", $(def.cf_apache_group)); "$(cfe_internal_hub_vars.docroot)/ldap/." -> { "ENT-9693" } comment => concat( "The ldap directory and it's subdirectories need to be", "executable by cfapache" ), depth_search => recurse("inf"), file_select => cfe_internal_docroot_perms, perms => mog("0550", "root", $(def.cf_apache_group)); "$(cfe_internal_hub_vars.docroot)/ldap/." -> { "ENT-9693" } depth_search => recurse("inf"), file_select => dirs, comment => concat( "The ldap subdirectories need to be executable by cfapache", "but ignore static here, it needs to be writeable as well,", "well take care of it separately" ), perms => mog("0550", "root", $(def.cf_apache_group)); "$(cfe_internal_hub_vars.docroot)/api/." -> { "CFE-951" } depth_search => recurse_basedir("inf"), handle => "cfe_internal_setup_knowledge_files_doc_root_api", file_select => cfe_internal_exclude_sh_pl_scripts, perms => mog("0440", "root", $(def.cf_apache_group)), comment => "No one should be able to write to the application config code, and only the webserver needs access to read the config."; "$(cfe_internal_hub_vars.docroot)/api/." depth_search => recurse_basedir("inf"), handle => "cfe_internal_setup_knowledge_files_doc_root_api_scripts", file_select => cfe_internal_sh_pl_scripts, perms => mog("0550", "root", $(def.cf_apache_group)), comment => "The scripts need to be executable, but only by the webserver and root users."; "$(cfe_internal_hub_vars.docroot)/api/static/." perms => mog("0770", "root", $(def.cf_apache_group)), comment => "This is where exported PDF and CSV reports from Mission Portal are written, it be writeable by the webserver"; "$(cfe_internal_hub_vars.docroot)/api/static/." -> { "CFE-951" } comment => "Exported reports only need to be readable by the webserver.", handle => "cfe_internal_setup_knowledge_files_doc_root_api_static_not_dir", depth_search => recurse("inf"), file_select => cfe_internal_docroot_api_static_perms, perms => mog("0440", "root", $(def.cf_apache_group)); "$(cfe_internal_hub_vars.docroot)/api/static/." -> { "ENT-4551", "CFE-951" } comment => ".status, .pid, and potentially .abort files need to be writeable so that the async query API will function properly", handle => "cfe_internal_setup_knowledge_files_doc_root_api_static_async_query_status", depth_search => recurse("inf"), file_select => cfe_internal_docroot_api_static_async_query_status_status_perms, perms => mog("0660", "root", $(def.cf_apache_group)); "$(sys.workdir)/httpd/logs/application/." -> { "ENT-7731", "ENT-2758", "ENT-8908", "CFE-951" } comment => "Ensure permissions for $(sys.workdir)/httpd/logs/application/.", handle => "cfe_internal_setup_knowledge_files_httpd_application_log_dir", create => "true", perms => mog("0750", $(def.cf_apache_user), $(def.cf_apache_group)); "$(sys.workdir)/httpd/logs/application/." -> { "ENT-7730" } comment => "Ensure permissions for $(sys.workdir)/httpd/logs/application/.*", handle => "cfe_internal_setup_knowledge_files_httpd_application_log_files", file_select => plain, depth_search => recurse("inf"), perms => mog("0600", $(def.cf_apache_user), $(def.cf_apache_group)); "$(sys.workdir)/httpd/logs/." -> { "CFE-951" } comment => "Ensure permissions for $(sys.workdir)/httpd/logs", handle => "cfe_internal_setup_knowledge_files_httpd_logs_dir", create => "true", perms => mog("0750", $(def.cf_apache_user), $(def.cf_apache_group)); "$(sys.workdir)/httpd/logs/." -> { "ENT-7730" } comment => "Ensure permissions for $(sys.workdir)/httpd/logs", handle => "cfe_internal_setup_knowledge_files_httpd_log_files", file_select => plain, depth_search => recurse_with_base("0"), perms => mog("0600", root, root); "/var/log/postgresql.log" -> { "ENT-7961" } comment => "Ensure permissions for PostgreSQL log", handle => "cfe_internal_setup_knowledge_files_postgresql_log_file", perms => mog("0600", "cfpostgres", "cfpostgres"); "$(cfe_internal_hub_vars.docroot)/../ssl/." perms => mog("0440", "root", "root"), if => not("ENT_3572"); "$(cfe_internal_hub_vars.docroot)/../ssl/." -> { "ENT-3572" } perms => mog("0444", "root", "root"), if => "ENT_3572", comment => "Exported be 0 bytes in some versions if the ssl directory is not accessible to all users."; "$(cfe_internal_hub_vars.docroot)/../ssl/private/." depth_search => recurse_with_base("inf"), perms => mog("0440", "root", "root"), comment => "Private keys are secrets and should not be accessible by anyone other than root."; "$(cfe_internal_hub_vars.docroot)/../ssl/csr/." depth_search => recurse_with_base("inf"), perms => mog("0440", "root", "root"), comment => "Certificate signing requests, while not secrets do not need to be readable by others."; "$(cfe_internal_hub_vars.docroot)/../ssl/certs/." -> { "ENT-3050", "Mission Portal" } depth_search => recurse_with_base("inf"), perms => mog("0444", "root", "root"), comment => "Certificates need to be read by any user wishing to validate a request. For example Mission Portals api."; "$(cfe_internal_hub_vars.docroot)/." -> { "CFE-951" } depth_search => recurse_basedir("inf"), handle => "cfe_internal_setup_knowledge_files_doc_root_htaccess_perms", file_select => cfe_internal_htaccess, perms => mog("0440", "root", $(def.cf_apache_group)), comment => ".htaccess files should only be readable by webserver."; "$(cfe_internal_hub_vars.docroot)/ldap/config/settings.ldap.php" -> { "ENT-3400" } handle => "cfe_internal_setup_knowledge_files_ldap_config_settings_perms", perms => mog("0600", $(def.cf_apache_user), $(def.cf_apache_group)), if => fileexists( "$(cfe_internal_hub_vars.docroot)/ldap/config/settings.ldap.php" ), comment => "If the ldap settings are not writeable by $(def.cf_apache_user) then users will not be able to change ldap settings."; "$(sys.workdir)/share/GUI/." handle => "cfe_internal_setup_knowledge_files_workdir_share_gui_perms", perms => mog("0400", "root", "root"), depth_search => recurse_basedir("inf"), comment => concat( "No Mission Portal code in share needs to be accessed", " by anyone" ), if => "mpf_enforce_workdir_share_gui_perms"; "$(sys.workdir)/." -> { "ENT-3299" } perms => mog("755", "root", "root"), comment => "Ensure that others (like cfpostgres and cfapache) are able to enter and read from cfengines workdir"; "$(moduledir)/." perms => mog("755", "root", "root"), comment => "The agent will complain if any other users (group or other) have write access to the modules directory."; "/opt/cfengine/notification_scripts/." -> { "ENT-5070" } create => "true", perms => mog("770", "root", $(def.cf_apache_group)), comment => "If this directory is not present and writable by the web-server, then Mission Portal users will be unable to upload custom action scripts."; reports: mpf_disable_mission_portal_docroot_sync_from_share_gui:: "$(with)" -> { "ENT-13172" } with => concat( "The class 'default:mpf_disable_mission_portal_docroot_sync_from_share_gui'", " is no longer necessary. Synchronizing files from share/GUI to Mission", " Portal is now done only if explicitly requested by defining the class", " 'default:mpf_enable_mission_portal_docroot_sync_from_share_gui'" ); } bundle agent cfe_internal_permissions # @brief Specific expectations for permissions and ownership of CFEngine with respect to the Enterprise Edition { vars: # nonstandard directories in statedir "_statedir_standard_perm_exceptions" slist => { "pg", "cf-execd.sockets" }; # Derive the users that should be able to access cf-execd sockets "_cf_execd_socket_allow_users" slist => { @(def.control_executor_runagent_socket_allow_users) }; "_cf_statedir_allow_users" slist => { "cfpostgres", "cfapache", @(def.control_executor_runagent_socket_allow_users), }, if => "enterprise_edition.(policy_server|am_policy_hub)"; # Derive the aces for users allowed to access cf-execd sockets "_cf_execd_socket_dir_user_aces" -> { "ENT-6777" } slist => maplist( "user:$(this):rx:allow", @(_cf_execd_socket_allow_users) ); "_cf_execd_socket_runagent_user_aces" -> { "ENT-6777" } slist => maplist( "user:$(this):rw:allow", @(_cf_execd_socket_allow_users) ); "_cf_statedir_user_aces" -> { "ENT-6777" } slist => maplist("user:$(this):rx:allow", @(_cf_statedir_allow_users)); files: !(policy_server|am_policy_hub):: "$(sys.statedir)/." -> { "ENT-4773", "CFE-951" } handle => "state_dir_not_dir_perms", perms => state_dir_system_owned_files(), # Important to recurse across file system boundaries, as databases and or state are commonly on different filesystems depth_search => recurse_with_base(inf), file_select => not_dir; "$(sys.statedir)/." -> { "ENT-4773", "CFE-951" } handle => "state_dir_dirs_perms", perms => state_dir_system_owned_dirs(), # Important to recurse across file system boundaries, as databases and or state are commonly on different filesystems depth_search => recurse_with_base(inf), file_select => dirs; enterprise_edition.(policy_server|am_policy_hub):: "$(sys.statedir)/." -> { "CFE-951" } perms => mog("0750", "root", "cfpostgres"), acl => cf_statedir_acl(@(_cf_statedir_user_aces)), comment => "The database user must be able to read the parent directory of the database or it won't be accessible"; "$(sys.statedir)/." -> { "CFE-951" } perms => state_dir_system_owned_files(), depth_search => recurse_except( inf, @(_statedir_standard_perm_exceptions) ), file_select => not_dir, comment => "The database user must be able to read the parent directory of the database or it won't be accessible"; "$(sys.statedir)/." -> { "CFE-951" } perms => state_dir_system_owned_dirs(), depth_search => recurse_except( inf, @(_statedir_standard_perm_exceptions) ), file_select => dirs, comment => "The database user must be able to read the parent directory of the database or it won't be accessible"; "$(sys.statedir)/pg/." -> { "CFE-951" } perms => mog("0600", "cfpostgres", "cfpostgres"), depth_search => recurse_with_base(inf), file_select => not_dir, comment => "No one except for the database user needs to access where the db is installed."; "$(sys.statedir)/pg/." -> { "CFE-951" } perms => mog("0700", "cfpostgres", "cfpostgres"), depth_search => recurse_with_base(inf), file_select => dirs, comment => "No one except for the database user needs to access where the db is installed."; "$(sys.statedir)/cf-execd.sockets/." -> { "ENT-6777" } acl => cf_execd_socket_dir_acl(@(_cf_execd_socket_dir_user_aces)), if => isdir("$(sys.statedir)/cf-execd.sockets"); "$(sys.statedir)/cf-execd.sockets/runagent.socket" -> { "ENT-6777" } acl => cf_execd_socket_runagent_acl( @(_cf_execd_socket_runagent_user_aces) ), if => fileexists("$(sys.statedir)/cf-execd.sockets/runagent.socket"); } body acl cf_statedir_acl(aces) # @brief Describe ACL for state directory (sys.statedir) # @param aces A list of additional access control rules that should be used # # * User is allowed read, write, execute # * Group is allowed read, execute # * Permissions described by @(aces) # * Other is allowed nothing # # **Example:** # # ``` # bundle agent example # { # vars: # "_cf_statedir_allow_users" # slist => { "root", "cfpostgres", "cfapache" }; # "_cf_statedir_user_aces" # slist => maplist( "user:$(this):rx:allow", @(_cf_statedir_allow_users) ); # files: # "$(sys.statedir)/." # acl => cf_statedir_aces( @(_cf_statedir_user_aces) ); # } # ``` { acl_method => "overwrite"; acl_type => "posix"; aces => { "user:*:rwx:allow", "group:*:rx:allow", @(aces), "all:---:allow" }; } body acl cf_execd_socket_dir_acl(aces) # @brief Describe ACL for cf-execd socket directory # @param aces A list of additional access control rules that should be used # # * Owner is allowed read, write, execute # * Group is allowed nothing # * Permissions described by @(aces) # * Other is allowed nothing # # **Example:** # # ``` # bundle agent example # { # vars: # "_cf_execd_socket_allow_users" # slist => { "cfapache" }; # "_cf_execd_socket_dir_user_aces" # slist => maplist( "user:$(this):rx:allow", @(_cf_execd_socket_allow_users) ); # files: # "$(sys.statedir)/cf-execd.sockets/runagent.socket" # acl => cf_execd_socket_dir_aces( @(_cf_execd_socket_runagent_dir_aces) ); # } # ``` { acl_method => "overwrite"; acl_type => "posix"; aces => { "user:*:rwx:allow", "group:*:---:allow", @(aces), "all:---:allow" }; } body acl cf_execd_socket_runagent_acl(aces) # @brief Describe ACL for cf-execd runagent socket # @param aces A list of additional access control rules that should be used # # * Owner is allowed read, write # * Group is allowed nothing # * Permissions described by @(aces) # * Other is allowed nothing # # **Example:** # # ``` # bundle agent example # { # vars: # "_cf_execd_socket_allow_users" # slist => { "cfapache" }; # "_cf_execd_socket_runagent_user_aces" # slist => maplist( "user:$(this):rx:allow", @(_cf_execd_socket_allow_users) ); # files: # "$(sys.statedir)/cf-execd.sockets/runagent.socket" # acl => cf_execd_socket_runagent_acl( @(_cf_execd_socket_dir_user_aces) ); # } # ``` { acl_method => "overwrite"; acl_type => "posix"; aces => { "user:*:rw:allow", "group:*:---:allow", @(aces), "all:---:allow" }; } ############################################################################# body depth_search recurse_except(d, exceptions) # @breif Recurse (across device boundaires) `d` levels (excluding basedir) excluding `exceptions` # @param `d` Levels to decend in recursion # @param `exceptions` List of directories to exclude from depth search { depth => "$(d)"; include_basedir => "false"; exclude_dirs => { @(exceptions) }; } ############################################################################ body depth_search recurse_basedir(d) # @brief Search `d` levels deep including the base dir # @param `d` Levels to decend in recursion { depth => "$(d)"; include_basedir => "true"; } ########################################################################### body depth_search recurse_basedir_exclude(d) # @brief Search `d` levels deep including the base dir but exclude some specific dirs { depth => "$(d)"; include_basedir => "true"; exclude_dirs => { "static" }; } ############################################################################ body file_select cfe_internal_docroot_perms # @brief Select files (not dirs) not named `.htaccess` or `settings.ldap.php` { leaf_name => { "\.htaccess", "settings.ldap.php", "ha_enabled" }; path_name => { "$(cfe_internal_hub_vars.docroot)/vendor/.*" }; file_types => { "dir" }; # htaccess are going the way of the dodo bird # settings.ldap.php permissions are handled explicitly in it's own bundle # ha_enabled permissions is handled explicitly by cfengine_enterprise_ha_enabled_semaphore_present file_result => "!leaf_name.!file_types.!path_name"; } ############################################################################ body depth_search recurse_exclude(d) # @brief Search to a depth of `d` excluding known directories { depth => "$(d)"; exclude_dirs => { "hub", "graphs", "scripts", "tmp", "static", "logs", "api", "rest", "application", "dc-scripts", }; } ############################################################################ body file_select cfe_internal_exclude_sh_pl_scripts # @brief select plain files not ending in `.sh` and `.pl` { leaf_name => { ".*\.sh", ".*\.pl" }; file_types => { "plain" }; file_result => "!leaf_name.file_types"; } ############################################################################ body file_select cfe_internal_sh_pl_scripts # @brief select plain files ending in `.sh` and `.pl` { leaf_name => { ".*\.sh", ".*\.pl" }; file_types => { "plain" }; file_result => "leaf_name.file_types"; } ############################################################################ body file_select cfe_internal_htaccess # @brief select files named `.htaccess` { leaf_name => { "\.htaccess" }; file_types => { "dir" }; file_result => "leaf_name.!file_types"; } ############################################################################ body file_select cfe_internal_exclude_index_html { leaf_name => { "index.html" }; file_result => "!leaf_name"; } ############################################################################ body file_select cfe_internal_docroot_api_static_perms { # ENT-4551 - .status, .pid, and potentially .abort files used by async # query mechanism need to be writeable by the webserver, we exclude those # files here to avoid continual promise repair. leaf_name => { "\.htaccess", "\.status", "\.pid", "\.abort" }; file_types => { "dir" }; file_result => "!leaf_name.!file_types"; } ############################################################################ body file_select cfe_internal_docroot_api_static_async_query_status_status_perms # @brief .status, .pid and .abort files are used by the asynchronous query API and need to be writeable { # ENT-4551 - .status, .pid, and potentially .abort files used by async # query mechanism need to be writeable by the webserver leaf_name => { "\.status", "\.pid", "\.abort" }; file_types => { "dir" }; file_result => "leaf_name.!file_types"; } ############################################################################ body depth_search cfe_internal_docroot_application_perms { depth => "inf"; exclude_dirs => { "logs", "cache" }; } ############################################################################ body perms state_dir_system_owned_files { #+begin_ENT-951 # Remove after 3.20 is not supported rxdirs => "true"; @if minimum_version(3.20) rxdirs => "false"; @endif #+end mode => "0600"; !windows:: owners => { "root" }; freebsd|openbsd|netbsd|darwin:: groups => { "wheel" }; aix:: groups => { "system" }; hpux:: groups => { "sys" }; !(freebsd|openbsd|netbsd|darwin|aix|hpux):: groups => { "root" }; } body perms state_dir_system_owned_dirs { inherit_from => state_dir_system_owned_files; mode => "0700"; } cfengine-masterfiles-3.27.3/cfe_internal/enterprise/PaxHeaders/federation0000644000000000000000000000003615266337437023655 xustar0030 mtime=1792655135.129796305 cfengine-masterfiles-3.27.3/cfe_internal/enterprise/federation/0000755000000000000000000000000015266337437023037 5ustar0000000000000000cfengine-masterfiles-3.27.3/cfe_internal/enterprise/federation/federation.cf0000644000000000000000000013335114735102600025455 0ustar0000000000000000# @brief This policy file handles Federated Reporting setup and ongoing operations. # # There are several augments which can be used to tune the behavior of this policy: # # - `cfengine_mp_fr_dependencies_auto_install` class # # If defined then all non-shipped dependencies needed for Federated Reporting will be installed. # # ```json # { # "classes": { # "cfengine_mp_fr_dependencies_auto_install": [ "any::" ] # } # } # ``` # # - `cfengine_mp_fr_enable_distributed_cleanup` class # If defined then the distributed_cleanup script is partially setup and enabled to run. # Setup involves some manual steps detailed in templates/federated/distributed_cleanup.py. # The script deletes hosts on feeder hubs when a different feeder has a more recent # incoming communication (last seen database). Each feeder queries the superhub for # last seen information from other feeders. # # ```json # { # "classes": { # "cfengine_mp_fr_enable_distributed_cleanup": [ "any::" ] # } # } # ``` body file control { namespace => "cfengine_enterprise_federation"; } bundle agent config # @brief Read/parse config JSON, define variables and classes for use later { vars: enterprise_edition.(policy_server|am_policy_hub):: "federation_dir" string => "/opt/cfengine/federation"; "bin_dir" string => "$(federation_dir)/bin"; "path" string => "$(federation_dir)/cfapache/federation-config.json"; "path_setup_status" string => "$(federation_dir)/cfapache/setup-status.json"; "dump_interval" -> { "ENT-4806", "ENT-10900" } int => "20", if => not( isvariable("cfengine_enterprise_federation:config.dump_interval") ), comment => "Dump data on the feeders every 20 minutes"; # TODO: don't hard-code cftransport user "transport_user" -> { "ENT-4610" } string => "cftransport"; "transport_home" string => "$(cfengine_enterprise_federation:config.federation_dir)/cftransport"; config_present:: "data" data => readjson($(path)); classes: enterprise_edition.(policy_server|am_policy_hub):: "config_present" expression => fileexists($(path)); config_present:: "enabled" expression => or( strcmp("on", "$(data[target_state])"), strcmp("paused", "$(data[target_state])") ), scope => "namespace"; "am_off" expression => strcmp("off", "$(data[target_state])"), scope => "namespace"; "am_on" expression => strcmp("on", "$(data[target_state])"), scope => "namespace"; # _stdlib_path_exists_getenforce and paths.getenforce are defined by masterfiles/lib/paths.cf default:_stdlib_path_exists_getenforce:: "selinux_enabled" expression => strcmp( "Enforcing", execresult("$(default:paths.getenforce)", useshell) ), scope => "namespace"; vars: enabled:: "role" string => "$(data[role])"; "remotes" slist => getindices(@(data[remote_hubs])); "login" string => ""; # default "login" string => "$(data[remote_hubs][$(remotes)][transport][ssh_user])@$(data[remote_hubs][$(remotes)][transport][ssh_host])", if => and( # To ensure we are using a remote hub that's actually enabled strcmp("on", "$(data[remote_hubs][$(remotes)][target_state])"), # To ensure the remote we are pushing to actually needs the data (is a superhub) strcmp("superhub", "$(data[remote_hubs][$(remotes)][role])") ); am_superhub:: # Public keys of enabled pushing feeders need to be trusted (on a superhub) "pubkey[$(remotes)]" string => "$(data[remote_hubs][$(remotes)][transport][ssh_pubkey])", if => and( strcmp("on", "$(data[remote_hubs][$(remotes)][target_state])"), strcmp("feeder", "$(data[remote_hubs][$(remotes)][role])"), strcmp( "push_over_rsync", "$(data[remote_hubs][$(remotes)][transport][mode])" ) ); am_feeder:: # List of superhub hostkeys for use with dump process "superhubs[$(remotes)]" string => "$(data[remote_hubs][$(remotes)][hostkey])", if => and( strcmp("on", "$(data[remote_hubs][$(remotes)][target_state])"), strcmp("superhub", "$(data[remote_hubs][$(remotes)][role])"), strcmp( "pull_over_rsync", "$(data[remote_hubs][$(remotes)][transport][mode])" ) ); "superhub_hostkeys" string => join(" ", getvalues(superhubs)); # Public key(s) of enabled pulling superhub(s) need(s) to be trusted (on a feeder) "pubkey[$(remotes)]" string => "$(data[remote_hubs][$(remotes)][transport][ssh_pubkey])", if => and( strcmp("on", "$(data[remote_hubs][$(remotes)][target_state])"), strcmp("superhub", "$(data[remote_hubs][$(remotes)][role])"), strcmp( "pull_over_rsync", "$(data[remote_hubs][$(remotes)][transport][mode])" ) ); am_superhub|am_feeder:: "pubkeys" slist => getvalues(pubkey); "fingerprint[$(data[remote_hubs][$(remotes)][transport][ssh_host])]" slist => string_split( "$(data[remote_hubs][$(remotes)][transport][ssh_fingerprint])", "$(const.n)", "inf" ), # To ensure we are using a remote hub that's enabled if => strcmp("on", "$(data[remote_hubs][$(remotes)][target_state])"); "fingerprints" slist => maparray("$(this.k) $(this.v)", fingerprint); "feeder[$(remotes)]" string => "$(data[remote_hubs][$(remotes)][hostkey])", if => strcmp("feeder", "$(data[remote_hubs][$(remotes)][role])"); classes: enabled:: # Knowing if feeder or superhub is based on explicit setting of role in # path (federation-config.json) "am_feeder" expression => strcmp("feeder", "$(data[role])"), scope => "namespace"; "am_superhub" expression => strcmp("superhub", "$(data[role])"), scope => "namespace"; "am_pusher" and => { strcmp("superhub", "$(data[remote_hubs][$(remotes)][role])"), strcmp("on", "$(data[remote_hubs][$(remotes)][target_state])"), strcmp( "push_over_rsync", "$(data[remote_hubs][$(remotes)][transport][mode])" ), }, comment => "Has an enabled remote superhub with push as transport method, should run push transport", scope => "namespace"; "am_puller" and => { "am_superhub", strcmp("on", "$(data[remote_hubs][$(remotes)][target_state])"), strcmp( "pull_over_rsync", "$(data[remote_hubs][$(remotes)][transport][mode])" ), }, comment => "Superhub with some enabled remote hub with pull as transport method, should run pull transport", scope => "namespace"; "am_transporter" or => { "am_pusher", "am_puller" }, scope => "namespace"; "am_paused" expression => strcmp("paused", "$(data[target_state])"), scope => "namespace"; # Note: in order to see these debugs you must either define the default DEBUG class # or the namespace prefixed class like: # cf-agent -KI -DDEBUG # or # cf-agent -KI -Dcfengine_enterprise_federation:DEBUG_config reports: enabled.(default:DEBUG|DEBUG_config):: "Federation enabled!"; am_superhub.(default:DEBUG|DEBUG_config):: "I'm a superhub!"; am_feeder.(default:DEBUG|DEBUG_config):: "I'm a feeder!"; am_pusher.(default:DEBUG|DEBUG_config):: "I'm pushing dumps!"; am_puller.(default:DEBUG|DEBUG_config):: "I'm pulling dumps!"; am_transporter.(default:DEBUG|DEBUG_config):: "I'm a transporter!"; am_paused.(default:DEBUG|DEBUG_config):: "I'm paused so won't do any import/dump"; } bundle agent distributed_cleanup_dependencies # @brief warn if python3 and urllib3 required dependencies are not installed # if cfengine_mp_fr_enable_distributed_cleanup class is defined # Note: these requirements are only needed on superhub to run the distributed cleanup python script. # on feeders only the shell script is run so no python dependencies needed there. { vars: debian|ubuntu|redhat_9|rocky_9:: "packages" slist => { "python3", "python3-urllib3" }; redhat_8|centos_8:: "packages" slist => { "python36", "python3-urllib3" }; redhat_7|centos_7:: "packages" slist => { "python3" }; classes: (redhat_6|centos_6):: "cfengine_mp_fr_distributed_cleanup_python3_installed" expression => returnszero( "$(sys.bindir)/cfengine-selected-python --version | grep -q ' 3.'", "useshell" ); (redhat_6|centos_6|redhat_7|centos_7):: "cfengine_mp_fr_distributed_cleanup_urllib3_installed" expression => returnszero( "echo 'import urllib3' | $(sys.bindir)/cfengine-selected-python 2>/dev/null", "useshell" ); packages: debian|ubuntu:: "$(packages)" policy => "present", classes => default:results( "bundle", "cfengine_mp_fr_distributed_cleanup_packages" ), action => default:policy("warn"), package_module => default:apt_get; redhat.!(centos_6|redhat_6):: "$(packages)" policy => "present", classes => default:results( "bundle", "cfengine_mp_fr_distributed_cleanup_packages" ), package_module => default:yum; reports: (redhat_6|centos_6).!cfengine_mp_fr_distributed_cleanup_python3_installed:: "error: python3 is required for distributed cleanup utility. On this platform it is recommened you install python3 from source (https://docs.python.org/3.10/using/unix.html#building-python)"; (redhat_6|centos_6).!cfengine_mp_fr_distributed_cleanup_urllib3_installed:: "error: python3 module urllib3 is required for distributed cleanup utility. On this platform it is recommend you install via pip3 after installing python3 from source"; (redhat_7|centos_7).!cfengine_mp_fr_distributed_cleanup_urllib3_installed:: "error: python3 module urllib3 is required for distributed cleanup utility. On this platform please install with the command `pip3 install urllib3`"; } bundle agent semanage_installed # @brief Install semanage utility if selinux enabled and # cfengine_mp_fr_dependencies_auto_install class is defined # if not defined then only warn { vars: "semanage_action" string => ifelse( "default:_stdlib_path_exists_semanage", "fix", "default:cfengine_mp_fr_dependencies_auto_install", "fix", "warn" ), comment => "We only want to use semanage if it's available, or if we have indicated it's ok to install it automatically. This variable is subsequently used by a commands and packages promises to warn or fix based."; debian_6|debian_7|debian_8|ubuntu_12|ubuntu_14|ubuntu_16|rhel_5:: "semanage_package" string => "policycoreutils"; debian_9|debian_10|ubuntu_18|redhat_8|centos_8|redhat_9|rocky_9|redhat_10|rocky_10:: "semanage_package" string => "policycoreutils-python-utils"; redhat_6|centos_6|redhat_7|centos_7:: "semanage_package" string => "policycoreutils-python"; packages: debian|ubuntu:: "$(semanage_package)" policy => "present", package_module => default:apt_get, action => default:policy($(semanage_action)); redhat:: "$(semanage_package)" policy => "present", package_module => default:yum, action => default:policy($(semanage_action)); reports: default:DEBUG|DEBUG_semanage_installed:: "paths.semanage = $(default:paths.semanage)"; !default:_stdlib_path_exists_semanage.!default:cfengine_mp_fr_dependencies_auto_install:: "semanage command is not available at $(default:paths.semanage). Will only install needed package if cfengine_mp_fr_dependencies_auto_install class is defined in augments(def.json) or with --define cf-agent option."; } bundle agent ssh_keygen(key_path) { commands: "/usr/bin/ssh-keygen" handle => "ssh_keys_configured", args => "-N '' -f $(key_path)", if => not(fileexists("$(key_path)")); } bundle agent ssh_selinux_context(home, ssh_paths) { classes: default:_stdlib_path_exists_semanage:: "cftransport_fcontext_missing" expression => not( returnszero( "$(default:paths.semanage) fcontext -l | grep '$(home)/.ssh(/.*)?'", "useshell" ) ), if => fileexists("$(home)"); any:: # For all the files below it must be true that if they exist they need # to have the right context. # IOW, the following implication: if fileexists() then correct_context. # IOW, the following OR: not(filexists()) or correct_context. # not( and()) means that if for one of the files the implication is false, we get a true. "incorrect_ssh_context" expression => not( and( or( not(fileexists("$(home)")), regcmp( ".*[\s:]ssh_home_t[\s:].*", execresult("$(default:paths.ls) -dZ $(home)/.ssh", noshell) ) ), or( not(fileexists("$(ssh_paths[auth_keys])")), regcmp( ".*[\s:]ssh_home_t[\s:].*", execresult( "$(default:paths.ls) -Z $(ssh_paths[auth_keys])", noshell ) ) ), or( not(fileexists("$(ssh_paths[priv_key])")), regcmp( ".*[\s:]ssh_home_t[\s:].*", execresult( "$(default:paths.ls) -Z $(ssh_paths[priv_key])", noshell ) ) ), or( not(fileexists("$(ssh_paths[pub_key])")), regcmp( ".*[\s:]ssh_home_t[\s:].*", execresult( "$(default:paths.ls) -Z $(ssh_paths[pub_key])", noshell ) ) ), or( not(fileexists("$(ssh_paths[config])")), regcmp( ".*[\s:]ssh_home_t[\s:].*", execresult( "$(default:paths.ls) -Z $(ssh_paths[config])", noshell ) ) ) ) ); commands: # _stdlib_path_exists_ and paths. are defined is masterfiles/lib/paths.cf cftransport_fcontext_missing.default:_stdlib_path_exists_semanage:: "$(default:paths.semanage) fcontext -a -t ssh_home_t '$(home)/.ssh(/.*)?'"; incorrect_ssh_context.default:_stdlib_path_exists_restorecon:: "$(default:paths.restorecon) -R -F $(home)/.ssh/"; reports: incorrect_ssh_context.!default:_stdlib_path_exists_semanage:: "need to fix incorrect ssh context for transport user but semanage path in $(sys.libdir)/paths.cf $(default:paths.semanage) does not resolve"; incorrect_ssh_context.!default:_stdlib_path_exists_restorecon):: "need to fix incorrect ssh context for transport user but restorecon path in $(sys.libdir)/paths.cf $(default:paths.restorecon) does not resolve"; } bundle agent transport_user # @brief Manage transport user and permissions for remote SSH access { vars: "user" string => "$(cfengine_enterprise_federation:config.transport_user)"; "home" string => "$(cfengine_enterprise_federation:config.transport_home)"; "ssh_key_name" string => "id_FR"; "ssh_priv_key" string => "$(home)/.ssh/$(ssh_key_name)"; "ssh_pub_key" string => "$(ssh_priv_key).pub"; "ssh_auth_keys" string => "$(home)/.ssh/authorized_keys"; "ssh_known_hosts" string => "$(home)/.ssh/known_hosts"; "ssh_config" string => "$(home)/.ssh/config"; "create_files" slist => { "$(home)/.", "$(home)/.ssh/.", "$(home)/source/.", # Dumps from feeders are taken from here "$(home)/destination/.", # And dropped here on superhub "$(ssh_auth_keys)", "$(ssh_known_hosts)", "$(ssh_config)", }; "ssh_paths" data => parsejson( '{ "key_name": "id_FR", "priv_key": "$(home)/.ssh/$(ssh_key_name)", "pub_key": "$(ssh_priv_key).pub", "auth_keys": "$(home)/.ssh/authorized_keys", "known_hosts": "$(home)/.ssh/known_hosts", "config": "$(home)/.ssh/config" }' ); users: "$(user)" policy => "present", home_dir => "$(home)"; files: "$(create_files)" create => "true"; "$(home)/." -> { "CFE-951" } depth_search => default:recurse_with_base("inf"), file_select => default:dirs, perms => default:mog("700", $(user), "root"), comment => "The transport users home directory and children should be accessible only by the transport user itself."; "$(home)/." -> { "CFE-951" } depth_search => default:recurse_with_base("inf"), file_select => default:not_dir, perms => default:mog("600", $(user), "root"), comment => "The files within the transport users home directory should be readable and writable by the transport user"; "$(ssh_auth_keys)" create => "true", handle => "ssh_auth_keys_configured", edit_template_string => "{{#-top-}}{{{.}}}$(const.n){{/-top-}}", template_data => @(cfengine_enterprise_federation:config.pubkeys), template_method => "inline_mustache"; "$(ssh_known_hosts)" create => "true", handle => "ssh_known_hosts_configured", edit_template_string => "{{#-top-}}{{{.}}}$(const.n){{/-top-}}", template_data => @(cfengine_enterprise_federation:config.fingerprints), template_method => "inline_mustache", if => isvariable("cfengine_enterprise_federation:config.fingerprints"); "$(ssh_config)" create => "true", handle => "ssh_config_configured", edit_line => default:insert_lines("IdentityFile $(ssh_priv_key)"); methods: selinux_enabled:: "semanage_installed" usebundle => semanage_installed; enabled.selinux_enabled:: # Ensure correct SElinux context "ssh_selinux_context" usebundle => ssh_selinux_context("$(home)", @(ssh_paths)); enabled:: # Generate ssh keypair "ssh_keygen" usebundle => ssh_keygen("$(ssh_priv_key)"); } bundle agent clean_when_off # @brief cleanup changes made for federated reporting on a feeder # NOTE: a superhub turned off by removing federation-config.json or setting # federation_manage_files will always run regardless of off or not # so as to be prepared for enablement via Mission Portal UI { vars: "user" string => "$(cfengine_enterprise_federation:transport_user.user)"; "home" string => "$(cfengine_enterprise_federation:transport_user.home)"; @if minimum_version(3.15) "remote_hubs_table_row_count" string => execresult( `$(sys.bindir)/psql cfsettings --quiet --tuples-only --command "SELECT COUNT(*) FROM remote_hubs" 2>/dev/null`, useshell ); "federated_reporting_settings_table_row_count" string => execresult( `$(sys.bindir)/psql cfsettings --quiet --tuples-only --command "SELECT COUNT(*) FROM federated_reporting_settings" 2>/dev/null`, useshell ); @endif users: "$(user)" policy => "absent"; files: "$(cfengine_enterprise_federation:config.path_setup_status)" -> { "ENT-7233" } comment => "We must remove this file for Mission Portal to understand that the federation is not configured", delete => default:tidy; "$(cfengine_enterprise_federation:config.path)" -> { "ENT-7969" } comment => "We must remove this file for Mission Portal to understand that the federation is not configured", delete => default:tidy; methods: "rm_rf_cftransport_home_dir" usebundle => default:rm_rf("$(home)"); classes: selinux_enabled.default:_stdlib_path_exists_semanage:: "has_cftransport_fcontext" expression => returnszero( "$(default:paths.semanage) fcontext -l | grep $(home)", "useshell" ); commands: # Oh, the humanity! Where for art thou databases: promises for psql! `$(sys.bindir)/psql cfsettings --quiet --command "TRUNCATE TABLE remote_hubs"` -> { "ENT-7233" } if => isgreaterthan("$(remote_hubs_table_row_count)", "0"); `$(sys.bindir)/psql cfsettings --quiet --command "TRUNCATE TABLE federated_reporting_settings"` -> { "ENT-7233" } if => isgreaterthan( "$(federated_reporting_settings_table_row_count)", "0" ); # _stdlib_path_exists_ and paths. are defined in masterfiles/lib/paths.cf selinux_enabled.default:_stdlib_path_exists_semanage.has_cftransport_fcontext:: "$(default:paths.semanage) fcontext -d '$(home)/.ssh(/.*)?'"; } bundle agent federation_manage_files # @brief Manage files, directories and permissions in $(cfengine_enterprise_federation:config.federation_dir) # # By default the import process will not prohibit the inclusion of duplicate hostkey data from feeders. # By defining the `cfengine_mp_fr_handle_duplicate_hostkeys` class in augments a step will be performed # during import which will find the which feeder's data is most recent for each duplicate hostkey and # use that data. Duplicate hostkey data will be moved to a `dup` schema for analysis. # # This class only applies to superhubs. # # ```json # { # "classes": { # "cfengine_mp_fr_handle_duplicate_hostkeys": [ "any::" ] # } # } # ``` { vars: "transport_user" string => "$(cfengine_enterprise_federation:config.transport_user)"; "login" data => parsejson( '{"login":"$(cfengine_enterprise_federation:config.login)"}' ); "feeder_username" data => parsejson( '{"feeder_username":"$(cfengine_enterprise_federation:config.transport_user)"}' ); "superhub_hostkeys" string => ifelse( isvariable("cfengine_enterprise_federation:config.superhub_hostkeys"), "$(cfengine_enterprise_federation:config.superhub_hostkeys)", "" ); "this_hostkey" data => parsejson('{"this_hostkey":"$(default:sys.key_digest)"}'); "feeder" data => parsejson('{"feeder": "$(sys.key_digest)"}'); "cf_version" data => parsejson('{"cf_version":"$(sys.cf_version)"}'); "workdir" data => parsejson('{"workdir":"$(sys.workdir)"}'); "handle_duplicates_value" string => ifelse( "default:cfengine_mp_fr_handle_duplicate_hostkeys", "yes", "no" ); "handle_duplicates" data => parsejson('{"handle_duplicates":"$(handle_duplicates_value)"}'); "debug_import_value" string => ifelse("default:cfengine_mp_fr_debug_import", "yes", "no"); "debug_import" data => parsejson('{"debug_import":"$(debug_import_value)"}'); files: enterprise_edition.(policy_server|am_policy_hub):: # Both cfpache and $(transport_user) need permission so adding o+x here "$(cfengine_enterprise_federation:config.federation_dir)/." -> { "CFE-951" } create => "true", perms => default:mog("755", "root", "cfapache"); "$(cfengine_enterprise_federation:config.federation_dir)/cfapache/." create => "true", perms => default:mog("700", "cfapache", "root"); "$(cfengine_enterprise_federation:config.federation_dir)/cfapache/." -> { "CFE-951" } depth_search => default:recurse_with_base("inf"), file_select => default:dirs, perms => default:mog("700", "cfapache", "root"), comment => "The cfapache home directory and children need to be accessible by the web-server"; "$(cfengine_enterprise_federation:config.federation_dir)/cfapache/." -> { "CFE-951" } depth_search => default:recurse_with_base("inf"), file_select => default:not_dir, perms => default:mog("600", "cfapache", "root"), comment => "Files within the cfapache home directory need to be readable and writable by the web server."; enabled:: "$(cfengine_enterprise_federation:config.bin_dir)/." -> { "CFE-951" } create => "true", perms => default:mog("0770", "root", "$(transport_user)"); am_superhub:: "$(cfengine_enterprise_federation:config.federation_dir)/superhub/." create => "true", perms => default:mog("770", "root", "$(transport_user)"); "$(cfengine_enterprise_federation:config.federation_dir)/superhub/import/." create => "true", perms => default:mog("600", "root", "root"); "$(cfengine_enterprise_federation:config.federation_dir)/superhub/import/filters/." create => "true", perms => default:mog("600", "root", "root"); am_feeder:: "$(cfengine_enterprise_federation:config.federation_dir)/fedhub/." create => "true", perms => default:mog("660", "root", "$(transport_user)"); "$(cfengine_enterprise_federation:config.federation_dir)/fedhub/dump/." create => "true", perms => default:mog("660", "root", "$(transport_user)"); "$(cfengine_enterprise_federation:config.federation_dir)/fedhub/transport/." create => "true", perms => default:mog("660", "root", "$(transport_user)"); "$(cfengine_enterprise_federation:config.federation_dir)/fedhub/dump/filters/." create => "true", perms => default:mog("600", "root", "root"); am_feeder|am_transporter|am_superhub:: # TODO: Instrument augments "$(cfengine_enterprise_federation:config.bin_dir)/config.sh" create => "true", template_method => "mustache", edit_template => "$(this.promise_dirname)/../../../templates/federated_reporting/config.sh.mustache", template_data => mergedata( @(login), @(feeder_username), @(feeder), parsejson('{"superhub_hostkeys": "$(superhub_hostkeys)"}'), @(debug_import), @(this_hostkey), @(cf_version), @(handle_duplicates), parsejson('{"inventory_refresh_cmd": ""}') ), perms => default:mog("640", "root", "$(transport_user)"); # TODO: Instrument augments "$(cfengine_enterprise_federation:config.bin_dir)/log.sh" create => "true", template_method => "mustache", edit_template => "$(this.promise_dirname)/../../../templates/federated_reporting/log.sh.mustache", perms => default:mog("640", "root", "$(transport_user)"); "$(cfengine_enterprise_federation:config.bin_dir)/parallel.sh" copy_from => default:local_dcp( "$(this.promise_dirname)/../../../templates/federated_reporting/parallel.sh" ), perms => default:mog("640", "root", "$(transport_user)"); "$(cfengine_enterprise_federation:config.bin_dir)/psql_wrapper.sh" -> { "ENT-4792" } create => "true", edit_template => "$(this.promise_dirname)/../../../templates/federated_reporting/psql_wrapper.sh.mustache", template_method => "mustache", perms => default:mog("700", "root", "root"); am_feeder:: "$(cfengine_enterprise_federation:config.bin_dir)/dump.sh" copy_from => default:local_dcp( "$(this.promise_dirname)/../../../templates/federated_reporting/dump.sh" ), perms => default:mog("700", "root", "root"); am_transporter:: "$(cfengine_enterprise_federation:config.bin_dir)/transport.sh" -> { "CFE-951" } copy_from => default:local_dcp( "$(this.promise_dirname)/../../../templates/federated_reporting/transport.sh" ), perms => default:mog("500", "$(transport_user)", "root"); am_puller:: "$(cfengine_enterprise_federation:config.bin_dir)/pull_dumps_from.sh" copy_from => default:local_dcp( "$(this.promise_dirname)/../../../templates/federated_reporting/pull_dumps_from.sh" ), perms => default:mog("500", "$(transport_user)", "root"); am_superhub:: "$(cfengine_enterprise_federation:config.bin_dir)/import.sh" copy_from => default:local_dcp( "$(this.promise_dirname)/../../../templates/federated_reporting/import.sh" ), perms => default:mog("700", "root", "root"); "$(cfengine_enterprise_federation:config.bin_dir)/import_file.sh" copy_from => default:local_dcp( "$(this.promise_dirname)/../../../templates/federated_reporting/import_file.sh" ), perms => default:mog("700", "root", "root"); "$(cfengine_enterprise_federation:config.federation_dir)/superhub/import/filters/10-base_filter.sed" copy_from => default:local_dcp( "$(this.promise_dirname)/../../../templates/federated_reporting/10-base_filter.sed" ), perms => default:mog("600", "root", "root"); am_superhub.default:cfengine_mp_fr_enable_distributed_cleanup:: "$(cfengine_enterprise_federation:config.bin_dir)/transfer_distributed_cleanup_items.sh" copy_from => default:local_dcp( "$(this.promise_dirname)/../../../templates/federated_reporting/transfer_distributed_cleanup_items.sh" ), perms => default:mog("500", "$(transport_user)", "root"); "$(cfengine_enterprise_federation:config.bin_dir)/distributed_cleanup.py" copy_from => default:local_dcp( "$(this.promise_dirname)/../../../templates/federated_reporting/distributed_cleanup.py" ), perms => default:mog("500", "root", "root"); "$(cfengine_enterprise_federation:config.bin_dir)/nova_api.py" copy_from => default:local_dcp( "$(this.promise_dirname)/../../../templates/federated_reporting/nova_api.py" ), perms => default:mog("500", "root", "root"); "$(cfengine_enterprise_federation:config.bin_dir)/cfsecret.py" copy_from => default:local_dcp( "$(this.promise_dirname)/../../../templates/federated_reporting/cfsecret.py" ), perms => default:mog("500", "root", "root"); } bundle agent postgres_config # @brief Customize postgres config for superhub # @variable cfengine_enterprise_federation:postgres_config.shared_buffers - Sets the maximum number of locks per transaction. # @variable cfengine_enterprise_federation:postgres_config.max_locks_per_transaction - Sets the maximum number of locks per transaction. # @variable cfengine_enterprise_federation:postgres_config.log_lock_waits - Logs long lock waits. # @variable cfengine_enterprise_federation:postgres_config.max_wal_size - Sets the WAL size that triggers a checkpoint. # @variable cfengine_enterprise_federation:postgres_config.checkpoint_timeout- Sets the maximum time between automatic WAL checkpoints. { vars: am_superhub:: "c[shared_buffers]" -> { "ENT-8617" } string => ifelse( isvariable( "cfengine_enterprise_federation:postgres_config.shared_buffers" ), $(cfengine_enterprise_federation:postgres_config.shared_buffers), "1GB" ), comment => "Changing this setting requires restarting the database."; "c[max_locks_per_transaction]" -> { "ENT-8617" } string => ifelse( isvariable( "cfengine_enterprise_federation:postgres_config.max_locks_per_transaction" ), $(cfengine_enterprise_federation:postgres_config.max_locks_per_transaction), "4000" ), comment => "Changing this setting requires restarting the database."; "c[log_lock_waits]" -> { "ENT-8617" } string => ifelse( isvariable( "cfengine_enterprise_federation:postgres_config.log_lock_waits" ), $(cfengine_enterprise_federation:postgres_config.log_lock_waits), "on" ), comment => "Changing this setting requires restarting the database."; "c[max_wal_size]" -> { "ENT-8617" } string => ifelse( isvariable( "cfengine_enterprise_federation:postgres_config.max_wal_size" ), $(cfengine_enterprise_federation:postgres_config.max_wal_size), "1GB" ); "c[checkpoint_timeout]" -> { "ENT-8617" } string => ifelse( isvariable( "cfengine_enterprise_federation:postgres_config.checkpoint_timeout" ), $(cfengine_enterprise_federation:postgres_config.checkpoint_timeout), "5min" ); files: am_superhub:: "$(sys.statedir)/pg/data/postgresql.conf" edit_line => default:set_line_based( "$(this.namespace):$(this.bundle).c", "=", "\s*=\s*", ".*", "" ), classes => default:results("bundle", "postgresql_conf"), if => fileexists("$(sys.statedir)/pg/data/postgresql.conf"); commands: am_superhub.postgresql_conf_repaired.!systemd:: # smart mode tries to wait for operations to finish and clients to # disconnect, fast mode terminates open connections gracefully "$(sys.bindir)/pg_ctl --pgdata $(sys.statedir)/pg/data --log /var/log/postgresql.log --wait --mode smart restart || $(sys.bindir)/pg_ctl --pgdata $(sys.statedir)/pg/data --log /var/log/postgresql.log --wait --mode fast restart" contain => cfpostgres_user; services: am_superhub.postgresql_conf_repaired.systemd:: "cf-postgres" service_method => default:standard_services, service_policy => "restart"; } body contain cfpostgres_user { useshell => "useshell"; exec_owner => "cfpostgres"; exec_group => "cfpostgres"; chdir => "/tmp"; no_output => "false"; } bundle agent exported_data # @brief Run script to dump pg data on feeder hub # @note Since version 3.24.0, the inventory view is automatically refreshed by # cf-reactor whenever inventory is updated. Hence, you can assume that the # inventory is refreshed. However, there is one exception; if the previous # refresh happened too recently, the following one will be delayed. { @if before_version(3.24.0) methods: am_feeder.!am_paused:: "Refresh Inventory" usebundle => "default:cfe_internal_refresh_inventory_view", handle => "fr_inventory_refresh", comment => "Use standard inventory refresh so that we don't run it twice"; @endif commands: am_feeder.!am_paused:: "/bin/bash" arglist => { "$(cfengine_enterprise_federation:config.bin_dir)/dump.sh" }, contain => default:in_shell, @if before_version(3.24.0) depends_on => { "fr_inventory_refresh" }, @endif comment => "Refresh Inventory must be completed before dumping data"; } bundle agent data_transport # @brief Run script to transport data from feeder to superhub { vars: am_puller.!am_paused:: # local copies of the variables to make using them below sane "remotes" slist => { @(cfengine_enterprise_federation:config.remotes) }; "data" data => @(cfengine_enterprise_federation:config.data); "enabled_pull_hosts[$(remotes)]" string => "$(data[remote_hubs][$(remotes)][transport][ssh_host])", if => and( strcmp("on", "$(data[remote_hubs][$(remotes)][target_state])"), strcmp( "pull_over_rsync", "$(data[remote_hubs][$(remotes)][transport][mode])" ) ); "pull_args" -> { "ENT-4499" } string => join(" ", getvalues(@(enabled_pull_hosts))); commands: am_pusher.!am_paused:: "/bin/bash" arglist => { "$(cfengine_enterprise_federation:config.bin_dir)/transport.sh push" }, contain => contain_transport_user; am_puller.!am_paused:: "/bin/bash" arglist => { "$(cfengine_enterprise_federation:config.bin_dir)/transport.sh pull $(pull_args)", }, contain => contain_transport_user; am_puller.!am_paused.default:cfengine_mp_fr_enable_distributed_cleanup:: "/bin/bash" arglist => { "$(cfengine_enterprise_federation:config.bin_dir)/transfer_distributed_cleanup_items.sh $(pull_args)", }, contain => contain_transport_user; } body contain contain_transport_user { exec_owner => "$(cfengine_enterprise_federation:config.transport_user)"; exec_group => "$(cfengine_enterprise_federation:config.transport_user)"; chdir => "$(cfengine_enterprise_federation:config.transport_home)"; useshell => "true"; } bundle agent imported_data # @brief Run script to import dumps on superhub { commands: "/bin/bash" arglist => { "$(cfengine_enterprise_federation:config.bin_dir)/import.sh" }, contain => default:in_shell; } bundle agent superhub_schema # @brief Run SQL script to ensure schema is migrated to superhub partitioned tables architecture { commands: am_superhub:: "$(cfengine_enterprise_federation:config.bin_dir)/psql_wrapper.sh" arglist => { "cfdb", @if minimum_version(3.24) "select superhub_schema('$(sys.key_digest)');", @else `"select superhub_schema('$(sys.key_digest)');"`, @endif }, classes => psql_wrapper_exit_codes; } bundle agent ensure_feeders # @brief Run SQL function to ensure that all configured feeder hubs are in __hubs table { vars: am_superhub:: "feeders" slist => getvalues("cfengine_enterprise_federation:config.feeder"); "feeders_arg" string => concat("ARRAY['", join("', '", feeders), "']"); commands: am_superhub:: "$(cfengine_enterprise_federation:config.bin_dir)/psql_wrapper.sh" arglist => { "cfdb", @if minimum_version(3.24) "select ensure_feeders($(feeders_arg));", @else `"select ensure_feeders($(feeders_arg));"`, @endif }, classes => psql_wrapper_exit_codes, if => isgreaterthan(length(feeders), 0); } body classes psql_wrapper_exit_codes { kept_returncodes => { "0" }; repaired_returncodes => { "1" }; failed_returncodes => { "2" }; } bundle agent entry # @brief Conditionally runs all federated reporting bundles { meta: (policy_server|am_policy_hub).enterprise_edition:: "tags" -> { "ENT-4383" } slist => { "enterprise_maintenance" }; classes: enterprise_edition.(policy_server|am_policy_hub):: "config_exists" expression => fileexists( "$(cfengine_enterprise_federation:config.federation_dir)/cfapache/federation-config.json" ); enterprise_edition.(policy_server|am_policy_hub):: "config_not_exists" expression => not( fileexists( "$(cfengine_enterprise_federation:config.federation_dir)/cfapache/federation-config.json" ) ); methods: config_exists:: "CFEngine Enterprise Federation Configuration" handle => "config", usebundle => config; am_policy_hub.(am_off|config_not_exists):: "CFEngine Enterprise Federation Transport Off" handle => "clean_when_off", usebundle => clean_when_off, if => cf_version_minimum("3.15"); enabled.am_on:: "CFEngine Enterprise Federation Transport User" handle => "transport_user", usebundle => transport_user; enterprise_edition.(policy_server|am_policy_hub):: "federation_manage_files" handle => "federation_manage_files", usebundle => federation_manage_files; enabled.am_on:: "CFEngine Enterprise Federation Postgres Configuration" handle => "postgres_config", usebundle => postgres_config; "CFEngine Enterprise Federation Schema Migration" handle => "superhub_schema", depends_on => { "postgres_config" }, usebundle => superhub_schema; "CFEngine Enterprise Federation Ensure Feeder Hubs in Database" handle => "ensure_feeders", depends_on => { "superhub_schema" }, usebundle => ensure_feeders; "CFEngine Enterprise Federation Feeder Data Transport" handle => "data_transport", depends_on => { "transport_user" }, usebundle => data_transport; "CFEngine Enterprise Federation Feeder Data Export" usebundle => exported_data, action => default:if_elapsed( $(cfengine_enterprise_federation:config.dump_interval) ); "Configuration Status" usebundle => setup_status; enabled.am_on.am_superhub.!am_paused:: "CFEngine Enterprise Federation Feeder Data Import" handle => "imported_data", depends_on => { "transport_user", "ensure_feeders" }, usebundle => imported_data; am_policy_hub.default:cfengine_mp_fr_enable_distributed_cleanup:: "Distributed Cleanup Dependencies" handle => "distributed_cleanup_dependencies", if => "enabled.am_on.am_superhub.!am_paused", usebundle => "distributed_cleanup_dependencies"; "Distributed Cleanup Setup" handle => "distributed_cleanup_setup", depends_on => { "transport_user", "data_transport" }, usebundle => "distributed_cleanup_setup"; "Distributed Federated Host Cleanup" handle => "distributed_cleanup", if => "enabled.am_on.am_superhub.!am_paused", depends_on => { "imported_data", "distributed_cleanup_setup", "distributed_cleanup_dependencies", }, usebundle => distributed_cleanup_run; reports: !enterprise_edition:: "Federated reporting is only available in CFEngine Enterprise."; enterprise_edition.!(policy_server|am_policy_hub):: "Federated reporting is only available on the policy server / hub."; } bundle agent setup_status { vars: "role" string => "$(cfengine_enterprise_federation:config.role)"; "ssh_pub_key" string => readfile( "$(cfengine_enterprise_federation:transport_user.ssh_pub_key)" ), if => fileexists( "$(cfengine_enterprise_federation:transport_user.ssh_pub_key)" ); "ssh_server_fingerprint" # ssh-keyscan is used because it's more reliable/easy than trying to # parse sshd config to find the file and then readfile(): string => execresult( "ssh-keyscan localhost 2>/dev/null | sed 's/localhost //g' | sort", useshell ); classes: "ssh_server_fingerprint_collected" expression => not(strcmp("$(ssh_server_fingerprint)", "")); "superhub_setup_status_complete" expression => "any", depends_on => { "config", "transport_user", "postgres_config", # We are depending on a deep guard within this bundle "federation_manage_files", }; files: # An empty fingerprint (ssh-keyscan returned nothing, e.g. sshd not yet # reachable on localhost) must not be advertised: a superhub would render # an empty known_hosts entry for this host and its rsync pull would later # fail with "Host key verification failed". Skip the status update until # the fingerprint is collected; the next agent run will retry. superhub_setup_status_complete.ssh_server_fingerprint_collected:: "$(cfengine_enterprise_federation:config.path_setup_status)" create => "true", perms => default:mog("600", "cfapache", "root"), template_method => "inline_mustache", edit_template_string => "{{%-top-}}$(const.n)", template_data => '{ "configured": true, "role": "$(role)", "hostkey": "$(sys.key_digest)", "transport_ssh_public_key": "$(ssh_pub_key)", "transport_ssh_server_fingerprint": "$(ssh_server_fingerprint)", }', if => isvariable(ssh_pub_key); reports: superhub_setup_status_complete.!ssh_server_fingerprint_collected:: "warning: 'ssh-keyscan localhost' returned no SSH host key; federation setup status not written yet. Will retry next run."; } bundle agent distributed_cleanup_setup { vars: "distributed_cleanup_dir" string => "/opt/cfengine/federation/cftransport/distributed_cleanup"; # TODO: Remove this once sys.keydir is always available (3.26+ only) "keydir" string => ifelse( isvariable("sys.keydir"), "$(sys.keydir)", "$(sys.workdir)/ppkeys" ); files: am_superhub|am_feeder:: "${distributed_cleanup_dir}/." perms => default:mog( "700", "$(cfengine_enterprise_federation:config.transport_user)", "root" ), create => "true"; "${distributed_cleanup_dir}/${sys.fqhost}.pub" perms => default:mog( "600", "$(cfengine_enterprise_federation:config.transport_user)", "root" ), copy_from => default:local_cp("${keydir}/localhost.pub"); "${distributed_cleanup_dir}/${sys.fqhost}.cert" perms => default:mog( "600", "$(cfengine_enterprise_federation:config.transport_user)", "root" ), copy_from => default:local_cp( "${sys.workdir}/httpd/ssl/certs/${sys.fqhost}.cert" ); } bundle agent distributed_cleanup_run { vars: "_arglist" slist => { ifelse("debug_mode", "--debug", "inform_mode", "--inform", "") }; commands: am_superhub.!am_paused.default:cfengine_mp_fr_enable_distributed_cleanup:: "$(sys.bindir)/cfengine-selected-python" args => "$(cfengine_enterprise_federation:config.bin_dir)/distributed_cleanup.py", arglist => { @(_arglist) }, unless => isvariable("default:def.DISTRIBUTED_CLEANUP_SSL_CERT_DIR"); "SSL_CERT_DIR=$(default:def.DISTRIBUTED_CLEANUP_SSL_CERT_DIR) $(sys.bindir)/cfengine-selected-python" -> { "ENT-8477", "ENT-8464" } args => "$(cfengine_enterprise_federation:config.bin_dir)/distributed_cleanup.py", arglist => { @(_arglist) }, if => isvariable("default:def.DISTRIBUTED_CLEANUP_SSL_CERT_DIR"), contain => default:in_shell, comment => "When custom SSL certificates are used from the non default location we need to let the script know where to find them."; } body file control { namespace => "default"; } bundle agent __main__ # @brief You can run this policy file from shell without specifying bundle { methods: "entry" usebundle => cfengine_enterprise_federation:entry; } cfengine-masterfiles-3.27.3/cfe_internal/enterprise/file_change.cf0000644000000000000000000000446114735102600023440 0ustar0000000000000000######################################################################### # # file_change.cf - Change Management # # NOTE: Be careful with the amount of data that CFEngine is to watch. # Large amounts can cause resource hogs and long-running agents. # ######################################################################### bundle agent change_management { vars: linux:: "watch_files_report_diffs" slist => { "/etc/passwd", "/etc/group", "/etc/services", "$(sys.statedir)/pg/data/postgresql.conf", }, comment => "These files will be watched for change, and diffs will be reported back to mission portal if you are running CFEngine Enterprise."; "watch_files_report_change" slist => { "/etc/shadow" }, comment => "These files will be watched for change. No diffs will be reported back to mission portal, only that the file did change."; files: linux:: "$(watch_files_report_diffs)" -> { "InfoSec" } changes => diff, handle => "change_management_files_watch_files_report_diffs", if => fileexists($(watch_files_report_diffs)), comment => "Unplanned changes of these files may indicate a security breach."; "$(watch_files_report_change)" -> { "InfoSec" } changes => detect_content_using("sha256"), if => fileexists($(watch_files_report_change)), comment => "Unplanned changes of these files may indicate a security breach. (Diffs are not reported in case those with access to this report should not have access to shadow entries.)"; ####################################################################### # Redundant cross monitoring for strong `tripwire' ............... ####################################################################### # "$(sys.workdir)/nw/$(neighbours)_checksum_digests.db" # comment => "Watching our peers remote hash tables for changes - cross check", # copy_from => remote_cp("$(sys.workdir)/checksum_digests.db","$(neighbours)"), # action => neighbourwatch("File hash changes observed on $(neighbours) (neighbourhood watch)"); } cfengine-masterfiles-3.27.3/cfe_internal/enterprise/PaxHeaders/ha0000644000000000000000000000003515266337437022124 xustar0029 mtime=1792655135.12579617 cfengine-masterfiles-3.27.3/cfe_internal/enterprise/ha/0000755000000000000000000000000015266337437021307 5ustar0000000000000000cfengine-masterfiles-3.27.3/cfe_internal/enterprise/ha/ha.cf0000644000000000000000000001066514735102600022177 0ustar0000000000000000bundle agent ha_main { classes: enable_cfengine_enterprise_hub_ha:: "have_ha_hub_active_ip" expression => isvariable("sys.hub_active_ip"); methods: policy_server.enterprise:: "manage_mp_enable_cfengine_enterprise_hub_ha_file" usebundle => ha_manage_mp_status_file; policy_server.enable_cfengine_enterprise_hub_ha.hub_active:: "manage_mp_enable_cfengine_enterprise_hub_ha_file" usebundle => ha_manage_notification_scripts_dir; policy_server.!hub_active.have_ha_hub_active_ip:: "sync_config_data" usebundle => ha_hub_sync_config_data; } # enable_cfengine_enterprise_hub_ha 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.!enable_cfengine_enterprise_hub_ha:: "$(sys.workdir)/httpd/htdocs/ha_enabled" -> { "Mission Portal" } delete => tidy, handle => "cfengine_enterprise_ha_enabled_semaphore_absent", comment => "If this file is present when HA is not enabled Mission Portal will incorrectly report HA status."; policy_server.enable_cfengine_enterprise_hub_ha:: "$(sys.workdir)/httpd/htdocs/ha_enabled" -> { "Mission Portal", "ENT-4751" } create => "true", handle => "cfengine_enterprise_ha_enabled_semaphore_present", perms => mog("0440", $(def.cf_apache_user), $(def.cf_apache_group)), comment => "This file is read by mission portal to know that HA is enabled. Without it the UI will not report the correct HA status."; } bundle agent ha_manage_notification_scripts_dir { files: "/opt/cfengine/notification_scripts/." -> { "Mission Portal" } create => "true", perms => mog("770", "root", $(def.cf_apache_group)), comment => "This directory is used by Mission Portal to store custom user-defined scripts. Having HA set up we need to synchronize content of this directory between active and passive hubs. In case of no user-scripts being defined directory may not exist on active hub. To avoid policy synchronizing content of this directory being not kept we are creating directory in advance."; } bundle agent ha_hub_sync_config_data # @brief Keep passive hub configuration in sync with active hub { vars: "htdocs" string => "$(sys.workdir)/httpd/htdocs/"; "application_config_path" string => "$(htdocs)/application/config/"; "application_config_files" comment => "These files are from application/config and if not in sync will cause various authentication errors", slist => { "cf_robot.php", "appsettings.php", "config.php", # ENT-4944 }; files: "$(application_config_path)/$(application_config_files)" copy_from => ha_no_backup_scp( "$(application_config_path)/$(application_config_files)", $(sys.hub_active_ip) ), comment => "Ensure application configuration files are in sync to avoid authentication issues", handle => "ha_sync_application_config"; "/opt/cfengine/notification_scripts" copy_from => ha_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"); @if minimum_version(3.11) # These configuration settings were introduced in CFEngine non-LTS 3.11 # Used macro as there is no class based way to do version X and greater "$(htdocs)/ldap/config/settings.php" -> { "ENT-4944" } copy_from => ha_no_backup_scp( "$(htdocs)/ldap/config/settings.php", $(sys.hub_active_ip) ), comment => "Ensure LDAP configuration files are in sync to avoid authentication issues", handle => "ha_sync_ldap_config"; "$(htdocs)/api/config/config.php" -> { "ENT-4944" } copy_from => ha_no_backup_scp( "$(htdocs)/api/config/config.php", $(sys.hub_active_ip) ), comment => "Ensure LDAP configuration files are in sync to avoid authentication issues", handle => "ha_sync_api_config"; @endif } body copy_from ha_no_backup_scp(from, server) { servers => { "$(server)" }; source => "$(from)"; compare => "digest"; copy_backup => "false"; encrypt => "true"; } cfengine-masterfiles-3.27.3/cfe_internal/enterprise/ha/ha_def.cf0000644000000000000000000000241614735102600023010 0ustar0000000000000000bundle common ha_def { vars: enable_cfengine_enterprise_hub_ha:: "master_hub_location" string => "$(sys.statedir)/master_hub.dat"; "hubs_keys_location" string => "$(sys.workdir)/ppkeys_hubs"; "ppkeys_staging" string => "$(sys.workdir)/ppkeys_staging"; #The location of the config file can not be changed! "config_file" string => "$(this.promise_dirname)/ha_info.json"; "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"; "replication_only_node[$(ips)]" string => "dummy", if => strcmp("$(config[$(ips)][is_in_cluster])", "false"); "replication_only_nodes" slist => getindices("replication_only_node"); classes: "ha_replication_only_node" expression => some($(sys.policy_hub), replication_only_nodes); reports: verbose_mode:: "HA hub $(ips) $(config[$(ips)][sha])"; } cfengine-masterfiles-3.27.3/cfe_internal/enterprise/ha/ha_update.cf0000644000000000000000000001714214735102600023536 0ustar0000000000000000bundle agent ha_update { methods: enable_cfengine_enterprise_hub_ha:: "Hubs have am_policy_hub marker" usebundle => ha_hubs_have_am_policy_hub_marker, comment => "All hubs should have the am_policy_hub marker. This bundle ensures that standby hubs get this marker even though they are not bootstrapped to themselves"; enable_cfengine_enterprise_hub_ha.am_policy_hub:: "share_keys" usebundle => ha_share_hub_keys; "sync_hub_data" usebundle => ha_hub_sync; enable_cfengine_enterprise_hub_ha.!am_policy_hub:: "sync_agent_data" usebundle => ha_agent_sync; enable_cfengine_enterprise_hub_ha.hub_data_synced:: "manage_keys" usebundle => manage_hub_synced_data; enable_cfengine_enterprise_hub_ha.ha_replication_only_node:: "syncronize_master_hub_dat" usebundle => sync_master_hub_dat; } bundle agent ha_hubs_have_am_policy_hub_marker # @brief Ensure that all ha hub members have the am_policy_hub state marker { classes: # We know we need the am_policy_hub marker if any of our ips are found in the ha definition "ha_hub_member" expression => iprange($(ha_def.ips)); files: ha_hub_member:: "$(sys.statedir)/am_policy_hub" -> { "ENT-3328" } create => "true", comment => "This file is automatically created when bootstrapping to self, but in a clustered environment standby hubs bootstrap to the primary and this marker will not be automatically created."; } bundle agent ha_agent_sync { vars: # TODO: Remove this once sys.keydir is always available (3.26+ only) "keydir" -> { "CFE-2822" } string => ifelse( isvariable("sys.keydir"), "$(sys.keydir)", "$(sys.workdir)/ppkeys" ); files: "$(sys.workdir)/policy_server.dat" copy_from => ha_update_ha_no_backup_scp( "$(ha_def.master_hub_location)", @(update_def.policy_servers) ), handle => "ha_cfengine_node_update_master_ip", comment => "Update master hub IP on CFEngine node. This is causing that clients will try to contact active/master hub first."; "$(keydir)" copy_from => ha_update_ha_no_backup_scp( "$(ha_def.hubs_keys_location)", @(update_def.policy_servers) ), file_select => hub_all_keys, depth_search => ha_update_ha_recurse("inf"), handle => "ha_copy_hub_keys_to_nodes", comment => "Download keys of all hubs working in HA cluster and store in client's ppkeys directory. This is important for establishing trusted connection with standby hub(s) in case of failover."; } bundle agent ha_share_hub_keys { vars: # TODO: Remove this once sys.keydir is always available (3.26+ only) "keydir" -> { "CFE-2822" } string => ifelse( isvariable("sys.keydir"), "$(sys.keydir)", "$(sys.workdir)/ppkeys" ); files: "$(ha_def.hubs_keys_location)" copy_from => ha_update_no_backup_cp("$(keydir)"), file_select => hubs_keys_select, handle => "ha_copy_hubs_keys", depth_search => ha_update_recurse("1"), comment => "Clients need to be able to download keys of all hubs working in HA cluster. This is needed to establish trusted connection with standby hubs in case of failover. In order to limit possibility of copying wrong keys hub keys are copied to separate directory first and only ppkeys_hubs is accessible by clients."; } bundle agent ha_hub_sync { vars: # TODO: Remove this once sys.keydir is always available (3.26+ only) "keydir" -> { "CFE-2822" } string => ifelse( isvariable("sys.keydir"), "$(sys.keydir)", "$(sys.workdir)/ppkeys" ); "exclude_files" slist => { "localhost.priv", "localhost.pub", @(ha_def.hub_shas) }; files: "$(ha_def.ppkeys_staging)" copy_from => ha_update_ha_no_backup_scp( "$(keydir)", @(update_def.standby_servers) ), file_select => ha_update_ex_list(@(exclude_files)), handle => "ha_copy_client_keys_between_replica_set_servers", depth_search => ha_update_recurse("1"), classes => ha_update_if_repaired("hub_data_synced"), comment => "Distribute all client keys between replica set servers. This is important in case of failover. Once clients keys are synchronized between all hubs working in HA cluster, clients will be able to authenticate and establish connection with all hubs working in HA cluster."; } bundle agent manage_hub_synced_data # @brief Manage trust of clients bootstrapped other hubs in cluster # # Ensures keys collected from other hubs are present in ppkeys so that the # agents bootstrapped to other hubs are trusted. { vars: # TODO: Remove this once sys.keydir is always available (3.26+ only) "keydir" -> { "CFE-2822" } string => ifelse( isvariable("sys.keydir"), "$(sys.keydir)", "$(sys.workdir)/ppkeys" ); files: # Ensure that localhost.pub and localhost.priv are not in the directory of # keys collected from standby hubs "$(ha_def.ppkeys_staging)/localhost.*" -> { "ENT-3303" } delete => ha_tidy, handle => "manage_hub_synced_data_ppkeys_staging_localhost_absent", comment => "We don't want localhost related key files from a standby server to end up over-writing the active hubs key. That will cause an identity crisis and trust issues."; # Ensure that keys collected from standby hubs are present in this hubs # ppkeys directory so that agents bootstrapped to standby hubs will be # trusted. "$(keydir)" copy_from => ha_update_no_backup_cp("$(ha_def.ppkeys_staging)"), file_select => ha_update_plain, depth_search => ha_update_recurse("1"), handle => "ha_copy_staged_client_keys", comment => "Copy staged client keys to ppkeys. First client keys are copied to ppkeys_staging directory and then to ppkeys. Only clients which keys are copied to ppkeys will be able to authenticate and connect to hub."; } bundle agent sync_master_hub_dat { files: "$(ha_def.master_hub_location)" copy_from => ha_update_ha_no_backup_scp( "$(ha_def.master_hub_location)", @(update_def.standby_servers) ), comment => "Update master hub IP on CFEngine node", handle => "ha_cfengine_hub_update_master_ip"; } 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[$(update_def.standby_servers)][sha]).pub") }; file_result => "leaf_name"; } body copy_from ha_update_ha_no_backup_scp(from, server) { servers => { "$(server)" }; source => "$(from)"; compare => "digest"; copy_backup => "false"; encrypt => "true"; } body depth_search ha_update_ha_recurse(d) { depth => "$(d)"; exclude_dirs => { "\.svn", "\.git", "git-core" }; } body depth_search ha_update_recurse(d) { depth => "$(d)"; xdev => "true"; } body classes ha_update_if_repaired(x) { promise_repaired => { "$(x)" }; } body file_select ha_update_ex_list(names) { leaf_name => { @(names) }; file_result => "!leaf_name"; } body file_select ha_update_plain { file_types => { "plain" }; file_result => "file_types"; } body copy_from ha_update_no_backup_cp(from) { source => "$(from)"; copy_backup => "false"; } body delete ha_tidy # @brief Copy of body delete tidy from the standard library { dirlinks => "delete"; rmdirs => "true"; } cfengine-masterfiles-3.27.3/cfe_internal/enterprise/main.cf0000644000000000000000000001010614735102600022131 0ustar0000000000000000bundle agent cfe_internal_enterprise_main # @brief Drive policy related to CFEngine Enterprise { methods: any:: "security" -> { InfoSec } usebundle => change_management, comment => "Basic change management", handle => "cfe_internal_enterprise_main_change_management"; enterprise_edition.(policy_server|am_policy_hub):: "hub" usebundle => update_cli_rest_server_url_config, handle => "update_cli_rest_server_url_config", comment => "Update https port in php config files from cfe_internal_hub_vars.https_port"; "hub" usebundle => cfe_internal_update_folders, handle => "cfe_internal_management_update_folders", comment => "Create empty directories for CFE self-upgrade"; "hub" -> { "Mission Portal", "CFEngine Enterprise" } usebundle => cfe_internal_purge_scheduled_reports_older_than_days( $(def.purge_scheduled_reports_older_than_days) ), handle => "cfe_internal_management_purge_scheduled_reports_older_than_days", comment => "So that we do not fill up the disk we need to purge scheduled reports after some time."; "hub" usebundle => cfe_internal_setup_knowledge, handle => "cfe_internal_management_setup_knowledge", comment => "Manage CFE Knowledge Map"; "Enterprise Maintenance" usebundle => cfe_internal_enterprise_maintenance; "hub" usebundle => cfe_internal_php_runalerts, handle => "cfe_internal_management_php_runalerts", comment => concat( "To run PHP runalerts to check bundle status on SQL and Sketch.", " ENT-5432: must run after cfe_internal_enterprise_maintenance bundle", " so that active_hub class is determined. Since version 3.24.0 running", " alerts is part of cf-reactor" ), if => cf_version_before("3.24"); "Inventory Enterprise License Utilization" -> { "ENT-5089" } usebundle => inventory_cfengine_enterprise_license_utilization; enterprise_edition.(policy_server|am_policy_hub).enable_log_cfengine_enterprise_license_utilization:: "hub" -> { "ENT-3186" } usebundle => log_cfengine_enterprise_license_utilization, handle => "log_cfengine_enterprise_license_utilization", comment => "Log license utilization information"; # As passive hub is supposed to run read-only PostgreSQL instance # doing maintenance makes no sense and is not possible at all. (enterprise_edition.(policy_server|am_policy_hub).!enable_cfengine_enterprise_hub_ha)||(enable_cfengine_enterprise_hub_ha.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", action => measure_promise_time( "cfe_internal_management_postgresql_maintenance" ), comment => "Run clean up on PostgreSQL database"; postgresql_vacuum:: "hub" usebundle => cfe_internal_postgresql_vacuum, handle => "cfe_internal_management_postgresql_vacuum", action => measure_promise_time( "cfe_internal_management_postgresql_vacuum" ), comment => "Maintain PostgreSQL by executing vacuum"; enable_cfe_internal_cleanup_agent_reports:: "any" usebundle => cfe_internal_cleanup_agent_reports, handle => "cfe_internal_management_cleanup_agent_reports", comment => "Remove accumulated reports if they grow too large in size"; !windows:: "Permissions and Ownership" usebundle => cfe_internal_permissions, comment => "Specific expectations for permissions and ownership for cfengine itself"; } cfengine-masterfiles-3.27.3/cfe_internal/enterprise/mission_portal.cf0000644000000000000000000005756714735102600024275 0ustar0000000000000000bundle agent cfe_internal_enterprise_mission_portal { meta: "description" string => "Manage mission portal configuration"; classes: "mission_portal_http2_enabled" expression => and( fileexists("$(sys.workdir)/httpd/php/sbin/php-fpm"), fileexists("$(sys.workdir)/httpd/modules/mod_http2.so") ), scope => "namespace", # so it is visible in datastate() used in httpd.conf template rendering in bundle cfe_internal_enterprise_mission_portal_apache comment => "If php-fpm and mod_http2.so are present then http2 is enabled and we use this class in httpd.conf to configure accordingly."; vars: policy_server.enterprise_edition.mission_portal_http2_enabled:: "cpu_info_source" string => "/proc/cpuinfo"; "cpu_cores_number" int => int( execresult( "grep -c ^processor $(cpu_info_source) 2>/dev/null", "useshell" ) ), if => fileexists($(cpu_info_source)); "mem_info_source" string => "/proc/meminfo"; "mem_total_kb" int => int( execresult( "grep ^MemTotal $(mem_info_source) | awk '{print $2}' 2>/dev/null", "useshell" ) ), if => fileexists($(mem_info_source)); "php_fpm_www_pool_min_spare_servers_calculated" int => int( ifelse( isvariable("cpu_cores_number"), eval("$(cpu_cores_number) * 2"), # min spare servers are cpu cores number * 2 "8" # fallback ) ); "php_fpm_www_pool_max_spare_servers_calculated" int => int( ifelse( isvariable("cpu_cores_number"), eval("$(cpu_cores_number) * 4"), # max spare servers are cpu cores number * 4 "16" # fallback ) ); #start servers between min & max spare "php_fpm_www_pool_start_servers_calculated" int => int( eval( "($(php_fpm_www_pool_min_spare_servers_calculated) + $(php_fpm_www_pool_max_spare_servers_calculated)) / 2" ) ); "fpm_children_average_memory_kb" int => "25600"; # average memory taken by one fpm process 25MB * 1024 "php_fpm_www_pool_max_children_calculated" int => int( ifelse( isvariable("mem_total_kb"), eval("$(mem_total_kb) * 0.6 / $(fpm_children_average_memory_kb)"), # get only 60% of total memory and devide by avarage memory taken by one fpm process "60" # fallback ) ); "php_fpm_pid_file" string => "$(sys.workdir)/httpd/php-fpm.pid"; "php_fpm_www_pool_max_children" string => ifelse( isvariable("default:def.php_fpm_www_pool_max_children"), "$(default:def.php_fpm_www_pool_max_children)", "${php_fpm_www_pool_max_children_calculated}" ); "php_fpm_www_pool_start_servers" string => ifelse( isvariable("default:def.php_fpm_www_pool_start_servers"), "$(default:def.php_fpm_www_pool_start_servers)", "$(php_fpm_www_pool_start_servers_calculated)" ); "php_fpm_www_pool_min_spare_servers" string => ifelse( isvariable("default:def.php_fpm_www_pool_min_spare_servers"), "$(default:def.php_fpm_www_pool_min_spare_servers)", "$(php_fpm_www_pool_min_spare_servers_calculated)" ); "php_fpm_www_pool_max_spare_servers" string => ifelse( isvariable("default:def.php_fpm_www_pool_max_spare_servers"), "$(default:def.php_fpm_www_pool_max_spare_servers)", "$(php_fpm_www_pool_max_spare_servers_calculated)" ); "php_fpm_state" data => mergedata( '{"vars": { "sys": { "workdir": "${default:sys.workdir}" } } }', '{ "max_children":"${php_fpm_www_pool_max_children}", "start_servers":"${php_fpm_www_pool_start_servers}", "min_spare_servers":"${php_fpm_www_pool_min_spare_servers}", "max_spare_servers":"${php_fpm_www_pool_max_spare_servers}" }' ); files: # http -> https redirection moved from Apache to PHP # Here the flag files are managed so that PHP will know what to do cfe_enterprise_disable_http_redirect_to_https:: "/opt/cfengine/flags/." perms => mog("750", "root", "cfapache"), create => "true"; "/opt/cfengine/flags/http_redirect_to_https.disabled" -> { "ENT-11481" } perms => mog("660", "root", "cfapache"), create => "true"; !cfe_enterprise_disable_http_redirect_to_https:: "/opt/cfengine/flags/http_redirect_to_https.disabled" -> { "ENT-11481" } delete => tidy; reports: DEBUG:: "Using variable default:def.php_fpm_www_pool_max_children: ${default:def.php_fpm_www_pool_max_children} instead of built-in default" if => isvariable("default:def.php_fpm_www_pool_max_children"); "Using variable default:def.php_fpm_www_pool_start_servers: ${default:def.php_fpm_www_pool_start_servers} instead of built-in default" if => isvariable("default:def.php_fpm_www_pool_start_servers"); "Using variable default:def.php_fpm_www_pool_min_spare_servers: ${default:def.php_fpm_www_pool_min_spare_servers} instead of built-in default" if => isvariable("default:def.php_fpm_www_pool_min_spare_servers"); "Using variable default:def.php_fpm_www_pool_max_spare_servers: ${default:def.php_fpm_www_pool_max_spare_servers} instead of built-in default" if => isvariable("default:def.php_fpm_www_pool_max_spare_servers"); methods: policy_server:: "Apache Configuration" -> { "CFEngine Enterprise", "Mission Portal" } usebundle => cfe_internal_enterprise_mission_portal_apache; "Apache Service" -> { "CFEngine Enterprise", "Mission Portal" } usebundle => cfe_internal_webserver("on"), handle => "cfe_internal_management_web_server", comment => "Manage Apache Web server (on/off)"; "Port Configuration" -> { "CFEngine Enterprise", "Mission Portal" } usebundle => update_cli_rest_server_url_config, handle => "cfe_internal_management_update_cli_rest_server_url_config", comment => "Update the REST server URL port in the Mission Portal when cfe_internal_hub_vars.https_port is changed"; policy_server.mission_portal_http2_enabled:: "PHP FastCGI process manager" usebundle => service_config( "cf-php-fpm", "$(this.promise_dirname)/templates/php-fpm.conf.mustache", "$(sys.workdir)/httpd/php/etc/php-fpm.conf", "$(sys.workdir)/httpd/php/sbin/php-fpm -t --fpm-config ", @(php_fpm_state), "$(php_fpm_pid_file)" ); services: policy_server.mission_portal_http2_enabled:: "cf-php-fpm" service_policy => "start"; } bundle agent apachectl_patched_for_upgrade # @brief Ensure that apacehctl is patched so that it is able to re-start services # # @description This bundle addresses an issue where upgrades fail trying to stop # httpd. Versions prior to 3.20.0, 3.18.2, and 3.15.6 need to have apachectl # patched to make it wait for processes to shut down before exiting before # upgrading binaries to 3.20.0, 3.18.2, or 3.15.6. CFEngine packages for # versions after 3.20.0, 3.18.2, 3.15.6 ship with this patched apachectl which # should make this bundle a no-op. # # TODO Redact when 3.21.0 is the oldest supported version # # NOTE The rendering of apachectl is done slightly differently for different # versions of CFEngine. We need to maintain support for 3.15.x and many macros # were not available at 3.15.0, so we use classes instead of macros. # # Versions prior to CFEngine 3.20.0 do not create files by default when managed # by a template, if the file is absent but it's presence was desired the use of # create => "true" or some other machinery is necessary. # # When 3.15.0 (Currently oldest supported version) was released, 3.10.0 was supported. { vars: "considered_versions" slist => { "cfengine_3_10", "cfengine_3_11", "cfengine_3_12", "cfengine_3_13", "cfengine_3_14", "cfengine_3_15", "cfengine_3_16", "cfengine_3_17", "cfengine_3_18", }; classes: "_running_cfengine_version_where_templated_files_automatically_created" or => { @(considered_versions) }; "_running_cfengine_version_where_templated_files_NOT_automatically_created" not => or(@(considered_versions)); files: _running_cfengine_version_where_templated_files_automatically_created:: "$(sys.workdir)/httpd/bin/apachectl" edit_template => "$(this.promise_dirname)/templates/apachectl.mustache", handle => "apachectl_content_pre_create_default_templated_files", template_method => "mustache", template_data => parsejson( '{ "cfengine_enterprise_mission_portal_httpd_dir": "$(sys.workdir)/httpd" }' ), classes => results("bundle", "apachectl_file"); _running_cfengine_version_where_templated_files_NOT_automatically_created:: "$(sys.workdir)/httpd/bin/apachectl" create => "true", edit_template => "$(this.promise_dirname)/templates/apachectl.mustache", handle => "apachectl_content_post_create_default_templated_files", template_method => "mustache", template_data => parsejson( '{ "cfengine_enterprise_mission_portal_httpd_dir": "$(sys.workdir)/httpd" }' ), classes => results("bundle", "apachectl_file"); cfengine:: "$(sys.workdir)/httpd/bin/apachectl" handle => "apachectl_perms", perms => mog("0755", "root", "root"); commands: # This only runs if apachectl touched (repaired) and restorecon path exists apachectl_file_repaired.default:_stdlib_path_exists_restorecon:: "$(default:paths.restorecon) $(sys.workdir)/httpd/bin/apachectl" comment => "Ensure the templated apachectl has the correct SELinux context."; } bundle agent cfe_internal_enterprise_mission_portal_apache # @brief Manage Apache instance that runs Mission Portal { vars: policy_server.enterprise_edition:: "template" string => "$(this.promise_dirname)/templates/httpd.conf.mustache", comment => "The template used to render the apache config file."; "config" string => "$(sys.workdir)/httpd/conf/httpd.conf", comment => "This is the location of the apache config file."; "staged_config" string => "$(config).staged", comment => "This is the temporary file we will render the config and valid against before deploying to the final $(config) location."; # TODO: Consider collecting the classes and variables used based on a tag # to prepare a smaller subset of data "data" data => datastate(); methods: "apachectl patched for resilient stop " -> { "ENT-8823" } usebundle => apachectl_patched_for_upgrade; "Stage Apache Config" usebundle => file_make_mustache($(staged_config), $(template), @(data)), comment => "We render the config to a staging location so that it can be validated before deploying the final apache config so that we don't end up with a broken service."; "Manage Final Apache Config" usebundle => mission_portal_apache_from_stage( $(config), $(staged_config) ); reports: DEBUG|DEBUG_cfe_internal_enterprise_mission_portal_apache:: "DEBUG $(this.bundle): Should stage '$(staged_config)' from '$(template)'."; classes: (policy_server|am_policy_hub).enterprise_edition:: "mission_portal_index_php_redirect_enabled" expression => isgreaterthan( countlinesmatching( ".*config\['index_page'\] = \"\".*", "$(cfe_internal_hub_vars.docroot)/application/config/config.php" ), 0 ), comment => "We need to know if index_page config in Mission Portal is empty to enable redirect from /index.php/path to /path in httpd.conf"; } bundle agent mission_portal_apache_from_stage(config, staged_config) # @brief Make sure the live Apache config is based on a staged config that has # been validated. # @param config Path to the live config # @param staged_config Path to the staged configuration # # **Example:** # # ```cf3 # bundle agent example # { # vars: # # "config" # string => "$(sys.workdir)/httpd/conf/httpd.conf", # comment => "This is the location of the apache config file."; # # "staged_config" # string => "$(config).staged", # comment => "This is the temporary file we will render the config and # valid against before deploying to the final $(config) # location."; # # methods: # # "Manage Final Apache Config" # usebundle => mission_portal_apache_from_stage( $(config), $(staged_config) ); # } #``` { meta: "description" string => "Configure apache based on successfully staged config"; classes: "systemd_supervised" -> { "ENT-11189" } expression => returnszero( "$(paths.systemctl) cat cf-apache > /dev/null 2>&1", "useshell" ), if => fileexists($(paths.systemctl)), comment => "Set when cf-apache.service is a unit known to systemd"; "httpd_config_validated" expression => strcmp("$(validate_result[exit_code])", "0"); "httpd_config_error" expression => not(strcmp("$(validate_result[exit_code])", "0")); vars: "validate_config" string => "$(sys.workdir)/httpd/bin/httpd -t -f $(staged_config)"; "validate_result" data => execresult_as_data("$(validate_config)", "useshell", "both"); # The location of the apache pid file moved from httpd/logs/httpd.pid to # httpd/httpd.pid in 3.15.5, 3.18.1 and, 3.19.0 "httpd_pid_file" -> { "ENT-7966" } string => ifelse( classmatch("cfengine_3_1[0-4]"), "$(sys.workdir)/httpd/logs/httpd.pid", classmatch("cfengine_3_15_[0-4]"), "$(sys.workdir)/httpd/logs/httpd.pid", "cfengine_3_18_0", "$(sys.workdir)/httpd/logs/httpd.pid", "$(sys.workdir)/httpd/httpd.pid" ); files: "$(config)" create => "true", comment => "Without an apache config, Mission Mortal and Enterprise API services will not work"; "$(config)" -> { "ENT-9686" } copy_from => local_dcp($(staged_config)), handle => "cfapache_httpd_conf_from_staged", if => and( or( "apache_stop_after_new_staged_config_repaired", not(fileexists("$(httpd_pid_file)")), isnewerthan($(config), $(staged_config)) ), "httpd_config_validated" ), classes => results("bundle", "mission_portal_apache_config"), comment => "We make sure that the deployed config is a copy of the staged config if the staged config passes a syntax check. We redirect the output to keep policy runs clean and not generate lots of unnecessary email."; # Note: RPM package spec must align or the file will come up in rpm verification "$(config)" -> { "ENT-11096" } handle => "cfengine_mp_apache_config_ownership_perms", perms => mog("400", "root", "root"); commands: !systemd_supervised:: "LD_LIBRARY_PATH=$(sys.workdir)/lib:$LD_LIBRARY_PATH $(sys.workdir)/httpd/bin/apachectl" args => "stop", if => and( "httpd_config_validated", isnewerthan($(staged_config), $(config)), fileexists("$(httpd_pid_file)") ), contain => in_shell, classes => results("bundle", "apache_stop_after_new_staged_config"), comment => concat( "We have to stop apache before trying to start with a", "new config, or the new config could prevent apache from stopping." ); "LD_LIBRARY_PATH=$(sys.workdir)/lib:$LD_LIBRARY_PATH $(sys.workdir)/httpd/bin/apachectl" args => "start", if => and( "mission_portal_apache_config_repaired", "apache_stop_after_new_staged_config_repaired" ), contain => in_shell, comment => concat( "We start apache after the new valid config is in ", "place only if we have stopped apache already." ); "LD_LIBRARY_PATH=$(sys.workdir)/lib:$LD_LIBRARY_PATH $(sys.workdir)/httpd/bin/apachectl" -> { "ENT-9686" } args => "graceful", if => and( "mission_portal_apache_config_repaired", not("apache_stop_after_new_staged_config_repaired") ), contain => in_shell, comment => "We restart apache after the new valid config is in place"; methods: systemd_supervised:: "Reset cf-apache failed state" -> { "ENT-11189" } usebundle => cf_apache_reset_failed_state, if => "mission_portal_apache_config_repaired", comment => "Clear any latched failed state before restarting cf-apache"; services: systemd_supervised:: "cf-apache" service_policy => "stop", if => and( "httpd_config_validated", isnewerthan($(staged_config), $(config)) ), classes => results("bundle", "apache_stop_after_new_staged_config"), comment => concat( "We have to stop apache before trying to start with a", "new config, or the new config could prevent apache from stopping." ); "cf-apache" service_policy => "start", if => and( "mission_portal_apache_config_repaired", "apache_stop_after_new_staged_config_repaired" ), comment => concat( "We start apache after the new valid config is in ", "place only if we have stopped apache already." ); "cf-apache" -> { "ENT-9686" } service_policy => "restart", if => and( "mission_portal_apache_config_repaired", not("apache_stop_after_new_staged_config_repaired") ), comment => "We restart apache after the new valid config is in place"; reports: httpd_config_error:: "'$(staged_config)' failed to validate: $(validate_result[output])"; DEBUG|DEBUG_mission_portal_apache_from_stage:: "DEBUG $(this.bundle): '$(config)' should be a copy of '$(staged_config)' because it validates with '$(validate_config)'" if => "httpd_config_validated"; "DEBUG $(this.bundle): '$(config)' should *not* be a copy of '$(staged_config)' because it failed to validate with '$(validate_config)'" if => not("httpd_config_validated"); } ################################################################## # # cfe_internal_webserver(on/off) # ################################################################## bundle agent cfe_internal_webserver(state) { meta: "description" string => "Manage the Mission Portal 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:: ".*$(sys.workdir)/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=$(sys.workdir)/lib:$LD_LIBRARY_PATH $(sys.workdir)/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; } bundle agent cfe_enterprise_selfsigned_cert # @brief Generate a self signed certificate for Mission Portal # # By default this bundle will only regenerate a certificate if one of the # necessary files is missing. To force certificate regeneration run with the # class '_cfe_enterprise_selfsigned_cert_regenerate_certificate' defined. { meta: "description" string => "Generate a self signed SSL certificate for secure hub communications."; vars: policy_server:: "SSLCertificateFile" string => "$(cfe_internal_hub_vars.SSLCertificateFile)"; "SSLCertificateKeyFile" string => "$(cfe_internal_hub_vars.SSLCertificateKeyFile)"; "SSLCertificatePasswdKeyFile" string => "$(cfe_internal_hub_vars.SSLCertificatePasswdKeyFile)"; "SSLCertificateKeySize" string => "$(cfe_internal_hub_vars.SSLCertificateKeySize)"; "SSLCertificateSigningRequest" string => "$(cfe_internal_hub_vars.SSLCertificateSigningRequest)"; "SSLCnf" string => "$(cfe_internal_hub_vars.SSLCnf)"; "SSLCertificateDaysValid" string => "$(cfe_internal_hub_vars.SSLCertificateDaysValid)"; "SSLCertificateFileSymlink" string => "$(sys.workdir)/ssl/cert.pem"; "openssl" string => "$(sys.workdir)/bin/openssl"; "_generated_files" slist => { $(SSLCertificateFile), $(SSLCertificateKeyFile), $(SSLCertificatePasswdKeyFile), $(SSLCertificateSigningRequest), }; classes: "_cfe_enterprise_selfsigned_cert_regenerate_certificate" not => filesexist(@(_generated_files)), comment => "We only want to automatically regenerate the certificate if one of the files does not exist."; commands: policy_server._cfe_enterprise_selfsigned_cert_regenerate_certificate:: "$(openssl)" args => "genrsa -passout pass:x -out $(SSLCertificatePasswdKeyFile) $(SSLCertificateKeySize)"; # Strip password from key in ${CFENGINE_MP_PASS_KEY} and produce ${CFENGINE_MP_KEY} "$(openssl)" args => "rsa -passin pass:x -in $(SSLCertificatePasswdKeyFile) -out $(SSLCertificateKeyFile)"; # Generate a CSR in ${CFENGINE_MP_CSR} with key ${CFENGINE_MP_KEY} "$(openssl)" args => 'req -utf8 -sha256 -nodes -new -subj "/CN=$(sys.fqhost)" -key $(SSLCertificateKeyFile) -out $(SSLCertificateSigningRequest) -config $(SSLCnf)'; # Generate CRT "$(openssl)" args => "x509 -req -days $(SSLCertificateDaysValid) -in $(SSLCertificateSigningRequest) -signkey $(SSLCertificateKeyFile) -out $(SSLCertificateFile)"; files: "$(SSLCertificateFile)" -> { "jira:ENT-760" } perms => mog("644", "root", "root"), comment => "The SSL Certificate File needs to be readable so that it can be read by other services like Mission Portal."; "$(SSLCertificateKeyFile)" perms => mog("600", "root", "root"), comment => "The SSL Certificate Key should only be readable by root."; "$(SSLCertificatePasswdKeyFile)" perms => mog("600", "root", "root"), comment => "The SSL Certificate Key should only be readable by root."; "$(SSLCertificateFileSymlink)" -> { "jira:ENT-760" } link_from => ln_s($(SSLCertificateFile)), move_obstructions => "true", comment => "Mission Portal reads the certificate from this stable location, so it must always point to the current certificate."; reports: DEBUG|DEBUG_cfe_enterprise_selfsigned_cert:: "DEBUG $(this.bundle): Certificate Generation Requested" if => "_cfe_enterprise_selfsigned_cert_regenerate_certificate"; "DEBUG $(this.bundle): No Certificate Generation Requested" if => "!_cfe_enterprise_selfsigned_cert_regenerate_certificate"; } bundle agent cf_apache_reset_failed_state # @brief Clear any latched 'failed' state on cf-apache.service so subsequent # service operations are not refused by systemd's start rate limiter # (StartLimitBurst). Safe no-op when the unit is not in a failed state. { commands: "$(paths.systemctl) reset-failed cf-apache" -> { "ENT-11189" } contain => in_shell, handle => "cf_apache_systemctl_reset_failed", comment => "Reset latched failed state on cf-apache.service"; } cfengine-masterfiles-3.27.3/cfe_internal/enterprise/PaxHeaders/templates0000644000000000000000000000003615266337437023533 xustar0030 mtime=1792655135.217799274 cfengine-masterfiles-3.27.3/cfe_internal/enterprise/templates/0000755000000000000000000000000015266337437022715 5ustar0000000000000000cfengine-masterfiles-3.27.3/cfe_internal/enterprise/templates/apachectl.mustache0000644000000000000000000001244214735102600026355 0ustar0000000000000000#!/bin/sh # # This is CFEngine version of apachectl script, being more persistent when # killing httpd and more resillient when doing so. The only change is special # processing of "stop" inside "case $ACMD in". When asked to kill httpd # process, it not just sends a "kill" signal and happily quits, but first waits # for it to be gone (by checking `ps p` output), and if it's not gone - kills # the main httpd process and all its children (found via `pgrep --parent` or by # parsing `ps -eo ppid,pid` output) by sending `kill -9` singal to them. If # process(es) exist even after that - it gives up with an error message. # # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # # Apache control script designed to allow an easy command line interface # to controlling Apache. Written by Marc Slemko, 1997/08/23 # # Modified by Northern.Tech to try harder in killing httpd process(es) # and wait for them to be gone before returning to caller. # # The exit codes returned are: # XXX this doc is no longer correct now that the interesting # XXX functions are handled by httpd # 0 - operation completed successfully # 1 - # 2 - usage error # 3 - httpd could not be started # 4 - httpd could not be stopped # 5 - httpd could not be started during a restart # 6 - httpd could not be restarted during a restart # 7 - httpd could not be restarted during a graceful restart # 8 - configuration syntax error # # When multiple arguments are given, only the error from the _last_ # one is reported. Run "apachectl help" for usage info # ACMD="$1" ARGV="$@" # # |||||||||||||||||||| START CONFIGURATION SECTION |||||||||||||||||||| # -------------------- -------------------- # # the path to your httpd binary, including options if necessary HTTPD='{{{cfengine_enterprise_mission_portal_httpd_dir}}}/bin/httpd' # # pick up any necessary environment variables if test -f {{{cfengine_enterprise_mission_portal_httpd_dir}}}/bin/envvars; then . {{{cfengine_enterprise_mission_portal_httpd_dir}}}/bin/envvars fi # # a command that outputs a formatted text version of the HTML at the # url given on the command line. Designed for lynx, however other # programs may work. LYNX="lynx -dump" # # the URL to your server's mod_status status page. If you do not # have one, then status and fullstatus will not work. STATUSURL="http://localhost:80/server-status" # # Set this variable to a command that increases the maximum # number of file descriptors allowed per child process. This is # critical for configurations that use many file descriptors, # such as mass vhosting, or a multithreaded server. ULIMIT_MAX_FILES="ulimit -S -n `ulimit -H -n`" # -------------------- -------------------- # |||||||||||||||||||| END CONFIGURATION SECTION |||||||||||||||||||| # Set the maximum number of file descriptors allowed per child process. if [ "x$ULIMIT_MAX_FILES" != "x" ] ; then $ULIMIT_MAX_FILES fi ERROR=0 if [ "x$ARGV" = "x" ] ; then ARGV="-h" fi case $ACMD in start|restart|graceful|graceful-stop) $HTTPD -k $ARGV ERROR=$? ;; stop) # Added by CFEngine PIDFILE='{{{cfengine_enterprise_mission_portal_httpd_dir}}}/httpd.pid' if [ ! -f "$PIDFILE" ] ; then PIDFILE='{{{cfengine_enterprise_mission_portal_httpd_dir}}}/logs/httpd.pid' fi if [ ! -f "$PIDFILE" ] ; then echo PID file not found, nothing to stop exit 2 fi PID="$(cat "$PIDFILE")" $HTTPD -k $ARGV ERROR=$? # wait for pid to terminate, up to 5 seconds for _iteration in `seq 50`; do ps p $PID >/dev/null || exit $ERROR sleep 0.1 done echo "process didn't finish gracefully, commencing murder" # collect all child processes if command -v pgrep >/dev/null; then PIDS="$PID $(pgrep --parent $PID)" else PIDS="$PID $(ps -eo ppid,pid | awk "/ $PID /{print \$2}")" fi # send KILL signal to all of them kill -9 $PIDS # wait for them to terminate, up to 5 seconds for _iteration in `seq 50`; do ps p $PIDS >/dev/null || exit $ERROR sleep 0.1 done echo Failed to terminate processes ps p $PIDS ;; startssl|sslstart|start-SSL) echo The startssl option is no longer supported. echo Please edit httpd.conf to include the SSL configuration settings echo and then use "apachectl start". ERROR=2 ;; configtest) $HTTPD -t ERROR=$? ;; status) $LYNX $STATUSURL | awk ' /process$/ { print; exit } { print } ' ;; fullstatus) $LYNX $STATUSURL ;; *) $HTTPD "$@" ERROR=$? esac exit $ERROR cfengine-masterfiles-3.27.3/cfe_internal/enterprise/templates/httpd.conf.mustache0000644000000000000000000002724114735102600026503 0ustar0000000000000000# This file is rendered by CFEngine # manual edits will be reverted. ServerSignature Off ServerTokens ProductOnly ServerName {{{vars.sys.fqhost}}} ServerRoot "{{{vars.sys.workdir}}}/httpd" {{^classes.cfe_enterprise_disable_plain_http}} # ENT-10411 # ENT-10646 - Listen 80 often causes IPv6 related errors, specifying ipv4 squashes them. # Unclear why the same is not an issue for 443 # To enable listening on ipv6 add Listen [::]:80 Listen 0.0.0.0:{{{vars.cfe_internal_hub_vars.http_port}}} {{/classes.cfe_enterprise_disable_plain_http}} PidFile "{{{vars.mission_portal_apache_from_stage.httpd_pid_file}}}" # Modules # Note: Not all modules that are built are loaded. # Find built modules in {{{vars.sys.workdir}}}/httpd/modules # Our default log format uses features provided by these modules LoadModule log_config_module modules/mod_log_config.so LoadModule logio_module modules/mod_logio.so # We use the Header directive which is provided by this module LoadModule headers_module modules/mod_headers.so # We use the BrowserMatch directive which is provided by this module LoadModule setenvif_module modules/mod_setenvif.so # Associates the requested filename's extensions with the file's behavior # (handlers and filters) and content (mime-type, language, character set and # encoding) LoadModule mime_module modules/mod_mime.so # Provides for "trailing slash" redirects and serving directory index files LoadModule dir_module modules/mod_dir.so # Used for mapping in some nicer URL names # TODO Consider removal after 3.20 is EOL (used by transition in 3.16) LoadModule alias_module modules/mod_alias.so # Required for http->https redirection and handling indexes LoadModule rewrite_module modules/mod_rewrite.so # Required for secure access LoadModule ssl_module modules/mod_ssl.so # Required to drop privledges LoadModule unixd_module modules/mod_unixd.so # Required for use of Order and Require commands LoadModule access_compat_module modules/mod_access_compat.so # Required for SSL Session Caching LoadModule socache_shmcb_module modules/mod_socache_shmcb.so # Required to log into mission portal LoadModule authz_core_module modules/mod_authz_core.so # TRACE can be useful for debugging, but can be abused to perform Cross-Site # Tracing (XST) attacheks in order to obtain access to user cooking via # malicious scripting on the client side. TraceEnable off # The 'HttpOnly' flag makes the cookie inaccessible to client-side scripts, # preventing it from being stolen using malicious client side scripts. The # absence of this flag increases the likelihood of an attacker being able to # compromise the user's cookie via a malicious script. When the 'secure' flag is # used, the cookie is only sent over an encrypted HTTPS channel, and not over # unencrypted HTTP. Header edit Set-Cookie ^(.*)$ $1;HttpOnly;Secure # This module should not be loaded, this is just an extra measure. UserDir disabled User cfapache Group cfapache # Server configuration # ServerAdmin root@localhost DocumentRoot "{{{vars.cfe_internal_hub_vars.public_docroot}}}" Order deny,allow Deny from all Options FollowSymLinks AllowOverride None DirectoryIndex index.html index.php Order allow,deny Deny from all Satisfy All ErrorLog "logs/error_log" {{#data:cfengine_enterprise_mission_portal_debug_php_fpm}} LogLevel warn rewrite:trace6 proxy:debug proxy_fcgi:debug dir:debug {{/data:cfengine_enterprise_mission_portal_debug_php_fpm}} {{^data:cfengine_enterprise_mission_portal_debug_php_fpm}} LogLevel warn {{/data:cfengine_enterprise_mission_portal_debug_php_fpm}} LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined LogFormat "%h %l %u %t \"%r\" %>s %b" common LogFormat "%h %l %{username}n %t \"%r\" %>s %b" common_with_apache_notes_username LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio CustomLog "logs/access_log" common_with_apache_notes_username TypesConfig conf/mime.types AddType application/x-compress .Z AddType application/x-gzip .gz .tgz # Include conf/extra/httpd-ssl.conf # This content used to be included from an external file # /var/cfengine/httpd/conf/extra/httpd-ssl.conf Listen {{{vars.cfe_internal_hub_vars.https_port}}} AddType application/x-x509-ca-cert .crt AddType application/x-pkcs7-crl .crl SSLPassPhraseDialog builtin SSLSessionCache "shmcb:{{{vars.sys.workdir}}}/httpd/logs/ssl_scache(512000)" SSLSessionCacheTimeout 300 SSLSessionTickets Off # OCSP stapling is an extension that aims to improve SSL negotiation # performance while mainting visitor privacy. Disabled because of # issues with self signed certs. SSLUseStapling off # SSLStaplingCache "shmcb:logs/stabling-cache(150000)" # TLS Compression should be disabled to avoid CRIME # https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2012-4929 # SSLCompression off # As part of security hardening we minimize the features provided by OpenSSL. # Case in point, we build openssl 3 without support for compression. As such, # we do not explicitly disable SSL Compression beginning with CFEngine # Enteprprise 3.21.0 as apache is unable to then validate the configuration. # This is not explicitly enabled to allow the requesting client the first # choice of support ciphers # SSLHonorCipherOrder On # We expect that openssl is upgraded with each release and that the most # recent openssl version possible will be used and that it defines ciphers # considered HIGH appropriately. We use HIGH to get a good balance between # browser compatibility and security. Use ~{{vars.sys.workdir}}/openssl ciphers # -v HIGH~ to see what ciphers are considered HIGH security. # SSLCipherSuite HIGH # A more secure setting might be: # SSLCipherSuite EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH SSLCipherSuite {{{vars.def.cfe_enterprise_mission_portal_apache_sslciphersuite}}} # The SSL protocol versions allowed SSLProtocol {{{vars.def.cfe_enterprise_mission_portal_apache_sslprotocol}}} SSLRandomSeed startup builtin SSLRandomSeed connect builtin DocumentRoot "{{{vars.cfe_internal_hub_vars.public_docroot}}}" Alias "/api" "{{{vars.cfe_internal_hub_vars.docroot}}}/api" Alias "/api/static" "{{{vars.cfe_internal_hub_vars.docroot}}}/api/static" Alias "/ldap" "{{{vars.cfe_internal_hub_vars.docroot}}}/ldap" ServerName {{{vars.sys.fqhost}}}:{{{vars.cfe_internal_hub_vars.https_port}}} # ServerAdmin root@localhost ErrorLog "{{{vars.cfe_internal_hub_vars.error_log}}}" LogFormat "%h %l %{username}n %t \"%r\" %>s %b" TransferLog "{{{vars.cfe_internal_hub_vars.access_log}}}" SSLEngine on SSLCertificateFile "{{{vars.cfe_internal_hub_vars.SSLCertificateFile}}}" SSLCertificateKeyFile "{{{vars.cfe_internal_hub_vars.SSLCertificateKeyFile}}}" {{#classes.cfe_enterprise_have_SSLCACertificateFile_defined}} SSLCACertificateFile "{{{vars.cfe_internal_hub_vars.SSLCACertificateFile}}}" {{/classes.cfe_enterprise_have_SSLCACertificateFile_defined}} # Enable Strict Transport Security to prevent HTTPS users from # accessing http content. Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains; preload" Header always set X-Frame-Options DENY Header always set X-Content-Type-Options nosniff Header always set Content-Security-Policy \ "frame-ancestors 'self'; \ default-src 'self'; \ script-src 'self' 'unsafe-inline'; \ style-src 'self' 'unsafe-inline' fonts.googleapis.com; \ object-src 'none'; \ frame-src 'self'; \ child-src 'self'; \ img-src 'self' data: blob: avatars.githubusercontent.com badges.gitter.im fonts.gstatic.com kiwiirc.com raw.githubusercontent.com raw.github.com; \ font-src 'self' data: fonts.googleapis.com fonts.gstatic.com; \ connect-src 'self' fonts.gstatic.com fonts.googleapis.com; \ manifest-src 'self'; \ base-uri 'self'; \ form-action 'self'; \ media-src 'self'; \ worker-src 'self' blob:;" SSLOptions +StdEnvVars SSLOptions +StdEnvVars AllowOverride None BrowserMatch "MSIE [2-5]" \ nokeepalive ssl-unclean-shutdown \ downgrade-1.0 force-response-1.0 CustomLog "{{{vars.cfe_internal_hub_vars.ssl_request_log}}}" \ "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b" # Timeout defaults to 60 but that is too short for some operations on slower hub hardware Timeout 120 {{#classes.mission_portal_http2_enabled}} # Use mod_http2 LoadModule http2_module modules/mod_http2.so # Prefer http2 protocol Protocols h2 h2c http/1.1 # Setup php to be handled by php-fpm. Required for use of mod_http2 due to threading issues in php. LoadModule proxy_module modules/mod_proxy.so LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so # Need to pass auth headers to fpm SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1 SetHandler "proxy:fcgi://127.0.0.1:9000" {{/classes.mission_portal_http2_enabled}} {{^classes.mission_portal_http2_enabled}} LoadModule php{{{vars.cfe_internal_hub_vars.php_version}}}_module modules/libphp{{{vars.cfe_internal_hub_vars.php_version}}}.so AddHandler php{{{vars.cfe_internal_hub_vars.php_version}}}-script .php AddType application/x-httpd-php-source php{{{vars.cfe_internal_hub_vars.php_version}}} {{/classes.mission_portal_http2_enabled}} Options -Indexes +FollowSymLinks +MultiViews Order deny,allow AllowOverride None RewriteEngine On {{#classes.mission_portal_index_php_redirect_enabled}} # redirect from `index.php/path` to `/path` RewriteCond %{REQUEST_URI} !(.*)/api/(.*) [NC] #do not apply redirect to internal APIs for backward compatibility RewriteCond %{THE_REQUEST} /index\.php/(.+)\sHTTP [NC] RewriteRule ^ /%1 [NE,L,R] {{/classes.mission_portal_index_php_redirect_enabled}} RewriteCond %{REQUEST_FILENAME} -s [OR] RewriteCond %{REQUEST_FILENAME} -l [OR] RewriteCond %{REQUEST_FILENAME} -d RewriteRule ^.*$ - [NC,L] RewriteRule ^(.*)$ /index.php/$1 [NC,L] Order deny,allow AllowOverride None RewriteEngine On RewriteRule ^static/(.+)$ static/$1 [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)$ dispatch.php [QSA,L] Order deny,allow AllowOverride None # What do we use mod_mime for? AddType text/csv .csv AddType application/pdf .pdf AddType application/json .json Order deny,allow AllowOverride None RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^ index.php [QSA,L] # Whats in here that got a specific deny? Deny from all AllowOverride None cfengine-masterfiles-3.27.3/cfe_internal/enterprise/templates/php-fpm.conf.mustache0000644000000000000000000006600414735102600026727 0ustar0000000000000000;;;;;;;;;;;;;;;;;;;;; ; FPM Configuration ; ;;;;;;;;;;;;;;;;;;;;; ; All relative paths in this configuration file are relative to PHP's install ; prefix (/var/cfengine/httpd/php). This prefix can be dynamically changed by using the ; '-p' argument from the command line. ;;;;;;;;;;;;;;;;;; ; Global Options ; ;;;;;;;;;;;;;;;;;; [global] ; Pid file ; Note: the default prefix is /var/cfengine/httpd/php/var ; Default Value: none ;pid = run/php-fpm.pid pid = {{{vars.sys.workdir}}}/httpd/php-fpm.pid ; Error log file ; If it's set to "syslog", log is sent to syslogd instead of being written ; into a local file. ; Note: the default prefix is /var/cfengine/httpd/php/var ; Default Value: log/php-fpm.log ;error_log = log/php-fpm.log error_log = syslog ; syslog_facility is used to specify what type of program is logging the ; message. This lets syslogd specify that messages from different facilities ; will be handled differently. ; See syslog(3) for possible values (ex daemon equiv LOG_DAEMON) ; Default Value: daemon ;syslog.facility = daemon ; syslog_ident is prepended to every message. If you have multiple FPM ; instances running on the same server, you can change the default value ; which must suit common needs. ; Default Value: php-fpm ;syslog.ident = php-fpm ; Log level ; Possible Values: alert, error, warning, notice, debug ; Default Value: notice ;log_level = notice {{#data:cfengine_enterprise_mission_portal_debug_php_fpm}} log_level = debug {{/data:cfengine_enterprise_mission_portal_debug_php_fpm}} ; Log limit on number of characters in the single line (log entry). If the ; line is over the limit, it is wrapped on multiple lines. The limit is for ; all logged characters including message prefix and suffix if present. However ; the new line character does not count into it as it is present only when ; logging to a file descriptor. It means the new line character is not present ; when logging to syslog. ; Default Value: 1024 ;log_limit = 4096 ; Log buffering specifies if the log line is buffered which means that the ; line is written in a single write operation. If the value is false, then the ; data is written directly into the file descriptor. It is an experimental ; option that can potentially improve logging performance and memory usage ; for some heavy logging scenarios. This option is ignored if logging to syslog ; as it has to be always buffered. ; Default value: yes ;log_buffering = no ; If this number of child processes exit with SIGSEGV or SIGBUS within the time ; interval set by emergency_restart_interval then FPM will restart. A value ; of '0' means 'Off'. ; Default Value: 0 ;emergency_restart_threshold = 0 ; Interval of time used by emergency_restart_interval to determine when ; a graceful restart will be initiated. This can be useful to work around ; accidental corruptions in an accelerator's shared memory. ; Available Units: s(econds), m(inutes), h(ours), or d(ays) ; Default Unit: seconds ; Default Value: 0 ;emergency_restart_interval = 0 ; Time limit for child processes to wait for a reaction on signals from master. ; Available units: s(econds), m(inutes), h(ours), or d(ays) ; Default Unit: seconds ; Default Value: 0 ;process_control_timeout = 0 ; The maximum number of processes FPM will fork. This has been designed to control ; the global number of processes when using dynamic PM within a lot of pools. ; Use it with caution. ; Note: A value of 0 indicates no limit ; Default Value: 0 ; process.max = 128 ; Specify the nice(2) priority to apply to the master process (only if set) ; The value can vary from -19 (highest priority) to 20 (lowest priority) ; Note: - It will only work if the FPM master process is launched as root ; - The pool process will inherit the master process priority ; unless specified otherwise ; Default Value: no set ; process.priority = -19 ; Send FPM to background. Set to 'no' to keep FPM in foreground for debugging. ; Default Value: yes ;daemonize = yes ; Set open file descriptor rlimit for the master process. ; Default Value: system defined value ;rlimit_files = 1024 ; Set max core size rlimit for the master process. ; Possible Values: 'unlimited' or an integer greater or equal to 0 ; Default Value: system defined value ;rlimit_core = 0 ; Specify the event mechanism FPM will use. The following is available: ; - select (any POSIX os) ; - poll (any POSIX os) ; - epoll (linux >= 2.5.44) ; - kqueue (FreeBSD >= 4.1, OpenBSD >= 2.9, NetBSD >= 2.0) ; - /dev/poll (Solaris >= 7) ; - port (Solaris >= 10) ; Default Value: not set (auto detection) ;events.mechanism = epoll ; When FPM is built with systemd integration, specify the interval, ; in seconds, between health report notification to systemd. ; Set to 0 to disable. ; Available Units: s(econds), m(inutes), h(ours) ; Default Unit: seconds ; Default value: 10 ;systemd_interval = 10 ;;;;;;;;;;;;;;;;;;;; ; Pool Definitions ; ;;;;;;;;;;;;;;;;;;;; ; Multiple pools of child processes may be started with different listening ; ports and different management options. The name of the pool will be ; used in logs and stats. There is no limitation on the number of pools which ; FPM can handle. Your system will tell you anyway :) ; Start a new pool named 'www'. ; the variable $pool can be used in any directive and will be replaced by the ; pool name ('www' here) [www] ; Per pool prefix ; It only applies on the following directives: ; - 'access.log' ; - 'slowlog' ; - 'listen' (unixsocket) ; - 'chroot' ; - 'chdir' ; - 'php_values' ; - 'php_admin_values' ; When not set, the global prefix (or /var/cfengine/httpd/php) applies instead. ; Note: This directive can also be relative to the global prefix. ; Default Value: none ;prefix = /path/to/pools/$pool ; Unix user/group of the child processes. This can be used only if the master ; process running user is root. It is set after the child process is created. ; The user and group can be specified either by their name or by their numeric ; IDs. ; Note: If the user is root, the executable needs to be started with ; --allow-to-run-as-root option to work. ; Default Values: The user is set to master process running user by default. ; If the group is not set, the user's group is used. user = cfapache group = cfapache ; The address on which to accept FastCGI requests. ; Valid syntaxes are: ; 'ip.add.re.ss:port' - to listen on a TCP socket to a specific IPv4 address on ; a specific port; ; '[ip:6:addr:ess]:port' - to listen on a TCP socket to a specific IPv6 address on ; a specific port; ; 'port' - to listen on a TCP socket to all addresses ; (IPv6 and IPv4-mapped) on a specific port; ; '/path/to/unix/socket' - to listen on a unix socket. ; Note: This value is mandatory. listen = 127.0.0.1:9000 ; Set listen(2) backlog. ; Default Value: 511 (-1 on Linux, FreeBSD and OpenBSD) ;listen.backlog = 511 ; Set permissions for unix socket, if one is used. In Linux, read/write ; permissions must be set in order to allow connections from a web server. Many ; BSD-derived systems allow connections regardless of permissions. The owner ; and group can be specified either by name or by their numeric IDs. ; Default Values: Owner is set to the master process running user. If the group ; is not set, the owner's group is used. Mode is set to 0660. ;listen.owner = nobody ;listen.group = nobody ;listen.mode = 0660 ; When POSIX Access Control Lists are supported you can set them using ; these options, value is a comma separated list of user/group names. ; When set, listen.owner and listen.group are ignored ;listen.acl_users = ;listen.acl_groups = ; List of addresses (IPv4/IPv6) of FastCGI clients which are allowed to connect. ; Equivalent to the FCGI_WEB_SERVER_ADDRS environment variable in the original ; PHP FCGI (5.2.2+). Makes sense only with a tcp listening socket. Each address ; must be separated by a comma. If this value is left blank, connections will be ; accepted from any ip address. ; Default Value: any ;listen.allowed_clients = 127.0.0.1 ; Set the associated the route table (FIB). FreeBSD only ; Default Value: -1 ;listen.setfib = 1 ; Specify the nice(2) priority to apply to the pool processes (only if set) ; The value can vary from -19 (highest priority) to 20 (lower priority) ; Note: - It will only work if the FPM master process is launched as root ; - The pool processes will inherit the master process priority ; unless it specified otherwise ; Default Value: no set ; process.priority = -19 ; Set the process dumpable flag (PR_SET_DUMPABLE prctl for Linux or ; PROC_TRACE_CTL procctl for FreeBSD) even if the process user ; or group is different than the master process user. It allows to create process ; core dump and ptrace the process for the pool user. ; Default Value: no ; process.dumpable = yes ; Choose how the process manager will control the number of child processes. ; Possible Values: ; static - a fixed number (pm.max_children) of child processes; ; dynamic - the number of child processes are set dynamically based on the ; following directives. With this process management, there will be ; always at least 1 children. ; pm.max_children - the maximum number of children that can ; be alive at the same time. ; pm.start_servers - the number of children created on startup. ; pm.min_spare_servers - the minimum number of children in 'idle' ; state (waiting to process). If the number ; of 'idle' processes is less than this ; number then some children will be created. ; pm.max_spare_servers - the maximum number of children in 'idle' ; state (waiting to process). If the number ; of 'idle' processes is greater than this ; number then some children will be killed. ; pm.max_spawn_rate - the maximum number of rate to spawn child ; processes at once. ; ondemand - no children are created at startup. Children will be forked when ; new requests will connect. The following parameter are used: ; pm.max_children - the maximum number of children that ; can be alive at the same time. ; pm.process_idle_timeout - The number of seconds after which ; an idle process will be killed. ; Note: This value is mandatory. pm = dynamic ; The number of child processes to be created when pm is set to 'static' and the ; maximum number of child processes when pm is set to 'dynamic' or 'ondemand'. ; This value sets the limit on the number of simultaneous requests that will be ; served. Equivalent to the ApacheMaxClients directive with mpm_prefork. ; Equivalent to the PHP_FCGI_CHILDREN environment variable in the original PHP ; CGI. The below defaults are based on a server without much resources. Don't ; forget to tweak pm.* to fit your needs. ; Note: Used when pm is set to 'static', 'dynamic' or 'ondemand' ; Note: This value is mandatory. pm.max_children = {{{max_children}}} ; The number of child processes created on startup. ; Note: Used only when pm is set to 'dynamic' ; Default Value: (min_spare_servers + max_spare_servers) / 2 pm.start_servers = {{{start_servers}}} ; The desired minimum number of idle server processes. ; Note: Used only when pm is set to 'dynamic' ; Note: Mandatory when pm is set to 'dynamic' pm.min_spare_servers = {{{min_spare_servers}}} ; The desired maximum number of idle server processes. ; Note: Used only when pm is set to 'dynamic' ; Note: Mandatory when pm is set to 'dynamic' pm.max_spare_servers = {{{max_spare_servers}}} ; The number of rate to spawn child processes at once. ; Note: Used only when pm is set to 'dynamic' ; Note: Mandatory when pm is set to 'dynamic' ; Default Value: 32 ;pm.max_spawn_rate = 32 ; The number of seconds after which an idle process will be killed. ; Note: Used only when pm is set to 'ondemand' ; Default Value: 10s ;pm.process_idle_timeout = 10s; ; The number of requests each child process should execute before respawning. ; This can be useful to work around memory leaks in 3rd party libraries. For ; endless request processing specify '0'. Equivalent to PHP_FCGI_MAX_REQUESTS. ; Default Value: 0 ;pm.max_requests = 500 ; The URI to view the FPM status page. If this value is not set, no URI will be ; recognized as a status page. It shows the following information: ; pool - the name of the pool; ; process manager - static, dynamic or ondemand; ; start time - the date and time FPM has started; ; start since - number of seconds since FPM has started; ; accepted conn - the number of request accepted by the pool; ; listen queue - the number of request in the queue of pending ; connections (see backlog in listen(2)); ; max listen queue - the maximum number of requests in the queue ; of pending connections since FPM has started; ; listen queue len - the size of the socket queue of pending connections; ; idle processes - the number of idle processes; ; active processes - the number of active processes; ; total processes - the number of idle + active processes; ; max active processes - the maximum number of active processes since FPM ; has started; ; max children reached - number of times, the process limit has been reached, ; when pm tries to start more children (works only for ; pm 'dynamic' and 'ondemand'); ; Value are updated in real time. ; Example output: ; pool: www ; process manager: static ; start time: 01/Jul/2011:17:53:49 +0200 ; start since: 62636 ; accepted conn: 190460 ; listen queue: 0 ; max listen queue: 1 ; listen queue len: 42 ; idle processes: 4 ; active processes: 11 ; total processes: 15 ; max active processes: 12 ; max children reached: 0 ; ; By default the status page output is formatted as text/plain. Passing either ; 'html', 'xml' or 'json' in the query string will return the corresponding ; output syntax. Example: ; http://www.foo.bar/status ; http://www.foo.bar/status?json ; http://www.foo.bar/status?html ; http://www.foo.bar/status?xml ; ; By default the status page only outputs short status. Passing 'full' in the ; query string will also return status for each pool process. ; Example: ; http://www.foo.bar/status?full ; http://www.foo.bar/status?json&full ; http://www.foo.bar/status?html&full ; http://www.foo.bar/status?xml&full ; The Full status returns for each process: ; pid - the PID of the process; ; state - the state of the process (Idle, Running, ...); ; start time - the date and time the process has started; ; start since - the number of seconds since the process has started; ; requests - the number of requests the process has served; ; request duration - the duration in µs of the requests; ; request method - the request method (GET, POST, ...); ; request URI - the request URI with the query string; ; content length - the content length of the request (only with POST); ; user - the user (PHP_AUTH_USER) (or '-' if not set); ; script - the main script called (or '-' if not set); ; last request cpu - the %cpu the last request consumed ; it's always 0 if the process is not in Idle state ; because CPU calculation is done when the request ; processing has terminated; ; last request memory - the max amount of memory the last request consumed ; it's always 0 if the process is not in Idle state ; because memory calculation is done when the request ; processing has terminated; ; If the process is in Idle state, then informations are related to the ; last request the process has served. Otherwise informations are related to ; the current request being served. ; Example output: ; ************************ ; pid: 31330 ; state: Running ; start time: 01/Jul/2011:17:53:49 +0200 ; start since: 63087 ; requests: 12808 ; request duration: 1250261 ; request method: GET ; request URI: /test_mem.php?N=10000 ; content length: 0 ; user: - ; script: /home/fat/web/docs/php/test_mem.php ; last request cpu: 0.00 ; last request memory: 0 ; ; Note: There is a real-time FPM status monitoring sample web page available ; It's available in: /var/cfengine/httpd/php/share/php/fpm/status.html ; ; Note: The value must start with a leading slash (/). The value can be ; anything, but it may not be a good idea to use the .php extension or it ; may conflict with a real PHP file. ; Default Value: not set ;pm.status_path = /status ; The address on which to accept FastCGI status request. This creates a new ; invisible pool that can handle requests independently. This is useful ; if the main pool is busy with long running requests because it is still possible ; to get the status before finishing the long running requests. ; ; Valid syntaxes are: ; 'ip.add.re.ss:port' - to listen on a TCP socket to a specific IPv4 address on ; a specific port; ; '[ip:6:addr:ess]:port' - to listen on a TCP socket to a specific IPv6 address on ; a specific port; ; 'port' - to listen on a TCP socket to all addresses ; (IPv6 and IPv4-mapped) on a specific port; ; '/path/to/unix/socket' - to listen on a unix socket. ; Default Value: value of the listen option ;pm.status_listen = 127.0.0.1:9001 ; The ping URI to call the monitoring page of FPM. If this value is not set, no ; URI will be recognized as a ping page. This could be used to test from outside ; that FPM is alive and responding, or to ; - create a graph of FPM availability (rrd or such); ; - remove a server from a group if it is not responding (load balancing); ; - trigger alerts for the operating team (24/7). ; Note: The value must start with a leading slash (/). The value can be ; anything, but it may not be a good idea to use the .php extension or it ; may conflict with a real PHP file. ; Default Value: not set ;ping.path = /ping ; This directive may be used to customize the response of a ping request. The ; response is formatted as text/plain with a 200 response code. ; Default Value: pong ;ping.response = pong ; The access log file ; Default: not set ;access.log = log/$pool.access.log {{#data:cfengine_enterprise_mission_portal_debug_php_fpm}} access.log = {{{vars.sys.workdir}}}/httpd/logs/www-pool.access.log {{/data:cfengine_enterprise_mission_portal_debug_php_fpm}} ; The access log format. ; The following syntax is allowed ; %%: the '%' character ; %C: %CPU used by the request ; it can accept the following format: ; - %{user}C for user CPU only ; - %{system}C for system CPU only ; - %{total}C for user + system CPU (default) ; %d: time taken to serve the request ; it can accept the following format: ; - %{seconds}d (default) ; - %{milliseconds}d ; - %{milli}d ; - %{microseconds}d ; - %{micro}d ; %e: an environment variable (same as $_ENV or $_SERVER) ; it must be associated with embraces to specify the name of the env ; variable. Some examples: ; - server specifics like: %{REQUEST_METHOD}e or %{SERVER_PROTOCOL}e ; - HTTP headers like: %{HTTP_HOST}e or %{HTTP_USER_AGENT}e ; %f: script filename ; %l: content-length of the request (for POST request only) ; %m: request method ; %M: peak of memory allocated by PHP ; it can accept the following format: ; - %{bytes}M (default) ; - %{kilobytes}M ; - %{kilo}M ; - %{megabytes}M ; - %{mega}M ; %n: pool name ; %o: output header ; it must be associated with embraces to specify the name of the header: ; - %{Content-Type}o ; - %{X-Powered-By}o ; - %{Transfert-Encoding}o ; - .... ; %p: PID of the child that serviced the request ; %P: PID of the parent of the child that serviced the request ; %q: the query string ; %Q: the '?' character if query string exists ; %r: the request URI (without the query string, see %q and %Q) ; %R: remote IP address ; %s: status (response code) ; %t: server time the request was received ; it can accept a strftime(3) format: ; %d/%b/%Y:%H:%M:%S %z (default) ; The strftime(3) format must be encapsulated in a %{}t tag ; e.g. for a ISO8601 formatted timestring, use: %{%Y-%m-%dT%H:%M:%S%z}t ; %T: time the log has been written (the request has finished) ; it can accept a strftime(3) format: ; %d/%b/%Y:%H:%M:%S %z (default) ; The strftime(3) format must be encapsulated in a %{}t tag ; e.g. for a ISO8601 formatted timestring, use: %{%Y-%m-%dT%H:%M:%S%z}t ; %u: remote user ; ; Default: "%R - %u %t \"%m %r\" %s" ;access.format = "%R - %u %t \"%m %r%Q%q\" %s %f %{milli}d %{kilo}M %C%%" ; A list of request_uri values which should be filtered from the access log. ; ; As a security precuation, this setting will be ignored if: ; - the request method is not GET or HEAD; or ; - there is a request body; or ; - there are query parameters; or ; - the response code is outwith the successful range of 200 to 299 ; ; Note: The paths are matched against the output of the access.format tag "%r". ; On common configurations, this may look more like SCRIPT_NAME than the ; expected pre-rewrite URI. ; ; Default Value: not set ;access.suppress_path[] = /ping ;access.suppress_path[] = /health_check.php ; The log file for slow requests ; Default Value: not set ; Note: slowlog is mandatory if request_slowlog_timeout is set ;slowlog = log/$pool.log.slow ; The timeout for serving a single request after which a PHP backtrace will be ; dumped to the 'slowlog' file. A value of '0s' means 'off'. ; Available units: s(econds)(default), m(inutes), h(ours), or d(ays) ; Default Value: 0 ;request_slowlog_timeout = 0 ; Depth of slow log stack trace. ; Default Value: 20 ;request_slowlog_trace_depth = 20 ; The timeout for serving a single request after which the worker process will ; be killed. This option should be used when the 'max_execution_time' ini option ; does not stop script execution for some reason. A value of '0' means 'off'. ; Available units: s(econds)(default), m(inutes), h(ours), or d(ays) ; Default Value: 0 ;request_terminate_timeout = 0 ; The timeout set by 'request_terminate_timeout' ini option is not engaged after ; application calls 'fastcgi_finish_request' or when application has finished and ; shutdown functions are being called (registered via register_shutdown_function). ; This option will enable timeout limit to be applied unconditionally ; even in such cases. ; Default Value: no ;request_terminate_timeout_track_finished = no ; Set open file descriptor rlimit. ; Default Value: system defined value ;rlimit_files = 1024 ; Set max core size rlimit. ; Possible Values: 'unlimited' or an integer greater or equal to 0 ; Default Value: system defined value ;rlimit_core = 0 ; Chroot to this directory at the start. This value must be defined as an ; absolute path. When this value is not set, chroot is not used. ; Note: you can prefix with '$prefix' to chroot to the pool prefix or one ; of its subdirectories. If the pool prefix is not set, the global prefix ; will be used instead. ; Note: chrooting is a great security feature and should be used whenever ; possible. However, all PHP paths will be relative to the chroot ; (error_log, sessions.save_path, ...). ; Default Value: not set ;chroot = ; Chdir to this directory at the start. ; Note: relative path can be used. ; Default Value: current directory or / when chroot ;chdir = /var/www ; Redirect worker stdout and stderr into main error log. If not set, stdout and ; stderr will be redirected to /dev/null according to FastCGI specs. ; Note: on highloaded environment, this can cause some delay in the page ; process time (several ms). ; Default Value: no ;catch_workers_output = yes ; Decorate worker output with prefix and suffix containing information about ; the child that writes to the log and if stdout or stderr is used as well as ; log level and time. This options is used only if catch_workers_output is yes. ; Settings to "no" will output data as written to the stdout or stderr. ; Default value: yes ;decorate_workers_output = no ; Clear environment in FPM workers ; Prevents arbitrary environment variables from reaching FPM worker processes ; by clearing the environment in workers before env vars specified in this ; pool configuration are added. ; Setting to "no" will make all environment variables available to PHP code ; via getenv(), $_ENV and $_SERVER. ; Default Value: yes ;clear_env = no ; Limits the extensions of the main script FPM will allow to parse. This can ; prevent configuration mistakes on the web server side. You should only limit ; FPM to .php extensions to prevent malicious users to use other extensions to ; execute php code. ; Note: set an empty value to allow all extensions. ; Default Value: .php ;security.limit_extensions = .php .php3 .php4 .php5 .php7 ; Pass environment variables like LD_LIBRARY_PATH. All $VARIABLEs are taken from ; the current environment. ; Default Value: clean env ;env[HOSTNAME] = $HOSTNAME ;env[PATH] = /usr/local/bin:/usr/bin:/bin ;env[TMP] = /tmp ;env[TMPDIR] = /tmp ;env[TEMP] = /tmp ; Additional php.ini defines, specific to this pool of workers. These settings ; overwrite the values previously defined in the php.ini. The directives are the ; same as the PHP SAPI: ; php_value/php_flag - you can set classic ini defines which can ; be overwritten from PHP call 'ini_set'. ; php_admin_value/php_admin_flag - these directives won't be overwritten by ; PHP call 'ini_set' ; For php_*flag, valid values are on, off, 1, 0, true, false, yes or no. ; Defining 'extension' will load the corresponding shared extension from ; extension_dir. Defining 'disable_functions' or 'disable_classes' will not ; overwrite previously defined php.ini values, but will append the new value ; instead. ; Note: path INI options can be relative and will be expanded with the prefix ; (pool, global or /var/cfengine/httpd/php) ; Default Value: nothing is defined by default except the values in php.ini and ; specified at startup with the -d argument ;php_admin_value[sendmail_path] = /usr/sbin/sendmail -t -i -f www@my.domain.com ;php_flag[display_errors] = off ;php_admin_value[error_log] = /var/log/fpm-php.www.log ;php_admin_flag[log_errors] = on ;php_admin_value[memory_limit] = 32M cfengine-masterfiles-3.27.3/cfe_internal/enterprise/templates/runalerts.php.mustache0000644000000000000000000000134314735102600027234 0ustar0000000000000000#!{{{vars.sys.workdir}}}/httpd/php/bin/php # Rendered by CFEngine cfengine-masterfiles-3.27.3/cfe_internal/enterprise/templates/runalerts.sh.mustache0000644000000000000000000000073714735102600027065 0ustar0000000000000000# Rendered by CFEngine #!/bin/bash while true; do touch {{{vars.sys.workdir}}}/httpd/php/runalerts_all if [ -f {{{vars.sys.workdir}}}/httpd/php/runalerts_all ]; then {{{vars.sys.workdir}}}/httpd/php/bin/php {{{vars.cfe_internal_hub_vars.public_docroot}}}/index.php cli_tasks runalerts {{{vars.cfe_internal_php_runalerts.all[limit]}}} {{{vars.cfe_internal_php_runalerts.all[running]}}} all >/dev/null 2>&1 fi sleep {{{vars.cfe_internal_php_runalerts.sleep_time}}} done cfengine-masterfiles-3.27.3/cfe_internal/recommendations.cf0000644000000000000000000002424214735102600022222 0ustar0000000000000000bundle agent mpf_class_recommendations { meta: (policy_server|am_policy_hub).enterprise_edition:: "tags" slist => { "cfengine_recommends" }; classes: "cfengine_recommendation_instruct_disablement" expression => "cfengine_recommendation_emitted", scope => "namespace"; reports: "`cfengine_internal_purge_policies` no longer has any effect. Please use `cfengine_internal_purge_policies_disabled` instead, to choose where you want to disable purging or remove the class completely if you want purging enabled everywhere (the new default in 3.18+)." -> { "CFE-3662" } if => "cfengine_internal_purge_policies", classes => results("bundle", "cfengine_recommendation_emitted"); } bundle agent federated_reporting_superhub_recommendations { meta: "tags" slist => { "cfengine_recommends" }; classes: "cfengine_recommendation_instruct_disablement" expression => "cfengine_recommendation_emitted_reached", scope => "namespace"; reports: cfengine_enterprise_federation:am_superhub:: "CFEngine recommends installing gnu parallel on federated reporting superhubs." if => not( isgreaterthan( length(packagesmatching("parallel", ".*", ".*", ".*")), 0 ) ), classes => results("bundle", "cfengine_recommendation_emitted"); } @if minimum_version(3.21.4) # The preferred location for ignore_interfaces.rx changed from # $(sys.inputdir)/ignore_interfaces.rx to $(sys.workdir)/ignore_interfaces.rx in # 3.23.0 and 3.21.4. Versions lower than 3.23.0 and 3.21.4 only look for the file in inputdir. bundle agent ignore_interfaces_rx_reccomendations # @brief Recommend completing migration of ignore_interfaces.rx from inputdir to workdir # # @description This bundle identifies the presence of ignore_interfaces.rx in # inputdir and emits messages about its presence. Additionally, the file is # automatically copied if the file is present in inputdir and the class # default:mpf_auto_migrate_ignore_interfaces_rx_to_workdir is defined (not # defined by default). { meta: "tags" slist => { "cfengine_recommends" }; classes: "ignore_interfaces_in_workdir_supported" and => { cf_version_minimum("3.21.4"), not(cf_version_at("3.22")) }, comment => concat( "CFEngine doesn't look for ignore_interfaces.rx in", " workdir except for versions greater than or equal", "to 3.21.4." ); "ignore_interfaces_in_workdir" -> { "ENT-9402" } if => fileexists("$(sys.workdir)/ignore_interfaces.rx"); "ignore_interfaces_in_inputdir" -> { "ENT-9402" } if => fileexists("$(sys.inputdir)/ignore_interfaces.rx"); "cfengine_recommendation_instruct_disablement" expression => "cfengine_recommendation_emitted_reached", scope => "namespace"; files: ignore_interfaces_in_workdir_supported.default:mpf_auto_migrate_ignore_interfaces_rx_to_workdir.ignore_interfaces_in_inputdir:: "$(sys.workdir)/ignore_interfaces.rx" -> { "ENT-9402" } copy_from => local_dcp("$(sys.inputdir)/ignore_interfaces.rx"), comment => concat( "Excluding interfaces should be done outside of the", " policy input directory so that it's easier to", " ignore different interfaces on different hosts." ); ignore_interfaces_in_workdir_supported:: "$(sys.inputdir)/ignore_interfaces.rx" -> { "ENT-9402" } delete => tidy, action => policy("warn"), comment => concat( "Excluding interfaces should be done outside of the", " policy input directory so that it's easier to", " ignore different interfaces on different hosts.", " This file should be deleted once it's been migrated", " to sys.workdir" ); reports: ignore_interfaces_in_workdir_supported.(ignore_interfaces_in_inputdir.!default:mpf_auto_migrate_ignore_interfaces_rx_to_workdir_reports_disabled):: "NOTICE: 'ignore_interfaces.rx' is present in '$(const.dollar)(sys.inputdir)' ('$(sys.inputdir)/ignore_interfaces.rx'). We recommend that it be removed and migrated to '$(const.dollar)(sys.workdir)' ('$(sys.workdir)/ignore_interfaces.rx')" if => not(fileexists("$(sys.workdir)/ignore_interfaces.rx")), classes => results("bundle", "cfengine_recommendation_emitted"); ignore_interfaces_in_workdir_supported.(ignore_interfaces_in_workdir.ignore_interfaces_in_inputdir).!default:mpf_auto_migrate_ignore_interfaces_rx_to_workdir_reports_disabled:: "NOTICE: 'ignore_interfaces.rx' identical in '$(const.dollar)(sys.workdir)' and '$(const.dollar)(sys.inputdir)'. We recommend removing '$(const.dollar)(sys.inputdir)/ignore_interfaces.rx'" if => strcmp( readfile("$(sys.workdir)/ignore_interfaces.rx"), readfile("$(sys.inputdir)/ignore_interfaces.rx") ), classes => results("bundle", "cfengine_recommendation_emitted"); "NOTICE: 'ignore_interfaces.rx' in '$(const.dollar)(sys.workdir)' and '$(const.dollar)(sys.inputdir)' but not identical. We recommend verifying the desired content of '$(const.dollar)(sys.workdir)/ignore_interfaces.rx', correcting it if necessary and removing '$(const.dollar)(sys.inputdir)/ignore_interfaces.rx'" if => not( strcmp( readfile("$(sys.workdir)/ignore_interfaces.rx"), readfile("$(sys.inputdir)/ignore_interfaces.rx") ) ), classes => results("bundle", "cfengine_recommendation_emitted"); } @endif bundle agent nfs_mount_recommendations # @brief Recommendations about configured NFS servers { meta: "tags" slist => { "cfengine_recommends" }; vars: "nfs_server_list" slist => getvalues("default:inventory_linux.nfs_server"), depends_on => { "cfe_internal_inventory_mounted_nfs_server" }; classes: # If we end up emitting the recommendation, then we define a class so that # instructions about disabling these reports are also emitted. "cfengine_recommendation_instruct_disablement" expression => "cfengine_recommendation_emitted_kept", scope => "namespace"; reports: "$(with)" with => concat( "NOTICE: At least one of your NFS servers is specified", " in-consistently. Consider aligning your definitions to", " consistently use or avoid a trailing dot when specifying", " the NFS server." ), if => and( # Check if there exists inventory of mounted nfs servers isvariable("nfs_server_list"), # Check if any other NFS server looks identical when adding a trailing dot some(concat(escape("$(nfs_server_list)"), "\.$"), "nfs_server_list") ), classes => results("bundle", "cfengine_recommendation_emitted"); } bundle agent postgresql_conf_recommendations # @brief Recommendations about the configuration of postgresql.conf for CFEngine Enterprise Hubs { meta: (policy_server|am_policy_hub).enterprise_edition:: "tags" slist => { "cfengine_recommends" }; vars: "pgsql_conf" string => "$(sys.statedir)/pg/data/postgresql.conf"; "mem_info_source" string => "/proc/meminfo"; "mem_info_data" data => data_readstringarray($(mem_info_source), "", "(:|\s+)", inf, inf), if => fileexists($(mem_info_source)); "upper" string => "67108864"; # 64 * 1024 * 1024 in KB "lower" string => "3145728"; # 3 * 1024 * 1024 in KB "conf[maintenance_work_mem]" string => "2GB", if => isgreaterthan("$(mem_info_data[MemTotal][1])", $(lower)), comment => "If we have more than 2GB of memory available then we set the maintenance_work_memory to 2G to improve index creation, and vacuuming. Else we leave the default value."; "conf[shared_buffers]" string => "16GB", if => isgreaterthan("$(mem_info_data[MemTotal][1])", $(upper)); "conf[effective_cache_size]" string => "11GB", # 70% of 16GB if => isgreaterthan("$(mem_info_data[MemTotal][1])", $(upper)); "calculated_shared_buffers_MB" string => format( "%d0", eval( "$(mem_info_data[MemTotal][1]) * 25 / 100 / 1024", "math", "infix" ) ); "conf[shared_buffers]" string => concat($(calculated_shared_buffers_MB), "MB"), if => and( not(isvariable("conf[maintenance_work_mem]")), not(isvariable("conf[shared_buffers]")) ); "calculated_effective_cache_size_MB" string => format( "%d0", eval( "$(mem_info_data[MemTotal][1]) * 70 / 100 / 1024", "math", "infix" ) ); "conf[effective_cache_size]" string => concat($(calculated_effective_cache_size_MB), "MB"), if => and( not(isvariable("conf[maintenance_work_mem]")), not(isvariable("conf[effective_cache_size]")) ); classes: "cfengine_recommendation_instruct_disablement" expression => "cfengine_recommendation_emitted_reached", scope => "namespace"; files: "$(pgsql_conf)" edit_line => set_line_based( "$(this.bundle).conf", "=", "\s*=\s*", ".*", "\s*#\s*" ), classes => results("bundle", "psql_conf_recommendations"), action => policy("warn"), if => fileexists($(pgsql_conf)); reports: psql_conf_recommendations_not_kept:: "CFEngine Recommended Settings:"; "You have less than $(lower)KB of total memory, please consider adding more memory." if => islessthan("$(mem_info_data[MemTotal][1])", $(lower)); "shared_buffers = $(conf[shared_buffers])" if => isvariable("conf[shared_buffers]"), classes => results("bundle", "cfengine_recommendation_emitted"); "effective_cache_size = $(conf[effective_cache_size])" if => isvariable("conf[effective_cache_size]"), classes => results("bundle", "cfengine_recommendation_emitted"); "$(with)" with => concat( "maintenance_work_mem = $(conf[maintenance_work_mem]);", " If we have more than 2GB of memory available then", " we set the maintenance_work_memory to 2G to improve", " index creation, and vacuuming. Else we leave the default value." ), if => isvariable("conf[maintenance_work_mem]"), classes => results("bundle", "cfengine_recommendation_emitted"); } cfengine-masterfiles-3.27.3/cfe_internal/PaxHeaders/update0000644000000000000000000000003515266337437020636 xustar0029 mtime=1792655135.14179671 cfengine-masterfiles-3.27.3/cfe_internal/update/0000755000000000000000000000000015266337437020021 5ustar0000000000000000cfengine-masterfiles-3.27.3/cfe_internal/update/cfe_internal_dc_workflow.cf0000644000000000000000000000100614735102600025337 0ustar0000000000000000bundle agent cfe_internal_dc_workflow # @brief Update default policy distribution point from upstream repository { methods: am_policy_hub.enterprise.cfengine_internal_masterfiles_update:: "Masterfiles from VCS" usebundle => cfe_internal_update_from_repository, handle => "cfe_internal_dc_workflow_methods_masterfiles_from_vcs", action => u_immediate, comment => "Update masterfiles from upstream VCS automatically for best OOTB Enterprise experience"; } cfengine-masterfiles-3.27.3/cfe_internal/update/cfe_internal_update_from_repository.cf0000644000000000000000000000321214735102600027624 0ustar0000000000000000bundle common cfe_internal_update_from_repository_file_control # @brief Define inputs needed for updating *masterfiles*, the default policy distribution point with content from an upstream VCS { vars: "inputs" slist => { "$(this.promise_dirname)/lib.cf" }; } body file control # @brief Include policy needed for updating *masterfiles*, the default policy distribution point with content from an upstream VCS { inputs => { @(cfe_internal_update_from_repository_file_control.inputs) }; } bundle agent cfe_internal_update_from_repository # @brief Ensure *masterfiles*, the default policy is up to date { methods: am_policy_hub.cfengine_internal_masterfiles_update:: "Update staged masterfiles from VCS" usebundle => cfe_internal_masterfiles_stage, handle => "cfe_internal_update_from_repository_methods_masterfiles_fetch", action => u_immediate, comment => "Grab the latest updates from upstream VCS repo before deploying masterfiles"; } bundle agent cfe_internal_masterfiles_stage # @brief Run masterfiles-stage.sh to update the default distribution of masterfiles { commands: "$(update_def.dc_scripts)/masterfiles-stage.sh" classes => u_kept_successful_command_results( "bundle", "masterfiles_deploy" ), handle => "masterfiles_update_stage", action => u_immediate; reports: masterfiles_deploy_not_kept:: "Masterfiles deployment failed, for more info see '$(sys.workdir)/outputs/dc-scripts.log'"; (DEBUG|DEBUG_cfe_internal_masterfiles_stage).(masterfiles_deploy_kept|masterfiles_deploy_repaired):: "DEBUG $(this.bundle): Masterfiles deployed successfully"; } cfengine-masterfiles-3.27.3/cfe_internal/update/lib.cf0000644000000000000000000002124114735102600021057 0ustar0000000000000000### The following bodies were plucked from the standard library. They have been ### prefixed with =u_=. body classes u_results(scope, class_prefix) # @brief Define classes prefixed with `class_prefix` and suffixed with # appropriate outcomes: _kept, _repaired, _not_kept, _error, _failed, # _denied, _timeout, _reached # # @param scope The scope in which the class should be defined (`bundle` or `namespace`) # @param class_prefix The prefix for the classes defined # # This body can be applied to any promise and sets global # (`namespace`) or local (`bundle`) classes based on its outcome. For # instance, with `class_prefix` set to `abc`: # # * if the promise is to change a file's owner to `nick` and the file # was already owned by `nick`, the classes `abc_reached` and # `abc_kept` will be set. # # * if the promise is to change a file's owner to `nick` and the file # was owned by `adam` and the change succeeded, the classes # `abc_reached` and `abc_repaired` will be set. # # This body is a simpler, more consistent version of the body # `scoped_classes_generic`, which see. The key difference is that # fewer classes are defined, and only for outcomes that we can know. # For example this body does not define "OK/not OK" outcome classes, # since a promise can be both kept and failed at the same time. # # It's important to understand that promises may do multiple things, # so a promise is not simply "OK" or "not OK." The best way to # understand what will happen when your specific promises get this # body is to test it in all the possible combinations. # # **Suffix Notes:** # # * `_reached` indicates the promise was tried. Any outcome will result # in a class with this suffix being defined. # # * `_kept` indicates some aspect of the promise was kept # # * `_repaired` indicates some aspect of the promise was repaired # # * `_not_kept` indicates some aspect of the promise was not kept. # error, failed, denied and timeout outcomes will result in a class # with this suffix being defined # # * `_error` indicates the promise repair encountered an error # # * `_failed` indicates the promise failed # # * `_denied` indicates the promise repair was denied # # * `_timeout` indicates the promise timed out # # **Example:** # # ```cf3 # bundle agent example # { # commands: # "/bin/true" # classes => results("bundle", "my_class_prefix"); # # reports: # my_class_prefix_kept:: # "My promise was kept"; # # my_class_prefix_repaired:: # "My promise was repaired"; # } # ``` # # **See also:** `scope`, `scoped_classes_generic`, `classes_generic` { scope => "$(scope)"; promise_kept => { "$(class_prefix)_reached", "$(class_prefix)_kept" }; promise_repaired => { "$(class_prefix)_reached", "$(class_prefix)_repaired" }; repair_failed => { "$(class_prefix)_reached", "$(class_prefix)_error", "$(class_prefix)_not_kept", "$(class_prefix)_failed", }; repair_denied => { "$(class_prefix)_reached", "$(class_prefix)_error", "$(class_prefix)_not_kept", "$(class_prefix)_denied", }; repair_timeout => { "$(class_prefix)_reached", "$(class_prefix)_error", "$(class_prefix)_not_kept", "$(class_prefix)_timeout", }; } body depth_search u_cfe_internal_recurse(d) # @brief Search for files recursively to a depth of `d` across file system boundaries # @param d Number of levels deep to traverse { depth => "$(d)"; xdev => "true"; } body classes u_kept_successful_command_results(scope, class_prefix) # @brief Set command to "kept" instead of "repaired" if it returns 0 and define # classes suffixed with the appropriate outcomes. # # @param scope The scope in which the class should be defined (`bundle` or `namespace`) # @param class_prefix The prefix for the classes defined # # **See also:** `scope`, `scoped_classes_generic`, `classes_generic`, `results` { inherit_from => u_results("$(scope)", "$(class_prefix)"); kept_returncodes => { "0" }; failed_returncodes => { "1" }; } body service_method u_systemd_services # @brief Define service method for systemd { service_autostart_policy => "none"; service_dependence_chain => "ignore"; service_type => "generic"; service_args => ""; } bundle agent u_systemd_services(service, state) # @brief Manage standard systemd services # @param service The name of the service # @param state The desired state the service should be in. { vars: # We explicitly guard for systemd to avoid unnecessary agent time in # pre-eval systemd:: "systemctl" string => "/bin/systemctl"; "call_systemctl" string => "$(systemctl) --no-ask-password --global --system"; "systemd_properties" string => "-pLoadState,CanStop,UnitFileState,ActiveState,LoadState,CanStart,CanReload"; "systemd_service_info" slist => string_split( execresult( "$(call_systemctl) $(systemd_properties) show $(service)", "noshell" ), "\n", "10" ); classes: systemd:: # define a class named after the desired state "$(state)" expression => "any"; "non_disabling" or => { "start", "stop", "restart", "reload" }; # A collection of classes to determine the capabilities of a given systemd # service, then start, stop, etc. the service. Also supports a custom action # for anything not supported "service_enabled" expression => reglist(@(systemd_service_info), "UnitFileState=enabled"); "service_active" expression => reglist(@(systemd_service_info), "ActiveState=active"); "service_loaded" expression => reglist(@(systemd_service_info), "LoadState=loaded"); "service_notfound" expression => reglist(@(systemd_service_info), "LoadState=not-found"); "can_stop_service" expression => reglist(@(systemd_service_info), "CanStop=yes"); "can_start_service" expression => reglist(@(systemd_service_info), "CanStart=yes"); "can_reload_service" expression => reglist(@(systemd_service_info), "CanReload=yes"); "request_start" expression => strcmp("start", "$(state)"); "request_stop" expression => strcmp("stop", "$(state)"); "request_reload" expression => strcmp("reload", "$(state)"); "request_restart" expression => strcmp("restart", "$(state)"); "action_custom" expression => "!(request_start|request_stop|request_reload|request_restart)"; "action_start" expression => "request_start.!service_active.can_start_service"; "action_stop" expression => "request_stop.service_active.can_stop_service"; "action_reload" expression => "request_reload.service_active.can_reload_service"; "action_restart" or => { "request_restart", # Possibly undesirable... if a reload is # requested, and the service "can't" be # reloaded, then we restart it instead. "request_reload.!can_reload_service.service_active", }; # Starting a service implicitly enables it "action_enable" expression => "request_start.!service_enabled"; # Respectively, stopping it implicitly disables it "action_disable" expression => "request_stop.service_enabled"; commands: systemd.service_loaded:: # note this class is defined in `inventory/linux.cf` # conveniently, systemd states map to `services` states, except # for `enable` "$(call_systemctl) -q start $(service)" if => "action_start"; "$(call_systemctl) -q stop $(service)" if => "action_stop"; "$(call_systemctl) -q reload $(service)" if => "action_reload"; "$(call_systemctl) -q restart $(service)" if => "action_restart"; "$(call_systemctl) -q enable $(service)" if => "action_enable"; "$(call_systemctl) -q disable $(service)" if => "action_disable"; # Custom action for any of the non-standard systemd actions such a # status, try-restart, isolate, et al. "$(call_systemctl) $(state) $(service)" if => "action_custom"; reports: DEBUG|DEBUG_u_systemd_service:: "DEBUG $(this.bundle): using systemd layer to $(state) $(service)"; "DEBUG $(this.bundle): Service $(service) unit file is not loaded; doing nothing" if => "systemd.!service_loaded"; "DEBUG $(this.bundle): Could not find service: $(service)" if => "systemd.service_notfound"; } body perms u_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)"; #+begin_ENT-951 # Remove after 3.20 is not supported rxdirs => "true"; @if minimum_version(3.20) rxdirs => "false"; @endif #+end } cfengine-masterfiles-3.27.3/cfe_internal/update/systemd_units.cf0000644000000000000000000000641714735102600023233 0ustar0000000000000000bundle agent cfe_internal_systemd_unit_files # @brief This bundle is responsible for ensuring the systemd units are in place # with the proper content and permissions. Any time a unit is repaired systemd # is reloaded and the repaired unit(s) are restarted. the # cfe_internal_systemd_unit_state bundle is responsible for making sure the # service units are in the appropriate state. So a service may be restarted # because of a change, and subsequently stopped if the desired state was for it # to not be running. { vars: systemd:: "systemctl" string => "/bin/systemctl"; "unit_dir" string => "/etc/systemd/system", comment => "This is the directory where the systemd units should be placed."; "unit_template_dir" string => "$(this.promise_dirname)/../../templates", comment => "This is where the templates for the units exist. In the templates dir in the root of masterfiles."; "service_units" slist => { @(cfe_internal_update_processes.all_agents) }, handle => "systemd_core_units", comment => "These are the services which should have systemd units on all systems."; files: systemd:: "$(unit_dir)/$(service_units).service" create => "true", edit_template => "$(unit_template_dir)/$(service_units).service.mustache", template_method => "mustache", classes => u_results( "bundle", "cfe_systemd_service_unit_$(service_units)" ), perms => u_mog("644", "root", "root"), comment => "We need to make each service units content is correct."; commands: systemd:: "$(systemctl)" args => "daemon-reload --no-ask-password", handle => "cfe_internal_systemd_unit_files_reload_when_changed", if => classmatch("cfe_systemd_service_unit_.*_repaired"), comment => "We need to reload the systemd configuration after any unit is changed in order for systemd to recognize the change."; "$(systemctl)" args => "restart $(service_units).service --no-ask-password", handle => "cfe_internal_systemd_unit_restart_when_changed", if => and( classify("cfe_systemd_service_unit_$(service_units)_repaired"), returnszero( "$(systemctl) --quiet is-active $(service_units)", noshell ) ), comment => "We need to restart any units which have been changed in order for the new configuration to be in effect. But we only want to restart them if they are currently running."; } bundle agent cfe_internal_systemd_service_unit_state # @brief This bundle is responsible for managing the various cfengine components # units state. It uses information from # cfe_internal_update_processes.agents_to_be_enabled, # cfe_internal_update_processes.agents_to_be_disabled to determine which units # should be running or not. { vars: "enabled" slist => { @(cfe_internal_update_processes.agents_to_be_enabled) }; "disabled" slist => { @(cfe_internal_update_processes.agents_to_be_disabled) }; methods: "Disabled Components" usebundle => u_systemd_services($(disabled), "stop"); "Enabled Components" usebundle => u_systemd_services($(enabled), "start"); } cfengine-masterfiles-3.27.3/cfe_internal/update/update_bins.cf0000644000000000000000000005146714735102600022623 0ustar0000000000000000################################################################################ # # DO NOT EDIT THIS FILE. All policy files prefixed with CFE_ and update_bins.cf # 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. # ################################################################################ ################################################################################ # # update_bins # - CFEngine binary update (native packages) # ################################################################################ bundle agent cfe_internal_update_bins # @brief Update cfengine binaries # TODO Redact this file, not in use. The policy here was migrated into # standalone self upgrade, nothing includes this policy nor references it's # bundles { vars: enterprise:: "cf_components" slist => { "cf-key", "cf-monitord", "cf-promises", "cf-runagent", "cf-serverd", "cf-hub", }, comment => "Define cfengine robot agents", handle => "cfe_internal_update_bins_vars_cf_components"; "master_software_location" string => "/var/cfengine/master_software_updates", comment => "The Cfengine binary updates directory on the policy host", handle => "cfe_internal_update_bins_vars_master_software_location"; !hpux:: "package_dir" string => "$(sys.flavour)_$(sys.arch)", comment => "The directory within software updates to look for packages"; hpux:: "package_dir" string => "$(sys.class)_$(sys.arch)", comment => "The directory within software updates to look for packages. On HPUX sys.flavor includes versions, so we use sys.class instead."; enterprise:: "local_software_dir" string => translatepath( "$(sys.workdir)/software_updates/$(package_dir)" ), comment => "Local directory containing binary updates for this host", handle => "cfe_internal_update_bins_vars_local_software_dir"; "local_update_log_dir" string => translatepath("$(sys.workdir)/software_updates/update_log"), comment => "Local directory to store update log for this host", handle => "cfe_internal_update_bins_vars_local_update_log_dir"; !windows.enterprise:: # backup script for cf-upgrade # the script should have 2 conditions, BACKUP and RESTORE # BACKUP and RESTORE status is $(const.dollar)1 variable in the script # see more details at bundle edit_line u_backup_script "backup_script" string => "/tmp/cf-upgrade_backup.sh"; # a single compressed backup file for cf-upgrade # this backup_file is passed to backup_script as $(const.dollar)2 variable # cf-upgrade will extract this file if return signal of upgrade command is not 0 "backup_file" string => "/tmp/cfengine-nova-$(sys.cf_version).tar.gz"; # install script for cf-upgrade # each distribution has its own way to upgrade a package # see more details at bundle edit_line u_install_script "install_script" string => "/tmp/cf-upgrade_install.sh"; (solarisx86|solaris).enterprise:: # to automatically remove or install packages on Solaris # admin_file is a must to have to avoid pop-up interaction # see more details at bundle edit_line u_admin_file "admin_file" string => "/tmp/cf-upgrade_admin_file"; (solarisx86|solaris).enterprise:: "novapkg" string => "cfengine-nova", comment => "Name convention of Nova package on Solaris", handle => "cfe_internal_update_bins_vars_novapkg_solaris", if => "nova_edition"; aix.enterprise:: "novapkg" string => "cfengine-nova", comment => "Name convention of Nova package on AIX", handle => "cfe_internal_update_bins_vars_novapkg_aix", if => "nova_edition"; !(solarisx86|solaris|aix).enterprise:: "novapkg" string => "cfengine-nova", comment => "Name convention of Nova package for all but not Solaris", handle => "cfe_internal_update_bins_vars_novapkg_not_solaris_aix", if => "nova_edition"; solaris.!sunos_i86pc.enterprise:: "pkgarch" string => "sparc", comment => "Name convention of package arch on Solaris", handle => "cfe_internal_update_bins_vars_pkgarch_solaris"; solarisx86.enterprise:: "pkgarch" string => "i386", comment => "Name convention of package arch on Solaris", handle => "cfe_internal_update_bins_vars_pkgarch_solarisx86"; redhat.i686.enterprise:: "pkgarch" string => "i386", comment => "Name convention of package arch on 32-bit RHEL", handle => "cfe_internal_update_bins_vars_pkgarch_redhat_32b"; redhat.(x86_64|ppc64).enterprise:: "pkgarch" string => "$(sys.arch)", comment => "Name convention of package arch on RHEL x86_64 and ppc64", handle => "cfe_internal_update_bins_vars_pkgarch_redhat_x86_64_and_ppc64"; (freebsd|netbsd|debian|aix).enterprise:: "pkgarch" string => "*", comment => "Name convention of package arch on *BSD/Debian", handle => "cfe_internal_update_bins_vars_pkgarch_bsd_debian_aix"; !(solarisx86|solaris|freebsd|netbsd|debian|aix|redhat).enterprise:: "pkgarch" string => "$(sys.arch)", comment => "Name convention of package arch for other system except Solaris and *BSD", handle => "cfe_internal_update_bins_vars_pkgarch_not_solaris_bsd_debian_aix_redhat_32b"; classes: "have_software_dir" expression => fileexists($(local_software_dir)); packages: !am_policy_hub.linux.enterprise.trigger_upgrade.!bootstrap_mode:: "$(novapkg)" comment => "Update Nova package to a newer version (package is there)", handle => "cfe_internal_update_bins_packages_nova_update_linux_pkg_there", package_policy => "update", package_select => "==", # picks the newest Nova available package_architectures => { "$(pkgarch)" }, package_version => "$(update_def.current_version)-$(update_def.current_release)", package_method => u_generic("$(local_software_dir)"), if => "nova_edition.have_software_dir", classes => u_if_else("bin_update_success", "bin_update_fail"); !am_policy_hub.(solaris|solarisx86).enterprise.trigger_upgrade.!bootstrap_mode:: "$(novapkg)" comment => "Update Nova package to a newer version (package is there)", handle => "cfe_internal_update_bins_packages_nova_update_solaris_pkg_there", package_policy => "update", package_select => "==", # picks the newest Nova available package_architectures => { "$(pkgarch)" }, package_version => "$(update_def.current_version)", package_method => u_generic("$(local_software_dir)"), if => "nova_edition.have_software_dir", classes => u_if_else("bin_update_success", "bin_update_fail"); !am_policy_hub.windows.enterprise.trigger_upgrade.!bootstrap_mode:: "$(novapkg)" comment => "Update Nova package to a newer version (package is there)", handle => "cfe_internal_update_bins_packages_nova_update_windows_only_pkg_there", package_policy => "update", package_select => "==", # picks the newest Nova available package_architectures => { "$(pkgarch)" }, package_version => "$(update_def.current_version)", package_method => u_generic("$(local_software_dir)"), if => "nova_edition.have_software_dir", classes => u_if_else("bin_update_success", "bin_update_fail"); !am_policy_hub.aix.enterprise.trigger_upgrade.!bootstrap_mode:: "$(novapkg)" comment => "Update Nova package to a newer version (package is there)", handle => "cfe_internal_update_bins_packages_nova_update_aix_only_pkg_there", package_policy => "update", package_select => "==", # picks the newest Nova available package_architectures => { "$(pkgarch)" }, package_version => "$(update_def.current_version).0", package_method => u_generic("$(local_software_dir)"), if => "nova_edition.have_software_dir", classes => u_if_else("bin_update_success", "bin_update_fail"); files: enterprise:: "$(local_update_log_dir)/$(sys.nova_version)_is_running" comment => "Create an empty file about a version that is running", handle => "cfe_internal_update_bins_files_version_is_running", create => "true"; am_policy_hub.enterprise:: "$(master_software_location)/cf-upgrade/linux.i386/." comment => "Prepare a directory for cf-upgrade", handle => "cfe_internal_update_bins_files_linux_i386", create => "true"; "$(master_software_location)/cf-upgrade/linux.x86_64/." comment => "Prepare a directory for cf-upgrade", handle => "cfe_internal_update_bins_files_linux_x86_64", create => "true"; !am_policy_hub.enterprise.trigger_upgrade:: "$(admin_file)" comment => "Create solaris admin_file to automate remove and install packages", handle => "cfe_internal_update_bins_files_solaris_admin_file", create => "true", edit_defaults => u_empty_no_backup, edit_line => u_admin_file, perms => u_m("0644"), if => "solarisx86|solaris"; "$(backup_script)" comment => "Create a backup script for cf-upgrade", handle => "cfe_internal_update_bins_files_backup_script", create => "true", if => "!windows", edit_defaults => u_empty_no_backup, edit_line => u_backup_script, perms => u_m("0755"); "$(install_script)" comment => "Create an install script for cf-upgrade", handle => "cfe_internal_update_bins_files_install_script", create => "true", if => "!windows", edit_defaults => u_empty_no_backup, edit_line => u_install_script, perms => u_m("0755"); "$(local_software_dir)/." create => "true", handle => "cfe_internal_update_bins_files_local_software_dir_presence", comment => "Ensure the local software directory exists for new binaries to be downloaded to"; "$(local_software_dir)/." comment => "Copy binary updates from master source on policy server", handle => "cfe_internal_update_bins_files_pkg_copy", copy_from => u_pcp( "$(master_software_location)/$(package_dir)", @(update_def.policy_servers) ), depth_search => u_recurse("1"), # Nova updates should be in root dir action => u_immediate, classes => u_if_repaired("bin_newpkg"); bin_update_success.enterprise.trigger_upgrade:: "$(local_update_log_dir)/upgraded_binary_from_$(sys.nova_version)" comment => "Create an empty file after successfully upgrade the binary", handle => "cfe_internal_update_bins_files_update_from_log", create => "true"; reports: DEBUG|DEBUG_cfe_internal_update_bins:: "DEBUG $(this.bundle): Evaluating binaries for upgrade using internal update mechanism" if => "trigger_upgrade"; } ################################################################################ bundle edit_line u_admin_file # @brief Admin file for automating solaris package installs { insert_lines: sunos_5_8:: "mail= instance=unique partial=nocheck runlevel=nocheck idepend=nocheck rdepend=nocheck space=nocheck setuid=nocheck conflict=nocheck action=nocheck basedir=default"; solaris.!sunos_5_8:: "mail= instance=overwrite 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"; } ################################################################################ bundle edit_line u_backup_script # brief Script to execute before package upgrade { insert_lines: linux:: "#!/bin/sh if [ $(const.dollar)1 = \"BACKUP\" ]; then tar cfzS $(const.dollar)2 $(sys.workdir) > /dev/null fi if [ $(const.dollar)1 = \"RESTORE\" ]; then tar xfz $(const.dollar)2 fi"; solarisx86|solaris:: "#!/bin/sh if [ $(const.dollar)1 = \"BACKUP\" ]; then tar cf $(const.dollar)2 $(sys.workdir); gzip $(const.dollar)2 fi if [ $(const.dollar)1 = \"RESTORE\" ]; then gunzip $(const.dollar)2.gz; tar xf $(const.dollar)2 fi"; } ################################################################################ bundle edit_line u_install_script # brief Script to upgrade package { insert_lines: redhat|suse|sles:: "#!/bin/sh /bin/rpm -U $(const.dollar)1"; debian:: "#!/bin/sh /usr/bin/dpkg --force-confdef --force-confnew --install $(const.dollar)1 > /dev/null"; solarisx86|solaris:: "#!/bin/sh pkgname=`pkginfo -d $(const.dollar)1 | awk '{print $(const.dollar)2}'` /usr/sbin/pkgrm -n -a $(cfe_internal_update_bins.admin_file) $pkgname /usr/sbin/pkgadd -n -a $(cfe_internal_update_bins.admin_file) -d $(const.dollar)1 all $(sys.workdir)/bin/cf-execd || true exit 0"; } ################################################################################ body edit_defaults u_empty_no_backup # @brief Empty file before editing and create no backups { empty_file_before_editing => "true"; edit_backup => "false"; } ################################################################################ body copy_from u_pcp(from, server) # @brief Copy from `from` on `server` using digest comparison # @param from Path on remote server to copy from # @param server Remote host to copy from { source => "$(from)"; compare => "digest"; trustkey => "false"; purge => "true"; !am_policy_hub:: servers => { "$(server)" }; cfengine_internal_encrypt_transfers:: encrypt => "true"; } ################################################################################ bundle common u_common_knowledge # @brief standalone common packages knowledge bundle # # This common bundle defines general things about platforms. # @see common_knowledge { vars: "list_update_ifelapsed_now" string => "10080"; } ################################################################################ body package_method u_generic(repo) { debian:: package_changes => "individual"; package_list_command => "/usr/bin/dpkg -l"; # package_list_update_command => "/usr/bin/apt-get update"; package_list_update_ifelapsed => "$(u_common_knowledge.list_update_ifelapsed_now)"; package_list_name_regex => "ii\s+([^\s:]+).*"; # package_list_version_regex => "ii\s+[^\s]+\s+([^\s]+).*"; package_list_version_regex => "ii\s+[^\s]+\s+(\d+\.\d+((\.|-)\d+)+).*"; package_installed_regex => ".*"; # all reported are installed package_file_repositories => { "$(repo)" }; package_version_equal_command => "/usr/bin/dpkg --compare-versions '$(v1)' eq '$(v2)'"; package_version_less_command => "/usr/bin/dpkg --compare-versions '$(v1)' lt '$(v2)'"; debian.x86_64:: package_name_convention => "$(name)_$(version)_amd64.deb"; debian.i686:: package_name_convention => "$(name)_$(version)_i386.deb"; debian:: package_add_command => "/usr/bin/dpkg --force-confdef --force-confnew --install"; package_delete_command => "/usr/bin/dpkg --purge"; debian:: package_update_command => "$(sys.workdir)/bin/cf-upgrade -b $(cfe_internal_update_bins.backup_script) -s $(cfe_internal_update_bins.backup_file) -i $(cfe_internal_update_bins.install_script)"; redhat|SuSE|suse|sles:: package_changes => "individual"; package_list_command => "/bin/rpm -qa --queryformat \"i | repos | %{name} | %{version}-%{release} | %{arch}\n\""; package_list_update_ifelapsed => "$(u_common_knowledge.list_update_ifelapsed_now)"; package_list_name_regex => "[^|]+\|[^|]+\|\s+([^\s|]+).*"; package_list_version_regex => "[^|]+\|[^|]+\|[^|]+\|\s+([^\s|]+).*"; package_list_arch_regex => "[^|]+\|[^|]+\|[^|]+\|[^|]+\|\s+([^\s]+).*"; package_installed_regex => "i.*"; package_file_repositories => { "$(repo)" }; package_name_convention => "$(name)-$(version).$(arch).rpm"; package_add_command => "/bin/rpm -ivh "; package_delete_command => "/bin/rpm -e --nodeps"; package_verify_command => "/bin/rpm -V"; package_noverify_regex => ".*[^\s].*"; package_version_less_command => "$(sys.bindir)/rpmvercmp '$(v1)' lt '$(v2)'"; package_version_equal_command => "$(sys.bindir)/rpmvercmp '$(v1)' eq '$(v2)'"; (redhat|SuSE|suse|sles):: package_update_command => "$(sys.workdir)/bin/cf-upgrade -b $(cfe_internal_update_bins.backup_script) -s $(cfe_internal_update_bins.backup_file) -i $(cfe_internal_update_bins.install_script)"; redhat.!redhat_4:: package_list_update_command => "/usr/bin/yum --quiet check-update"; redhat_4:: package_list_update_command => "/usr/bin/yum check-update"; SuSE|suse|sles:: package_list_update_command => "/usr/bin/zypper list-updates"; windows:: package_changes => "individual"; package_list_update_ifelapsed => "$(u_common_knowledge.list_update_ifelapsed_now)"; package_file_repositories => { "$(repo)" }; package_installed_regex => ".*"; package_name_convention => "$(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"; freebsd:: package_changes => "individual"; package_list_command => "/usr/sbin/pkg_info"; package_list_update_command => "/usr/bin/true"; package_list_update_ifelapsed => "$(u_common_knowledge.list_update_ifelapsed_now)"; package_list_name_regex => "^(\S+)-(\d+\.?)+"; package_list_version_regex => "^\S+-((\d+\.?)+\_\d)"; package_file_repositories => { "$(repo)" }; package_installed_regex => ".*"; package_name_convention => "$(name)-$(version).tbz"; package_delete_convention => "$(name)-$(version)"; package_add_command => "/usr/sbin/pkg_add"; package_delete_command => "/usr/sbin/pkg_delete"; netbsd:: package_changes => "individual"; package_list_command => "/usr/sbin/pkg_info"; package_list_update_command => "/usr/bin/true"; package_list_update_ifelapsed => "$(u_common_knowledge.list_update_ifelapsed_now)"; package_list_name_regex => "^(\S+)-(\d+\.?)+"; package_list_version_regex => "^\S+-((\d+\.?)+\nb\d)"; package_file_repositories => { "$(repo)" }; package_installed_regex => ".*"; package_name_convention => "$(name)-$(version).tgz"; package_delete_convention => "$(name)-$(version)"; package_add_command => "/usr/sbin/pkg_add"; package_delete_command => "/usr/sbin/pkg_delete"; solarisx86|solaris:: package_changes => "individual"; package_list_command => "/usr/bin/pkginfo -l"; package_list_update_command => "/usr/bin/true"; package_list_update_ifelapsed => "$(u_common_knowledge.list_update_ifelapsed_now)"; 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_file_repositories => { "$(repo)" }; package_installed_regex => "\s*STATUS:\s*(completely|partially)\s+installed.*"; package_name_convention => "$(name)-$(version)-$(arch).pkg"; package_delete_convention => "$(name)"; # Cfengine appends path to package and package name below, respectively package_add_command => "/bin/sh $(repo)/add_scr $(repo)/admin_file"; package_delete_command => "/usr/sbin/pkgrm -n -a $(repo)/admin_file"; (solarisx86|solaris):: package_update_command => "$(sys.workdir)/bin/cf-upgrade -b $(cfe_internal_update_bins.backup_script) -s $(cfe_internal_update_bins.backup_file) -i $(cfe_internal_update_bins.install_script)"; aix:: package_changes => "individual"; package_list_update_command => "/usr/bin/true"; package_list_update_ifelapsed => "$(u_common_knowledge.list_update_ifelapsed_now)"; package_list_command => "/usr/bin/lslpp -lc"; package_list_name_regex => "[^:]+:([^:]+):[^:]+:.*"; package_list_version_regex => "[^:]+:[^:]+:([^:]+):.*"; package_file_repositories => { "$(repo)" }; package_installed_regex => "[^:]+:[^:]+:[^:]+:[^:]*:(COMMITTED|APPLIED):.*"; package_name_convention => "$(name)-$(version).bff"; package_delete_convention => "$(name)"; package_add_command => "/usr/bin/rm -f $(repo)/.toc && /usr/sbin/geninstall -IqacgXNY -d $(repo) cfengine-nova$"; package_update_command => "/usr/bin/rm -f $(repo)/.toc && /usr/sbin/geninstall -IqacgXNY -d $(repo) cfengine-nova$"; package_delete_command => "/usr/sbin/installp -ug cfengine-nova$"; } cfengine-masterfiles-3.27.3/cfe_internal/update/update_policy.cf0000644000000000000000000010462214735102600023157 0ustar0000000000000000################################################################################ # # DO NOT EDIT THIS FILE. All policy files prefixed with CFE_ and update_bins.cf # 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. # ################################################################################ ######################################################### # # update_policy # - Cfengine policy update (masterfiles -> inputs) # ######################################################### bundle agent cfe_internal_update_policy # @brief This bundle is responsible for activating the policy to update inputs. # @description Users may define `def.mpf_update_policy_bundle` to override the # default policy update bundle. { classes: # Define classes if we see a user is requesting a custom policy update bundle "have_user_specified_update_bundle" expression => isvariable("def.mpf_update_policy_bundle"); # Define classes if we are able to find the specific bundle they requested # (otherwise we may get an error about undefined bundle) "have_found_user_specified_update_bundle" expression => some(".*", "found_matching_user_specified_bundle"); "missing_user_specified_update_bundle" not => some(".*", "found_matching_user_specified_bundle"); vars: "default_policy_update_bundle" string => "cfe_internal_update_policy_cpv"; # Look for a bundle that matches what the user wants "found_matching_user_specified_bundle" slist => bundlesmatching("^$(def.mpf_update_policy_bundle)$"); methods: # Use the user specified bundle when it's found have_found_user_specified_update_bundle:: "User specified policy update bundle" usebundle => $(found_matching_user_specified_bundle); # Fall back to stock policy update bundle if we have not found one # specified by user !have_found_user_specified_update_bundle:: "Stock policy update" usebundle => cfe_internal_update_policy_cpv; any:: "CMDB data update" -> { "ENT-6788", "ENT-8847" } usebundle => cfe_internal_update_cmdb, action => u_immediate; reports: inform_mode|verbose_mode|DEBUG|DEBUG_cfe_internal_update_policy:: # Report a human readable way to understand the policy behavior "User specified update bundle: $(def.mpf_update_policy_bundle)" if => "have_user_specified_update_bundle"; "User specified update bundle MISSING! Falling back to $(default_policy_update_bundle)." if => and( "have_user_specified_update_bundle", "missing_user_specified_update_bundle" ); any:: "WARNING User specified update bundle '$(def.mpf_update_policy_bundle)' does not specify a namespace. Please specify a namespace, e.g. 'default:$(def.mpf_update_policy_bundle)'." if => and( not(regcmp(".*:.*", $(def.mpf_update_policy_bundle))), "have_user_specified_update_bundle" ); } bundle agent cfe_internal_setup_python_symlink(symlink_path) # @brief Create the /var/cfengine/bin/python symlink pointing to some installed python (if any) { vars: "path" string => getenv("PATH", 1024); "path_folders" slist => splitstring("$(path)", ":", 128); windows:: "abs_path_folders" -> { "CFE-2309" } slist => filter("([A-Z]|//):.*", path_folders, "true", "false", 128), comment => "findfiles() complains about relative directories"; !windows:: "abs_path_folders" -> { "CFE-2309" } slist => filter("/.*", path_folders, "true", "false", 128), comment => "findfiles() complains about relative directories"; any:: "exact_version_globs" slist => maplist("$(this)/python[23]", @(abs_path_folders)), comment => "Looking for Python 2 and/or Python 3 in the $PATH folders"; "generic_python_globs" slist => maplist("$(this)/python", @(abs_path_folders)), comment => "Looking for the 'python' symlink/executable which can be any version of Python (usually Python 2 for backwards compatibility)"; "python_exact[$(exact_version_globs)]" slist => findfiles("$(exact_version_globs)"); "python_generic[$(generic_python_globs)]" slist => findfiles("$(generic_python_globs)"); "python_platform_fallback[/usr/libexec/platform-python]" -> { "CFE-3291" } slist => { "/usr/libexec/platform-python" }; "python_exact_sorted" slist => reverse(sort(getvalues(@(python_exact)), "lex")), comment => "Prefer higher major versions of Python"; "pythons" slist => getvalues( mergedata( @(python_exact_sorted), getvalues(@(python_generic)), getvalues(@(python_platform_fallback)) ) ), comment => "Prefer exact versions over unknown"; "python" string => nth(@(pythons), 0), if => isgreaterthan(length(@(pythons)), 0), comment => "Taking the first item from the list (sorted by preference)"; files: "$(symlink_path)" delete => u_tidy, if => not(isvariable("python")); "$(symlink_path)" link_from => u_ln_s("$(python)"), move_obstructions => "true", if => isvariable("python"); "$(sys.bindir)/python" -> { "CFE-3512", "CFE-4146" } delete => u_tidy, if => and( islink("$(sys.bindir)/python"), strcmp("$(sys.bindir)", "/var/cfengine/bin") ), comment => concat( "We don't want to leave a python that is potentially in $PATH ", "after having re-named our python symlink that is used for various ", "modules. Additionally we want to be cautious that we don't delete ", "system python symlinks in the event the binary was built for FHS." ); } bundle agent cfe_internal_update_policy_cpv # @brief Update inputs from masterfiles when cf_promises_validated changes # # @description This bundle updates inputdir, and modules. It uses the # cf_promises_validated file as a gating mechanism to prevent # unnecessary burden on the server from remote agents checking to # see if each individual file needs an update. # - The class `validated_updates_ready` is defined when `cf_promises_validated` is repaired # - Executing `cf-agent -KIf update.cf --define validated_updates_ready` will # cause the update policy to scan all files in masterfiles and modules to be # scanned for update. { vars: # TODO: Remove this once sys.keydir is always available (3.26+ only) "keydir" -> { "CFE-2822" } string => ifelse( isvariable("sys.keydir"), "$(sys.keydir)", "$(sys.workdir)/ppkeys" ); "inputs_dir" string => translatepath("$(sys.inputdir)"), comment => "Directory containing CFEngine policies", handle => "cfe_internal_update_policy_vars_inputs_dir"; "master_location" -> { "ENT-3692" } string => "$(update_def.mpf_update_policy_master_location)", comment => "The path to request updates from the policy server.", handle => "cfe_internal_update_policy_vars_master_location"; windows:: "modules_dir_source" string => "/var/cfengine/masterfiles/modules", comment => "Directory containing CFEngine modules", handle => "cfe_internal_update_policy_vars_modules_dir_windows"; !windows:: "modules_dir_source" string => translatepath("$(master_location)/modules"), comment => "Directory containing CFEngine modules", handle => "cfe_internal_update_policy_vars_modules_dir"; any:: "file_check" string => translatepath("$(inputs_dir)/promises.cf"), comment => "Path to a policy file", handle => "cfe_internal_update_vars_file_check"; "ppkeys_file" string => translatepath("$(keydir)/localhost.pub"), comment => "Path to public key file", handle => "cfe_internal_update_policy_vars_ppkeys_file"; "postgresdb_dir" string => "$(sys.workdir)/state/pg/data", comment => "Directory where Postgres database files will be stored on hub -", handle => "cfe_internal_update_policy_postgresdb_dir"; "postgresdb_log" string => "/var/log/postgresql.log", comment => "File where Postgres database files will be logging -", handle => "cfe_internal_update_policy_postgresdb_log_file"; "python_symlink" -> { "CFE-2602", "CFE-3512" } string => "$(sys.bindir)/cfengine-selected-python", comment => "Symlink to Python we found (if any)", handle => "cfe_internal_update_policy_python_symlink"; classes: "validated_updates_ready" expression => "cfengine_internal_disable_cf_promises_validated", comment => "If cf_promises_validated is disabled, then updates are always considered validated."; any:: "local_files_ok" expression => fileexists("$(file_check)"), comment => "Check for $(sys.masterdir)/promises.cf", handle => "cfe_internal_update_classes_files_ok"; # create a global files_ok class "cfe_internal_trigger" expression => "local_files_ok", classes => u_if_else("files_ok", "files_ok"); files: !am_policy_hub:: # policy hub should not alter inputs/ uneccessary "$(inputs_dir)/cf_promises_validated" comment => "Check whether a validation stamp is available for a new policy update to reduce the distributed load", handle => "cfe_internal_update_policy_check_valid_update", copy_from => u_rcp( "$(master_location)/cf_promises_validated", @(update_def.policy_servers) ), action => u_immediate, classes => u_if_repaired("validated_updates_ready"); am_policy_hub|validated_updates_ready:: # policy hub should always put masterfiles in inputs in order to check new policy "$(inputs_dir)" comment => "Copy policy updates from master source on policy server if a new validation was acquired", handle => "cfe_internal_update_policy_files_inputs_dir", copy_from => u_rcp("$(master_location)", @(update_def.policy_servers)), depth_search => u_infinite_client_policy, file_select => u_input_files, action => u_immediate, classes => u_results("bundle", "update_inputs"), move_obstructions => "true"; # Note that here we do not filter with `update_def.input_name_patterns` so # that we copy any and all modules scripts. "$(inputs_dir)/modules" comment => "Copy any files in modules from master source on policy server if a new validation was acquired", handle => "cfe_internal_update_policy_files_modules_dir", copy_from => u_rcp( "$(modules_dir_source)", @(update_def.policy_servers) ), depth_search => u_recurse("inf"), action => u_immediate; update_inputs_not_kept:: "$(inputs_dir)/cf_promises_validated" -> { "CFE-2587" } delete => u_tidy, comment => "If there is any problem copying to $(inputs_dir) then purge the cf_promises_validated file must be purged so that subsequent agent runs will perform a full scan."; !policy_server.enable_cfengine_enterprise_hub_ha:: "$(sys.workdir)/policy_server.dat" comment => "Copy policy_server.dat file from server", handle => "cfe_internal_update_ha_policy_server", copy_from => u_rcp( "$(sys.workdir)/state/master_hub.dat", @(update_def.policy_servers) ), action => u_immediate, classes => u_if_repaired("replica_failover"); # not needed ? am_policy_hub:: "$(master_location)/." -> { "CFE-951" } comment => "Make sure masterfiles folder has right file permissions", handle => "cfe_internal_update_policy_files_sys_workdir_masterfiles_dirs", perms => u_m($(update_def.masterfiles_perms_mode_dirs)), file_select => u_dirs, depth_search => u_recurse_basedir("inf"), action => u_immediate; "$(master_location)/." -> { "CFE-951" } comment => "Make sure masterfiles folder has right file permissions", handle => "cfe_internal_update_policy_files_sys_workdir_masterfiles_not_dir", perms => u_m($(update_def.masterfiles_perms_mode_not_dir)), file_select => u_not_dir, depth_search => u_recurse_basedir("inf"), action => u_immediate; methods: debian|redhat|amazon_linux|suse|sles|opensuse:: # Only needed on distros with Python-based package modules "setup_python_symlink" -> { "CFE-2602" } usebundle => cfe_internal_setup_python_symlink("$(python_symlink)"); any:: # Install vendored and user provided modules to $(sys.workdir) from $(sys.inputdir) "modules_presence"; } bundle agent cfe_internal_update_cmdb # @brief Ensure local cache of CMDB data is up to date { classes: "have_cf_reactor" expression => fileexists("$(sys.bindir)/cf-reactor"); methods: policy_server.enterprise_edition.(!have_cf_reactor|cmdb_data_files_updates_done_in_policy):: "cfe_internal_update_cmdb_data_distribution"; @if feature(host_specific_data_load) # Only hosts with this feature, introduced in 3.18.0 can use the data. # Don't pull CMDB data on policy_hub self bootstrap because # there will be no cf-serverd listening to serve files yet. enterprise_edition.!(bootstrap_mode):: # ENT-6840 "cfe_internal_update_cmdb_data_consumption" -> { "ENT-8847" } action => u_immediate; @endif } bundle agent cfe_internal_update_cmdb_data_distribution # @brief Ensure data is ready for agents to download { classes: "_have_cmdb_next_request_state_file" -> { "ENT-9933" } expression => fileexists("$(_cmdb_next_request_state_file)"); vars: !bootstrap_mode.(policy_server.enterprise_edition):: # The API response for host specific data from cmdb tells us the timestamp of the last data change # We store this timestamp and use it for the next request. "_cmdb_next_request_state_file" string => "$(sys.statedir)/cmdb_next_request_from.dat"; !bootstrap_mode.(policy_server.enterprise_edition._have_cmdb_next_request_state_file):: # If we have the timestamp from a previous response we use it, else we start from 0 "_cmdb_previous_next_request_from" string => readfile($(_cmdb_next_request_state_file), inf), if => regline("^\d+$", $(_cmdb_next_request_state_file)); "_cmdb_previous_next_request_from" string => "0", unless => regline("^\d+$", $(_cmdb_next_request_state_file)); !bootstrap_mode.(policy_server.enterprise_edition):: # We need a script to call that should return the API response "_get_cmdb_data_bin" string => "$(sys.workdir)/httpd/htdocs/scripts/get_cmdb.php"; "_get_cmdb_data_cmd" string => "/var/cfengine/httpd/php/bin/php $(_get_cmdb_data_bin) $(_cmdb_previous_next_request_from)"; # We call the script and we pass it the timestamp from the prior call "_get_cmdb_data_response" string => execresult($(_get_cmdb_data_cmd), useshell), if => fileexists($(_get_cmdb_data_bin)); "_get_cmdb_data_response_d" data => parsejson('$(_get_cmdb_data_response)'), if => validjson('$(_get_cmdb_data_response)'); # So that we can write a JSON file for each host we get the indicies of data in the response "_i" slist => getindices("_get_cmdb_data_response_d[data]"); # We need to store the timestamp from the most recent change so that we can use that as a starting point for future requests. "_next_request_from" string => "$(_get_cmdb_data_response_d[meta][cmdb_epoch])"; files: # "$(_get_cmdb_data_cmd)" perms => m( 700 ); @if minimum_version(3.18) !bootstrap_mode.(policy_server.enterprise_edition):: # This functionality is only present on 3.18.0+ Enterprise hubs, and this # promise uses the /content/ attribute which was first introduced in # 3.16.0. # If the next request state file doesn't exist, we seed one with 0, the # lowest epoch value possible. because we populate variables from this # file content. "$(_cmdb_next_request_state_file)" content => "0$(const.n)", handle => "cmdb_data_change_next_seed", if => and( not(fileexists("$(_cmdb_next_request_state_file)")), isvariable("_cmdb_next_request_state_file") ); @endif # Write out the data for each host that had a data change "$(sys.workdir)/cmdb/$(_i)/host_specific.json" create => "true", # CFE-2329, ENT-4792 template_data => mergedata("_get_cmdb_data_response_d[data][$(_i)]"), # mergedata() is necessary in order to pick out a substructure, parsejson() is insufficient because expanding a key results in iteration of /values/ under that key template_method => "inline_mustache", edit_template_string => string_mustache( "{{$-top-}}", "_get_cmdb_data_response_d[data][$(_i)]" ), if => isgreaterthan( $(_next_request_from), $(_cmdb_previous_next_request_from) ); @if minimum_version(3.18) # This functionality is only present on 3.18.0+ Enterprise hubs, and this # promise uses the /content/ attribute which was first introduced in # 3.16.0. # Write out the last data change timestamp so we can use it as a startring point "$(_cmdb_next_request_state_file)" handle => "cmdb_data_change_next_update", content => "$(_next_request_from)$(const.n)", unless => strcmp( $(_next_request_from), $(_cmdb_previous_next_request_from) ); @endif reports: DEBUG|DEBUG_cfe_internal_update_cmdb_data_distribution:: "'$(_get_cmdb_data_cmd)' response indicates '$(sys.workdir)/cmdb/$(_i)/host_specific.json' needs refreshed" if => and( isvariable("_i"), isgreaterthan( $(_next_request_from), $(_cmdb_previous_next_request_from) ) ); } bundle agent cfe_internal_update_cmdb_data_consumption # @brief Ensure data to load is up to date { files: "$(sys.workdir)/data/." create => "true", comment => "If a host is to load data from the CMDB, it needs to have a directory where said data is cached."; "$(sys.workdir)/data/." -> { "ENT-6788", "ENT-8847" } depth_search => u_recurse(inf), file_select => u_all, copy_from => u_cmdb_data, comment => "So that hosts have access to the most recent CMDB data, we make sure that it's up to date.", action => u_immediate; } ######################################################### # Self-contained bodies from the lib to avoid dependencies ######################################################### body copy_from u_cmdb_data # @brief Sync CMDB data from policy server # Note: Not all hosts necessarily have CMDB data { copy_backup => "false"; trustkey => "false"; compare => "digest"; source => "hub_cmdb"; servers => { "$(sys.policy_hub)" }; purge => "true"; @if minimum_version(3.12) missing_ok => "true"; @endif } body perms u_m(p) # @brief Ensure file mode is `p` # @param p Desired file mode { mode => "$(p)"; #+begin_ENT-951 # Remove after 3.20 is not supported rxdirs => "true"; @if minimum_version(3.20) rxdirs => "false"; @endif #+end } ######################################################### body perms u_mo(p, o) # @brief Ensure file mode is `p` and owner is `o` # @param p Desired file mode # @param p Desired file owner (username or uid) { mode => "$(p)"; #+begin_ENT-951 # Remove after 3.20 is not supported rxdirs => "true"; @if minimum_version(3.20) rxdirs => "false"; @endif #+end !(windows|termux):: owners => { "$(o)" }; } ######################################################### body perms u_shared_lib_perms # @brief Shared library permissions { #+begin_ENT-951 # Remove after 3.20 is not supported rxdirs => "true"; @if minimum_version(3.20) rxdirs => "false"; @endif #+end !hpux:: mode => "0644"; hpux:: mode => "0755"; # Mantis 1114, Redmine 1179 } ######################################################### body file_select u_all # @brief Select all file system entries { leaf_name => { ".*" }; file_result => "leaf_name"; } body file_select u_cf3_files # @brief Select files starting with `cf-` (cfengine binaries) { leaf_name => { "cf-.*" }; file_result => "leaf_name"; } ######################################################### body file_select u_input_files # @brief Select files by extension that we should include when updating inputs { leaf_name => { @(update_def.input_name_patterns), @(update_def.input_name_patterns_extra) }; file_result => "leaf_name"; } ######################################################### body copy_from u_rcp(from, server) # @brief Ensure file is a copy of `from` on `server` using digest comparison # @param from The path to copy from # @param server The remote host to copy from { source => "$(from)"; compare => "digest"; trustkey => "false"; purge => "true"; # CFE-3662 # CFE-2932 For testing, we want to be able to avoid this local copy optimiztion !am_policy_hub|mpf_skip_local_copy_optimizaton:: servers => { "$(server)" }; !am_policy_hub.(sys_policy_hub_port_exists|mpf_skip_local_copy_optimization):: portnumber => "$(sys.policy_hub_port)"; cfengine_internal_encrypt_transfers:: encrypt => "true"; cfengine_internal_purge_policies_disabled:: purge => "false"; cfengine_internal_preserve_permissions:: preserve => "true"; cfengine_internal_verify_update_transfers:: verify => "true"; } ######################################################### body copy_from u_cp(from) # @brief Ensure file is a copy from `from` on the local server based on digest comparison { source => "$(from)"; compare => "digest"; } ######################################################### body copy_from u_cp_nobck(from) # @brief copy from `from` locally with digest comparison and making no backups { source => "$(from)"; compare => "digest"; copy_backup => "false"; } ######################################################### body copy_from u_cp_missing_ok(from) # @brief same as u_cp but allow from to be missing { inherit_from => u_cp($(from)); missing_ok => "true"; } body copy_from u_remote_dcp_missing_ok(from, server) # @brief Download a file from a remote server if available and if differs 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 # # **See Also:** `remote_dcp()` { servers => { "$(server)" }; source => "$(from)"; compare => "digest"; missing_ok => "true"; } ######################################################### body action u_immediate # @brief Actuate the promise immediately, ignoring locks { ifelapsed => "0"; } ######################################################### body depth_search u_recurse(d) # @brief Search recursively for files up to `d` levels excluding common version control data # @param d Maximum depth to search recursively { depth => "$(d)"; exclude_dirs => { "\.svn", "\.git", "git-core" }; } ######################################################### body depth_search u_infinite_client_policy # @brief Search recursively for files excluding vcs related files and .no-distrib directories # @param d Maximum depth to search recursively # Duplicated in embedded bootstrap/failsafe { depth => "inf"; exclude_dirs => { "\.svn", "\.git", "git-core", "\.no-distrib" }; } ######################################################### body depth_search u_recurse_basedir(d) # @brief Search recursively for files up to `d` levels excluding common version control data and including the base directory # @param d Maximum depth to search recursively { include_basedir => "true"; depth => "$(d)"; exclude_dirs => { "\.svn", "\.git", "git-core" }; } ######################################################### body classes u_if_repaired(x) # @brief Define `x` if the promise is repaired # @param x Class to define if promise repaired { promise_repaired => { "$(x)" }; } ######################################################### body classes u_if_repaired_then_cancel(y) # @brief Cancel class `x` if the promise is repaired # @param x Class to undefine if promise repaired { cancel_repaired => { "$(y)" }; } ######################################################### body classes u_if_else(yes, no) # @brief define `yes` if the promise is repaired, and `no` if the promise fails to repair (notkept) # @param yes Class to define if promise repaired # @param no Class to undefine if promise notkept { # promise_kept => { "$(yes)" }; promise_repaired => { "$(yes)" }; repair_failed => { "$(no)" }; repair_denied => { "$(no)" }; repair_timeout => { "$(no)" }; } ######################################################### body contain u_in_shell # @brief Run command within shell environment { useshell => "true"; } ######################################################### body contain u_in_shell_and_silent # @brief Run command within shell environment suppressing output { useshell => "true"; no_output => "true"; } ########################################################"" body contain u_postgres # @brief Run command within postgres users shell environment { useshell => "useshell"; exec_owner => "cfpostgres"; exec_group => "cfpostgres"; chdir => "/tmp"; no_output => "true"; } ######################################################### body action u_ifwin_bg # @brief Run command in the background if windows is defined { windows:: background => "true"; } ######################################################### body service_method u_bootstart # @brief Attributes for u_bootstart service method { service_autostart_policy => "boot_time"; } ######################################################### body contain u_in_dir(s) # @brief Run command from within `s` # @param s Path to change into before running command { chdir => "$(s)"; } ######################################################### body contain u_silent_in_dir(s) # @brief Run command from within `s` and suppress output # @param s Path to change into before running command { chdir => "$(s)"; no_output => "true"; } ######################################################### body link_from u_ln_s(x) # @brief Symlink to `x`, even if it does not exist # @param x Path to symlink #@ **Example:** #@ ```cf3 #@ bundle agent example u_ln_s { #@ files: #@ "$(symlink_path)" #@ link_from => u_ln_s("$(python)"), #@ move_obstructions => "true", #@ if => isvariable("python"); #@ } #@ ``` { link_type => "symlink"; source => "$(x)"; when_no_source => "force"; } ######################################################### body delete u_tidy # @brief Delete directories and symlinks #@ **Example:** #@ ```cf3 #@ bundle agent example u_tidy { #@ files: #@ "$(symlink_path)" #@ delete => u_tidy, #@ if => not(isvariable("python")); #@ } #@ ``` { dirlinks => "delete"; rmdirs => "true"; } bundle agent modules_presence # @brief Render vendored and user provided modules from $(sys.inputdir) to $(sys.workdir) # # @description This bundle manages the contents of moduledir (/var/cfengine/modules) by # first dealing with package module scripts. # Preference is given to user provided package module scripts in # modules/packages directory. If a module there matches a mustache # template in modules/packages/vendored directory then the user # provided module will be installed. # # e.g. modules/packages/apt_get takes precedence over modules/packages/apt_get.mustache # # Any other files in the modules directory will be promised to # be updated in moduledir (/var/cfengine/modules), including any sub-directories. { vars: # TODO: Remove this once sys.moduledir is always available (3.26+ only) "moduledir" string => ifelse( isvariable("sys.moduledir"), "$(sys.moduledir)", "$(sys.workdir)/modules" ); "_vendored_dir" string => "$(this.promise_dirname)$(const.dirsep)..$(const.dirsep)..$(const.dirsep)modules$(const.dirsep)packages$(const.dirsep)vendored$(const.dirsep)"; "_vendored_dir_filter" string => "$(this.promise_dirname)$(const.dirsep)..$(const.dirsep)..$(const.dirsep)modules$(const.dirsep)packages$(const.dirsep)vendored"; "_override_dir" string => "$(this.promise_dirname)$(const.dirsep)..$(const.dirsep)..$(const.dirsep)modules$(const.dirsep)packages$(const.dirsep)"; "_custom_template_dir" string => "$(this.promise_dirname)$(const.dirsep)..$(const.dirsep)..$(const.dirsep)modules$(const.dirsep)mustache$(const.dirsep)"; "_vendored_paths" slist => findfiles("$(_vendored_dir)*.mustache"); "_custom_template_paths" slist => findfiles("$(_custom_template_dir)*.mustache"), if => isdir("$(_custom_template_dir)"); "_package_paths" with => ifelse( or( cf_version_between("3.24.0", "3.24.3"), cf_version_at("3.26.0"), cf_version_at("3.27.0") ), "$(const.dirsep)", "" ), slist => filter( "$(_override_dir)vendored$(with)", _package_paths_tmp, "false", "true", 999 ); windows:: "_package_paths" slist => filter( "\Q${_vendored_dir_filter}\E.*", _package_paths_tmp, "true", "true", 999 ), comment => "The list will include the vendored sub-directory that we don't want so remove it."; "_vendored_modules" slist => maplist( regex_replace( "$(this)", "\Q$(_vendored_dir)\E(.*).mustache", "$1", "g" ), @(_vendored_paths) ); "_override_modules" slist => maplist( regex_replace("$(this)", "\Q$(_override_dir)\E(.*)", "$1", "g"), @(_package_paths) ); # replace single backslashes in a windows path with double-backslashes # to avoid problems with things like `C:\Program Files` and `\promises` # causing PCRE to try and interpret special escape sequences. "_not_vendored_modules_pathname_regex" string => regex_replace( "$(sys.inputdir)$(const.dirsep)modules$(const.dirsep)(?!packages$(const.dirsep)vendored).*", "\\\\", "\\\\\\\\", "g" ); !windows:: "_package_paths" slist => filter( "${_vendored_dir_filter}.*", _package_paths_tmp, "true", "true", 999 ), comment => "The list will include the vendored sub-directory that we don't want so remove it."; "_vendored_modules" slist => maplist( regex_replace("$(this)", "$(_vendored_dir)(.*).mustache", "$1", "g"), @(_vendored_paths) ); "_override_modules" slist => maplist( regex_replace("$(this)", "$(_override_dir)(.*)", "$1", "g"), @(_package_paths) ); "_custom_template_modules" slist => maplist( regex_replace( "$(this)", "$(_custom_template_dir)(.*).mustache", "$1", "g" ), @(_custom_template_paths) ); "_not_vendored_modules_pathname_regex" string => "$(sys.inputdir)/modules/(?!(packages/vendored|mustache/)).*"; classes: "override_vendored_module_$(_vendored_modules)" expression => fileexists("$(_override_dir)$(_vendored_modules)"); "override_module_$(_override_modules)" expression => fileexists("$(_override_dir)$(_override_modules)"); # NOTE: here we are using the .mustache extension only to # ensure that the modules scripts are copied as part of # update (see controls/update_def.cf input_name_patterns var. files: "$(moduledir)/packages/$(_vendored_modules)" create => "true", perms => u_mo("755", "root"), unless => canonify("override_vendored_module_$(_vendored_modules)"), edit_template => "$(_vendored_dir)$(_vendored_modules).mustache", template_method => "mustache"; "$(moduledir)/packages/$(_override_modules)" copy_from => u_cp_missing_ok("$(_override_dir)$(_override_modules)"), perms => u_mo("755", "root"), if => or( canonify("override_vendored_module_$(_override_modules)"), canonify("override_module_$(_override_modules)") ); "$(moduledir)/$(_custom_template_modules)" -> { "ENT-10793" } comment => "We want to render mustache templated modules", handle => "cfe_internal_update_policy_files_custom_template_modules", template_method => "mustache", edit_template => "$(_custom_template_dir)$(_custom_template_modules).mustache", perms => u_mo("500", "root"), if => fileexists( "$(_custom_template_dir)$(_custom_template_modules).mustache" ); "$(moduledir)" comment => "Copy any non-packages modules", handle => "cfe_internal_update_policy_files_nonpackages_modules", copy_from => u_cp("$(sys.inputdir)$(const.dirsep)modules"), if => fileexists("$(sys.inputdir)$(const.dirsep)modules"), depth_search => u_recurse("inf"), perms => u_mo("755", "root"), action => u_immediate, file_select => not_vendored_modules( "$(_not_vendored_modules_pathname_regex)" ); reports: DEBUG:: "_override_dir: $(_override_dir)"; "_package_paths: $(with)" with => storejson(_package_paths); "_not_vendored_modules_pathname_regex: $(_not_vendored_modules_pathname_regex)"; "_vendored_modules: $(_vendored_modules)"; "_override_modules: $(_override_modules)"; "_vendored_dir: $(_vendored_dir)"; "_vendored_paths: $(_vendored_paths)"; "_override_dir: $(_override_dir)"; "override_vendored_module_$(_vendored_modules)" if => "override_vendored_module_$(_vendored_modules)"; "override_module_$(_override_modules)" if => "override_module_$(_override_modules)"; "canonified: $(with)" with => canonify("override_vendored_module_$(_vendored_modules)"); } body file_select not_vendored_modules(pathname) { path_name => { "$(pathname)" }; file_result => "path_name"; } ######################################################### body file_select u_dirs # @brief Select directories { file_types => { "dir" }; file_result => "file_types"; } body file_select u_not_dir # @brief Select all files that are not directories { file_types => { "dir" }; file_result => "!file_types"; } cfengine-masterfiles-3.27.3/cfe_internal/update/update_processes.cf0000644000000000000000000004234214735102600023666 0ustar0000000000000000################################################################################ # # DO NOT EDIT THIS FILE. All policy files prefixed with CFE_ and update_bins.cf # 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. # ################################################################################ ################################################################################ # # update_processes # - To enable/disable CFEngine based processes, use the slists below. ################################################################################ bundle common cfe_internal_process_knowledge # @brief Variables related to CFEngine's own processes used in other bundles # TODO Redact use of this bundle. It's no longer useful now that bindir variable exists. Not clear why its unset on windows. { vars: !windows:: "bindir" string => "$(sys.bindir)", comment => "Use a system variable"; } bundle agent cfe_internal_update_processes # @brief Determine which cfengine components should be managed, and what their # state should be. # # By default all the relevant services will run on each host. For example all # hosts will run cf-execd, cf-serverd, and cf-monitord. Individual services can # be disabled: # # * If persistent_disable_COMPONENT ( persistent_disable_cf_serverd, # persistent_disable_cf_monitord) is defined the service will be disabled. # # * If the component is found in def.agents_to_be_disabled it will be disabled. # # * To enable component management on hosts with systemd define the class # `mpf_enable_cfengine_systemd_component_management`. { classes: "systemd_supervised" scope => "bundle", expression => "systemd"; reports: inform.systemd_supervised.!mpf_enable_cfengine_systemd_component_management:: "NOTE: You have defined a class to persistently disable a cfengine component on a systemd managed host, but you have not defined mpf_enable_cfengine_systemd_component_management in order to enable management" if => classmatch("persistent_disable_cf_.*"); "NOTE: You have explicitly listed components that should be disabled in def.agents_to_be_disabled. This host is managed by systemd and requires the class mpf_enable_cfengine_systemd_component_management in order to enable active management" if => some(".*", @(def.agents_to_be_disabled)); vars: any:: # By default the core components are expected to be running in all cases. "agent[cf_execd]" string => "cf-execd"; "agent[cf_serverd]" string => "cf-serverd"; "agent[cf_monitord]" string => "cf-monitord"; policy_server.enterprise_edition:: "agent[cf_hub]" string => "cf-hub", comment => "cf-hub is only relevant on Enterprise hubs"; "agent[cf_reactor]" string => "cf-reactor", comment => "cf-reactor is only provided on Enterprise hubs"; systemd:: # On systemd hosts the cfengine3 service acts as an umbrella for other # services. "agent[cfengine3]" string => "cfengine3", comment => "systemd hosts use the cfengine3 service as an umbrella. systemd_supervised hosts additionally have individual units for each managed service."; systemd_supervised.enterprise_edition.policy_server:: # Only enterprise systemd supervised hosts these additional service # definitions for each component. "agent[cf_postgres]" string => "cf-postgres"; "agent[cf_php_fpm]" string => "cf-php-fpm"; "agent[cf_apache]" string => "cf-apache"; any:: # We get a consolidated list of all agents for the executing host. "all_agents" slist => getvalues(agent); # We use def.agents_to_be_disabled if it exists, otherwise we default to # no agents being disabled. "agents_to_be_disabled" comment => "CFE processes that should not be enabled", handle => "cfe_internal_update_processes_vars_agents_to_be_disabled", slist => { @(def.agents_to_be_disabled) }, if => isvariable("def.agents_to_be_disabled"); "agents_to_be_disabled" comment => "The default agents that should not be enabled.", handle => "cfe_internal_update_processes_vars_default_agents_to_be_disabled", slist => {}, if => not(isvariable("def.agents_to_be_disabled")); # An agent is disabled if there is a persistently defined disablement # class OR if the agent is found in a list of agents to be specifically # disabled. "disabled[$(all_agents)]" string => "$(all_agents)", if => or( canonify("persistent_disable_$(all_agents)"), some("$(all_agents)", agents_to_be_disabled) ); systemd_supervised.policy_server.enterprise.hub_passive|(ha_replication_only_node.!failover_to_repliacation_node_enabled):: # We want the enterprise component cf-hub to be disabled if running on a # passive hub or replication only hub. "disabled[cf_hub]" string => "cf-hub"; any:: # First we get the consolidated list of agents to be disabled. "agents_to_be_disabled" slist => getvalues(disabled); # Any agent that is not explicitly disabled should be enabled. "agents_to_be_enabled" slist => difference(all_agents, agents_to_be_disabled); methods: systemd.!systemd_supervised:: # TODO Remove from policy. # This makes sure the cfengine3 (umbrella) unit is active. It does not # make any assertions about individual components. Furthermore, since # commit 6a7fe6b3fa466e55b29eca75cd53ff8b2883ff0e (introduced in 3.14) # this policy won't be run because systemd_supervised is defined any time # systemd is defined. "CFENGINE systemd service" usebundle => maintain_cfe_systemd, comment => "Call a bundle to maintain CFEngine with systemd", handle => "cfe_internal_update_processes_methods_maintain_systemd"; systemd_supervised.mpf_enable_cfengine_systemd_component_management:: "CFEngine systemd Unit Definitions" usebundle => cfe_internal_systemd_unit_files; "CFEngine systemd Unit States" usebundle => cfe_internal_systemd_service_unit_state; am_policy_hub.enterprise.!systemd_supervised:: "TAKING CARE CFE HUB PROCESSES" usebundle => maintain_cfe_hub_process, comment => "Call a bundle to maintian HUB processes", handle => "cfe_internal_update_processes_methods_maintain_hub"; !windows.!systemd_supervised:: "DISABLING CFE AGENTS" usebundle => disable_cfengine_agents("$(agents_to_be_disabled)"), comment => "Call a bundle to disable CFEngine given processes", handle => "cfe_internal_update_processes_methods_disabling_cfe_agents"; "CHECKING FOR PERSISTENTLY DISABLED CFE AGENTS" usebundle => disable_cfengine_agents($(all_agents)), if => canonify("persistent_disable_$(all_agents)"), comment => "Call a bundle to disable CFEngine given processes if persistent_disable_x is set", handle => "cfe_internal_update_processes_methods_maybe_disabling_cfe_agents"; "ENABLING CFE AGENTS" usebundle => enable_cfengine_agents("$(agents_to_be_enabled)"), comment => "Call a bundle to enable CFEngine given processes", handle => "cfe_internal_update_processes_methods_enabling_cfe_agents"; windows:: "CFENGINE on Windows" usebundle => maintain_cfe_windows, comment => "Call a bundle to maintain CFEngine on Windows", handle => "cfe_internal_update_processes_methods_maintain_windows"; } ############################################################################### bundle agent maintain_cfe_hub_process # @brief Ensure the proper processes are running on Enterprise hubs. { vars: am_policy_hub:: "file_check" string => translatepath( "$(cfe_internal_update_policy_cpv.inputs_dir)/promises.cf" ), comment => "Path to a policy file", handle => "cfe_internal_maintain_cfe_hub_process_vars_file_check"; classes: am_policy_hub:: "files_ok" expression => fileexists("$(file_check)"), comment => "Check for $(sys.workdir)/inputs/promises.cf", handle => "cfe_internal_maintain_cfe_hub_process_classes_files_ok"; am_policy_hub.enable_cfengine_enterprise_hub_ha:: "ha_run_hub_process" or => { "!ha_replication_only_node", "ha_replication_only_node.failover_to_replication_node_enabled", }; "ha_kill_hub_process" or => { "ha_replication_only_node.!failover_to_replication_node_enabled" }; processes: am_policy_hub:: "$(cfe_internal_process_knowledge.bindir)/vacuumdb" restart_class => "no_vacuumdb", comment => "Monitor vacuumdb process", handle => "cfe_internal_maintain_cfe_hub_process_processes_check_vacuumdb", if => "nova|enterprise"; am_policy_hub.!enable_cfengine_enterprise_hub_ha:: "$(cfe_internal_process_knowledge.bindir)/postgres" restart_class => "start_postgres_server", comment => "Monitor postgres process", handle => "cfe_internal_maintain_cfe_hub_process_processes_postgres", if => "nova|enterprise"; am_policy_hub.!enable_cfengine_enterprise_hub_ha.files_ok.!windows|ha_run_hub_process:: "cf-hub" restart_class => "start_hub", comment => "Monitor cf-hub process", handle => "cfe_internal_maintain_cfe_hub_process_processes_cf_hub", if => and( "(nova|enterprise).no_vacuumdb", "!persistent_disable_cf_hub" ); # Don't start it if it's persistently disabled am_policy_hub.ha_kill_hub_process:: "cf-hub" signals => { "term" }, comment => "Terminate cf-hub on backup HA node outside cluster", handle => "cfe_internal_kill_hub_process_on_inactive_ha_node"; files: "/var/log/postgresql.log" comment => "Ensure postgres.log file is there with right permissions", handle => "cfe_internal_maintain_cfe_hub_process_files_create_postgresql_log", create => "true", perms => u_mo("0600", "cfpostgres"); commands: !windows.am_policy_hub.!enable_cfengine_enterprise_hub_ha.start_postgres_server:: "$(cfe_internal_process_knowledge.bindir)/pg_ctl -D $(cfe_internal_update_policy_cpv.postgresdb_dir) -l $(cfe_internal_update_policy_cpv.postgresdb_log) start" contain => u_postgres, comment => "Start postgres process", classes => u_kept_successful_command, handle => "cfe_internal_maintain_cfe_hub_process_commands_start_postgres"; !windows.am_policy_hub.start_hub:: "$(sys.cf_hub)" comment => "Start cf-hub process", classes => u_kept_successful_command, handle => "cfe_internal_maintain_cfe_hub_process_commands_start_cf_hub"; } ############################################################################### bundle agent disable_cfengine_agents(process) # @brief Ensure cfengine component is not running # @param process The name of the cfengine component binary to ensure not running. [cf-agent, cf-serverd, cf-monitord, cf-hub] { vars: !windows:: "cprocess" string => canonify("$(process)"), comment => "Canonify a given process", handle => "cfe_internal_disable_cfengine_agents_vars_cprocess"; classes: !windows:: "disable_$(cprocess)" expression => strcmp("$(process)", "$(process)"), comment => "Create a class to disable a given process", handle => "cfe_internal_disable_cfengine_agents_classes_disable_process"; processes: !windows:: "$(cfe_internal_process_knowledge.bindir)/$(process)" signals => { "term" }, comment => "Terminate $(process)", handle => "cfe_internal_disable_cfengine_agents_processes_terminate_process", if => "disable_$(cprocess)"; } ############################################################################### bundle agent enable_cfengine_agents(process) # @brief Ensure cfengine component is running # @param process The name of the cfengine component binary to ensure running. [cf-agent, cf-serverd, cf-monitord, cf-hub] { vars: !windows:: "cprocess" string => canonify("$(process)"), comment => "Canonify a given process", handle => "cfe_internal_enable_cfengine_agents_vars_cprocess"; classes: !windows:: "enable_$(cprocess)" expression => "!persistent_disable_$(cprocess)", comment => "Create a class to enable a given process", handle => "cfe_internal_enable_cfengine_agents_classes_enable_process"; processes: !windows:: "$(cfe_internal_process_knowledge.bindir)/$(process)" restart_class => "restart_$(cprocess)", comment => "Create a class to restart a process", handle => "cfe_internal_enable_cfengine_agents_processes_restart_process", if => "enable_$(cprocess)"; commands: !windows:: "$(sys.$(cprocess))" comment => "Restart a process", handle => "cfe_internal_enable_cfengine_agents_commands_restart_process", classes => u_kept_successful_command, if => and("restart_$(cprocess)", isvariable("sys.$(cprocess)")); reports: "The process $(process) is persistently disabled. Run with '-Dclear_persistent_disable_$(cprocess)' to re-enable it." if => and( "persistent_disable_$(cprocess)", isvariable("sys.$(cprocess)") ); "The process $(process) has been re-enabled. Run with '-Dset_persistent_disable_$(cprocess)' to disable it persistently again." if => and( "clear_persistent_disable_$(cprocess)", isvariable("sys.$(cprocess)") ), classes => u_clear_always("persistent_disable_$(cprocess)"); "The process $(process) has been disabled persistently. Run with '-Dclear_persistent_disable_$(cprocess)' to re-enable it." if => "set_persistent_disable_$(cprocess)", classes => u_always_forever("persistent_disable_$(cprocess)"); } ############################################################################### bundle agent maintain_cfe_windows # @brief Ensure cfengine components are running { vars: windows:: "file_check" string => translatepath( "$(cfe_internal_update_policy_cpv.inputs_dir)/promises.cf" ), comment => "Path to a policy file", handle => "cfe_internal_maintain_cfe_windows_vars_file_check"; classes: windows:: "files_ok" expression => fileexists("$(file_check)"), comment => "Check for /var/cfengine/masterfiles/promises.cf", handle => "cfe_internal_maintain_cfe_windows_classes_files_ok"; processes: files_ok:: "cf-serverd" restart_class => "start_server", comment => "Monitor cf-serverd process", handle => "cfe_internal_maintain_cfe_windows_processes_cf_serverd"; "cf-monitord" restart_class => "start_monitor", comment => "Monitor cf-monitord process", handle => "cfe_internal_maintain_cfe_windows_processes_cf_monitord"; services: files_ok.windows:: "CfengineNovaExec" service_policy => "start", service_method => u_bootstart, comment => "Start the executor windows service now and at boot time", handle => "cfe_internal_maintain_cfe_windows_services_windows_executor"; commands: start_server:: "$(sys.cf_serverd)" action => u_ifwin_bg, comment => "Start cf-serverd process", classes => u_kept_successful_command, handle => "cfe_internal_maintain_cfe_windows_commands_start_cf_serverd"; start_monitor|restart_monitor:: "$(sys.cf_monitord)" action => u_ifwin_bg, comment => "Start cf-monitord process", classes => u_kept_successful_command, handle => "cfe_internal_maintain_cfe_windows_commands_start_cf_monitord"; } bundle agent maintain_cfe_systemd # @brief Ensure cfengine components are running { classes: systemd:: "restart_cfe" not => returnszero("/bin/systemctl -q is-active cfengine3", "noshell"), comment => "Check running status of CFEngine using systemd", handle => "cfe_internal_maintain_cfe_systemd_classes_restart_cfe"; commands: restart_cfe:: "/bin/systemctl -q start cfengine3" comment => "Start CFEngine using systemd", handle => "cfe_internal_maintain_cfe_systemd_commands_start_cfe"; } body classes u_clear_always(theclass) # @brief Undefine, `theclass` for as a result of the promise actuation, no matter the outcome (kept, notkept, repaired) { cancel_kept => { $(theclass) }; cancel_notkept => { $(theclass) }; cancel_repaired => { $(theclass) }; } body classes u_always_forever(theclass) # @brief Define `theclass` for 999999999 minutes (1902 years) as a result of the promise actuation, no matter the outcome (kept, notkept, repaired) { promise_kept => { $(theclass) }; promise_repaired => { $(theclass) }; repair_failed => { $(theclass) }; repair_denied => { $(theclass) }; repair_timeout => { $(theclass) }; persist_time => 999999999; scope => "namespace"; } cfengine-masterfiles-3.27.3/cfe_internal/update/windows_unattended_upgrade.cf0000644000000000000000000001076214735102600025733 0ustar0000000000000000bundle agent windows_unattended_upgrade # @brief This bundle creates two scripts: one to schedule a cfengine agent upgrade # and one to actually perform the upgrade after the scripts are rendered the schedule script is run. # If the requested version and release is already installed the scripts will be deleted. { classes: windows:: "_expected_version_installed" expression => and( strcmp($(sys.cf_version), $(cfengine_software.pkg_version)), strcmp($(sys.cf_version_release), $(cfengine_software.pkg_release)) ); vars: windows:: "_schedule_upgrade_script" string => "$(const.dirsep)schedule_unattended_upgrade.ps1", # TODO examine and fix/document specific issue(s) comment => "sys.bindir has issues when used as execution path"; "_upgrade_script_name" string => "unattended-upgrade.bat"; "_upgrade_script" string => "$(sys.bindir)$(const.dirsep)$(_upgrade_script_name)"; "_scripts" slist => { "$(_schedule_upgrade_script)", "$(_upgrade_script)" }; "_min_offset" string => "2"; files: windows:: # /sigh/. In order to make a stable promise, we render a script that runs # to create the scheduled task that runs another script to perform the # upgrade outside of cf-agent. Since the command differs based on the time # of of day, the only way to have a stable promise is to promise a script # where the time base difference is handeled inside the script. One # alternative would be to use inline subshell exection (iex) "$(_schedule_upgrade_script)" create => "true", edit_template_string => ` $scheduled_time_to_upgrade = (Get-Date).AddMinutes($(_min_offset)).ToString("HH:mm") $schedule = "/SC ONCE" $taskname = '/TN "CFEngine Agent Upgrade"' $starttime = "/ST $scheduled_time_to_upgrade" $taskrun = @" "cmd /c '$(_upgrade_script)'" "@ $schtasks = "$(sys.winsysdir)$(const.dirsep)schtasks.exe" $username = '/RU "System"' $force = "/F" Invoke-Expression "$schtasks /Create $schedule $taskname /TR $taskrun $starttime $username $force" `, template_method => "inline_mustache", template_data => '{}'; "$(_upgrade_script)" edit_template_string => ` set LOGFILE=$(sys.workdir)$(const.dirsep)outputs/standalone_self_upgrade_bat.log call :SCRIPT > "%LOGFILE%" 2>&1 exit /B :SCRIPT REM kill all cf procs first so that installed can run Taskkill /IM cf-execd.exe /F Taskkill /IM cf-monitord.exe /F Taskkill /IM cf-serverd.exe /F Taskkill /IM cf-agent.exe /F set bat="$(sys.workdir)$(const.dirsep)modules$(const.dirsep)packages$(const.dirsep)msiexec.bat" echo File=$(cfengine_software.local_software_dir)$(const.dirsep)$(cfengine_package_names.my_pkg) | call %bat% file-install @echo off REM A failed install at this point can leave cf-execd not running leaving the host unable to try and self heal REM We at least want to try and start cf-execd if it is not running set TARGET_SERVICE=CfengineNovaExec set SERVICE_STATE= REM Surgically target third line, as some locales (such as Spanish) translate the output for /F "skip=3 tokens=3" %%i in ('""%windir%\system32\sc.exe" query "%TARGET_SERVICE%" 2>nul"') do ( if not defined SERVICE_STATE set SERVICE_STATE=%%i ) rem Process result if not defined SERVICE_STATE ( echo ERROR: could not obtain service state! ) else ( REM NOTE: values correspond to "SERVICE_STATUS.dwCurrentState" REM https://msdn.microsoft.com/en-us/library/windows/desktop/ms685996(v=vs.85).aspx if not %SERVICE_STATE%==4 ( echo WARNING: service is not running, attempting to start net start "%TARGET_SERVICE%" ) else ( echo INFORMATION: service is running ) ) REM exit 0 so that scheduled task will not keep trying a failing situation REM looking at package module logs of one failure should help in debugging exit 0 `, template_method => "inline_mustache", template_data => '{}', create => "true", if => not("_expected_version_installed"); "$(_scripts)" delete => windows_unattended_upgrade_tidy, if => "_expected_version_installed"; commands: windows:: 'powershell -NoProfile -ExecutionPolicy bypass -F $(_schedule_upgrade_script)' if => not("_expected_version_installed"), contain => windows_unattended_upgrade:powershell; } body delete windows_unattended_upgrade_tidy { dirlinks => "delete"; rmdirs => "true"; } body file control { namespace => "windows_unattended_upgrade"; } body contain powershell { useshell => "powershell"; } cfengine-masterfiles-3.27.3/config.guess0000755000000000000000000012564414735102600016420 0ustar0000000000000000#! /bin/sh # Attempt to guess a canonical system name. # Copyright 1992-2016 Free Software Foundation, Inc. timestamp='2016-10-02' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # # Originally written by Per Bothner; maintained since 2000 by Ben Elliston. # # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess # # Please send patches to . me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright 1992-2016 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi trap 'exit 1' 1 2 15 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. set_cc_for_build=' trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; : ${TMPDIR=/tmp} ; { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; dummy=$tmp/dummy ; tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in ,,) echo "int x;" > $dummy.c ; for c in cc gcc c89 c99 ; do if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found ; fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac ; set_cc_for_build= ;' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown case "${UNAME_SYSTEM}" in Linux|GNU|GNU/*) # If the system lacks a compiler, then just pick glibc. # We could probably try harder. LIBC=gnu eval $set_cc_for_build cat <<-EOF > $dummy.c #include #if defined(__UCLIBC__) LIBC=uclibc #elif defined(__dietlibc__) LIBC=dietlibc #else LIBC=gnu #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` ;; esac # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ /sbin/$sysctl 2>/dev/null || \ /usr/sbin/$sysctl 2>/dev/null || \ echo unknown)` case "${UNAME_MACHINE_ARCH}" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; earmv*) arch=`echo ${UNAME_MACHINE_ARCH} | sed -e 's,^e\(armv[0-9]\).*$,\1,'` endian=`echo ${UNAME_MACHINE_ARCH} | sed -ne 's,^.*\(eb\)$,\1,p'` machine=${arch}${endian}-unknown ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently (or will in the future) and ABI. case "${UNAME_MACHINE_ARCH}" in earm*) os=netbsdelf ;; arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # Determine ABI tags. case "${UNAME_MACHINE_ARCH}" in earm*) expr='s/^earmv[0-9]/-eabi/;s/eb$//' abi=`echo ${UNAME_MACHINE_ARCH} | sed -e "$expr"` ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case "${UNAME_VERSION}" in Debian*) release='-gnu' ;; *) release=`echo ${UNAME_RELEASE} | sed -e 's/[-_].*//' | cut -d. -f1,2` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}${abi}" exit ;; *:Bitrig:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} exit ;; *:LibertyBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` echo ${UNAME_MACHINE_ARCH}-unknown-libertybsd${UNAME_RELEASE} exit ;; *:ekkoBSD:*:*) echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} exit ;; *:SolidBSD:*:*) echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} exit ;; macppc:MirBSD:*:*) echo powerpc-unknown-mirbsd${UNAME_RELEASE} exit ;; *:MirBSD:*:*) echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} exit ;; *:Sortix:*:*) echo ${UNAME_MACHINE}-unknown-sortix exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") UNAME_MACHINE=alpha ;; "EV4.5 (21064)") UNAME_MACHINE=alpha ;; "LCA4 (21066/21068)") UNAME_MACHINE=alpha ;; "EV5 (21164)") UNAME_MACHINE=alphaev5 ;; "EV5.6 (21164A)") UNAME_MACHINE=alphaev56 ;; "EV5.6 (21164PC)") UNAME_MACHINE=alphapca56 ;; "EV5.7 (21164PC)") UNAME_MACHINE=alphapca57 ;; "EV6 (21264)") UNAME_MACHINE=alphaev6 ;; "EV6.7 (21264A)") UNAME_MACHINE=alphaev67 ;; "EV6.8CB (21264C)") UNAME_MACHINE=alphaev68 ;; "EV6.8AL (21264B)") UNAME_MACHINE=alphaev68 ;; "EV6.8CX (21264D)") UNAME_MACHINE=alphaev68 ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE=alphaev69 ;; "EV7 (21364)") UNAME_MACHINE=alphaev7 ;; "EV7.9 (21364A)") UNAME_MACHINE=alphaev79 ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` # Reset EXIT trap before exiting to avoid spurious non-zero exit code. exitcode=$? trap '' 0 exit $exitcode ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead # of the specific Alpha model? echo alpha-pc-interix exit ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition exit ;; *:z/VM:*:*) echo s390-ibm-zvmoe exit ;; *:OS400:*:*) echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit ;; arm*:riscos:*:*|arm*:RISCOS:*:*) echo arm-unknown-riscos exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit ;; DRS?6000:unix:4.0:6*) echo sparc-icl-nx6 exit ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7; exit ;; esac ;; s390x:SunOS:*:*) echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) echo i386-pc-auroraux${UNAME_RELEASE} exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) eval $set_cc_for_build SUN_ARCH=i386 # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. if [ "$CC_FOR_BUILD" != no_compiler_found ]; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then SUN_ARCH=x86_64 fi fi echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` exit ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x${UNAME_RELEASE}" = x && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} ;; sun4) echo sparc-sun-sunos${UNAME_RELEASE} ;; esac exit ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint${UNAME_RELEASE} exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint${UNAME_RELEASE} exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint${UNAME_RELEASE} exit ;; m68k:machten:*:*) echo m68k-apple-machten${UNAME_RELEASE} exit ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} exit ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix${UNAME_RELEASE} exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && SYSTEM_NAME=`$dummy $dummyarg` && { echo "$SYSTEM_NAME"; exit; } echo mips-mips-riscos${UNAME_RELEASE} exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax exit ;; Motorola:*:4.3:PL8-*) echo powerpc-harris-powermax exit ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) echo powerpc-harris-powermax exit ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ [ ${TARGET_BINARY_INTERFACE}x = x ] then echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi else echo i586-dg-dgux${UNAME_RELEASE} fi exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit ;; ia64:AIX:*:*) if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` then echo "$SYSTEM_NAME" else echo rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit ;; *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/lslpp ] ; then IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "${sc_cpu_version}" in 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "${sc_kernel_bits}" in 32) HP_ARCH=hppa2.0n ;; 64) HP_ARCH=hppa2.0w ;; '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 esac ;; esac fi if [ "${HP_ARCH}" = "" ]; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS="" $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if [ ${HP_ARCH} = hppa2.0w ] then eval $set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then HP_ARCH=hppa2.0w else HP_ARCH=hppa64 fi fi echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit ;; ia64:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux${HPUX_REV} exit ;; 3050*:HI-UX:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-osf1 fi exit ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi${UNAME_RELEASE} exit ;; *:BSD/OS:*:*) echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit ;; *:FreeBSD:*:*) UNAME_PROCESSOR=`/usr/bin/uname -p` case ${UNAME_PROCESSOR} in amd64) echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; *) echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; esac exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit ;; *:MINGW64*:*) echo ${UNAME_MACHINE}-pc-mingw64 exit ;; *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; *:MSYS*:*) echo ${UNAME_MACHINE}-pc-msys exit ;; i*:windows32*:*) # uname -m includes "-pc" on this system. echo ${UNAME_MACHINE}-mingw32 exit ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; *:Interix*:*) case ${UNAME_MACHINE} in x86) echo i586-pc-interix${UNAME_RELEASE} exit ;; authenticamd | genuineintel | EM64T) echo x86_64-unknown-interix${UNAME_RELEASE} exit ;; IA64) echo ia64-unknown-interix${UNAME_RELEASE} exit ;; esac ;; [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks exit ;; 8664:Windows_NT:*) echo x86_64-pc-mks exit ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we # UNAME_MACHINE based on the output of uname instead of i386? echo i586-pc-interix exit ;; i*:UWIN*:*) echo ${UNAME_MACHINE}-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) echo x86_64-unknown-cygwin exit ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin exit ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; *:GNU:*:*) # the GNU system echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; aarch64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC=gnulibc1 ; fi echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; arc:Linux:*:* | arceb:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; arm*:Linux:*:*) eval $set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then echo ${UNAME_MACHINE}-unknown-linux-${LIBC} else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi else echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf fi fi exit ;; avr32*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; cris:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; crisv32:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; e2k:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; frv:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; hexagon:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; i*86:Linux:*:*) echo ${UNAME_MACHINE}-pc-linux-${LIBC} exit ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; k1om:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; m32r*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; mips:Linux:*:* | mips64:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef ${UNAME_MACHINE} #undef ${UNAME_MACHINE}el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=${UNAME_MACHINE}el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=${UNAME_MACHINE} #else CPU= #endif #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } ;; mips64el:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; openrisc*:Linux:*:*) echo or1k-unknown-linux-${LIBC} exit ;; or32:Linux:*:* | or1k*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; padre:Linux:*:*) echo sparc-unknown-linux-${LIBC} exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-${LIBC} exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; *) echo hppa-unknown-linux-${LIBC} ;; esac exit ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-${LIBC} exit ;; ppc:Linux:*:*) echo powerpc-unknown-linux-${LIBC} exit ;; ppc64le:Linux:*:*) echo powerpc64le-unknown-linux-${LIBC} exit ;; ppcle:Linux:*:*) echo powerpcle-unknown-linux-${LIBC} exit ;; riscv32:Linux:*:* | riscv64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux-${LIBC} exit ;; sh64*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; tile*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; vax:Linux:*:*) echo ${UNAME_MACHINE}-dec-linux-${LIBC} exit ;; x86_64:Linux:*:*) echo ${UNAME_MACHINE}-pc-linux-${LIBC} exit ;; xtensa*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. echo i386-sequent-sysv4 exit ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. echo ${UNAME_MACHINE}-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) echo ${UNAME_MACHINE}-unknown-stop exit ;; i*86:atheos:*:*) echo ${UNAME_MACHINE}-unknown-atheos exit ;; i*86:syllable:*:*) echo ${UNAME_MACHINE}-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit ;; i*86:*DOS:*:*) echo ${UNAME_MACHINE}-pc-msdosdjgpp exit ;; i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} fi exit ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub # prints for the "djgpp" host, or else GDB configure will decide that # this is a cross-build. echo i586-pc-msdosdjgpp exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit ;; paragon:*:*:*) echo i860-intel-osf1 exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit ;; mc68k:UNIX:SYSTEM5:3.51m) echo m68k-convergent-sysv exit ;; M680?0:D-NIX:5.3:*) echo m68k-diab-dnix exit ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; NCR*:*:4.2:* | MPRAS*:*:4.2:*) OS_REL='.3' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit ;; rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) echo powerpc-unknown-lynxos${UNAME_RELEASE} exit ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 exit ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo ${UNAME_MACHINE}-sni-sysv4 else echo ns32k-sni-sysv fi exit ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. echo ${UNAME_MACHINE}-stratus-vos exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-unknown-sysv${UNAME_RELEASE} fi exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit ;; BePC:Haiku:*:*) # Haiku running on Intel PC compatible. echo i586-pc-haiku exit ;; x86_64:Haiku:*:*) echo x86_64-unknown-haiku exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux${UNAME_RELEASE} exit ;; SX-6:SUPER-UX:*:*) echo sx6-nec-superux${UNAME_RELEASE} exit ;; SX-7:SUPER-UX:*:*) echo sx7-nec-superux${UNAME_RELEASE} exit ;; SX-8:SUPER-UX:*:*) echo sx8-nec-superux${UNAME_RELEASE} exit ;; SX-8R:SUPER-UX:*:*) echo sx8r-nec-superux${UNAME_RELEASE} exit ;; SX-ACE:SUPER-UX:*:*) echo sxace-nec-superux${UNAME_RELEASE} exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit ;; *:Rhapsody:*:*) echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown eval $set_cc_for_build if test "$UNAME_PROCESSOR" = unknown ; then UNAME_PROCESSOR=powerpc fi if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then if [ "$CC_FOR_BUILD" != no_compiler_found ]; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then case $UNAME_PROCESSOR in i386) UNAME_PROCESSOR=x86_64 ;; powerpc) UNAME_PROCESSOR=powerpc64 ;; esac fi fi elif test "$UNAME_PROCESSOR" = i386 ; then # Avoid executing cc on OS X 10.9, as it ships with a stub # that puts up a graphical alert prompting to install # developer tools. Any system running Mac OS X 10.7 or # later (Darwin 11 and later) is required to have a 64-bit # processor. This is not true of the ARM version of Darwin # that Apple uses in portable devices. UNAME_PROCESSOR=x86_64 fi echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = x86; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; NEO-?:NONSTOP_KERNEL:*:*) echo neo-tandem-nsk${UNAME_RELEASE} exit ;; NSE-*:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk${UNAME_RELEASE} exit ;; NSR-?:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk${UNAME_RELEASE} exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux exit ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "$cputype" = 386; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi echo ${UNAME_MACHINE}-unknown-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 exit ;; *:TENEX:*:*) echo pdp10-unknown-tenex exit ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 exit ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 exit ;; *:TOPS-20:*:*) echo pdp10-unknown-tops20 exit ;; *:ITS:*:*) echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) echo mips-sei-seiux${UNAME_RELEASE} exit ;; *:DragonFly:*:*) echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case "${UNAME_MACHINE}" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; esac ;; *:XENIX:*:SysV) echo i386-pc-xenix exit ;; i*86:skyos:*:*) echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE} | sed -e 's/ .*$//'` exit ;; i*86:rdos:*:*) echo ${UNAME_MACHINE}-pc-rdos exit ;; i*86:AROS:*:*) echo ${UNAME_MACHINE}-pc-aros exit ;; x86_64:VMkernel:*:*) echo ${UNAME_MACHINE}-unknown-esx exit ;; amd64:Isilon\ OneFS:*:*) echo x86_64-unknown-onefs exit ;; esac cat >&2 </dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = ${UNAME_MACHINE} UNAME_RELEASE = ${UNAME_RELEASE} UNAME_SYSTEM = ${UNAME_SYSTEM} UNAME_VERSION = ${UNAME_VERSION} EOF exit 1 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: cfengine-masterfiles-3.27.3/config.sub0000755000000000000000000010676314735102600016064 0ustar0000000000000000#! /bin/sh # Configuration validation subroutine script. # Copyright 1992-2016 Free Software Foundation, Inc. timestamp='2016-11-04' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # Please send patches to . # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS Canonicalize a configuration name. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright 1992-2016 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" exit 1 ;; *local*) # First pass through any local machine types. echo $1 exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \ kopensolaris*-gnu* | cloudabi*-eabi* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; android-linux) os=-linux-android basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple | -axis | -knuth | -cray | -microblaze*) os= basic_machine=$1 ;; -bluegene*) os=-cnk ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; -scout) ;; -wrs) os=-vxworks basic_machine=$1 ;; -chorusos*) os=-chorusos basic_machine=$1 ;; -chorusrdb) os=-chorusrdb basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco6) os=-sco5v6 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5v6*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -udk*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*178) os=-lynxos178 ;; -lynx*5) os=-lynxos5 ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; -windowsnt*) os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; -psos*) os=-psos ;; -mint | -mint[0-9]*) basic_machine=m68k-atari os=-mint ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ | aarch64 | aarch64_be \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc | arceb \ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ | avr | avr32 \ | ba \ | be32 | be64 \ | bfin \ | c4x | c8051 | clipper \ | d10v | d30v | dlx | dsp16xx \ | e2k | epiphany \ | fido | fr30 | frv | ft32 \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | hexagon \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ | k1om \ | le32 | le64 \ | lm32 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ | mips64octeon | mips64octeonel \ | mips64orion | mips64orionel \ | mips64r5900 | mips64r5900el \ | mips64vr | mips64vrel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mips64vr5900 | mips64vr5900el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa32r6 | mipsisa32r6el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ | mipsisa64r6 | mipsisa64r6el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipsr5900 | mipsr5900el \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | moxie \ | mt \ | msp430 \ | nds32 | nds32le | nds32be \ | nios | nios2 | nios2eb | nios2el \ | ns16k | ns32k \ | open8 | or1k | or1knd | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle \ | pru \ | pyramid \ | riscv32 | riscv64 \ | rl78 | rx \ | score \ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ | spu \ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ | ubicom32 \ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ | visium \ | we32k \ | x86 | xc16x | xstormy16 | xtensa \ | z8k | z80) basic_machine=$basic_machine-unknown ;; c54x) basic_machine=tic54x-unknown ;; c55x) basic_machine=tic55x-unknown ;; c6x) basic_machine=tic6x-unknown ;; leon|leon[3-9]) basic_machine=sparc-$basic_machine ;; m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; ms1) basic_machine=mt-unknown ;; strongarm | thumb | xscale) basic_machine=arm-unknown ;; xgate) basic_machine=$basic_machine-unknown os=-none ;; xscaleeb) basic_machine=armeb-unknown ;; xscaleel) basic_machine=armel-unknown ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ | aarch64-* | aarch64_be-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ | ba-* \ | be32-* | be64-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* \ | c8051-* | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | e2k-* | elxsi-* \ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | hexagon-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ | k1om-* \ | le32-* | le64-* \ | lm32-* \ | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ | microblaze-* | microblazeel-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ | mips64octeon-* | mips64octeonel-* \ | mips64orion-* | mips64orionel-* \ | mips64r5900-* | mips64r5900el-* \ | mips64vr-* | mips64vrel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ | mips64vr5900-* | mips64vr5900el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa32r6-* | mipsisa32r6el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64r6-* | mipsisa64r6el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipsr5900-* | mipsr5900el-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | mt-* \ | msp430-* \ | nds32-* | nds32le-* | nds32be-* \ | nios-* | nios2-* | nios2eb-* | nios2el-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | open8-* \ | or1k*-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ | pru-* \ | pyramid-* \ | riscv32-* | riscv64-* \ | rl78-* | romp-* | rs6000-* | rx-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \ | tahoe-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tile*-* \ | tron-* \ | ubicom32-* \ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ | vax-* \ | visium-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* \ | xstormy16-* | xtensa*-* \ | ymp-* \ | z8k-* | z80-*) ;; # Recognize the basic CPU types without company name, with glob match. xtensa*) basic_machine=$basic_machine-unknown ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) basic_machine=i386-unknown os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; a29khif) basic_machine=a29k-amd os=-udi ;; abacus) basic_machine=abacus-unknown ;; adobe68k) basic_machine=m68010-adobe os=-scout ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amd64) basic_machine=x86_64-pc ;; amd64-*) basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-unknown ;; amigaos | amigados) basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; apollo68bsd) basic_machine=m68k-apollo os=-bsd ;; aros) basic_machine=i386-pc os=-aros ;; asmjs) basic_machine=asmjs-unknown ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; blackfin) basic_machine=bfin-unknown os=-linux ;; blackfin-*) basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; bluegene*) basic_machine=powerpc-ibm os=-cnk ;; c54x-*) basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c55x-*) basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c6x-*) basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c90) basic_machine=c90-cray os=-unicos ;; cegcc) basic_machine=arm-unknown os=-cegcc ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | j90) basic_machine=j90-cray os=-unicos ;; craynv) basic_machine=craynv-cray os=-unicosmp ;; cr16 | cr16-*) basic_machine=cr16-unknown os=-elf ;; crds | unos) basic_machine=m68k-crds ;; crisv32 | crisv32-* | etraxfs*) basic_machine=crisv32-axis ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; crx) basic_machine=crx-unknown os=-elf ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; decsystem10* | dec10*) basic_machine=pdp10-dec os=-tops10 ;; decsystem20* | dec20*) basic_machine=pdp10-dec os=-tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; dicos) basic_machine=i686-pc os=-dicos ;; djgpp) basic_machine=i586-pc os=-msdosdjgpp ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2* | dpx2*-bull) basic_machine=m68k-bull os=-sysv3 ;; e500v[12]) basic_machine=powerpc-unknown os=$os"spe" ;; e500v[12]-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` os=$os"spe" ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=-ose ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; go32) basic_machine=i386-pc os=-go32 ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; h8300xray) basic_machine=h8300-hitachi os=-xray ;; h8500hms) basic_machine=h8500-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) basic_machine=hppa1.1-hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppa-next) os=-nextstep3 ;; hppaosf) basic_machine=hppa1.1-hp os=-osf ;; hppro) basic_machine=hppa1.1-hp os=-proelf ;; i370-ibm* | ibm*) basic_machine=i370-ibm ;; i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; i386-vsta | vsta) basic_machine=i386-unknown os=-vsta ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; leon-*|leon[3-9]-*) basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'` ;; m68knommu) basic_machine=m68k-unknown os=-linux ;; m68knommu-*) basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; microblaze*) basic_machine=microblaze-xilinx ;; mingw64) basic_machine=x86_64-pc os=-mingw64 ;; mingw32) basic_machine=i686-pc os=-mingw32 ;; mingw32ce) basic_machine=arm-unknown os=-mingw32ce ;; miniframe) basic_machine=m68000-convergent ;; *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) basic_machine=m68k-atari os=-mint ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; monitor) basic_machine=m68k-rom68k os=-coff ;; morphos) basic_machine=powerpc-unknown os=-morphos ;; moxiebox) basic_machine=moxie-unknown os=-moxiebox ;; msdos) basic_machine=i386-pc os=-msdos ;; ms1-*) basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` ;; msys) basic_machine=i686-pc os=-msys ;; mvs) basic_machine=i370-ibm os=-mvs ;; nacl) basic_machine=le32-unknown os=-nacl ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; netbsd386) basic_machine=i386-unknown os=-netbsd ;; netwinder) basic_machine=armv4l-rebel os=-linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; necv70) basic_machine=v70-nec os=-sysv ;; next | m*-next ) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; mon960) basic_machine=i960-intel os=-mon960 ;; nonstopux) basic_machine=mips-compaq os=-nonstopux ;; np1) basic_machine=np1-gould ;; neo-tandem) basic_machine=neo-tandem ;; nse-tandem) basic_machine=nse-tandem ;; nsr-tandem) basic_machine=nsr-tandem ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf ;; openrisc | openrisc-*) basic_machine=or32-unknown ;; os400) basic_machine=powerpc-ibm os=-os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose ;; os68k) basic_machine=m68k-none os=-os68k ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; parisc) basic_machine=hppa-unknown os=-linux ;; parisc-*) basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pc98) basic_machine=i386-pc ;; pc98-*) basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; pentiumpro | p6 | 6x86 | athlon | athlon_*) basic_machine=i686-pc ;; pentiumii | pentium2 | pentiumiii | pentium3) basic_machine=i686-pc ;; pentium4) basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium4-*) basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=power-ibm ;; ppc | ppcbe) basic_machine=powerpc-unknown ;; ppc-* | ppcbe-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; pw32) basic_machine=i586-unknown os=-pw32 ;; rdos | rdos64) basic_machine=x86_64-pc os=-rdos ;; rdos32) basic_machine=i386-pc os=-rdos ;; rom68k) basic_machine=m68k-rom68k os=-coff ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; s390 | s390-*) basic_machine=s390-ibm ;; s390x | s390x-*) basic_machine=s390x-ibm ;; sa29200) basic_machine=a29k-amd os=-udi ;; sb1) basic_machine=mipsisa64sb1-unknown ;; sb1el) basic_machine=mipsisa64sb1el-unknown ;; sde) basic_machine=mipsisa32-sde os=-elf ;; sei) basic_machine=mips-sei os=-seiux ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sh5el) basic_machine=sh5le-unknown ;; sh64) basic_machine=sh64-unknown ;; sparclite-wrs | simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; st2000) basic_machine=m68k-tandem ;; stratus) basic_machine=i860-stratus os=-sysv4 ;; strongarm-* | thumb-*) basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; sv1) basic_machine=sv1-cray os=-unicos ;; symmetry) basic_machine=i386-sequent os=-dynix ;; t3e) basic_machine=alphaev5-cray os=-unicos ;; t90) basic_machine=t90-cray os=-unicos ;; tile*) basic_machine=$basic_machine-unknown os=-linux-gnu ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; toad1) basic_machine=pdp10-xkl os=-tops20 ;; tower | tower-32) basic_machine=m68k-ncr ;; tpf) basic_machine=s390x-ibm os=-tpf ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; v810 | necv810) basic_machine=v810-nec os=-none ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; w65*) basic_machine=w65-wdc os=-none ;; w89k-*) basic_machine=hppa1.1-winbond os=-proelf ;; xbox) basic_machine=i686-pc os=-mingw32 ;; xps | xps100) basic_machine=xps100-honeywell ;; xscale-* | xscalee[bl]-*) basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` ;; ymp) basic_machine=ymp-cray os=-unicos ;; z8k-*-coff) basic_machine=z8k-unknown os=-sim ;; z80-*-coff) basic_machine=z80-unknown os=-sim ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) basic_machine=hppa1.1-winbond ;; op50n) basic_machine=hppa1.1-oki ;; op60c) basic_machine=hppa1.1-oki ;; romp) basic_machine=romp-ibm ;; mmix) basic_machine=mmix-knuth ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp10) # there are many clones, so DEC is not a safe bet basic_machine=pdp10-unknown ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) basic_machine=sparc-sun ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; mac | mpw | mac-mpw) basic_machine=m68k-apple ;; pmac | pmac-mpw) basic_machine=powerpc-apple ;; *-unknown) # Make sure to match an already-canonicalized machine name. ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. -auroraux) os=-auroraux ;; -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -svr4*) os=-sysv4 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # First accept the basic system types. # The portable systems comes first. # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ | -sym* | -kopensolaris* | -plan9* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* | -aros* | -cloudabi* | -sortix* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* | -cegcc* \ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ | -linux-newlib* | -linux-musl* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \ | -onefs* | -tirtos* | -phoenix* | -fuchsia*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) case $basic_machine in x86-* | i*86-*) ;; *) os=-nto$os ;; esac ;; -nto-qnx*) ;; -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo $os | sed -e 's|mac|macos|'` ;; -linux-dietlibc) os=-linux-dietlibc ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition ;; -os400*) os=-os400 ;; -wince*) os=-wince ;; -osfrose*) os=-osfrose ;; -osf*) os=-osf ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -atheos*) os=-atheos ;; -syllable*) os=-syllable ;; -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; -nova*) os=-rtmk-nova ;; -ns2 ) os=-nextstep2 ;; -nsk*) os=-nsk ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -tpf*) os=-tpf ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -ose*) os=-ose ;; -es1800*) os=-ose ;; -xenix) os=-xenix ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; -aros*) os=-aros ;; -zvmoe) os=-zvmoe ;; -dicos*) os=-dicos ;; -nacl*) ;; -ios) ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in score-*) os=-elf ;; spu-*) os=-elf ;; *-acorn) os=-riscix1.2 ;; arm*-rebel) os=-linux ;; arm*-semi) os=-aout ;; c4x-* | tic4x-*) os=-coff ;; c8051-*) os=-elf ;; hexagon-*) os=-elf ;; tic54x-*) os=-coff ;; tic55x-*) os=-coff ;; tic6x-*) os=-coff ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 ;; m68*-cisco) os=-aout ;; mep-*) os=-elf ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; or32-*) os=-coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; *-be) os=-beos ;; *-haiku) os=-haiku ;; *-ibm) os=-aix ;; *-knuth) os=-mmixware ;; *-wec) os=-proelf ;; *-winbond) os=-proelf ;; *-oki) os=-proelf ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next ) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-next) os=-nextstep3 ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f30[01]-fujitsu | f700-fujitsu) os=-uxpv ;; *-rom68k) os=-coff ;; *-*bug) os=-coff ;; *-apple) os=-macos ;; *-atari*) os=-mint ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -cnk*|-aix*) vendor=ibm ;; -beos*) vendor=be ;; -hpux*) vendor=hp ;; -mpeix*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs* | -opened*) vendor=ibm ;; -os400*) vendor=ibm ;; -ptx*) vendor=sequent ;; -tpf*) vendor=ibm ;; -vxsim* | -vxworks* | -windiss*) vendor=wrs ;; -aux*) vendor=apple ;; -hms*) vendor=hitachi ;; -mpw* | -macos*) vendor=apple ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) vendor=atari ;; -vos*) vendor=stratus ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os exit # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: cfengine-masterfiles-3.27.3/configure0000755000000000000000000037650614735102600016014 0ustar0000000000000000#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69 for cfengine-masterfiles 3.27.3. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # Use a proper internal environment variable to ensure we don't fall # into an infinite loop, continuously re-executing ourselves. if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then _as_can_reexec=no; export _as_can_reexec; # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 as_fn_exit 255 fi # We don't want this to propagate to other subprocesses. { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1 test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : export CONFIG_SHELL # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, $0: including any error possibly output before this $0: message. Then install a modern shell, or manually run $0: the script under such a shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # If we had to re-execute with $CONFIG_SHELL, we're ensured to have # already done that, so ensure we don't try to do so again and fall # in an infinite loop. This has already happened in practice. _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='cfengine-masterfiles' PACKAGE_TARNAME='cfengine-masterfiles' PACKAGE_VERSION='3.27.3' PACKAGE_STRING='cfengine-masterfiles 3.27.3' PACKAGE_BUGREPORT='' PACKAGE_URL='' ac_subst_vars='LTLIBOBJS LIBOBJS MASTERFILES_INSTALL_TARGETS MASTERFILES_TESTS HAVE_SHUNIT2_FALSE HAVE_SHUNIT2_TRUE HAVE_PKG_INSTALL_FALSE HAVE_PKG_INSTALL_TRUE ac_cv_shunit2 ac_cv_pkg_install XNU_FALSE XNU_TRUE NETBSD_FALSE NETBSD_TRUE FREEBSD_FALSE FREEBSD_TRUE HPUX_FALSE HPUX_TRUE AIX_FALSE AIX_TRUE CYGWIN_FALSE CYGWIN_TRUE NT_FALSE NT_TRUE SOLARIS_FALSE SOLARIS_TRUE MACOSX_FALSE MACOSX_TRUE LINUX_FALSE LINUX_TRUE enterprise_dir HAVE_ENTERPRISE_FALSE HAVE_ENTERPRISE_TRUE core_dir HAVE_CORE_FALSE HAVE_CORE_TRUE MAINT MAINTAINER_MODE_FALSE MAINTAINER_MODE_TRUE AM_BACKSLASH AM_DEFAULT_VERBOSITY AM_DEFAULT_V AM_V am__untar am__tar AMTAR am__leading_dot SET_MAKE AWK mkdir_p MKDIR_P INSTALL_STRIP_PROGRAM STRIP install_sh MAKEINFO AUTOHEADER AUTOMAKE AUTOCONF ACLOCAL VERSION PACKAGE CYGPATH_W am__isrc INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM target_os target_vendor target_cpu target host_os host_vendor host_cpu host build_os build_vendor build_cpu build RELEASE target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir runstatedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking enable_silent_rules enable_maintainer_mode with_core with_enterprise ' ac_precious_vars='build_alias host_alias target_alias' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -runstatedir | --runstatedir | --runstatedi | --runstated \ | --runstate | --runstat | --runsta | --runst | --runs \ | --run | --ru | --r) ac_prev=runstatedir ;; -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ | --run=* | --ru=* | --r=*) runstatedir=$ac_optarg ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures cfengine-masterfiles 3.27.3 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/cfengine-masterfiles] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] --target=TARGET configure for building compilers for TARGET [HOST] _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of cfengine-masterfiles 3.27.3:";; esac cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-silent-rules less verbose build output (undo: "make V=1") --disable-silent-rules verbose build output (undo: "make V=0") --disable-maintainer-mode disable make rules and dependencies not useful (and sometimes confusing) to the casual installer Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-core= Build against core in directory . Defaults to "../core". If not found there or if --with-core=no then tests are disabled --with-enterprise= Build against enterprise in directory . Defaults to "../enterprise" Report bugs to the package provider. _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF cfengine-masterfiles configure 3.27.3 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by cfengine-masterfiles $as_me 3.27.3, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo $as_echo "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo $as_echo "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then $as_echo "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then $as_echo "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h $as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then # We do not want a PATH search for config.site. case $CONFIG_SITE in #(( -*) ac_site_file1=./$CONFIG_SITE;; */*) ac_site_file1=$CONFIG_SITE;; *) ac_site_file1=./$CONFIG_SITE;; esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu cfengine_version=3.27.3 RELEASE=1 cfengine_release=1 ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 $as_echo_n "checking build system type... " >&6; } if ${ac_cv_build+:} false; then : $as_echo_n "(cached) " >&6 else ac_build_alias=$build_alias test "x$ac_build_alias" = x && ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` test "x$ac_build_alias" = x && as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 $as_echo "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' set x $ac_cv_build shift build_cpu=$1 build_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: build_os=$* IFS=$ac_save_IFS case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 $as_echo_n "checking host system type... " >&6; } if ${ac_cv_host+:} false; then : $as_echo_n "(cached) " >&6 else if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 $as_echo "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' set x $ac_cv_host shift host_cpu=$1 host_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: host_os=$* IFS=$ac_save_IFS case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking target system type" >&5 $as_echo_n "checking target system type... " >&6; } if ${ac_cv_target+:} false; then : $as_echo_n "(cached) " >&6 else if test "x$target_alias" = x; then ac_cv_target=$ac_cv_host else ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $target_alias failed" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_target" >&5 $as_echo "$ac_cv_target" >&6; } case $ac_cv_target in *-*-*) ;; *) as_fn_error $? "invalid value of canonical target" "$LINENO" 5;; esac target=$ac_cv_target ac_save_IFS=$IFS; IFS='-' set x $ac_cv_target shift target_cpu=$1 target_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: target_os=$* IFS=$ac_save_IFS case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac # The aliases save the names the user supplied, while $host etc. # will get canonicalized. test -n "$target_alias" && test "$program_prefix$program_suffix$program_transform_name" = \ NONENONEs,x,x, && program_prefix=${target_alias}- am__api_version='1.15' # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if ${ac_cv_path_install+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in #(( ./ | .// | /[cC]/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 $as_echo "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 $as_echo_n "checking whether build environment is sane... " >&6; } # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[\\\"\#\$\&\'\`$am_lf]*) as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; esac case $srcdir in *[\\\"\#\$\&\'\`$am_lf\ \ ]*) as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$*" != "X $srcdir/configure conftest.file" \ && test "$*" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". as_fn_error $? "ls -t appears to fail. Make sure there is not a broken alias in your environment" "$LINENO" 5 fi if test "$2" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$2" = conftest.file ) then # Ok. : else as_fn_error $? "newly created file is older than distributed files! Check your system clock" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi rm -f conftest.file test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s&\$&$program_suffix&;$program_transform_name" # Double any \ or $. # By default was `s,x,x', remove it if useless. ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` # Expand $ac_aux_dir to an absolute path. am_aux_dir=`cd "$ac_aux_dir" && pwd` if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 $as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} fi if test x"${install_sh+set}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 $as_echo_n "checking for a thread-safe mkdir -p... " >&6; } if test -z "$MKDIR_P"; then if ${ac_cv_path_mkdir+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in mkdir gmkdir; do for ac_exec_ext in '' $ac_executable_extensions; do as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( 'mkdir (GNU coreutils) '* | \ 'mkdir (coreutils) '* | \ 'mkdir (fileutils) '4.1*) ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext break 3;; esac done done done IFS=$as_save_IFS fi test -d ./--version && rmdir ./--version if test "${ac_cv_path_mkdir+set}" = set; then MKDIR_P="$ac_cv_path_mkdir -p" else # As a last resort, use the slow shell script. Don't cache a # value for MKDIR_P within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. MKDIR_P="$ac_install_sh -d" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 $as_echo "$MKDIR_P" >&6; } for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AWK+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 $as_echo "$AWK" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AWK" && break done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null # Check whether --enable-silent-rules was given. if test "${enable_silent_rules+set}" = set; then : enableval=$enable_silent_rules; fi case $enable_silent_rules in # ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=1;; esac am_make=${MAKE-make} { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 $as_echo_n "checking whether $am_make supports nested variables... " >&6; } if ${am_cv_make_support_nested_variables+:} false; then : $as_echo_n "(cached) " >&6 else if $as_echo 'TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 $as_echo "$am_cv_make_support_nested_variables" >&6; } if test $am_cv_make_support_nested_variables = yes; then AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AM_BACKSLASH='\' if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." am__isrc=' -I$(srcdir)' # test to see if srcdir already configured if test -f $srcdir/config.status; then as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi # Define the identity of the package. PACKAGE='cfengine-masterfiles' VERSION='3.27.3' cat >>confdefs.h <<_ACEOF #define PACKAGE "$PACKAGE" _ACEOF cat >>confdefs.h <<_ACEOF #define VERSION "$VERSION" _ACEOF # Some tools Automake needs. ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # mkdir_p='$(MKDIR_P)' # We need awk for the "check" target (and possibly the TAP driver). The # system "awk" is bad on some platforms. # Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AMTAR='$${TAR-tar}' # We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar pax cpio none' { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to create a pax tar archive" >&5 $as_echo_n "checking how to create a pax tar archive... " >&6; } # Go ahead even if we have the value already cached. We do so because we # need to set the values for the 'am__tar' and 'am__untar' variables. _am_tools=${am_cv_prog_tar_pax-$_am_tools} for _am_tool in $_am_tools; do case $_am_tool in gnutar) for _am_tar in tar gnutar gtar; do { echo "$as_me:$LINENO: $_am_tar --version" >&5 ($_am_tar --version) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && break done # Work around CFEngine redmine #6925 by using --hard-dereference. { echo "$as_me:$LINENO: $_am_tar --hard-dereference 2>&1 | grep 'unrecognized option'" >&5 ($_am_tar --hard-dereference 2>&1 | grep 'unrecognized option') >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } # Check if --hard-dereference is supported by this version of GNU Tar if test "$ac_status" -eq 0; then _am_gnutar_hard_dereference=false am__tar="$_am_tar --format=posix -chf - "'"$$tardir"' am__tar_="$_am_tar --format=posix -chf - "'"$tardir"' else _am_gnutar_hard_dereference=true am__tar="$_am_tar --format=posix --hard-dereference -chf - "'"$$tardir"' am__tar_="$_am_tar --format=posix --hard-dereference -chf - "'"$tardir"' fi am__untar="$_am_tar -xf -" ;; plaintar) # Must skip GNU tar: if it does not support --format= it doesn't create # ustar tarball either. (tar --version) >/dev/null 2>&1 && continue am__tar='tar chf - "$$tardir"' am__tar_='tar chf - "$tardir"' am__untar='tar xf -' ;; pax) am__tar='pax -L -x pax -w "$$tardir"' am__tar_='pax -L -x pax -w "$tardir"' am__untar='pax -r' ;; cpio) am__tar='find "$$tardir" -print | cpio -o -H pax -L' am__tar_='find "$tardir" -print | cpio -o -H pax -L' am__untar='cpio -i -H pax -d' ;; none) am__tar=false am__tar_=false am__untar=false ;; esac # If the value was cached, stop now. We just wanted to have am__tar # and am__untar set. test -n "${am_cv_prog_tar_pax}" && break # tar/untar a dummy directory, and stop if the command works. rm -rf conftest.dir mkdir conftest.dir echo GrepMe > conftest.dir/file { echo "$as_me:$LINENO: tardir=conftest.dir && eval $am__tar_ >conftest.tar" >&5 (tardir=conftest.dir && eval $am__tar_ >conftest.tar) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } rm -rf conftest.dir if test -s conftest.tar; then { echo "$as_me:$LINENO: $am__untar &5 ($am__untar &5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { echo "$as_me:$LINENO: cat conftest.dir/file" >&5 (cat conftest.dir/file) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } grep GrepMe conftest.dir/file >/dev/null 2>&1 && break fi done rm -rf conftest.dir if ${am_cv_prog_tar_pax+:} false; then : $as_echo_n "(cached) " >&6 else am_cv_prog_tar_pax=$_am_tool fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_tar_pax" >&5 $as_echo "$am_cv_prog_tar_pax" >&6; } if test $_am_tool = gnutar; then # We've checked already, so we're just printing here { $as_echo "$as_me:${as_lineno-$LINENO}: checking if GNU tar supports --hard-dereference" >&5 $as_echo_n "checking if GNU tar supports --hard-dereference... " >&6; } if test x$_am_gnutar_hard_dereference = xtrue; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi # POSIX will say in a future version that running "rm -f" with no argument # is OK; and we want to be able to make that assumption in our Makefile # recipes. So use an aggressive probe to check that the usage we want is # actually supported "in the wild" to an acceptable degree. # See automake bug#10828. # To make any issue more visible, cause the running configure to be aborted # by default if the 'rm' program in use doesn't match our expectations; the # user can still override this though. if rm -f && rm -fr && rm -rf; then : OK; else cat >&2 <<'END' Oops! Your 'rm' program seems unable to run without file operands specified on the command line, even when the '-f' option is present. This is contrary to the behaviour of most rm programs out there, and not conforming with the upcoming POSIX standard: Please tell bug-automake@gnu.org about your system, including the value of your $PATH and any error possibly output before this message. This can help us improve future automake versions. END if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then echo 'Configuration will proceed anyway, since you have set the' >&2 echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 echo >&2 else cat >&2 <<'END' Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM to "yes", and re-run configure. END as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 $as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; } # Check whether --enable-maintainer-mode was given. if test "${enable_maintainer_mode+set}" = set; then : enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval else USE_MAINTAINER_MODE=yes fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5 $as_echo "$USE_MAINTAINER_MODE" >&6; } if test $USE_MAINTAINER_MODE = yes; then MAINTAINER_MODE_TRUE= MAINTAINER_MODE_FALSE='#' else MAINTAINER_MODE_TRUE='#' MAINTAINER_MODE_FALSE= fi MAINT=$MAINTAINER_MODE_TRUE cat >>confdefs.h <<_ACEOF #define ABS_TOP_SRCDIR "`cd -- "$srcdir"; pwd`" _ACEOF # Check whether --enable-silent-rules was given. if test "${enable_silent_rules+set}" = set; then : enableval=$enable_silent_rules; fi case $enable_silent_rules in # ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=0;; esac am_make=${MAKE-make} { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 $as_echo_n "checking whether $am_make supports nested variables... " >&6; } if ${am_cv_make_support_nested_variables+:} false; then : $as_echo_n "(cached) " >&6 else if $as_echo 'TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 $as_echo "$am_cv_make_support_nested_variables" >&6; } if test $am_cv_make_support_nested_variables = yes; then AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AM_BACKSLASH='\' # Check whether --with-core was given. if test "${with_core+set}" = set; then : withval=$with_core; if test "x$with_core" == "xno"; then : core_dir= else if test -d "$with_core/libpromises"; then : core_dir="$with_core" else as_fn_error $? "$with_core is not a valid core directory (--with-core=$with_core)" "$LINENO" 5 fi fi else if test -d `pwd`/../core/libpromises then core_dir="`pwd`/../core" else core_dir= fi fi if test "x$core_dir" != x; then HAVE_CORE_TRUE= HAVE_CORE_FALSE='#' else HAVE_CORE_TRUE='#' HAVE_CORE_FALSE= fi if test "x$core_dir" != x; then : case $core_dir in #( /*) : ;; #( *) : core_dir=`pwd`/$core_dir ;; esac fi # Check whether --with-enterprise was given. if test "${with_enterprise+set}" = set; then : withval=$with_enterprise; if test "x$with_enterprise" == "xno"; then : enterprise_dir= else enterprise_dir=$with_enterprise fi else enterprise_dir=`pwd`/../enterprise fi case $enterprise_dir in #( /*) : ;; #( *) : enterprise_dir=`pwd`/$enterprise_dir ;; esac if test -d "$enterprise_dir/libcfenterprise"; then HAVE_ENTERPRISE_TRUE= HAVE_ENTERPRISE_FALSE='#' else HAVE_ENTERPRISE_TRUE='#' HAVE_ENTERPRISE_FALSE= fi if test x"$prefix" = xNONE; then : prefix=/var/cfengine fi bindir="${bindir:-${exec_prefix}/bin}" _lcl_receval=""${bindir}"" bindir=`(test "x$prefix" = xNONE && prefix="$ac_default_prefix" test "x$exec_prefix" = xNONE && exec_prefix="${prefix}" _lcl_receval_old='' while test "$_lcl_receval_old" != "$_lcl_receval"; do _lcl_receval_old="$_lcl_receval" eval _lcl_receval="\"$_lcl_receval\"" done echo "$_lcl_receval")` bindir="${bindir}" # # Copyright 2024 Northern.tech AS # # This file is part of CFEngine 3 - written and maintained by Northern.tech AS. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; version 3. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # # 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. # # # OS kernels conditionals. Don't use those unless it is really needed (if code # depends on the *kernel* feature, and even then -- some kernel features are # shared by different kernels). # # Good example: use LINUX to select code which uses inotify and netlink sockets. # Bad example: use LINUX to select code which parses output of coreutils' ps(1). # if test -n "`echo ${target_os} | grep linux`"; then LINUX_TRUE= LINUX_FALSE='#' else LINUX_TRUE='#' LINUX_FALSE= fi if test -n "`echo ${target_os} | grep darwin`"; then MACOSX_TRUE= MACOSX_FALSE='#' else MACOSX_TRUE='#' MACOSX_FALSE= fi if test -n "`(echo ${target_os} | egrep 'solaris|sunos')`"; then SOLARIS_TRUE= SOLARIS_FALSE='#' else SOLARIS_TRUE='#' SOLARIS_FALSE= fi if test -n "`(echo ${target_os} | egrep 'mingw|cygwin')`"; then NT_TRUE= NT_FALSE='#' else NT_TRUE='#' NT_FALSE= fi if test -n "`(echo ${target_os} | egrep 'cygwin')`"; then CYGWIN_TRUE= CYGWIN_FALSE='#' else CYGWIN_TRUE='#' CYGWIN_FALSE= fi if test -n "`(echo ${target_os} | grep aix)`"; then AIX_TRUE= AIX_FALSE='#' else AIX_TRUE='#' AIX_FALSE= fi if test -n "`(echo ${target_os} | egrep 'hpux|hp-ux')`"; then HPUX_TRUE= HPUX_FALSE='#' else HPUX_TRUE='#' HPUX_FALSE= fi if test -n "`(echo ${target_os} | grep freebsd)`"; then FREEBSD_TRUE= FREEBSD_FALSE='#' else FREEBSD_TRUE='#' FREEBSD_FALSE= fi if test -n "`(echo ${target_os} | grep netbsd)`"; then NETBSD_TRUE= NETBSD_FALSE='#' else NETBSD_TRUE='#' NETBSD_FALSE= fi if test -n "`(echo ${target_os} | grep darwin)`"; then XNU_TRUE= XNU_FALSE='#' else XNU_TRUE='#' XNU_FALSE= fi # Extract the first word of "pkg_install", so it can be a program name with args. set dummy pkg_install; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_cv_pkg_install+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_cv_pkg_install"; then ac_cv_prog_ac_cv_pkg_install="$ac_cv_pkg_install" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_cv_pkg_install="yes" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_prog_ac_cv_pkg_install" && ac_cv_prog_ac_cv_pkg_install="no" fi fi ac_cv_pkg_install=$ac_cv_prog_ac_cv_pkg_install if test -n "$ac_cv_pkg_install"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_pkg_install" >&5 $as_echo "$ac_cv_pkg_install" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "shunit2", so it can be a program name with args. set dummy shunit2; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_cv_shunit2+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_cv_shunit2"; then ac_cv_prog_ac_cv_shunit2="$ac_cv_shunit2" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_cv_shunit2="yes" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_prog_ac_cv_shunit2" && ac_cv_prog_ac_cv_shunit2="no" fi fi ac_cv_shunit2=$ac_cv_prog_ac_cv_shunit2 if test -n "$ac_cv_shunit2"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_shunit2" >&5 $as_echo "$ac_cv_shunit2" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$ac_cv_pkg_install" = "yes"; then HAVE_PKG_INSTALL_TRUE= HAVE_PKG_INSTALL_FALSE='#' else HAVE_PKG_INSTALL_TRUE='#' HAVE_PKG_INSTALL_FALSE= fi if test "$ac_cv_shunit2" = "yes"; then HAVE_SHUNIT2_TRUE= HAVE_SHUNIT2_FALSE='#' else HAVE_SHUNIT2_TRUE='#' HAVE_SHUNIT2_FALSE= fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: " >&5 $as_echo "" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: Summary:" >&5 $as_echo "Summary:" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: Version -> $cfengine_version" >&5 $as_echo "Version -> $cfengine_version" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: Release -> $cfengine_release" >&5 $as_echo "Release -> $cfengine_release" >&6; } if test -z "$HAVE_CORE_TRUE"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: Core directory -> $core_dir" >&5 $as_echo "Core directory -> $core_dir" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: Core directory -> not set - tests are disabled" >&5 $as_echo "Core directory -> not set - tests are disabled" >&6; } fi if test -z "$HAVE_ENTERPRISE_TRUE"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: Enterprise directory -> $enterprise_dir" >&5 $as_echo "Enterprise directory -> $enterprise_dir" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: Enterprise directory -> not set - some tests are disabled" >&5 $as_echo "Enterprise directory -> not set - some tests are disabled" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: Install prefix -> $prefix" >&5 $as_echo "Install prefix -> $prefix" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: bindir -> $bindir" >&5 $as_echo "bindir -> $bindir" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: " >&5 $as_echo "" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: generating makefile targets" >&5 $as_echo "$as_me: generating makefile targets" >&6;} # Do not try to unroll these for loops by putting the find commands directly in # the assignments, it will overflow on the Solaris and HP-UX shells. MASTERFILES_TESTS='' for i in `cd "$srcdir/tests/acceptance/" && find . -name '*.cf*'` do MASTERFILES_TESTS="$MASTERFILES_TESTS $i" done MASTERFILES_INSTALL_TARGETS= find $srcdir -maxdepth 1 -name '*.cf' > tmp while IFS= read -r j do # Only add those that don't have a corresponding .in file. # They will be added later. if ! test -f "$j.in" then MASTERFILES_INSTALL_TARGETS="$MASTERFILES_INSTALL_TARGETS $j" fi done < tmp rm tmp for j in `echo $srcdir/*.cf.in` do # Add .in files, but without the .in suffix. MASTERFILES_INSTALL_TARGETS="$MASTERFILES_INSTALL_TARGETS `echo $j | sed -e 's/\.in$//'`" done for i in cfe_internal controls inventory lib services do for j in `find "$srcdir/$i" -name '*.cf'` do # Only add those that don't have a corresponding .in file. # They will be added later. if ! test -f "$j.in" then MASTERFILES_INSTALL_TARGETS="$MASTERFILES_INSTALL_TARGETS $j" fi done for j in `find "$srcdir/$i" -name '*.cf.in'` do # Add .in files, but without the .in suffix. MASTERFILES_INSTALL_TARGETS="$MASTERFILES_INSTALL_TARGETS `echo $j | sed -e 's/\.in$//'`" done done for i in templates cfe_internal modules/packages/vendored lib/templates do for j in `find "$srcdir/$i" -name '*.mustache' -o -name '*.sh' -o -name '*.awk' -o -name '*.sed' -o -name '*.ps1' -o -name '*.py'` do MASTERFILES_INSTALL_TARGETS="$MASTERFILES_INSTALL_TARGETS $j" done done ac_config_files="$ac_config_files Makefile controls/update_def.cf update.cf promises.cf standalone_self_upgrade.cf tests/Makefile tests/acceptance/Makefile tests/unit/Makefile" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' # Transform confdefs.h into DEFS. # Protect against shell expansion while executing Makefile rules. # Protect against Makefile macro expansion. # # If the first sed substitution is executed (which looks for macros that # take arguments), then branch to the quote section. Otherwise, # look for a macro that doesn't take arguments. ac_script=' :mline /\\$/{ N s,\\\n,, b mline } t clear :clear s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g t quote s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g t quote b any :quote s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g s/\[/\\&/g s/\]/\\&/g s/\$/$$/g H :any ${ g s/^\n// s/\n/ /g p } ' DEFS=`sed -n "$ac_script" confdefs.h` ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs { $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 $as_echo_n "checking that generated files are newer than configure... " >&6; } if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 $as_echo "done" >&6; } if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_CORE_TRUE}" && test -z "${HAVE_CORE_FALSE}"; then as_fn_error $? "conditional \"HAVE_CORE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_ENTERPRISE_TRUE}" && test -z "${HAVE_ENTERPRISE_FALSE}"; then as_fn_error $? "conditional \"HAVE_ENTERPRISE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${LINUX_TRUE}" && test -z "${LINUX_FALSE}"; then as_fn_error $? "conditional \"LINUX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${MACOSX_TRUE}" && test -z "${MACOSX_FALSE}"; then as_fn_error $? "conditional \"MACOSX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${SOLARIS_TRUE}" && test -z "${SOLARIS_FALSE}"; then as_fn_error $? "conditional \"SOLARIS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${NT_TRUE}" && test -z "${NT_FALSE}"; then as_fn_error $? "conditional \"NT\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${CYGWIN_TRUE}" && test -z "${CYGWIN_FALSE}"; then as_fn_error $? "conditional \"CYGWIN\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${AIX_TRUE}" && test -z "${AIX_FALSE}"; then as_fn_error $? "conditional \"AIX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HPUX_TRUE}" && test -z "${HPUX_FALSE}"; then as_fn_error $? "conditional \"HPUX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${FREEBSD_TRUE}" && test -z "${FREEBSD_FALSE}"; then as_fn_error $? "conditional \"FREEBSD\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${NETBSD_TRUE}" && test -z "${NETBSD_FALSE}"; then as_fn_error $? "conditional \"NETBSD\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${XNU_TRUE}" && test -z "${XNU_FALSE}"; then as_fn_error $? "conditional \"XNU\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_PKG_INSTALL_TRUE}" && test -z "${HAVE_PKG_INSTALL_FALSE}"; then as_fn_error $? "conditional \"HAVE_PKG_INSTALL\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_SHUNIT2_TRUE}" && test -z "${HAVE_SHUNIT2_FALSE}"; then as_fn_error $? "conditional \"HAVE_SHUNIT2\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by cfengine-masterfiles $as_me 3.27.3, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE Configuration files: $config_files Report bugs to the package provider." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ cfengine-masterfiles config.status 3.27.3 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' MKDIR_P='$MKDIR_P' AWK='$AWK' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --he | --h | --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "controls/update_def.cf") CONFIG_FILES="$CONFIG_FILES controls/update_def.cf" ;; "update.cf") CONFIG_FILES="$CONFIG_FILES update.cf" ;; "promises.cf") CONFIG_FILES="$CONFIG_FILES promises.cf" ;; "standalone_self_upgrade.cf") CONFIG_FILES="$CONFIG_FILES standalone_self_upgrade.cf" ;; "tests/Makefile") CONFIG_FILES="$CONFIG_FILES tests/Makefile" ;; "tests/acceptance/Makefile") CONFIG_FILES="$CONFIG_FILES tests/acceptance/Makefile" ;; "tests/unit/Makefile") CONFIG_FILES="$CONFIG_FILES tests/unit/Makefile" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" eval set X " :F $CONFIG_FILES " shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac ac_MKDIR_P=$MKDIR_P case $MKDIR_P in [\\/$]* | ?:[\\/]* ) ;; */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t s&@MKDIR_P@&$ac_MKDIR_P&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: " >&5 $as_echo "" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: DONE: Configuration done. Run \"make install\" to install CFEngine Masterfiles." >&5 $as_echo "DONE: Configuration done. Run \"make install\" to install CFEngine Masterfiles." >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: " >&5 $as_echo "" >&6; } cfengine-masterfiles-3.27.3/configure.ac0000644000000000000000000001734614735102600016365 0ustar0000000000000000dnl ########################################################################## dnl # dnl # Build CFEngine dnl # dnl # Run ./autogen.sh to build configure script dnl # dnl ########################################################################## AC_PREREQ(2.63) m4_define([cfversion_from_env], m4_normalize(m4_esyscmd([echo $EXPLICIT_VERSION]))) m4_define([cfversion_from_file], m4_normalize(m4_esyscmd([cat CFVERSION]))) m4_ifval(cfversion_from_env, [ m4_define([cfversion], cfversion_from_env) ], [ m4_ifval(cfversion_from_file, [ m4_define([cfversion], cfversion_from_file) ], [ m4_fatal([Could not determine CFEngine version; please set EXPLICIT_VERSION in the environment, or make sure all git tags are up to date and rerun autogen.sh]) ]) ]) AC_INIT([cfengine-masterfiles], cfversion) cfengine_version=cfversion m4_undefine([cfversion]) m4_undefine([cfversion_from_file]) m4_undefine([cfversion_from_env]) m4_define([cfrelease], m4_normalize(m4_esyscmd([cat CFRELEASE]))) AC_SUBST([RELEASE], [cfrelease]) cfengine_release=cfrelease m4_undefine([cfrelease]) AC_CANONICAL_TARGET dnl Selects the new pax interchange format. Recommended for making tar archives dnl more reproducible (see https://www.gnu.org/software/tar/manual/html_section/Reproducibility.html). _AM_SET_OPTION([tar-pax]) 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". \ If not found there or if --with-core=no then tests are disabled] ), AS_IF(test "x$with_core" == "xno", [ core_dir= ], [ dnl The user passed --with-core=path but we must check if it's a dnl valid core directory. AS_IF(test -d "$with_core/libpromises", [ core_dir="$with_core" ], [ AC_MSG_ERROR([$with_core is not a valid core directory (--with-core=$with_core)]) ]) ]), dnl If --with-core was not passed at all, then default to ../core dnl only if that is a valid core directory. [if test -d `pwd`/../core/libpromises then core_dir="`pwd`/../core" else core_dir= fi] ) dnl export HAVE_CORE for makefiles AM_CONDITIONAL(HAVE_CORE, test "x$core_dir" != x) dnl Transform the path from relative to absolute AS_IF(test "x$core_dir" != x, [ 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 ) bindir="${bindir:-${exec_prefix}/bin}" dnl Expand ${prefix} and whatnot in bindir adl_RECURSIVE_EVAL("${bindir}", bindir) AC_SUBST(bindir, "${bindir}") dnl ###################################################################### dnl OS specific stuff dnl ###################################################################### m4_include([m4/cf3_platforms.m4]) AC_CHECK_PROG([ac_cv_pkg_install], [pkg_install], [yes], [no]) AC_CHECK_PROG([ac_cv_shunit2], [shunit2], [yes], [no]) AM_CONDITIONAL([HAVE_PKG_INSTALL], [test "$ac_cv_pkg_install" = "yes"]) AM_CONDITIONAL([HAVE_SHUNIT2], [test "$ac_cv_shunit2" = "yes"]) dnl ###################################################################### dnl Print summary dnl ###################################################################### AC_MSG_RESULT() AC_MSG_RESULT(Summary:) AC_MSG_RESULT(Version -> $cfengine_version) AC_MSG_RESULT(Release -> $cfengine_release) AM_COND_IF(HAVE_CORE, AC_MSG_RESULT(Core directory -> $core_dir), AC_MSG_RESULT(Core directory -> not set - tests are disabled) ) AM_COND_IF(HAVE_ENTERPRISE, AC_MSG_RESULT(Enterprise directory -> $enterprise_dir), AC_MSG_RESULT(Enterprise directory -> not set - some tests are disabled) ) AC_MSG_RESULT(Install prefix -> $prefix) AC_MSG_RESULT(bindir -> $bindir) AC_MSG_RESULT() dnl ###################################################################### dnl Generate install target list. dnl ###################################################################### AC_MSG_NOTICE([generating makefile targets]) # Do not try to unroll these for loops by putting the find commands directly in # the assignments, it will overflow on the Solaris and HP-UX shells. MASTERFILES_TESTS='' for i in `cd "$srcdir/tests/acceptance/" && find . -name '*.cf*'` do MASTERFILES_TESTS="$MASTERFILES_TESTS $i" done AC_SUBST(MASTERFILES_TESTS) MASTERFILES_INSTALL_TARGETS= find $srcdir -maxdepth 1 -name '*.cf' > tmp while IFS= read -r j do # Only add those that don't have a corresponding .in file. # They will be added later. if ! test -f "$j.in" then MASTERFILES_INSTALL_TARGETS="$MASTERFILES_INSTALL_TARGETS $j" fi done < tmp rm tmp for j in `echo $srcdir/*.cf.in` do # Add .in files, but without the .in suffix. MASTERFILES_INSTALL_TARGETS="$MASTERFILES_INSTALL_TARGETS `echo $j | sed -e 's/\.in$//'`" done for i in cfe_internal controls inventory lib services do for j in `find "$srcdir/$i" -name '*.cf'` do # Only add those that don't have a corresponding .in file. # They will be added later. if ! test -f "$j.in" then MASTERFILES_INSTALL_TARGETS="$MASTERFILES_INSTALL_TARGETS $j" fi done for j in `find "$srcdir/$i" -name '*.cf.in'` do # Add .in files, but without the .in suffix. MASTERFILES_INSTALL_TARGETS="$MASTERFILES_INSTALL_TARGETS `echo $j | sed -e 's/\.in$//'`" done done for i in templates cfe_internal modules/packages/vendored lib/templates do for j in `find "$srcdir/$i" -name '*.mustache' -o -name '*.sh' -o -name '*.awk' -o -name '*.sed' -o -name '*.ps1' -o -name '*.py'` do MASTERFILES_INSTALL_TARGETS="$MASTERFILES_INSTALL_TARGETS $j" done done AC_SUBST(MASTERFILES_INSTALL_TARGETS) dnl ###################################################################### dnl Now make the Makefiles dnl ###################################################################### AC_CONFIG_FILES([Makefile controls/update_def.cf update.cf promises.cf standalone_self_upgrade.cf tests/Makefile tests/acceptance/Makefile tests/unit/Makefile ]) AC_OUTPUT AC_MSG_RESULT() AC_MSG_RESULT(DONE: Configuration done. Run "make install" to install CFEngine Masterfiles.) AC_MSG_RESULT() cfengine-masterfiles-3.27.3/PaxHeaders/controls0000644000000000000000000000003615266337437016567 xustar0030 mtime=1792655135.237799948 cfengine-masterfiles-3.27.3/controls/0000755000000000000000000000000015266337437015751 5ustar0000000000000000cfengine-masterfiles-3.27.3/controls/cf_agent.cf0000644000000000000000000000470014735102600020010 0ustar0000000000000000############################################################################### # # 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:: @if minimum_version(3.27.0) # The order in which promises are evaluated (top_down|classic) evaluation_order => "$(default:def.control_agent_evaluation_order)"; @endif # Minimum time (in minutes) which should have passed since the last time # the promise was verified before it is checked again. 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"; # explicitly not supported (but they should break long before) abortclasses => { "cfengine_3_3", "cfengine_3_4", @(def.control_agent_abortclasses) }; # The abortbundleclasses slist contains regular expressions that match # classes which if defined lead to termination of current bundle. abortbundleclasses => { @(def.control_agent_abortbundleclasses) }; # Maximum number of outgoing connections to a remote cf-serverd. maxconnections => "$(def.control_agent_maxconnections)"; # Environment variables of the agent process. # The values of environment variables are inherited by child commands # EMPTY list is not valid for environment attribute Ref: CFE-3927. So, we # do some validation on it so we can apply it selectively. @if minimum_version(3.27.0) default_directory_create_mode => "$(def.control_agent_default_directory_create_mode)"; @endif _control_agent_environment_vars_validated:: environment => { @(def.control_agent_environment_vars) }; _have_control_agent_files_single_copy:: # CFE-3622 # File patterns which allow a file to be copied over only a single time # per agent run. files_single_copy => { @(def.control_agent_files_single_copy) }; mpf_control_agent_default_repository:: # Location to backup files before they are edited by cfengine default_repository => "$(def.control_agent_default_repository)"; # Environment variables based on Distro control_agent_agentfacility_configured:: agentfacility => "$(default:def.control_agent_agentfacility)"; } cfengine-masterfiles-3.27.3/controls/cf_execd.cf0000644000000000000000000000466214735102600020011 0ustar0000000000000000############################################################################### # 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 # @brief Settings that determine the behavior of `cf-execd` # @variable `default:def.control_executor_mailmaxlines` - The maximum number of lines of output that `cf-execd` will email. { any:: # activity will be spread over this many time slices: splaytime => "$(def.control_executor_splaytime)"; agent_expireafter => "$(def.control_executor_agent_expireafter)"; @if minimum_version(3.18.0) _have_control_executor_runagent_socket_allow_users:: runagent_socket_allow_users => { @(def.control_executor_runagent_socket_allow_users) }; @endif cfengine_internal_agent_email.!cfengine_internal_disable_agent_email:: mailto => "$(def.mailto)"; mailfrom => "$(def.mailfrom)"; smtpserver => "$(def.smtpserver)"; mailmaxlines => "$(default:def.control_executor_mailmaxlines)"; control_executor_mailsubject_configured.cfengine_internal_agent_email.!cfengine_internal_disable_agent_email:: mailsubject => "$(default:def.control_executor_mailsubject)"; control_executor_mailfilter_exclude_configured.cfengine_internal_agent_email.!cfengine_internal_disable_agent_email:: mailfilter_exclude => { "@(default:def.control_executor_mailfilter_exclude)" }; control_executor_mailfilter_include_configured.cfengine_internal_agent_email.!cfengine_internal_disable_agent_email:: mailfilter_include => { "@(default:def.control_executor_mailfilter_include)" }; any:: # Default: # # schedule => { "Min00", "Min05", "Min10", "Min15", "Min20", # "Min25", "Min30", "Min35", "Min40", "Min45", # "Min50", "Min55" }; schedule => { @(def.control_executor_schedule_value) }; # The full path and command to the executable run by default (overriding builtin). windows:: exec_command => "$(sys.cf_agent) -Dfrom_cfexecd,cf_execd_initiated -f \"$(sys.update_policy_path)\" & $(sys.cf_agent) -Dfrom_cfexecd,cf_execd_initiated"; !windows:: exec_command => "$(sys.cf_agent) -Dfrom_cfexecd,cf_execd_initiated -f \"$(sys.update_policy_path)\" ; $(sys.cf_agent) -Dfrom_cfexecd,cf_execd_initiated"; } cfengine-masterfiles-3.27.3/controls/cf_hub.cf0000644000000000000000000000217514735102600017474 0ustar0000000000000000############################################################################### # # 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 # @brief Control attributes for `cf-hub` { enterprise_edition.policy_server:: exclude_hosts => { @(def.control_hub_exclude_hosts) }; # exclude_hosts => { "192.168.12.21", "10.10", "10.12.*" }; # cf-hub initiates a pull collection round if one of the listed classes is defined. hub_schedule => { @(def.control_hub_hub_schedule) }; # port => "5308"; @if minimum_version(3.15) query_timeout => "$(def.control_hub_query_timeout)"; @endif # Hub will discard accumulated reports on the clients # and download only information about current state of the client # in case of not successfully downloading the reports for defined # period of time. Default value is 6 hours. # Was introduced in CFEngine 3.6.4 # client_history_timeout => 6; # [hours] } cfengine-masterfiles-3.27.3/controls/cf_monitord.cf0000644000000000000000000000124714735102600020550 0ustar0000000000000000############################################################################### # # 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 # @brief Attributes controlling cf-monitord { any:: forgetrate => "0.7"; histograms => "true"; # tcpdump => "false"; # tcpdumpcommand => "/usr/sbin/tcpdump -t -n -v"; } cfengine-masterfiles-3.27.3/controls/cf_runagent.cf0000644000000000000000000000104114735102600020530 0ustar0000000000000000############################################################################### # # 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", ... } cfengine-masterfiles-3.27.3/controls/cf_serverd.cf0000644000000000000000000002550214735102600020367 0ustar0000000000000000############################################################################### # 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 # @brief Control attributes for cf-serverd { # List of hosts that may connect (change the ACL in def.cf) allowconnects => { @(default:def.control_server_allowconnects_derived) }; # Out of them, which ones should be allowed to have more than one # connection established at the same time? allowallconnects => { @(default:def.control_server_allowallconnects_derived) }; # Out of the hosts in allowconnects, trust new keys only from the # following ones. SEE COMMENTS IN def.cf trustkeysfrom => { @(def.trustkeysfrom) }; ## List of the hosts not using the latest protocol that we'll accept connections from ## (absence of this option or empty list means allow none) allowlegacyconnects => { @(def.control_server_allowlegacyconnects) }; # Maximum number of concurrent connections. # Suggested value >= total number of hosts maxconnections => "$(def.control_server_maxconnections)"; # Allow connections from nodes which are out-of-sync denybadclocks => "false"; control_server_allowtlsversion_defined:: # Minimum required version of TLS. Set to "1.0" if you need clients # running CFEngine in a version lower than 3.7.0 to connect. # # Example: # allowtlsversion => "1.0"; # See also: tls_min_version in body common control allowtlsversion => "$(default:def.control_server_allowtlsversion)"; control_server_allowciphers_defined:: # List of ciphers the server accepts. For Syntax help see man page for # "openssl-ciphers" (man:openssl-ciphers(1ssl)). The 'TLS_'-prefixed # ciphers are for TLS 1.3 and later. # # Example setting: # allowciphers => "AES256-GCM-SHA384:AES256-SHA:TLS_AES_256_GCM_SHA384"; # See also: tls_ciphers in body common control allowciphers => "$(default:def.control_server_allowciphers)"; enterprise_edition.client_initiated_reporting_enabled:: # How often cf-serverd should try to establish a reverse tunnel for report # collection call_collect_interval => "$(def.control_server_call_collect_interval)"; # The time in seconds that a collect-call tunnel will remain open for hub # to complete report transfer. collect_window => "$(def.control_server_collect_window)"; any:: # The remote user accounts which are allowed to initiate cf-agent via # cf-runagent. allowusers => { @(def.control_server_allowusers) }; # In 3.10 the quotation is properly closed when EOF is reached. It is left # open so that arguments (like -K and --remote-bundles) can be appended. # 3.10.x does not automatically append -I -Dcfruncommand windows:: # /s removes the first and last quote characters and aids in specifying paths with surrounding quotes cfruncommand => "$(def.cf_runagent_shell) /s /c \" $(sys.cf_agent) -I -D cf_runagent_initiated -f $(sys.update_policy_path) & $(sys.cf_agent) -I -D cf_runagent_initiated"; !windows:: cfruncommand => "$(def.cf_runagent_shell) -c \' $(sys.cf_agent) -I -D cf_runagent_initiated -f $(sys.update_policy_path) ; $(sys.cf_agent) -I -D cf_runagent_initiated"; # Use bindtointerface to specify interface to bind to, the default is :: + # 0.0.0.0/0 if IPV6 is supported or 0.0.0.0/0 if IPV6 is not supported. On # Windows, binding to :: means only IPV6 connections will be accepted. # !windows:: # bindtointerface => "::"; } ############################################################################### bundle server mpf_default_access_rules() # @brief Defines access to common resources { vars: # TODO: Remove this once sys.keydir is always available (3.26+ only) "keydir" -> { "CFE-2822" } string => ifelse( isvariable("sys.keydir"), "$(sys.keydir)", "$(sys.workdir)/ppkeys" ); access: any:: "$(def.dir_masterfiles)/" handle => "server_access_grant_access_policy", shortcut => "masterfiles", comment => "Grant access to the policy updates", if => isdir("$(def.dir_masterfiles)/"), admit => { @(def.acl_derived) }; "$(def.dir_masterfiles)/.no-distrib/" -> { "ENT-8079" } handle => "prevent_distribution_of_top_level_dot_no_distrib", deny => { "0.0.0.0/0" }; "$(def.dir_bin)/" handle => "server_access_grant_access_binary", comment => "Grant access to binary for cf-runagent", if => isdir("$(def.dir_bin)/"), admit => { @(def.acl_derived) }; "$(def.dir_data)/" handle => "server_access_grant_access_data", shortcut => "data", comment => "Grant access to data directory", if => isdir("$(def.dir_data)/"), admit => { @(def.acl_derived) }; "$(def.dir_modules)/" handle => "server_access_grant_access_modules", shortcut => "modules", comment => "Grant access to modules directory", if => isdir("$(def.dir_modules)/"), admit => { @(def.acl_derived) }; # TODO: Remove after 3.15 is no longer supported (December 18th 2022) "$(def.dir_plugins)/" -> { "CFE-3618" } handle => "server_access_grant_access_plugins", comment => "Grant access to plugins directory", if => isdir("$(def.dir_plugins)/"), admit => { @(def.acl_derived) }; "$(def.dir_templates)/" handle => "server_access_grant_access_templates", shortcut => "templates", comment => "Grant access to templates directory", if => isdir("$(def.dir_templates)/"), admit => { @(def.acl_derived) }; policy_server|am_policy_hub:: "$(def.dir_master_software_updates)/" -> { "ENT-4953" } handle => "server_access_grant_access_master_software_updates", shortcut => "master_software_updates", comment => "Grant access for hosts to download cfengine packages for self upgrade", if => isdir("$(sys.workdir)/master_software_updates"), admit => { @(def.acl_derived) }; "$(sys.statedir)/cf_version.txt" -> { "ENT-10664" } handle => "server_access_grant_access_state_cf_version", shortcut => "hub-cf_version", comment => concat( "We want remote hosts to default their target binary", " version to that of the hubs binary version, so we", " need to share this state with remote clients." ), admit => { @(def.acl_derived) }; enterprise_edition.policy_server:: "collect_calls" resource_type => "query", admit_ips => { @(def.mpf_access_rules_collect_calls_admit_ips) }; "$(sys.workdir)/cmdb/$(connection.key)/" -> { "ENT-6788" } handle => "server_access_grant_access_cmdb", comment => "Grant access to host specific CMDB data", shortcut => "hub_cmdb", admit_keys => { $(connection.key) }; any:: "$(def.cf_runagent_shell)" -> { "ENT-6673" } handle => "server_access_grant_access_shell_cmd", comment => "Grant access to shell for cfruncommand", admit => { @(def.mpf_admit_cf_runagent_shell_selected) }; policy_server.enable_cfengine_enterprise_hub_ha:: "$(keydir)/" handle => "server_access_grant_access_ppkeys_hubs", comment => "Grant access to ppkeys for HA hubs", if => isdir("$(keydir)/"), admit => { @(def.policy_servers) }; # Allow slave hub to synchronize cf_robot and appsettings, application # config config, ldap config settings, and ldap api config settings. # 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)/httpd/htdocs/application/config/appsettings.php" handle => "server_access_grant_access_appsettings", comment => "Grant access to appsettings for HA hubs", admit => { @(def.policy_servers) }; "$(sys.workdir)/httpd/htdocs/application/config/config.php" -> { "ENT-4944" } handle => "server_access_grant_access_application_config_config_php", comment => "Grant access to application config for HA hubs", admit => { @(def.policy_servers) }; "$(sys.workdir)/httpd/htdocs/ldap/config/settings.php" -> { "ENT-4944" } handle => "server_access_grant_access_ldap_config_settings_php", comment => "Grant access to ldap config settings for HA hubs", admit => { @(def.policy_servers) }; "$(sys.workdir)/httpd/htdocs/api/config/config.php" -> { "ENT-4944" } handle => "server_access_grant_access_api_config_settings_php", comment => "Grant access to LDAP api config 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 to notification scripts", if => isdir("/opt/cfengine/notification_scripts/"), admit => { @(def.policy_servers) }; # When HA is enabled clients are updating active hub IP address # using data stored in master_hub.dat file. "$(ha_def.master_hub_location)" handle => "server_access_grant_access_policy_server_dat", comment => "Grant access to policy_server.dat", admit => { @(def.acl_derived) }; # 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. "$(ha_def.hubs_keys_location)/" handle => "server_access_grant_access_to_clients", comment => "Grant access to hubs' keys to clients", if => isdir("$(ha_def.hubs_keys_location)/"), admit => { @(def.acl_derived) }; 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) }; roles: # Use roles to allow specific remote cf-runagent users to # define certain soft-classes when running cf-agent on this host ".*" authorize => { "root" }; } cfengine-masterfiles-3.27.3/controls/def.cf0000644000000000000000000012230014735102600016775 0ustar0000000000000000############################################################################### # # bundle common def # - common/global variables and classes here # ############################################################################### bundle common def # @brief Common settings for the Masterfiles Policy Framework { vars: any:: "augments_inputs" slist => {}, if => not(isvariable("augments_inputs")), comment => "It's important that we define this list, even if it's empty or we get errors about the list being unresolved."; # Your domain name, for use in access control # Note: this default may be inaccurate! "domain" string => "$(sys.domain)", comment => "Define a global domain for all hosts", handle => "common_def_vars_domain", if => not(isvariable("domain")); # Mail settings used by body executor control found in controls/cf_execd.cf "mailto" string => "root@$(def.domain)", if => not(isvariable("mailto")); "mailfrom" string => "root@$(sys.uqhost).$(def.domain)", if => not(isvariable("mailfrom")); "smtpserver" string => "localhost", if => not(isvariable("smtpserver")); "control_executor_mailmaxlines" -> { "ENT-9614" } int => "30", if => not(isvariable("control_executor_mailmaxlines")); "control_executor_mailsubject" -> { "ENT-10210" } string => "", if => not(isvariable("control_executor_mailsubject")); "control_executor_mailfilter_exclude" -> { "ENT-10210" } slist => {}, if => not(isvariable("control_executor_mailfilter_exclude")); "control_executor_mailfilter_include" -> { "ENT-10210" } slist => {}, if => not(isvariable("control_executor_mailfilter_include")); # 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", # Uncomment below if HA is used #"@(def.policy_servers)" # "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", if => and(not(isvariable("override_data_acl")), not(isvariable("acl"))), meta => { "defvar" }; !disable_always_accept_policy_server_acl:: "acl_derived" -> { "ENT-10951" } slist => { @(def.acl), "$(sys.policy_hub)" }, comment => "Define an acl for the machines to be granted accesses"; disable_always_accept_policy_server_acl:: "acl_derived" -> { "ENT-10951" } slist => { @(def.acl) }, comment => "Define an acl for the machines to be granted accesses"; any:: "control_server_allowconnects" -> { "ENT-10212" } slist => { "127.0.0.1", "::1", @(def.acl) }, if => not(isvariable("control_server_allowconnects")), comment => concat( "We want to define the default setting for", " allowconnects in body server control if not", " already specified" ); !disable_always_accept_policy_server_allowconnects:: "control_server_allowconnects_derived" -> { "ENT-10951" } slist => { "$(sys.policy_hub)", @(def.control_server_allowconnects) }, comment => concat( "We want to define the default setting for", " allowconnects in body server control if not", " already specified. Since not explicitly excluded", " we want the policy server itself to be allowed." ); disable_always_accept_policy_server_allowconnects:: "control_server_allowconnects_derived" -> { "ENT-10951" } slist => { @(def.control_server_allowconnects) }, comment => concat( "We want to define the default setting for", " allowconnects in body server control if not", " already specified. Since explicitly excluded", " we don't automatically include the policy server itself." ); any:: "control_server_allowallconnects" -> { "ENT-10212" } slist => { "127.0.0.1", "::1", @(def.acl) }, if => not(isvariable("control_server_allowallconnects")), comment => concat( "We want to define the default setting for", " allowallconnects in body server control if not", " already specified" ); !disable_always_accept_policy_server_allowallconnects:: "control_server_allowallconnects_derived" -> { "ENT-10951" } slist => { @(def.control_server_allowallconnects), "$(sys.policy_hub)" }, comment => concat( "We want to define the default setting for", " allowallconnects in body server control if not", " already specified" ); disable_always_accept_policy_server_allowallconnects:: "control_server_allowallconnects_derived" -> { "ENT-10951" } slist => { @(def.control_server_allowallconnects) }, comment => concat( "We want to define the default setting for", " allowallconnects in body server control if not", " already specified" ); any:: # 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", # (0.0.0.0/0 allows any IP }, comment => "Define from which machines keys can be trusted", if => and( not(isvariable("override_data_trustkeysfrom")), not(isvariable("trustkeysfrom")) ), meta => { "defvar" }; ## List of the hosts not using the latest protocol that we'll accept connections from ## (absence of this option or empty list means allow none) "control_server_allowlegacyconnects" slist => {}, if => not(isvariable("control_server_allowlegacyconnects")); # Users authorized to request executions via cf-runagent "control_server_allowusers_non_policy_server" slist => { "root" }, if => not(isvariable("control_server_allowusers_non_policy_server")); "control_server_allowusers_policy_server" slist => {}, if => not(isvariable("control_server_allowusers_policy_server")); policy_server:: "control_server_allowusers" -> { "CFE-3544", "ENT-6666" } handle => "def_control_server_allowusers_policy_server", slist => { @(control_server_allowusers_policy_server) }, meta => { "inventory", "attribute_name=Allowed users for cf-runagent" }, if => not(isvariable("control_server_allowusers")); !policy_server:: "control_server_allowusers" -> { "CFE-3544", "ENT-6666" } handle => "def_control_server_allowusers_non_policy_server", slist => { @(control_server_allowusers_non_policy_server) }, meta => { "inventory", "attribute_name=Allowed users for cf-runagent" }, if => not(isvariable("control_server_allowusers")); # Executor controls any:: "mpf_admit_cf_runagent_shell_selected" -> { "ENT-6673", "ENT-6666" } handle => "mpf_admit_cf_runagent_shell_default", if => not(isvariable("mpf_admit_cf_runagent_shell")), slist => { @(def.policy_servers) }, meta => { "inventory", "attribute_name=Allowed hosts for cf-runagent", "derived-from=def.policy_servers", }, comment => concat( "By default we admit our policy servers to initiate", "agent runs via cf-runagent" ); "mpf_admit_cf_runagent_shell_selected" -> { "ENT-6673", "ENT-6666" } handle => "mpf_admit_cf_runagent_shell_augments", if => isvariable("mpf_admit_cf_runagent_shell"), slist => { @(def.mpf_admit_cf_runagent_shell) }, meta => { "inventory", "attribute_name=Allowed hosts for cf-runagent", "derived-from=def.mpf_admit_cf_runagent_shell", }, comment => concat( "Users can override the default set of hosts that ", "can initiate agent runs via cf-runagent." ); # Executor Controls ## Default splaytime to 4 unless it's already defined (via augments) "control_executor_splaytime" string => "4", if => not(isvariable("control_executor_splaytime")), comment => "Splaytime controls the number of minutes hosts execution should be splayed over. This value should be less than the number of minutes between scheduled executions"; ## Default agent_expireafter to 120 unless it's already defined (via augments) "control_executor_agent_expireafter" -> { "ENT-4208" } string => "120", if => not(isvariable("control_executor_agent_expireafter")), comment => "This controls the number of minutes after no data has been recieved by cf-execd from a cf-agent process before that cf-agent process is killed."; ## Default schedule unless it's already defined (via augments) "control_executor_schedule_value" slist => { "Min00", "Min05", "Min10", "Min15", "Min20", "Min25", "Min30", "Min35", "Min40", "Min45", "Min50", "Min55", }, if => not(isvariable(control_executor_schedule)), comment => "This variable defines the list of classes that should trigger exec_command if any of them are defined."; # schedule cant use a data structure directly, so we must use an # intermediary variable to convert it to list "control_executor_schedule_value" slist => getvalues(control_executor_schedule), if => not(isvariable(control_executor_schedule_value)), comment => "This variable defines the list of classes that should trigger exec_command if any of them are defined."; # Users allowed on sockets # Set the users allowed by default, if not already set (e.g. via augments) "control_executor_runagent_socket_allow_users" slist => { "cfapache" }, unless => isvariable($(this.promiser)), if => and("enterprise_edition", "am_policy_hub"); # Agent Controls "control_agent_evaluation_order" -> { "ENT-13495" } string => ifelse( isvariable($(this.promiser)), "$(default:def.control_agent_evaluation_order)", "classic" ), comment => concat( 'We default to the classic "Normal Order"', ' for cf-agent if not otherwise specified' ); "control_agent_update_evaluation_order" -> { "ENT-13495" } string => ifelse( isvariable($(this.promiser)), "$(default:def.control_agent_update_evaluation_order)", "classic" ), comment => concat( 'We default to the classic "Normal Order"', ' for cf-agent when running update.cf if not otherwise specified' ); "control_agent_abortclasses" -> { "ENT-4823" } slist => {}, comment => "The control body has a variable, so a valid list must be defined or the agent will error", if => not(isvariable($(this.promiser))); "control_agent_agentfacility" -> { "ENT-10209" } string => "", if => not(isvariable($(this.promiser))); "control_agent_abortbundleclasses" -> { "ENT-4823" } slist => { "abortbundle" }, comment => "The control body has a variable, so a valid list must be defined or the agent will error", if => not(isvariable($(this.promiser))); "control_agent_default_repository" string => ifelse( isvariable("control_agent_default_repository"), $(control_agent_default_repository), "$(sys.workdir)/backups" ), if => "mpf_control_agent_default_repository"; "control_agent_maxconnections" int => "30", if => not(isvariable("control_agent_maxconnections")); # Common Controls # Because in some versions of cfengine bundlesequence in body common # control does not support iteration over data containers we must first # pick out the bundles into a shallow container that we can then get a # regular list from using getvalues(). "control_common_evaluation_order" -> { "ENT-13495" } string => ifelse( isvariable($(this.promiser)), "$(default:def.control_common_evaluation_order)", "classic" ), comment => concat( 'We default to the classic "Normal Order"', ' for all components if not otherwise specified.' ); "bundlesequence_end" -> { "CFE-4855" } slist => {}, if => not(isvariable("def.control_common_bundlesequence_end")), comment => concat( "We define an empty list so that the agent will not", " error about undefined variable when ", " def.bundlesequence_end is not defined." ); "bundlesequence_end" -> { "CFE-4855" } slist => getvalues(mergedata("def.control_common_bundlesequence_end")), comment => concat( "We define bundlesequence_end from Augments if it's", " available. This allows for customization without", " modifying the vendored policy." ); "bundlesequence_classification" -> { "CFE-4855" } slist => {}, if => not( isvariable("def.control_common_bundlesequence_classification") ), comment => concat( "We define an empty list so that the agent will not", " error about undefined variable when ", " def.bundlesequence_classification is not defined." ); "bundlesequence_classification" -> { "CFE-4855" } slist => getvalues( mergedata("def.control_common_bundlesequence_classification") ), comment => concat( "We define bundlesequence_classification from Augments if it's", " available. This allows for customization without", " modifying the vendored policy." ); "control_common_ignore_missing_bundles" -> { "CFE-2773" } string => ifelse( strcmp($(control_common_ignore_missing_bundles), "true"), "true", "false" ); "control_common_ignore_missing_inputs" -> { "CFE-2773" } string => ifelse( strcmp($(control_common_ignore_missing_inputs), "true"), "true", "false" ); "control_common_lastseenexpireafter" -> { "ENT-10414" } string => "10080", # 10080 minutes is 1 week if => not(isvariable("default:def.control_common_lastseenexpireafter")), comment => concat( "Since lastseenexpireafter is not defined, we default to", " the binary default of 10080 minutes (1 week)" ); # Agent controls "control_agent_default_directory_create_mode" -> { "CFE-4590" } string => ifelse( isvariable("control_agent_default_directory_create_mode"), "$(control_agent_default_directory_create_mode)", "700" ); @if minimum_version(3.18.0) # TODO When 3.18 is the oldest supported LTS, redact this macro and associated protections "control_agent_files_single_copy" -> { "CFE-3622" } slist => {}, if => not(isvariable("control_agent_files_single_copy")), comment => "Default files_single_copy to an empty list if it is not defined. It is expected that users can override the default by setting this value from the augments file (def.json)."; @endif "control_server_maxconnections" int => "200", if => not(isvariable("control_server_maxconnections")); #+begin_src def.control_agent_environment_vars # This configures environment_vars in body agent control # # It's configurable without having to modify policy, so the default values # are only applied if the variable is not already defined (via augments). # # Platform defaults are set first, and the global default is set last so # that global default does not override a platform specific setting since # the promises are only applied if the variable is not already defined # which is reverse of what you might normally do in CFEngine since # typically the last promise wins. classes: "disable_always_accept_policy_server_acl" -> { "ENT-10951" } expression => "disable_always_accept_policy_server"; "disable_always_accept_policy_server_allowconnects" -> { "ENT-10951" } expression => "disable_always_accept_policy_server"; "disable_always_accept_policy_server_allowallconnects" -> { "ENT-10951" } expression => "disable_always_accept_policy_server"; "control_agent_agentfacility_configured" -> { "ENT-10209" } expression => regcmp( "LOG_(USER|DAEMON|LOCAL[0-7])", $(control_agent_agentfacility) ), comment => concat( "If default:def.control_agent_agentfacility is a", " valid setting, we want to use it in body agent", " control for setting agentfacility" ); "_control_agent_environment_vars_validated" -> { "CFE-3927" } and => { # The variable must be defined isvariable("default:def.control_agent_environment_vars"), # The length of the variable must be greater than 0 (can't be an empty list) isgreaterthan(length("default:def.control_agent_environment_vars"), 0), # Each element of the list must be of the form KEY=VALUE every(".+=.+", "default:def.control_agent_environment_vars"), # In 3.18 and greater we can validate the type of variable in use @if minimum_version(3.18.0) regcmp( "(policy slist|data array)", type("default:def.control_agent_environment_vars", "true") ), @endif }; "control_executor_mailsubject_configured" -> { "ENT-10210" } expression => regcmp(".+", "$(control_executor_mailsubject)"), comment => concat( "If default:def.control_executor_mailsubject is not", " an empty string, we want to use it's value for", " emails sent by cf-execd." ); "control_executor_mailfilter_exclude_configured" -> { "ENT-10210" } expression => isgreaterthan( length("control_executor_mailfilter_exclude"), 0 ), comment => concat( "If default:def.control_executor_mailfilter_exclude is not", " an empty list, we want to use it's value for", " stripping lines from emails sent by cf-execd." ); "control_executor_mailfilter_include_configured" -> { "ENT-10210" } expression => isgreaterthan( length("control_executor_mailfilter_include"), 0 ), comment => concat( "If default:def.control_executor_mailfilter_include is not", " an empty list, we want to use it's value for", " including lines from emails sent by cf-execd." ); "control_server_allowciphers_defined" -> { "ENT-10182" } expression => isvariable("default:def.control_server_allowciphers"), comment => concat( "If default:def.control_server_allowciphers is defined then", " it's value will be used for allowciphers in body server", " control. Else the binary default will be used." ); "control_server_allowtlsversion_defined" -> { "ENT-10182" } expression => isvariable("default:def.control_server_allowtlsversion"), comment => concat( "If default:def.control_server_allowtlsversion is defined then", " it's value will be used for allowtlsversion in body server", " control. Else the binary default will be used." ); "control_common_system_log_level_defined" -> { "CFE-4452" } expression => isvariable("default:def.control_common_system_log_level"), comment => concat( "The minimum log level required for log messages to go to the", " system log (e.g. syslog or Windows Event Log).", " (critical|error|warning|notice|info)" ); "control_common_protocol_version_defined" -> { "CFE-4543" } expression => isvariable("default:def.control_common_protocol_version"), comment => concat( "Defines the protocol version to use for all outgoing", " connections.", # It's challenging to keep this aligned with the core agent code # cf-promises --syntax-description=json | jq -r '.bodyTypes.common.attributes.protocol_version.range' " (1|classic|2|tls|3|cookie|4|filestream|latest)" ); vars: debian:: "control_agent_environment_vars_default" -> { "CFE-3925" } handle => "common_def_vars_debian_control_agent_environment_vars_default", if => not(isvariable("control_agent_environment_vars_default")), comment => "Set default environment variables for using Debian non-interactively", slist => { "DEBIAN_FRONTEND=noninteractive", # "APT_LISTBUGS_FRONTEND=none", # "APT_LISTCHANGES_FRONTEND=none", }; any:: # Resolve the final state for environment vars if there is a default var # or if there is a user extra and merge the defined entities "control_agent_environment_vars" -> { "CFE-3925" } slist => { @(def.control_agent_environment_vars_default), @(def.control_agent_environment_vars_extra), }, policy => "ifdefined", if => or( isvariable("def.control_agent_environment_vars_default"), # Protect against defining isvariable("def.control_agent_environment_vars_extra") ); # an empty variable #+end_src Agent Environment Variables any:: "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_bin" string => translatepath("$(sys.bindir)"), comment => "Define binary path", handle => "common_def_vars_dir_bin"; "dir_data" string => ifelse( isvariable("def.dir_data"), $(def.dir_data), "$(sys.workdir)/data" ), comment => "Define data path", handle => "common_def_vars_dir_data"; "dir_modules" string => translatepath("$(sys.workdir)/modules"), comment => "Define modules path", handle => "common_def_vars_dir_modules"; # TODO: Remove after 3.15 is no longer supported (December 18th 2022) "dir_plugins" -> { "CFE-3618" } string => translatepath("$(sys.workdir)/plugins"), comment => "Define plugins path", handle => "common_def_vars_dir_plugins"; "dir_templates" string => ifelse( isvariable("def.dir_templates"), $(def.dir_templates), "$(sys.workdir)/templates" ), comment => "Define templates path", handle => "common_def_vars_dir_templates"; "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"; policy_server|am_policy_hub:: # Only hubs serve software updates "dir_master_software_updates" -> { "ENT-4953" } string => "$(sys.workdir)/master_software_updates", handle => "common_def_vars_dir_serve_master_software_updates", comment => "Path where software updates are served from the policy hub. This variable is overridable via augments as vars.dir_master_software_updates. All remote agents request this path via the master_software_updates shortcut.", if => not(isvariable("def.dir_master_software_updates")); enterprise_edition.(policy_server|am_policy_hub):: # Only enterprise hubs have Mission Portal "cfe_enterprise_mission_portal_apache_sslprotocol" -> { "ENT-10412" } string => "all -SSLv2 -SSLv3 -TLSv1", # We disable some versions of SSL # as they are known to be insecure if => not( isvariable( "default:def.cfe_enterprise_mission_portal_apache_sslprotocol" ) ), comment => "The SSL protocol versions that are allowed by Apache for Mission Portal"; "cfe_enterprise_mission_portal_apache_sslciphersuite" -> { "ENT-11393" } string => "HIGH", if => not( isvariable( "default:def.cfe_enterprise_mission_portal_apache_sslciphersuite" ) ), comment => "The SSL cipher suites that are allowed by Apache for Mission Portal"; 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:: "cf_runagent_shell" string => "${sys.winsysdir}${const.dirsep}cmd.exe", comment => "Define path to shell used by cf-runagent", handle => "common_def_vars_windows_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.uqhost).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", "$(sys.workdir)/state/promise_log.jsonl", "$(sys.workdir)/state/classes.jsonl", }; "hub_log_files" slist => { # Mission Portal: "$(cfe_internal_hub_vars.access_log)", "$(cfe_internal_hub_vars.error_log)", "$(cfe_internal_hub_vars.ssl_request_log)", # PostgreSQL: "/var/log/postgresql.log", }; "max_client_history_size" -> { "cf-hub", "CFEngine Enterprise" } int => "50M", unless => isvariable(max_client_history_size), comment => "The threshold of report diffs which will trigger purging of diff files."; 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) }; # Directories where logs are rotated and old files need to be purged: any:: "log_dir[outputs]" string => "$(sys.workdir)/outputs"; "log_dir[reports]" string => "$(sys.workdir)/reports"; # TODO ENT-6845 - move package module logs to $(sys.workdir)/log/something windows:: "log_dir[package_logs]" string => "$(const.dirsep)cfengine_package_logs"; enterprise.am_policy_hub:: "log_dir[mission_portal]" string => "$(sys.workdir)/httpd/logs"; "log_dir[application]" string => "$(sys.workdir)/httpd/logs/application"; any:: "cfe_log_dirs" slist => getvalues(log_dir); # MPF controls "mpf_log_dir_retention" string => "30", if => not(isvariable(mpf_log_dir_retention)), comment => "The default log file retention in cfe_log_dirs is 30 days unless it's already been defined (augments)."; "mpf_log_file_retention" string => "10", if => not(isvariable(mpf_log_file_retention)), comment => "This is the number of rotated versions of mpf log files to save"; "mpf_log_file_max_size" string => "1M", if => not(isvariable(mpf_log_file_max_size)), comment => "When individual mpf log files reach this size they should be rotated so that we don't fill up the disk"; "purge_scheduled_reports_older_than_days" -> { "ENT-4404" } string => "30", if => not(isvariable(purge_scheduled_reports_older_than_days)), comment => "This controls the maximum age of artifacts generated by the asynchronous query API and scheduled reports."; "mpf_extra_autorun_inputs" -> { "CFE-3524" } slist => {}, unless => isvariable($(this.promiser)); # Enterprise HA Related configuration # enable_cfengine_enterprise_hub_ha is defined below # Disabled by default enable_cfengine_enterprise_hub_ha:: "standby_servers" slist => filter("$(sys.policy_hub)", "ha_def.ips", false, true, 10); "policy_servers" slist => { "$(sys.policy_hub)", "@(standby_servers)" }; !enable_cfengine_enterprise_hub_ha:: "policy_servers" slist => { "$(sys.policy_hub)" }; enterprise_edition.policy_server:: "control_hub_exclude_hosts" slist => { "" }, unless => isvariable(control_hub_exclude_hosts); "control_hub_hub_schedule" comment => "By default Enterprise hubs initiate pull collection once every 5 minutes.", slist => { "Min00", "Min05", "Min10", "Min15", "Min20", "Min25", "Min30", "Min35", "Min40", "Min45", "Min50", "Min55", }, unless => isvariable(control_hub_hub_schedule); "control_hub_query_timeout" comment => "Configurable timeout for cf-hub outgoing connections", # 0 = default is set by cf-hub binary: string => "0", unless => isvariable(control_hub_query_timeout); "control_hub_port" comment => "cf-hub performs pull collection on port 5308, unless overridden by augments", string => "5308", unless => isvariable(control_hub_port); "control_hub_client_history_timeout" comment => "cf-hub instructs clients to discard reports older than this many hours to avoid a condition where a build up of reports causes a client to never be fully collected from", string => "6", unless => isvariable(control_hub_port); "mpf_access_rules_collect_calls_admit_ips" slist => { @(def.acl_derived) }, unless => isvariable(mpf_access_rules_collect_calls_admit_ips); enterprise_edition.client_initiated_reporting_enabled:: "control_server_call_collect_interval" string => "5", unless => isvariable(control_server_call_collect_interval); "control_server_collect_window" -> { "ENT-4102" } string => "30", unless => isvariable(control_server_collect_window); enterprise_edition.policy_server:: "default_data_select_host_monitoring_include" comment => "Most people have monitoring systems, so instead of collecting data people won't use we save the work unless its requested.", slist => {}, unless => isvariable(default_data_select_host_monitoring_include); "default_data_select_policy_hub_monitoring_include" comment => "Collect all the monitoring data from the hub itself. It can be useful in diagnostics.", slist => { ".*" }, unless => isvariable(default_data_select_policy_hub_monitoring_include); classes: "_have_control_agent_files_single_copy" -> { "CFE-3622" } expression => isvariable("def.control_agent_files_single_copy"); "_have_control_executor_runagent_socket_allow_users" expression => some( ".+", "def.control_executor_runagent_socket_allow_users" ); "cfengine_recommendations_enabled" expression => "!cfengine_recommendations_disabled"; ### 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" -> { "jira:CFE-2135" } comment => "This class enables the automatic parsing running of bundles tagged with 'autorun'. Evaluation limitations require that this class is set at the beginning of the agent run, so it must be defined in the augments file (def.json), or as an option to the agent with --define or -D. Changing the expression here will *NOT* work correctly. Setting the class here will result in an error due to the autorun bundle not being found.", expression => "!any"; # Internal CFEngine log files rotation "cfengine_internal_rotate_logs" expression => "any"; # Enable or disable agent email output (also see mailto, mailfrom and # smtpserver) "cfengine_internal_agent_email" expression => "any"; "cfengine_internal_disable_agent_email" expression => "!any"; # Enable or disable external watchdog to ensure cf-execd is running "cfe_internal_core_watchdog_enabled" expression => "!any"; "cfe_internal_core_watchdog_disabled" 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"; # Do not purge policies that don't exist on the server side. # you can also request it from the command line with # -Dcfengine_internal_purge_policies_disabled # NOTE THAT THIS CLASS ALSO NEEDS TO BE SET IN update.cf "cfengine_internal_purge_policies_disabled" expression => "!any"; # Preserve permissions of the policy server's masterfiles. # you can also request it from the command line with # -Dcfengine_internal_preserve_permissions # NOTE THAT THIS CLASS ALSO NEEDS TO BE SET IN update.cf "cfengine_internal_preserve_permissions" 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.!enable_cfengine_enterprise_hub_ha)|(policy_server.enterprise.enable_cfengine_enterprise_hub_ha.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"; # Run vacuum job on database # pre-defined to every night except Sunday when full cleanup is executed. "postgresql_vacuum" expression => "postgresql_maintenance_supported.!Sunday.Hr02.Min00_05"; # Enable CFEngine Enterprise HA Policy "enable_cfengine_enterprise_hub_ha" expression => "!any"; #"enable_cfengine_enterprise_hub_ha" expression => "enterprise_edition"; # Enable failover to node which is outside cluster #"failover_to_replication_node_enabled" expression => "enterprise_edition"; # Enable cleanup of agent report diffs when they exceed # `def.max_client_history_size` "enable_cfe_internal_cleanup_agent_reports" -> { "cf-hub", "CFEngine Enterprise" } expression => "enterprise_edition", comment => "If reports are not collected for an extended period of time the disk may fill up or cause additional collection issues."; # Enable paths to POSIX tools instead of native tools when possible. "mpf_stdlib_use_posix_utils" expression => "any"; enterprise_edition.(policy_server|am_policy_hub):: "cfe_enterprise_disable_http_redirect_to_https" scope => "namespace", expression => "cfe_cfengine_enterprise_enable_plain_http"; "cfe_enterprise_disable_http_redirect_to_https" expression => "cfe_enterprise_disable_plain_http", comment => "If plain http is disabled, it makes no sense to redirect to it, so we disable that as well."; reports: "Warning: the 'cfe_cfengine_enterprise_enable_plain_http' class has been deprecated in favor of 'cfe_enterprise_disable_http_redirect_to_https', please adjust accordingly. The 'cfe_enterprise_disable_http_redirect_to_https' class has been set automatically." if => "cfe_enterprise_disable_http_redirect_to_https.cfe_cfengine_enterprise_enable_plain_http"; "Warning: the 'cfe_cfengine_enterprise_enable_plain_http' class has been deprecated in favor of 'cfe_enterprise_disable_http_redirect_to_https', please adjust accordingly." if => "cfe_cfengine_enterprise_enable_plain_http.!cfe_enterprise_disable_http_redirect_to_https"; } bundle common inventory_control # @brief Inventory control bundle # # This common bundle is for controlling whether some inventory bundles # are disabled. { vars: "lldpctl_exec" string => ifelse( fileexists("/usr/sbin/lldpctl"), "/usr/sbin/lldpctl", fileexists("/usr/local/bin/lldpctl"), "/usr/local/bin/lldpctl", "/usr/sbin/lldpctl" ); "lldpctl_json" string => "$(lldpctl_exec) -f json", unless => isvariable("def.lldpctl_json"); "lldpctl_json" string => "$(def.lldpctl_json)", if => isvariable("def.lldpctl_json"); "lsb_exec" string => "/usr/bin/lsb_release"; "mtab" string => "/etc/mtab"; "proc" string => "/proc"; vars: freebsd:: "dmidecoder" string => "/usr/local/sbin/dmidecode"; !freebsd:: "dmidecoder" string => "/usr/sbin/dmidecode"; "proc_device_tree" string => "/proc/device-tree"; 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)); # If we have /proc/device-tree we should likely disable dmi completely # as of 2022 systems with dmi dont have device-tree and vice versa. "have_proc_device_tree" expression => fileexists($(proc_device_tree)); # 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" expression => "have_proc_device_tree"; "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|freebsd"; "disable_inventory_proc" not => isdir($(proc)); 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"; DEBUG|DEBUG_def:: "Executor Schedule: $(def.control_executor_schedule_value)"; } cfengine-masterfiles-3.27.3/controls/def_inputs.cf0000644000000000000000000000007614735102600020404 0ustar0000000000000000body file control { inputs => { @(def.augments_inputs) }; } cfengine-masterfiles-3.27.3/controls/reports.cf0000644000000000000000000000311414735102600017736 0ustar0000000000000000# Reporting bodies bundle server report_access_rules # @brief Access rules for Enterprise report collection { vars: enterprise:: "query_types" slist => { "delta", "rebase", "full" }; access: !policy_server.enterprise:: "$(query_types)" handle => "report_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 => "report_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 => { "127.0.0.1", "::1", @(def.policy_servers) }; } body report_data_select default_data_select_host # @brief Data authorized by non policy servers for collection by cf-hub { metatags_include => { "inventory", "report" }; metatags_exclude => { "noreport" }; promise_handle_exclude => { "noreport_.*" }; monitoring_include => { @(def.default_data_select_host_monitoring_include) }; } body report_data_select default_data_select_policy_hub # @brief Data authorized by policy servers for collection by cf-hub { metatags_include => { "inventory", "report" }; metatags_exclude => { "noreport" }; promise_handle_exclude => { "noreport_.*" }; monitoring_include => { @(def.default_data_select_policy_hub_monitoring_include) }; } cfengine-masterfiles-3.27.3/controls/update_def.cf0000644000000000000000000003074714735102600020354 0ustar0000000000000000bundle common update_def # @brief Main default settings for update policy { classes: any:: "sys_policy_hub_port_exists" expression => isvariable("sys.policy_hub_port"); "control_common_system_log_level_defined" -> { "CFE-4452" } expression => isvariable( "default:def.control_common_system_log_level" ), comment => concat( "The minimum log level required for log messages to go to the", " system log (e.g. syslog or Windows Event Log).", " (critical|error|warning|notice|info)" ); "control_common_protocol_version_defined" -> { "CFE-4543" } expression => isvariable( "default:def.control_common_protocol_version" ), comment => concat( "Defines the protocol version to use for all outgoing", " connections.", # It's challenging to keep this aligned with the core agent code # cf-promises --syntax-description=json | jq -r '.bodyTypes.common.attributes.protocol_version.range' " (1|classic|2|tls|3|cookie|4|filestream|latest)" ); vars: "hub_binary_version" -> { "ENT-10664" } data => data_regextract( "^(?\d+\.\d+\.\d+)-(?\d+)", readfile("$(sys.statedir)$(const.dirsep)hub_cf_version.txt" ) ), if => fileexists( "$(sys.statedir)$(const.dirsep)hub_cf_version.txt" ); "current_version" -> { "ENT-10664" } string => "$(hub_binary_version[major_minor_patch])"; "current_release" string => "$(hub_binary_version[release])"; # MPF Controls # Because in some versions of cfengine bundlesequence in body common # control does not support does not support iteration over data containers # we must first pick out the bundles into a shallow container that we can # then get a regular list from using getvalues(). "tbse" data => mergedata( "def.control_common_update_bundlesequence_end" ); # Since we have @(def.update_bundlesequence_end) in body common control # bundlesequence we must have a list variable defined. It can be empty, but it # must be defined. If it is not defined the agent will error complaining # that '@(def.bundlesequence_end) is not a defined bundle. # As noted in CFE-2460 getvalues behaviour varies between versions. 3.7.x # getvalues will return an empty list when run on a non existant data # container. On 3.9.1 it does not return an empty list. # So we initialize it as an empty list first to be safe. "bundlesequence_end" slist => {}; "bundlesequence_end" slist => getvalues( tbse ); "augments_inputs" slist => {}, if => not( isvariable( "def.update_inputs" ) ); "augments_inputs" slist => { @(def.update_inputs) }, if => isvariable( "def.update_inputs" ); # Default the input name patterns, if we don't find it defined in def # (from the augments_file). "input_name_patterns" -> { "CFE-3425" } slist => { ".*\.cf",".*\.dat",".*\.txt", ".*\.conf", ".*\.mustache", ".*\.sh", ".*\.pl", ".*\.py", ".*\.rb", ".*\.sed", ".*\.awk", "cf_promises_release_id", ".*\.json", ".*\.yaml", ".*\.csv", ".*\.ps1" }, comment => "Filename patterns to match when updating the policy (see update/update_policy.cf)", handle => "common_def_vars_input_name_patterns_policy_default", if => and(and(not(isvariable("override_data_acl")), not(isvariable("input_name_patterns"))), not(isvariable("def.input_name_patterns"))), meta => { "defvar" }; # define based on data in def (which comes from augments file), if # present and input_name_patterns is not yet defined.). "input_name_patterns" slist => { @(def.input_name_patterns) }, comment => "Filename patterns to match when updating the policy (see update/update_policy.cf)", handle => "common_def_vars_input_name_patterns", if => and( isvariable("def.input_name_patterns"), not(isvariable("input_name_patterns"))), meta => { "defvar" }; "input_name_patterns_extra" -> { "ENT-10480" } slist => {}, comment => "Additional filename patterns to copy during policy update.", if => not( isvariable( "input_name_patterns_extra" ) ); # the permissions for your masterfiles files (not dirs), which will propagate to inputs "masterfiles_perms_mode_not_dir" -> { "CFE-951" } string => "0600", handle => "common_def_vars_masterfiles_perms_mode_not_dir", meta => { "defvar" }; "masterfiles_perms_mode_dirs" -> { "CFE-951" } string => "0700", handle => "common_def_vars_masterfiles_perms_mode_dirs", meta => { "defvar" }; "dc_scripts" string => "$(sys.workdir)/httpd/htdocs/api/dc-scripts", comment => "Directory where VCS scripts are located on Enterprise Hub"; "DCWORKFLOW" string => "/opt/cfengine", comment => "Directory where VCS related data things is stored"; "local_masterfiles_git" string => "$(DCWORKFLOW)/masterfiles.git", comment => "Local bare git repository, serves as OOTB upstream repo"; "cf_git" string => "$(sys.workdir)/bin/git", comment => "Path to git binary installed with CFEngine Enterprise"; "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"; # Hubs get the explicit path because they perform local copies (especially # during bootstrap) when cf-serverd may not be available. Else we use the # "masterfiles" shortcut. "mpf_update_policy_master_location" -> { "ENT-3692" } string => ifelse( "am_policy_hub", "/var/cfengine/masterfiles", "masterfiles"); # Here we allow the masterfiles location to be overridden via augments. If # augments overides the value, use that. Note: Since hubs do not perform # copies to themselves over cf-serverd, this should be a fully qualified # path or special considerations must be made for hub bootstrapping. "mpf_update_policy_master_location" -> { "ENT-3692" } comment => "Directory where clients should get policy from.", string => "$(def.mpf_update_policy_master_location)", if => isvariable( "def.mpf_update_policy_master_location" ); # enable_cfengine_enterprise_hub_ha is defined below # Disabled by default # If we want to use the backup repository for update (because the class is # defined) and if the location is not already configured (via Augments), # set a default. "control_agent_default_repository" -> { "ENT-10481" } string => "$(sys.workdir)/backups", if => and( "mpf_update_control_agent_default_repository", not( isvariable( "control_agent_default_repository" ) ) ); "control_agent_default_directory_create_mode" -> { "CFE-4590" } string => ifelse( isvariable("control_agent_default_directory_create_mode"), "$(control_agent_default_directory_create_mode)", "700"); enable_cfengine_enterprise_hub_ha:: "standby_servers" slist => filter("$(sys.policy_hub)", "ha_def.ips", false, true, 10); "policy_servers" slist => { "$(sys.policy_hub)", "@(standby_servers)" }; !enable_cfengine_enterprise_hub_ha:: "policy_servers" slist => {"$(sys.policy_hub)"}; any:: "control_common_ignore_missing_bundles" -> { "CFE-2773" } string => ifelse( strcmp( $(control_common_ignore_missing_bundles), "true" ), "true", "false"); "control_common_ignore_missing_inputs" -> { "CFE-2773" } string => ifelse( strcmp( $(control_common_ignore_missing_inputs), "true" ), "true", "false"); "control_agent_agentfacility" -> { "ENT-10209" } string => "", if => not( isvariable ( "default:def.control_agent_agentfacility" )); classes: "control_agent_agentfacility_configured" -> { "ENT-10209" } expression => regcmp( "LOG_(USER|DAEMON|LOCAL[0-7])", $(control_agent_agentfacility) ), comment => concat( "If default:def.control_agent_agentfacility is a", " valid setting, we want to use it in body agent", " control for setting agentfacility" ); "control_common_tls_min_version_defined" -> { "ENT-10198" } expression => isvariable( "default:def.control_common_tls_min_version"), comment => concat( "If default:def.control_common_tls_min_version is defined then", " it's value will be used for the minimum version in outbound", " connections. Else the binary default will be used."); "control_common_tls_ciphers_defined" -> { "ENT-10198" } expression => isvariable( "default:def.control_common_tls_ciphers"), comment => concat( "If default:def.control_common_tls_ciphers is defined then", " it's value will be used for the set of tls ciphers allowed", " for outbound connections. Else the binary default will be used."); # Trigger binary upgrade from policy hub # Disable by default "trigger_upgrade" or => { "!any", }; # Update masterfiles from Git # Enabled for enterprise users by default # you can also request it from the command line with # -Dcfengine_internal_masterfiles_update # NOTE THAT ENABLING THIS BY DEFAULT *WILL* OVERWRITE THE HUB'S $(sys.workdir)/masterfiles #"cfengine_internal_masterfiles_update" expression => "enterprise.!(cfengine_3_4|cfengine_3_5)"; "cfengine_internal_masterfiles_update" 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 def.cf "cfengine_internal_encrypt_transfers" expression => "!any"; # Do not purge policies that don't exist on the server side. # you can also request it from the command line with # -Dcfengine_internal_purge_policies_disabled # NOTE THAT THIS CLASS ALSO NEEDS TO BE SET IN def.cf "cfengine_internal_purge_policies_disabled" expression => "!any"; # Preserve permissions of the policy server's masterfiles. # you can also request it from the command line with # -Dcfengine_internal_preserve_permissions # NOTE THAT THIS CLASS ALSO NEEDS TO BE SET IN def.cf "cfengine_internal_preserve_permissions" expression => "!any"; # Disable checking of cf_promises_validated before updating clients. # Disabling checking of cf_promises_validated ensures that remote agents # will **always** scan all of masterfiles for any changes and update # accordingly. This is not recommended as it both removes a safety # mechanism that checks for policy to be valid before allowing clients to # download updates, and the increased load on the hub will affect # scalability. Consider using time_based, select_class, or dist based classes # instead of any to retain some of the benefits. **DISABLE WITH CAUTION** "cfengine_internal_disable_cf_promises_validated" expression => "!any", comment => "When cf_promises_validated is disabled remote agents will always scan all of masterfiles for changes. Disabling this is not recommended as it will increase the load on the policy server and increases the possibility for remote agents to receive broken policy."; # Enable CFEngine Enterprise HA Policy "enable_cfengine_enterprise_hub_ha" expression => "!any"; #"enable_cfengine_enterprise_hub_ha" expression => "enterprise_edition"; # Enable failover to node which is outside cluster #"failover_to_replication_node_enabled" expression => "enterprise_edition"; } cfengine-masterfiles-3.27.3/controls/update_def.cf.in0000644000000000000000000003074214735102600020754 0ustar0000000000000000bundle common update_def # @brief Main default settings for update policy { classes: any:: "sys_policy_hub_port_exists" expression => isvariable("sys.policy_hub_port"); "control_common_system_log_level_defined" -> { "CFE-4452" } expression => isvariable( "default:def.control_common_system_log_level" ), comment => concat( "The minimum log level required for log messages to go to the", " system log (e.g. syslog or Windows Event Log).", " (critical|error|warning|notice|info)" ); "control_common_protocol_version_defined" -> { "CFE-4543" } expression => isvariable( "default:def.control_common_protocol_version" ), comment => concat( "Defines the protocol version to use for all outgoing", " connections.", # It's challenging to keep this aligned with the core agent code # cf-promises --syntax-description=json | jq -r '.bodyTypes.common.attributes.protocol_version.range' " (1|classic|2|tls|3|cookie|4|filestream|latest)" ); vars: "hub_binary_version" -> { "ENT-10664" } data => data_regextract( "^(?\d+\.\d+\.\d+)-(?\d+)", readfile("$(sys.statedir)$(const.dirsep)hub_cf_version.txt" ) ), if => fileexists( "$(sys.statedir)$(const.dirsep)hub_cf_version.txt" ); "current_version" -> { "ENT-10664" } string => "$(hub_binary_version[major_minor_patch])"; "current_release" string => "$(hub_binary_version[release])"; # MPF Controls # Because in some versions of cfengine bundlesequence in body common # control does not support does not support iteration over data containers # we must first pick out the bundles into a shallow container that we can # then get a regular list from using getvalues(). "tbse" data => mergedata( "def.control_common_update_bundlesequence_end" ); # Since we have @(def.update_bundlesequence_end) in body common control # bundlesequence we must have a list variable defined. It can be empty, but it # must be defined. If it is not defined the agent will error complaining # that '@(def.bundlesequence_end) is not a defined bundle. # As noted in CFE-2460 getvalues behaviour varies between versions. 3.7.x # getvalues will return an empty list when run on a non existant data # container. On 3.9.1 it does not return an empty list. # So we initialize it as an empty list first to be safe. "bundlesequence_end" slist => {}; "bundlesequence_end" slist => getvalues( tbse ); "augments_inputs" slist => {}, if => not( isvariable( "def.update_inputs" ) ); "augments_inputs" slist => { @(def.update_inputs) }, if => isvariable( "def.update_inputs" ); # Default the input name patterns, if we don't find it defined in def # (from the augments_file). "input_name_patterns" -> { "CFE-3425" } slist => { ".*\.cf",".*\.dat",".*\.txt", ".*\.conf", ".*\.mustache", ".*\.sh", ".*\.pl", ".*\.py", ".*\.rb", ".*\.sed", ".*\.awk", "cf_promises_release_id", ".*\.json", ".*\.yaml", ".*\.csv", ".*\.ps1" }, comment => "Filename patterns to match when updating the policy (see update/update_policy.cf)", handle => "common_def_vars_input_name_patterns_policy_default", if => and(and(not(isvariable("override_data_acl")), not(isvariable("input_name_patterns"))), not(isvariable("def.input_name_patterns"))), meta => { "defvar" }; # define based on data in def (which comes from augments file), if # present and input_name_patterns is not yet defined.). "input_name_patterns" slist => { @(def.input_name_patterns) }, comment => "Filename patterns to match when updating the policy (see update/update_policy.cf)", handle => "common_def_vars_input_name_patterns", if => and( isvariable("def.input_name_patterns"), not(isvariable("input_name_patterns"))), meta => { "defvar" }; "input_name_patterns_extra" -> { "ENT-10480" } slist => {}, comment => "Additional filename patterns to copy during policy update.", if => not( isvariable( "input_name_patterns_extra" ) ); # the permissions for your masterfiles files (not dirs), which will propagate to inputs "masterfiles_perms_mode_not_dir" -> { "CFE-951" } string => "0600", handle => "common_def_vars_masterfiles_perms_mode_not_dir", meta => { "defvar" }; "masterfiles_perms_mode_dirs" -> { "CFE-951" } string => "0700", handle => "common_def_vars_masterfiles_perms_mode_dirs", meta => { "defvar" }; "dc_scripts" string => "$(sys.workdir)/httpd/htdocs/api/dc-scripts", comment => "Directory where VCS scripts are located on Enterprise Hub"; "DCWORKFLOW" string => "/opt/cfengine", comment => "Directory where VCS related data things is stored"; "local_masterfiles_git" string => "$(DCWORKFLOW)/masterfiles.git", comment => "Local bare git repository, serves as OOTB upstream repo"; "cf_git" string => "$(sys.workdir)/bin/git", comment => "Path to git binary installed with CFEngine Enterprise"; "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"; # Hubs get the explicit path because they perform local copies (especially # during bootstrap) when cf-serverd may not be available. Else we use the # "masterfiles" shortcut. "mpf_update_policy_master_location" -> { "ENT-3692" } string => ifelse( "am_policy_hub", "@prefix@/masterfiles", "masterfiles"); # Here we allow the masterfiles location to be overridden via augments. If # augments overides the value, use that. Note: Since hubs do not perform # copies to themselves over cf-serverd, this should be a fully qualified # path or special considerations must be made for hub bootstrapping. "mpf_update_policy_master_location" -> { "ENT-3692" } comment => "Directory where clients should get policy from.", string => "$(def.mpf_update_policy_master_location)", if => isvariable( "def.mpf_update_policy_master_location" ); # enable_cfengine_enterprise_hub_ha is defined below # Disabled by default # If we want to use the backup repository for update (because the class is # defined) and if the location is not already configured (via Augments), # set a default. "control_agent_default_repository" -> { "ENT-10481" } string => "$(sys.workdir)/backups", if => and( "mpf_update_control_agent_default_repository", not( isvariable( "control_agent_default_repository" ) ) ); "control_agent_default_directory_create_mode" -> { "CFE-4590" } string => ifelse( isvariable("control_agent_default_directory_create_mode"), "$(control_agent_default_directory_create_mode)", "700"); enable_cfengine_enterprise_hub_ha:: "standby_servers" slist => filter("$(sys.policy_hub)", "ha_def.ips", false, true, 10); "policy_servers" slist => { "$(sys.policy_hub)", "@(standby_servers)" }; !enable_cfengine_enterprise_hub_ha:: "policy_servers" slist => {"$(sys.policy_hub)"}; any:: "control_common_ignore_missing_bundles" -> { "CFE-2773" } string => ifelse( strcmp( $(control_common_ignore_missing_bundles), "true" ), "true", "false"); "control_common_ignore_missing_inputs" -> { "CFE-2773" } string => ifelse( strcmp( $(control_common_ignore_missing_inputs), "true" ), "true", "false"); "control_agent_agentfacility" -> { "ENT-10209" } string => "", if => not( isvariable ( "default:def.control_agent_agentfacility" )); classes: "control_agent_agentfacility_configured" -> { "ENT-10209" } expression => regcmp( "LOG_(USER|DAEMON|LOCAL[0-7])", $(control_agent_agentfacility) ), comment => concat( "If default:def.control_agent_agentfacility is a", " valid setting, we want to use it in body agent", " control for setting agentfacility" ); "control_common_tls_min_version_defined" -> { "ENT-10198" } expression => isvariable( "default:def.control_common_tls_min_version"), comment => concat( "If default:def.control_common_tls_min_version is defined then", " it's value will be used for the minimum version in outbound", " connections. Else the binary default will be used."); "control_common_tls_ciphers_defined" -> { "ENT-10198" } expression => isvariable( "default:def.control_common_tls_ciphers"), comment => concat( "If default:def.control_common_tls_ciphers is defined then", " it's value will be used for the set of tls ciphers allowed", " for outbound connections. Else the binary default will be used."); # Trigger binary upgrade from policy hub # Disable by default "trigger_upgrade" or => { "!any", }; # Update masterfiles from Git # Enabled for enterprise users by default # you can also request it from the command line with # -Dcfengine_internal_masterfiles_update # NOTE THAT ENABLING THIS BY DEFAULT *WILL* OVERWRITE THE HUB'S $(sys.workdir)/masterfiles #"cfengine_internal_masterfiles_update" expression => "enterprise.!(cfengine_3_4|cfengine_3_5)"; "cfengine_internal_masterfiles_update" 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 def.cf "cfengine_internal_encrypt_transfers" expression => "!any"; # Do not purge policies that don't exist on the server side. # you can also request it from the command line with # -Dcfengine_internal_purge_policies_disabled # NOTE THAT THIS CLASS ALSO NEEDS TO BE SET IN def.cf "cfengine_internal_purge_policies_disabled" expression => "!any"; # Preserve permissions of the policy server's masterfiles. # you can also request it from the command line with # -Dcfengine_internal_preserve_permissions # NOTE THAT THIS CLASS ALSO NEEDS TO BE SET IN def.cf "cfengine_internal_preserve_permissions" expression => "!any"; # Disable checking of cf_promises_validated before updating clients. # Disabling checking of cf_promises_validated ensures that remote agents # will **always** scan all of masterfiles for any changes and update # accordingly. This is not recommended as it both removes a safety # mechanism that checks for policy to be valid before allowing clients to # download updates, and the increased load on the hub will affect # scalability. Consider using time_based, select_class, or dist based classes # instead of any to retain some of the benefits. **DISABLE WITH CAUTION** "cfengine_internal_disable_cf_promises_validated" expression => "!any", comment => "When cf_promises_validated is disabled remote agents will always scan all of masterfiles for changes. Disabling this is not recommended as it will increase the load on the policy server and increases the possibility for remote agents to receive broken policy."; # Enable CFEngine Enterprise HA Policy "enable_cfengine_enterprise_hub_ha" expression => "!any"; #"enable_cfengine_enterprise_hub_ha" expression => "enterprise_edition"; # Enable failover to node which is outside cluster #"failover_to_replication_node_enabled" expression => "enterprise_edition"; } cfengine-masterfiles-3.27.3/controls/update_def_inputs.cf0000644000000000000000000000115114735102600021741 0ustar0000000000000000bundle common u_cfengine_enterprise # @brief Inputs specific to CFEngine Enterprise { vars: enable_cfengine_enterprise_hub_ha:: "input[ha_update]" string => "cfe_internal/enterprise/ha/ha_update.cf"; "input[ha_def]" string => "cfe_internal/enterprise/ha/ha_def.cf"; "def" slist => { "ha_def", "ha_update" }; "inputs" slist => getvalues(input); !enable_cfengine_enterprise_hub_ha:: "inputs" slist => {}; "def" slist => { "$(this.bundle)" }; } body file control # @brief Include policy specific to CFEngine Enterprise { inputs => { @(u_cfengine_enterprise.inputs) }; } cfengine-masterfiles-3.27.3/install-sh0000755000000000000000000003546314735102600016103 0ustar0000000000000000#!/bin/sh # install - install a program, script, or datafile scriptversion=2014-09-12.12; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # 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 # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # 'make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. tab=' ' nl=' ' IFS=" $tab$nl" # Set DOITPROG to "echo" to test this script. doit=${DOITPROG-} doit_exec=${doit:-exec} # Put in absolute file names if you don't have them in your path; # or use environment vars. chgrpprog=${CHGRPPROG-chgrp} chmodprog=${CHMODPROG-chmod} chownprog=${CHOWNPROG-chown} cmpprog=${CMPPROG-cmp} cpprog=${CPPROG-cp} mkdirprog=${MKDIRPROG-mkdir} mvprog=${MVPROG-mv} rmprog=${RMPROG-rm} stripprog=${STRIPPROG-strip} posix_mkdir= # Desired mode of installed file. mode=0755 chgrpcmd= chmodcmd=$chmodprog chowncmd= mvcmd=$mvprog rmcmd="$rmprog -f" stripcmd= src= dst= dir_arg= dst_arg= copy_on_change=false is_target_a_directory=possibly usage="\ Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE or: $0 [OPTION]... SRCFILES... DIRECTORY or: $0 [OPTION]... -t DIRECTORY SRCFILES... or: $0 [OPTION]... -d DIRECTORIES... In the 1st form, copy SRCFILE to DSTFILE. In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. In the 4th, create DIRECTORIES. Options: --help display this help and exit. --version display version info and exit. -c (ignored) -C install only if different (preserve the last data modification time) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. -s $stripprog installed files. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG " while test $# -ne 0; do case $1 in -c) ;; -C) copy_on_change=true;; -d) dir_arg=true;; -g) chgrpcmd="$chgrpprog $2" shift;; --help) echo "$usage"; exit $?;; -m) mode=$2 case $mode in *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) echo "$0: invalid mode: $mode" >&2 exit 1;; esac shift;; -o) chowncmd="$chownprog $2" shift;; -s) stripcmd=$stripprog;; -t) is_target_a_directory=always dst_arg=$2 # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac shift;; -T) is_target_a_directory=never;; --version) echo "$0 $scriptversion"; exit $?;; --) shift break;; -*) echo "$0: invalid option: $1" >&2 exit 1;; *) break;; esac shift done # We allow the use of options -d and -T together, by making -d # take the precedence; this is for compatibility with GNU install. if test -n "$dir_arg"; then if test -n "$dst_arg"; then echo "$0: target directory not allowed when installing a directory." >&2 exit 1 fi fi if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. # Otherwise, the last argument is the destination. Remove it from $@. for arg do if test -n "$dst_arg"; then # $@ is not empty: it contains at least $arg. set fnord "$@" "$dst_arg" shift # fnord fi shift # arg dst_arg=$arg # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac done fi if test $# -eq 0; then if test -z "$dir_arg"; then echo "$0: no input file specified." >&2 exit 1 fi # It's OK to call 'install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi if test -z "$dir_arg"; then if test $# -gt 1 || test "$is_target_a_directory" = always; then if test ! -d "$dst_arg"; then echo "$0: $dst_arg: Is not a directory." >&2 exit 1 fi fi fi if test -z "$dir_arg"; then do_exit='(exit $ret); exit $ret' trap "ret=129; $do_exit" 1 trap "ret=130; $do_exit" 2 trap "ret=141; $do_exit" 13 trap "ret=143; $do_exit" 15 # Set umask so as not to create temps with too-generous modes. # However, 'strip' requires both read and write access to temps. case $mode in # Optimize common cases. *644) cp_umask=133;; *755) cp_umask=22;; *[0-7]) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw='% 200' fi cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; *) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw=,u+rw fi cp_umask=$mode$u_plus_rw;; esac fi for src do # Protect names problematic for 'test' and other utilities. case $src in -* | [=\(\)!]) src=./$src;; esac if test -n "$dir_arg"; then dst=$src dstdir=$dst test -d "$dstdir" dstdir_status=$? else # Waiting for this to be detected by the "$cpprog $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if test ! -f "$src" && test ! -d "$src"; then echo "$0: $src does not exist." >&2 exit 1 fi if test -z "$dst_arg"; then echo "$0: no destination specified." >&2 exit 1 fi dst=$dst_arg # If destination is a directory, append the input filename; won't work # if double slashes aren't ignored. if test -d "$dst"; then if test "$is_target_a_directory" = never; then echo "$0: $dst_arg: Is a directory" >&2 exit 1 fi dstdir=$dst dst=$dstdir/`basename "$src"` dstdir_status=0 else dstdir=`dirname "$dst"` test -d "$dstdir" dstdir_status=$? fi fi obsolete_mkdir_used=false if test $dstdir_status != 0; then case $posix_mkdir in '') # Create intermediate dirs using mode 755 as modified by the umask. # This is like FreeBSD 'install' as of 1997-10-28. umask=`umask` case $stripcmd.$umask in # Optimize common cases. *[2367][2367]) mkdir_umask=$umask;; .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; *[0-7]) mkdir_umask=`expr $umask + 22 \ - $umask % 100 % 40 + $umask % 20 \ - $umask % 10 % 4 + $umask % 2 `;; *) mkdir_umask=$umask,go-w;; esac # With -d, create the new directory with the user-specified mode. # Otherwise, rely on $mkdir_umask. if test -n "$dir_arg"; then mkdir_mode=-m$mode else mkdir_mode= fi posix_mkdir=false case $umask in *[123567][0-7][0-7]) # POSIX mkdir -p sets u+wx bits regardless of umask, which # is incompatible with FreeBSD 'install' when (umask & 300) != 0. ;; *) # $RANDOM is not portable (e.g. dash); use it when possible to # lower collision chance tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0 # As "mkdir -p" follows symlinks and we work in /tmp possibly; so # create the $tmpdir first (and fail if unsuccessful) to make sure # that nobody tries to guess the $tmpdir name. if (umask $mkdir_umask && $mkdirprog $mkdir_mode "$tmpdir" && exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 then if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or # other-writable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. test_tmpdir="$tmpdir/a" ls_ld_tmpdir=`ls -ld "$test_tmpdir"` case $ls_ld_tmpdir in d????-?r-*) different_mode=700;; d????-?--*) different_mode=755;; *) false;; esac && $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" } } then posix_mkdir=: fi rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" else # Remove any dirs left behind by ancient mkdir implementations. rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null fi trap '' 0;; esac;; esac if $posix_mkdir && ( umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" ) then : else # The umask is ridiculous, or mkdir does not conform to POSIX, # or it failed possibly due to a race condition. Create the # directory the slow way, step by step, checking for races as we go. case $dstdir in /*) prefix='/';; [-=\(\)!]*) prefix='./';; *) prefix='';; esac oIFS=$IFS IFS=/ set -f set fnord $dstdir shift set +f IFS=$oIFS prefixes= for d do test X"$d" = X && continue prefix=$prefix$d if test -d "$prefix"; then prefixes= else if $posix_mkdir; then (umask=$mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break # Don't fail if two instances are running concurrently. test -d "$prefix" || exit 1 else case $prefix in *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; *) qprefix=$prefix;; esac prefixes="$prefixes '$qprefix'" fi fi prefix=$prefix/ done if test -n "$prefixes"; then # Don't fail if two instances are running concurrently. (umask $mkdir_umask && eval "\$doit_exec \$mkdirprog $prefixes") || test -d "$dstdir" || exit 1 obsolete_mkdir_used=true fi fi fi if test -n "$dir_arg"; then { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 else # Make a couple of temp file names in the proper directory. dsttmp=$dstdir/_inst.$$_ rmtmp=$dstdir/_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 # Copy the file name to the temp name. (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && # and set any options; do chmod last to preserve setuid bits. # # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $cpprog $src $dsttmp" command. # { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && # If -C, don't bother to copy if it wouldn't change the file. if $copy_on_change && old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && set -f && set X $old && old=:$2:$4:$5:$6 && set X $new && new=:$2:$4:$5:$6 && set +f && test "$old" = "$new" && $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 then rm -f "$dsttmp" else # Rename the file to the real destination. $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || # The rename failed, perhaps because mv can't rename something else # to itself, or perhaps because mv is so ancient that it does not # support -f. { # Now remove or move aside any old file at destination location. # We try this two ways since rm can't unlink itself on some # systems and the destination file might be busy for other # reasons. In this case, the final cleanup might fail but the new # file should still install successfully. { test ! -f "$dst" || $doit $rmcmd -f "$dst" 2>/dev/null || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } } || { echo "$0: cannot unlink or rename $dst" >&2 (exit 1); exit 1 } } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dst" } fi || exit 1 trap '' 0 fi done # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: cfengine-masterfiles-3.27.3/PaxHeaders/inventory0000644000000000000000000000003615266337437016761 xustar0030 mtime=1792655135.245800218 cfengine-masterfiles-3.27.3/inventory/0000755000000000000000000000000015266337437016143 5ustar0000000000000000cfengine-masterfiles-3.27.3/inventory/README.md0000644000000000000000000002473714735102600017415 0ustar0000000000000000The CFEngine 3 inventory modules are pieces of CFEngine policy that are loaded and used by `promises.cf` 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. ## How It Works The inventory modules are called in `promises.cf`: ``` body common control { bundlesequence => { # Common bundle first (Best Practice) inventory_control, @(inventory.bundles), ... ``` As you see, this calls the `inventory_control` bundle, and then each bundle in the list `inventory.bundles`. That list is built in the top-level common `inventory` bundle, which will load the right things for some common cases. The `any.cf` inventory module is always loaded; the rest are loaded if they are appropriate for the platform. For instance, Debian systems will load `debian.cf` and `linux.cf` and `lsb.cf` but may load others as needed. The effect for users is that the right inventory modules will be loaded and evaluated. The `inventory_control` bundle lives in `def.cf` and defines what inventory modules should be disabled. You can simply set `disable_inventory` to avoid the whole system, or you can look for the `disable_inventory_xyz` class to disable module `xyz`. Any inventory module works the same way, by doing some discovery work and then tagging its classes and variables with the `report` or `inventory` tags. For example: ``` vars: "ports" slist => { @(mon.listening_ports) }, meta => { "inventory", "attribute_name=Ports listening" }; ``` This defines a reported attribute "Ports listening" which contains a list of strings representing the listening ports. More on this in a second. ## Your Very Own Inventory Module The good news is, writing an inventory module is incredibly easy. They are just CFEngine bundles. You can see a simple one that collects the listening ports in `any.cf`: ```cf3 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 => { @(mon.listening_ports) }, meta => { "inventory", "attribute_name=Ports listening" }; } ``` Well, the slist copy is a CFEngine detail (we get the listening ports from the monitoring daemon), so just assume that the data is correct. What's important is the second line that starts with [`meta`](https://docs.cfengine.com/docs/master/reference-promise-types.html#meta). That defines metadata for the promise that CFEngine will use to determine that this data is indeed inventory data and should be reported to the CFEngine Enterprise Hub. That's it. Really. The comments are optional but nice to have. You don't have to put your new bundle in a file under the `inventory` directory, either. The variables and classes can be declared anywhere as long as they have the right tags. So you can use the `services` directory or whatever else makes sense to you. # CFEngine Enterprise vs. Community In CFEngine Enterprise, the reported data is aggregated in the hub and reported across the whole host population. In CFEngine Community, users can use the `classesmatching()` and `variablesmatching()` functions to collect all the inventory variables and classes and report them in other ways. ## Implementation Best Practice for CFEngine Enterprise It is important that inventory variables and classes are continually defined. Only inventory variables and classes defined during the last reported run are available for use by the inventory reporting interface. Inventory items that change frequently can create a burden on the Enterprise reporting infrastructure. Generally, inventory attributes should change infrequently. If you wish to inventory attributes that frequently change or are expensive to discover consider implementing a sample interval and caching mechanism. # What Modules Are Available? As soon as you use the `promises.cf` provided in the parent directory, quite a few inventory modules will be enabled (if appropriate for your system). Here's the list of modules and what they provide. Note they are all enabled by code in `def.cf` as explained above. ## Package Inventory - lives in: `any.cf` - applies to: All systems - runs: package modules in order to report on packages installed and patches available - disable: define the class `disable_inventory_package_refresh`. Note this also disables the default package inventory used by the new packages promise implementation. This will cause the `packagesmatching()` and `packageupdatesmatching()` functions to rely on data supplied by the legacy package promise implementation. ## LSB - lives in: `lsb.cf` - applies to: LSB systems (most Linux distributions, basically) - runs: `lsb_release -a` - sample data: ``` Distributor ID: Ubuntu Description: Ubuntu 14.04 LTS Release: 14.04 Codename: trusty ``` - provides: - classes `lsb_$(os)`, `lsb_$(os)_$(release)`, `lsb_$(os)_$(codename)` - variables: `inventory_lsb.os` (Distributor ID), `inventory_lsb.codename`, `inventory_lsb.release`, `inventory_lsb.flavor`, `inventory_lsb.description` - sample output: ``` % cf-agent -KI -binventory_control,inventory_lsb R: inventory_lsb: OS = Ubuntu, codename = trusty, release = 14.04, flavor = Ubuntu_14_04, description = Ubuntu 14.04 LTS ``` ## SUSE - lives in: `suse.cf` - applies to: SUSE Linux - provides classes: `suse_pure` and `suse_derived` ## Debian - lives in: `debian.cf` - applies to: Debian and its derivatives - provides: - variables: `inventory_debian.mint_release` and `inventory_debian.mint_codename` - classes: `debian_pure`, `debian_derived`, `linuxmint`, `lmde`, `linuxmint_$(mint_release)`, `linuxmint_$(mint_codename)`, `$(mint_codename)` ## Red Hat - lives in: `redhat.cf` - applies to: Red Hat and its derivatives - provides classes: `redhat_pure`, `redhat_derived` ## Windows - lives in: `windows.cf` ## Mac OS X - lives in: `macos.cf` ## Generic (unknown OS) - lives in: `generic.cf` (see `any.cf` for generally applicable inventory modules) ## LLDP - lives in: `any.cf` - runs `inventory_control.lldpctl_exec` through a Perl filter - provides variables: `cfe_autorun_inventory_lldp.K` for each `K` returned by the LLDB executable ## mtab - lives in: `any.cf` - parses: `/etc/mtab` - provides classes: `have_mount_FSTYPE` and `have_mount_FSTYPE_MOUNTPOINT` - sample output (note this is verbose mode with `-v` because there's a lot of output): ``` % cf-agent -Kv -binventory_control,cfe_autorun_inventory_mtab|grep 'cfe_autorun_inventory_mtab: we have' R: cfe_autorun_inventory_mtab: we have a ext4 mount under / ... R: cfe_autorun_inventory_mtab: we have a cgroup mount under /sys/fs/cgroup/systemd R: cfe_autorun_inventory_mtab: we have a tmpfs mount under /run/shm ``` ## fstab - lives in: `any.cf` - parses: `sys.fstab` - provides classes: `have_fs_FSTYPE` `have_fs_MOUNTPOINT` and `have_fs_FSTYPE_MOUNTPOINT` - sample output (note this is verbose mode with `-v` because there's a LOT of output): ``` % cf-agent -Kv -binventory_control,cfe_autorun_inventory_fstab|grep 'cfe_autorun_inventory_fstab: we have' R: cfe_autorun_inventory_fstab: we have a ext4 fstab entry under / R: cfe_autorun_inventory_fstab: we have a cifs fstab entry under /backups/load R: cfe_autorun_inventory_fstab: we have a auto fstab entry under /mnt/cdrom ``` ## DMI decoding - lives in: `any.cf` - runs: `dmidecode` - provides variables: `cfe_autorun_inventory_dmidecode.dmi[K]` for each key K in the `dmidecode` output - sample output (sudo is needed to access the DMI): ``` % sudo /var/cfengine/bin/cf-agent -KI -binventory_control,cfe_autorun_inventory_dmidecode R: cfe_autorun_inventory_dmidecode: Obtained BIOS vendor = 'Intel Corp.' R: cfe_autorun_inventory_dmidecode: Obtained BIOS version = 'BLH6710H.86A.0146.2013.1555.1888' R: cfe_autorun_inventory_dmidecode: Obtained System serial number = '' R: cfe_autorun_inventory_dmidecode: Obtained System manufacturer = '' R: cfe_autorun_inventory_dmidecode: Obtained System version = '' R: cfe_autorun_inventory_dmidecode: Obtained CPU model = 'Intel(R) Core(TM) i7-2600 CPU @ 3.40GHz' ``` ## Listening ports - lives in: `any.cf` - provides variables: `cfe_autorun_inventory_listening_ports.ports` as a copy of `mon.listening_ports` ## Disk space - lives in: `any.cf` - provides variables: `cfe_autorun_inventory_disk.free` as a copy of `mon.value_diskfree` ## Available memory - lives in: `any.cf` - provides variables: `cfe_autorun_inventory_memory.free` as a copy of `mon.value_mem_free` and `cfe_autorun_inventory_memory.total` as a copy of `mon.value_mem_total` ## Load average - lives in: `any.cf` - provides variables: `cfe_autorun_inventory_loadaverage.value` as a copy of `mon.value_loadavg` ## procfs - lives in: `any.cf` - parses: `consoles`, `cpuinfo`, `modules`, `partitions`, `version` - provides variables: `cfe_autorun_inventory_proc.console_count`, `cfe_autorun_inventory_proc.cpuinfo[K]` for each CPU info key, `cfe_autorun_inventory_proc.paritions[K]` for each partition key - provides classes: `_have_console_CONSOLENAME`, `have_module_MODULENAME` - sample output (note this is verbose mode with `-v` because there's a LOT of output): ``` % cf-agent -Kv -binventory_control,cfe_autorun_inventory_proc|grep 'cfe_autorun_inventory_proc: we have' R: cfe_autorun_inventory_proc: we have console tty0 R: cfe_autorun_inventory_proc: we have module snd_seq_midi ... R: cfe_autorun_inventory_proc: we have module ghash_clmulni_intel R: cfe_autorun_inventory_proc: we have cpuinfo flags = fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx lahf_lm ida arat epb xsaveopt pln pts dtherm tpr_shadow vnmi flexpriority ept vpid ... R: cfe_autorun_inventory_proc: we have cpuinfo model name = Intel(R) Core(TM) i7-2600 CPU @ 3.40GHz R: cfe_autorun_inventory_proc: we have partitions sr0 with 1048575 blocks ... R: cfe_autorun_inventory_proc: we have partitions sda with 468851544 blocks R: cfe_autorun_inventory_proc: we have kernel version 'Linux version 3.11.0-15-generic (buildd@roseapple) (gcc version 4.8.1 (Ubuntu/Linaro 4.8.1-10ubuntu8) ) #25-Ubuntu SMP Thu Jan 30 17:22:01 UTC 2014' ``` cfengine-masterfiles-3.27.3/inventory/aix.cf0000644000000000000000000000424014735102600017214 0ustar0000000000000000bundle agent inventory_aix # @brief Red Hat inventory bundle # # This agent bundle is for AIX inventory work. { methods: "oslevel" usebundle => inventory_aix_oslevel; } bundle agent inventory_aix_oslevel # @brief Inventory oslevel # @description This policy inventories oslevel on aix. It caches the information # for up to 1 day before re-discovering. { vars: "oslevel" string => ifelse( isvariable("paths.oslevel"), $(paths.oslevel), "/usr/bin/oslevel" ); commands: aix:: "$(oslevel)" handle => "cache_aix_oslevel_s", args => "-s > $(sys.statedir)/aix-oslevel-s", if => not(fileexists("$(sys.statedir)/aix-oslevel-s")), contain => in_shell, comment => "We cache the highest service pack reached to avoid unnecessary command executions."; "$(oslevel)" handle => "cache_aix_oslevel_r", args => "-r > $(sys.statedir)/aix-oslevel-r", if => not(fileexists("$(sys.statedir)/aix-oslevel-r")), contain => in_shell, comment => "We cache the highest technology level reached to avoid unnecessary command executions."; files: aix:: "$(sys.statedir)/aix-oslevel-r" handle => "cache_expire_aix_oslevel_r", delete => tidy, file_select => days_old(1), comment => "We regularly clear the cache to avoid stale data"; "$(sys.statedir)/aix-oslevel-s" handle => "cache_expire_aix_oslevel_s", delete => tidy, file_select => days_old(1), comment => "We regularly clear the cache to avoid stale data"; vars: aix:: "oslevel_s" string => readfile("$(sys.statedir)/aix-oslevel-s", 1K), if => fileexists("$(sys.statedir)/aix-oslevel-s"), meta => { "inventory", "attribute_name=Highest Service Pack" }; "oslevel_r" string => readfile("$(sys.statedir)/aix-oslevel-r", 1K), if => fileexists("$(sys.statedir)/aix-oslevel-r"), meta => { "inventory", "attribute_name=Highest Technology Level" }; reports: DEBUG:: "Highest Service Pack: $(oslevel_s)"; "Highest Technology Level: $(oslevel_r)"; } cfengine-masterfiles-3.27.3/inventory/any.cf0000644000000000000000000014562214735102600017234 0ustar0000000000000000bundle common inventory_any # @brief Do inventory for any OS # # This common bundle is for any OS work not handled by specific # bundles. { vars: "release_data" string => "$(this.promise_dirname)/../cf_promises_release_id"; "data" data => readjson($(release_data), inf), if => fileexists($(release_data)); "id" string => "$(data[releaseId])", meta => { "inventory", "attribute_name=Policy Release Id" }; "policy_version" -> { "ENT-9806" } string => "$(default:control_common.version)", meta => { "inventory", "attribute_name=CFEngine policy version" }, if => not(isvariable("sys.policy_version")), comment => concat( "Don't inventory the policy version from policy when it's available", " as a sys var to avoid duplicate values being inventoried." ); reports: "DEBUG|DEBUG_$(this.bundle)":: "DEBUG $(this.bundle): Inventory Policy Release Id=$(id)"; } 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_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_policy_servers:: "Inventory Policy Servers" handle => "cfe_internal_autorun_inventory_policy_servers", usebundle => cfe_autorun_inventory_policy_servers; !disable_inventory_proc:: "proc" usebundle => cfe_autorun_inventory_proc(), handle => "cfe_internal_autorun_inventory_proc"; "proc_cpuinfo" usebundle => cfe_autorun_inventory_proc_cpuinfo(), handle => "cfe_internal_autorun_inventory_proc_cpuinfo"; !disable_inventory_cpuinfo:: "cpuinfo" usebundle => cfe_autorun_inventory_cpuinfo(), handle => "cfe_internal_autorun_inventory_cpuinfo"; !disable_inventory_fstab:: "fstab" usebundle => cfe_autorun_inventory_fstab(), handle => "cfe_internal_autorun_inventory_fstab"; !disable_inventory_mtab:: "mtab" -> { "ENT-8338" } usebundle => cfe_autorun_inventory_mtab(), handle => "cfe_internal_autorun_inventory_mtab", action => default:immediate; !disable_inventory_dmidecode:: "dmidecode" usebundle => cfe_autorun_inventory_dmidecode(), handle => "cfe_internal_autorun_inventory_dmidecode"; !disable_inventory_aws:: "aws" usebundle => cfe_autorun_inventory_aws(), handle => "cfe_internal_autorun_inventory_aws"; !disable_inventory_aws|disable_inventory_aws_ec2_metadata:: "aws" usebundle => cfe_autorun_inventory_aws_ec2_metadata(), handle => "cfe_internal_autorun_inventory_ec2_metadata"; !disable_inventory_setuid:: "Inventory SetUID Files" -> { "ENT-4158" } usebundle => cfe_autorun_inventory_setuid(), handle => "cfe_internal_autorun_inventory_setuid"; 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"; "IP addresses" -> { "ENT-2552", "ENT-4987" } usebundle => cfe_autorun_inventory_ip_addresses, handle => "cfe_internal_autorun_ip_addresses"; } 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" -> { "ENT-150" } slist => sort("mon.listening_ports", "int"), meta => { "inventory", "attribute_name=Ports listening" }, if => some("[0-9]+", "mon.listening_ports"), comment => "We only want to inventory the listening ports if we have values that make sense."; } bundle agent cfe_autorun_inventory_ip_addresses # @brief Inventory ipv4 addresses # This will filter the ipv4 and ipv4 loopback address (127.0.0.1, ::as it is likely not very interesting) { vars: "ipv4_regex" -> { "ENT-4987" } string => "\b(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\b"; "ipv4_loopback_regex" -> { "ENT-2552" } string => "127\.0\.0\.1", comment => "Addresses that match this regular expression will be filtered from the inventory for ipv4 addresses"; "ipv6_loopback_regex" -> { "ENT-4987" } string => "::1", comment => "Addresses that match this regular expression will be filtered from the inventory for ipv4 addresses"; # Strings are displayed more beautifully in Mission Portal than lists, so # we first generate the list of addresses to be inventoried and then do # inventory using an array. "ipv4_addresses" slist => sort( filter($(ipv4_regex), "sys.ip_addresses", "true", "false", inf), lex ), if => not(isvariable($(this.promiser))); "ipv4_addresses_non_loopback" -> { "ENT-2552" } slist => sort( filter( $(ipv4_loopback_regex), "$(this.bundle).ipv4_addresses", "true", "true", inf ) ), if => not(isvariable($(this.promiser))); "ipv4[$(ipv4_addresses_non_loopback)]" -> { "ENT-2552" } string => "$(ipv4_addresses_non_loopback)", meta => { "inventory", "attribute_name=IPv4 addresses" }; # sys.ip_addresses contains ipv4 and (as of 3.15.0) ipv6 addresses. We get # the ipv6 addresses indirectly, based on excluding the ipv4 addresses # (which we identify using a regular expression) "ipv6_addresses" -> { "ENT-4987" } slist => sort( difference("sys.ip_addresses", "$(this.bundle).ipv4_addresses"), lex ), if => not(isvariable($(this.promiser))); "ipv4_addresses_non_loopback" -> { "ENT-4987" } slist => sort( filter( $(ipv6_loopback_regex), "$(this.bundle).ipv4_addresses", "true", "true", inf ) ), if => not(isvariable($(this.promiser))); "ipv6[$(ipv6_addresses_non_loopback)]" -> { "ENT-4987" } string => "$(ipv6_addresses_non_loopback)", meta => { "inventory", "attribute_name=IPv6 addresses" }; reports: DEBUG|DEBUG_cfe_autorun_inventory_ipv4_addresses:: "DEBUG $(this.bundle)"; "$(const.t)Inventorying: '$(ipv4_addresses)'"; "$(const.t)Inventorying: '$(ipv6_addresses)'"; } bundle agent cfe_autorun_inventory_disk # @brief Inventory the disk (Enterprise only) { vars: enterprise:: "free" -> { "ENT-5190" } string => "$(mon.value_diskfree)", meta => { "inventory", "attribute_name=Disk free (%)" }, if => isvariable("mon.value_diskfree"); } bundle agent cfe_autorun_inventory_memory # @brief Inventory the memory (Enterprise only) { vars: @if minimum_version(3.11) # The `with` attribute is necessary for this to work in a single promise. enterprise_edition.windows:: # wmic returns "TotalVisibleMemorySize=10760224" so split on = and take # the second item (0-based with nth()) "total" -> { "ENT-4188" } meta => { "inventory", "attribute_name=Memory size (MB)" }, string => format("%d", eval("$(with)/1024", "math", "infix")), if => not(isvariable("total")), with => nth( string_split( execresult( "wmic OS get TotalVisibleMemorySize /format:list", useshell ), "=", 2 ), 1 ); "totalPhysical" -> { "CFE-2896" } meta => { "inventory", "attribute_name=Physical memory (MB)" }, string => format("%d", eval("$(with)/1024", "math", "infix")), if => not(isvariable("total")), with => nth( string_split( execresult( "wmic ComputerSystem get TotalPhysicalMemory /format:list", useshell ), "=", 2 ), 1 ); # This is a volatile metric, perhaps not well suited for inventory "free" meta => { "report" }, string => format("%d", eval("$(with)/1024", "math", "infix")), if => not(isvariable("free")), with => nth( string_split( execresult( "wmic OS get FreePhysicalMemory /format:list", useshell ), "=", 2 ), 1 ); @endif enterprise_edition.aix:: "total" -> { "CFE-2797", "CFE-2803" } string => execresult( "/usr/bin/lparstat -i | awk '/Online Memory/ { print $4 }'", "useshell" ), meta => { "inventory", "attribute_name=Memory size (MB)" }; enterprise_edition.hpux:: "total" -> { "ENT-4188" } string => execresult( "machinfo | awk '/^Memory =/ {print $3}'", useshell ), meta => { "inventory", "attribute_name=Memory size (MB)" }; enterprise_edition.!(aix|windows|hpux):: "total" string => "$(mon.value_mem_total)", meta => { "inventory", "attribute_name=Memory size (MB)" }, if => isvariable("mon.value_mem_total"); "free" string => "$(mon.value_mem_free)", if => and(not(isvariable("free")), isvariable("mon.value_mem_free")), meta => { "report" }; } bundle agent cfe_autorun_inventory_setuid # @brief Inventory setuid files and prune invalid entries from the setuid log # @inventory Setuid files # @inventory Root owned setuid files # @inventory Setgid files # @inventory Root owned setgid files { vars: !disable_inventory_setuid:: "candidates" slist => lsdir("$(sys.workdir)", "cfagent\..*\.log", true); "_reg_setuid_filestat_modeoct" string => "10(4|5|6|7)\d+"; "_reg_setgid_filestat_modeoct" string => "10(2|3|6|7)\d+"; "setuid_log_path" comment => "We select the file that matches the downcased version of the hostname since sys.fqhost always returns lower case", string => "$(candidates)", if => strcmp( "$(sys.workdir)/cfagent.$(sys.fqhost).log", string_downcase($(candidates)) ); "files" slist => readstringlist($(setuid_log_path), "", "$(const.n)", inf, inf); "setuid[$(files)]" string => "$(files)", meta => { "inventory", "attribute_name=Setuid files" }, if => regcmp( $(_reg_setuid_filestat_modeoct), filestat($(files), modeoct) ); "rootsetuid[$(files)]" string => "$(files)", meta => { "inventory", "attribute_name=Root owned setuid files" }, if => and( regcmp($(_reg_setuid_filestat_modeoct), filestat($(files), modeoct)), regcmp("0", filestat($(files), uid)) ); "setgid[$(files)]" -> { "ENT-6793" } string => "$(files)", meta => { "inventory", "attribute_name=Setgid files" }, if => regcmp( $(_reg_setuid_filestat_modeoct), filestat($(files), modeoct) ); "rootsetgid[$(files)]" -> { "ENT-6793" } string => "$(files)", meta => { "inventory", "attribute_name=Root owned setgid files" }, if => and( regcmp($(_reg_setuid_filestat_modeoct), filestat($(files), modeoct)), regcmp("0", filestat($(files), gid)) ); files: !disable_inventory_setuid:: "$(setuid_log_path)" comment => concat( "If the logged file is not currently setuid|setgid then we can", "safely purge it from the list to avoid unnecessary work." ), edit_line => delete_lines_matching(escape($(files))), if => not( regcmp( "($(_reg_setuid_filestat_modeoct))|($(_reg_setgid_filestat_modeoct))", filestat($(files), modeoct) ) ); reports: !disable_inventory_setuid.(DEBUG|DEBUG_cfe_autorun_inventory_setuid):: "$(setuid_log_path) present" if => fileexists($(setuid_log_path)); @if minimum_version(3.11) "Previously logged (setuid|setgid) file: $(files) modeoct=$(with)" with => filestat($(files), modeoct); "Should remove '$(files)' from '$(setuid_log_path)' because `filestat ($(files), modeoct )` returns '$(with)' which does not match '($(_reg_setuid_filestat_modeoct))|($(_reg_setgid_filestat_modeoct))' (setgid|setuid)" comment => concat( "If the logged file is not currently set(uid&|gid) then we can", "safely purge it from the list to avoid unnecessary work." ), with => filestat($(files), modeoct), if => not( regcmp( "($(_reg_setuid_filestat_modeoct))|($(_reg_setgid_filestat_modeoct))", filestat($(files), modeoct) ) ); # The `with` attribute was introduced in 3.11 "Inventory: setuid Files: $(files) modeoct=$(with)" with => filestat($(files), modeoct), if => regcmp( $(_reg_setuid_filestat_modeoct), filestat($(files), modeoct) ); "Inventory: root owned setuid Files: $(files) modeoct=$(with)" with => filestat($(files), modeoct), if => and( regcmp($(_reg_setuid_filestat_modeoct), filestat($(files), modeoct)), regcmp("0", filestat($(files), uid)) ); @endif } bundle agent cfe_autorun_inventory_timezone # @brief Inventory timezone and GMT offset { vars: "_now" int => now(); "timezone" -> { "ENT-6161" } string => strftime(localtime, "%Z", $(_now)), meta => { "inventory", "attribute_name=Timezone" }; "gmt_offset" -> { "ENT-6161" } string => strftime(localtime, "%z", $(_now)), meta => { "inventory", "attribute_name=Timezone GMT Offset" }; } bundle agent cfe_autorun_inventory_loadaverage # @brief Inventory the loadaverage (Enterprise only) { vars: enterprise:: "value" -> { "ENT-5190" } string => "$(mon.value_loadavg)", meta => { "report" }, if => isvariable("mon.value_loadavg"); } 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: # To override this set of base files, define default:cfe_autorun_inventory_proc.basefiles via augments. # { # "variables": { # "default:cfe_autorun_inventory_proc.basefiles" : { # "value": [ "consoles", "cpuinfo", "version" ], # "comment": "We do not need the extra variables this produces since we get the info differently", # "tags": [ "inventory", "attribute_name=My Inventory" ] # } # } # } "basefiles" -> { "CFE-4056" } slist => { "consoles", "cpuinfo", "modules", "partitions", "version" }, unless => isvariable("$(this.namespace):$(this.bundle).basefiles"); "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_proc_cpuinfo # @brief Inventory cpu information from proc { classes: "_have_cpuinfo" expression => isvariable( "default:cfe_autorun_inventory_proc.cpuinfo_idx" ); # So that we don't inventory non dereferenced variables we check to see # if we have the info first This is only necessary because its currently # invalid to do isvariable on an array key that contains a space # Ref: redmine#7088 https://dev.cfengine.com/issues/7088 "have_cpuinfo_cpu_cores" expression => strcmp( "cpu cores", "$(default:cfe_autorun_inventory_proc.cpuinfo_array[$(default:cfe_autorun_inventory_proc.cpuinfo_idx)][0])" ); "have_cpuinfo_model_name" expression => strcmp( "model name", "$(default:cfe_autorun_inventory_proc.cpuinfo_array[$(default:cfe_autorun_inventory_proc.cpuinfo_idx)][0])" ); "have_cpuinfo_hardware" expression => strcmp( "Hardware", "$(default:cfe_autorun_inventory_proc.cpuinfo_array[$(default:cfe_autorun_inventory_proc.cpuinfo_idx)][0])" ); "have_cpuinfo_revision" expression => strcmp( "Revision", "$(default:cfe_autorun_inventory_proc.cpuinfo_array[$(default:cfe_autorun_inventory_proc.cpuinfo_idx)][0])" ); vars: _have_cpuinfo:: "cpuinfo_physical_cores" string => "$(default:cfe_autorun_inventory_proc.cpuinfo[cpu cores])", if => "have_cpuinfo_cpu_cores"; "cpuinfo_cpu_model_name" string => "$(default:cfe_autorun_inventory_proc.cpuinfo[model name])", if => "have_cpuinfo_model_name"; "cpuinfo_hardware" string => "$(default:cfe_autorun_inventory_proc.cpuinfo[Hardware])", if => "have_cpuinfo_hardware"; "cpuinfo_revision" string => "$(default:cfe_autorun_inventory_proc.cpuinfo[Revision])", if => "have_cpuinfo_revision"; # We need to be able to count the number of unique physical id lines in # /proc/cpu in order to get a physical processor count. "cpuinfo_lines" slist => readstringlist( "$(default:cfe_autorun_inventory_proc.files[cpuinfo])", "\s*#[^\n]*", "\n", 500, 50000 ); "cpuinfo_processor_lines" slist => grep("processor\s+:\s\d+", "cpuinfo_lines"), comment => "The number of processor entries in $(default:cfe_autorun_inventory_proc.files[cpuinfo]). If no 'physical id' entries are found this is the processor count"; "cpuinfo_processor_lines_count" int => length("cpuinfo_processor_lines"); "cpuinfo_physical_id_lines" slist => grep("physical id.*", "cpuinfo_lines"), comment => "This identifies which physical socket a logical core is on, the count of the unique physical id lines tells you how many physical sockets you have. THis would not be present on systems that are not multicore."; "cpuinfo_physical_id_lines_unique" slist => unique("cpuinfo_physical_id_lines"); "cpuinfo_physical_id_lines_unique_count" int => length("cpuinfo_physical_id_lines_unique"); # If we have physical id lines in cpu info use that for socket inventory, # else we should use the number of processor lines. physical id lines # seem to only be present when multiple cores are active. "cpuinfo_physical_socket_inventory" string => ifelse( isgreaterthan(length("cpuinfo_physical_id_lines"), 0), "$(cpuinfo_physical_id_lines_unique_count)", "$(cpuinfo_processor_lines_count)" ), meta => { "inventory", "attribute_name=CPU sockets" }; reports: DEBUG|DEBUG_cfe_autorun_inventory_proc:: "DEBUG $(this.bundle)"; "$(const.t)cpuinfo[$(default:cfe_autorun_inventory_proc.cpuinfo_array[$(default:cfe_autorun_inventory_proc.cpuinfo_idx)][0])] = $(default:cfe_autorun_inventory_proc.cpuinfo[$(default:cfe_autorun_inventory_proc.cpuinfo_array[$(default:cfe_autorun_inventory_proc.cpuinfo_idx)][0])])"; "$(const.t)CPU physical cores: '$(cpuinfo_physical_cores)'" if => "have_cpuinfo_cpu_cores"; "$(const.t)CPU model name: '$(cpuinfo_cpu_model_name)'" if => "have_cpuinfo_model_name"; "$(const.t)CPU Physical Sockets: '$(cpuinfo_physical_socket_inventory)'"; } bundle agent cfe_autorun_inventory_cpuinfo # @brief Inventory cpu information { classes: "_have_proc_cpu_model_name" expression => isvariable( "default:cfe_autorun_inventory_proc_cpuinfo.cpuinfo_cpu_model_name" ); "_have_proc_hardware" expression => isvariable( "default:cfe_autorun_inventory_proc_cpuinfo.cpuinfo_hardware" ); "_have_proc_revision" expression => isvariable( "default:cfe_autorun_inventory_proc_cpuinfo.cpuinfo_revision" ); "_have_proc_cpu_physical_cores" expression => isvariable( "default:cfe_autorun_inventory_proc_cpuinfo.cpuinfo_physical_cores" ); # We only accept dmidecode values that don't look like cfengine variables, # (starting with dollar), or that have an apparent empty value. "_have_dmidecode_cpu_model_name" not => regcmp( "($(const.dollar)\(.*\)|^$)", "$(default:cfe_autorun_inventory_dmidecode.dmi[processor-version])" ); vars: _have_proc_cpu_physical_cores:: "cpuinfo_physical_cores" string => "$(default:cfe_autorun_inventory_proc.cpuinfo[cpu cores])", #if => "have_cpuinfo_cpu_cores", meta => { "inventory", "attribute_name=CPU physical cores", "derived-from=$(default:cfe_autorun_inventory_proc.files[cpuinfo])", }; _have_proc_cpu_model_name:: "cpu_model" string => "$(default:cfe_autorun_inventory_proc_cpuinfo.cpuinfo_cpu_model_name)", meta => { "inventory", "attribute_name=CPU model", "derived-from=$(default:cfe_autorun_inventory_proc.files[cpuinfo])", }; _have_proc_hardware:: "cpu_model" string => "$(default:cfe_autorun_inventory_proc_cpuinfo.cpuinfo_hardware)", meta => { "inventory", "attribute_name=CPU model", "derived-from=$(default:cfe_autorun_inventory_proc.files[cpuinfo])", }; _have_proc_revision:: "system_product_name" string => "$(default:cfe_autorun_inventory_proc_cpuinfo.cpuinfo_revision)", meta => { "inventory", "attribute_name=System product name", "derived-from=$(default:cfe_autorun_inventory_proc.files[cpuinfo])", }; _have_dmidecode_cpu_model_name.!_have_proc_cpu_model_name:: "cpu_model" string => "$(default:cfe_autorun_inventory_dmidecode.dmi[processor-version])", meta => { "inventory", "attribute_name=CPU model", "derived-from=$(inventory_control.dmidecoder) -s processor-version", }; reports: DEBUG|DEBUG_cfe_autorun_inventory_cpuinfo:: "DEBUG $(this.bundle)"; "$(const.t) CPU model: $(cpu_model)"; "$(const.t) CPU physical cores: $(cpuinfo_physical_cores)"; } bundle common cfe_autorun_inventory_aws # @brief inventory AWS EC2 instances # # Provides: # ec2_instance class based on Amazon markers in dmidecode's system-uuid, bios-version or bios-vendor { classes: !disable_inventory_aws:: "ec2_instance" -> { "CFE-2924" } comment => "See http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/identify_ec2_instances.html", scope => "namespace", expression => regcmp( "^[eE][cC]2.*", "$(cfe_autorun_inventory_dmidecode.dmi[system-uuid])" ), if => isvariable("cfe_autorun_inventory_dmidecode.dmi[system-uuid]"); "ec2_instance" -> { "CFE-2924" } expression => regcmp( ".*[aA]mazon.*", "$(cfe_autorun_inventory_dmidecode.dmi[bios-version])" ), scope => "namespace", if => isvariable("cfe_autorun_inventory_dmidecode.dmi[bios-version]"); "ec2_instance" -> { "CFE-2924" } expression => regcmp( ".*[aA]mazon.*", "$(cfe_autorun_inventory_dmidecode.dmi[bios-vendor])" ), scope => "namespace", if => isvariable("cfe_autorun_inventory_dmidecode.dmi[bios-vendor]"); @if minimum_version(3.22.0) "sys_hypervisor_uuid_readable" -> { "ENT-9931" } expression => isreadable("/sys/hypervisor/uuid", 1); @else "sys_hypervisor_uuid_readable" -> { "ENT-9931" } expression => returnszero( "${paths.cat} /sys/hypervisor/uuid >/dev/null 2>&1", "useshell" ); @endif !disable_inventory_aws.sys_hypervisor_uuid_readable:: "ec2_instance" -> { "CFE-2924" } expression => regline("^ec2.*", "/sys/hypervisor/uuid"), scope => "namespace", if => fileexists("/sys/hypervisor/uuid"); reports: (DEBUG|DEBUG_inventory_aws):: "DEBUG $(this.bundle)"; "$(const.t)+ec2_instance" if => "ec2_instance"; } bundle agent cfe_autorun_inventory_aws_ec2_metadata # @brief Inventory ec2 metadata # Provides: { methods: !(disable_inventory_aws|disable_inventory_aws_ec2_metadata):: "cfe_autorun_inventory_aws_ec2_metadata_data"; "cfe_autorun_inventory_aws_ec2_metadata_cache"; "cfe_aws_ec2_metadata_from_cache"; } bundle agent cfe_autorun_inventory_aws_ec2_metadata_data # @brief Retrieve metadata from AWS API, preferring IMDSV2 { vars: ec2_instance.!(disable_inventory_aws|disable_inventory_aws_ec2_metadata):: "base_url" string => "http://169.254.169.254/latest"; "imdsv2_token_cmd" string => '$(paths.curl) -s -X PUT "$(base_url)/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"'; # Store the token for imdsv2 query, and it's result just once. "imdsv2_token" string => execresult("$(imdsv2_token_cmd)", noshell, stdout), if => not(isvariable(imdsv2_token)); "imdsv2_cmd" string => '$(paths.curl) -s -H "X-aws-ec2-metadata-token: $(imdsv2_token)" $(base_url)/dynamic/instance-identity/document'; "imdsv2_cmd_result" string => execresult("$(imdsv2_cmd)", noshell), if => not(isvariable(imdsv2_cmd_result)); # Store the result of the imdsv1 query, just once (if it's not alredy been defined) only if imdsv2 result is not valid "imdsv1_cmd" string => "$(paths.curl) -s $(base_url)/dynamic/instance-identity/document"; "imdsv1_cmd_result" string => execresult("$(imdsv1_cmd)", noshell), if => and( not(isvariable(imdsv1_cmd_result)), not(validjson("$(imdsv2_cmd_result)")) ); } bundle agent cfe_autorun_inventory_aws_ec2_metadata_cache # @brief Cache ec2 metadata from http request # # Provides cache of ec2 instance metadata for inventory { vars: "cache" string => "$(sys.statedir)/aws_ec2_metadata"; classes: "imdsv1_result_valid" expression => validjson( "$(cfe_autorun_inventory_aws_ec2_metadata_data.imdsv1_cmd_result)" ); "imdsv2_result_valid" expression => validjson( "$(cfe_autorun_inventory_aws_ec2_metadata_data.imdsv2_cmd_result)" ); files: imdsv1_result_valid.!imdsv2_result_valid:: "$(cache)" content => "$(cfe_autorun_inventory_aws_ec2_metadata_data.imdsv1_cmd_result)"; imdsv2_result_valid:: "$(cache)" content => "$(cfe_autorun_inventory_aws_ec2_metadata_data.imdsv2_cmd_result)"; } bundle agent cfe_aws_ec2_metadata_from_cache # @brief Inventory ec2 metadata from cache # # Provides inventory for EC2 Region, EC2 Instance ID, EC2 Instance Type, EC2 # Image ID, and EC2 Availability Zone { classes: ec2_instance.!(disable_inventory_aws|disable_inventory_aws_ec2_metadata):: "have_cached_instance_identity" expression => fileexists( $(cfe_autorun_inventory_aws_ec2_metadata_cache.cache) ); vars: have_cached_instance_identity.ec2_instance.!(disable_inventory_aws|disable_inventory_aws_ec2_metadata):: "data" data => readjson( $(cfe_autorun_inventory_aws_ec2_metadata_cache.cache), 100K ); "region" string => "$(data[region])", meta => { "inventory", "attribute_name=EC2 Region" }; "instanceId" string => "$(data[instanceId])", meta => { "inventory", "attribute_name=EC2 Instance ID" }; "instanceType" string => "$(data[instanceType])", meta => { "inventory", "attribute_name=EC2 Instance Type" }; "imageId" string => "$(data[imageId])", meta => { "inventory", "attribute_name=EC2 Image ID" }; "availabilityZone" string => "$(data[availabilityZone])", meta => { "inventory", "attribute_name=EC2 Availability Zone" }; reports: DEBUG|DEBUG_inventory_ec2_metadata|DEBUG_inventory_ec2_metadata_from_cache:: "DEBUG $(this.bundle):"; "$(const.t)Inventory 'EC2 Region' = '$(region)'"; "$(const.t)Inventory 'EC2 Instance ID' = '$(instanceId)'"; "$(const.t)Inventory 'EC2 Instance Type' = '$(instanceType)'"; "$(const.t)Inventory 'EC2 Image ID' = '$(imageId)'"; "$(const.t)Inventory 'EC2 Availability Zone' = '$(availabilityZone)'"; } bundle agent cfe_autorun_inventory_mtab # @brief Do mtab inventory # @inventory `File system` - File system in use by active mounts # @inventory `Mount point` - Mount points that have active mounts # @class `have_mount_FSTYPE_MOUNTPOINT` - Namespace scoped class for each file system mount point. For example: `have_mount_ext4__var` for a `ext4` file system mounted at `/var` # @class `have_mount_FSTYPE` - if there is any mounted file system formatted with `ext4` # # 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:: "mounts" meta => { "noreport" }, data => data_readstringarrayidx( $(inventory_control.mtab), "\s*#[^\n]*", "\s+", inf, inf ); "mount_count" int => length(mounts); "idx" slist => getindices("mounts"); "inventory_mount_point[$(idx)]" -> { "ENT-8338" } string => "$(mounts[$(idx)][1])", meta => { "inventory", "attribute_name=Mount point" }; "inventory_mounted_fs[$(idx)]" string => "$(mounts[$(idx)][2])", meta => { "noreport" }; "slist_unique_fs_types" slist => unique(sort(getvalues(inventory_mounted_fs), lex)); "inventory_fs[$(slist_unique_fs_types)]" -> { "ENT-8338" } string => "$(slist_unique_fs_types)", meta => { "inventory", "attribute_name=File system" }; 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 hardware related inventory # # This agent bundle reads dmi information from the sysfs and/or from dmidecode. # Sysfs is preferred for most variables, but if no sysfs (e.g. on RHEL 5), # or no sysfs equivalent to a dmidecode variable (e.g. system-version), # then dmidecode is run to collect the info. # For system-uuid, a parsed version of dmidecode is the preferred source. # # The variable names dmi[...] are all based on dmidecode string keywords. # # Information collected is: # - BIOS vendor # - BIOS version # - System serial number # - System manufacturer # - System version # - System product name # - Physical memory (MB) # # On windows where powershell is available this bundle runs gwmi to inventory: # - BIOS vendor # - BIOS version # - System serial number # - System manufacturer { vars: any:: "sysfs_name_for" comment => "The names in /sys/devices/virtual/dmi/id/ don't match the strings to be passed to dmidecode, even though the values do. We use the dmidecode string names for our variables since that was the original source (i.e. for backward compatibility with policies based on prior versions of this code).", # system-version has no equivalent in sysfs that I can find. # Items after the line break aren't currently collected, but mapping is provided # in case someone adds them to a custom dmidefs (so that they could be gotten # from sysfs in that case). data => parsejson( ' { "bios-vendor": "bios_vendor", "bios-version": "bios_version", "system-serial-number": "product_serial", "system-manufacturer": "sys_vendor", "system-product-name": "product_name", "system-uuid": "product_uuid", "baseboard-manufacturer": "board_vendor", "baseboard-product-name": "board_name", "baseboard-serial-number": "board_serial", "baseboard-version": "board_version", "bios-release-date": "bios_date", "chassis-manufacturer": "chassis_vendor", }' ); vars: any:: # The dmidefs variable controls which values are collected # (and what are their inventory tags) "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", "system-product-name": "System product name", "system-uuid": "System UUID", }' ); # We override dmidefs from augments when we can. "dmidefs" -> { "CFE-2927" } data => mergedata("def.cfe_autorun_inventory_dmidecode[dmidefs]"), if => isvariable("def.cfe_autorun_inventory_dmidecode[dmidefs]"); # 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 #"processor-version": "CPU model" <- Collected by default, but not by iterating over the list "dmivars" slist => getindices(dmidefs); have_dmidecode:: "decoder" string => "$(inventory_control.dmidecoder)"; have_dmidecode._stdlib_path_exists_awk.!(redhat_4|redhat_3):: # Awk script from https://kb.vmware.com/s/article/53609 # Edited only to add "-t1" (an improvement tested on RHEL 4/5/6/7 and FreeBSD) # and to take out the "UUID: " prefix in the output. # This works on a superset of systems where dmidecode -s system-uuid works, # e.g. RHEL 5 with dmidecode-2.7-1.28.2.el5 where system-uuid is not one of the valid keywords; # also, this returns the correct UUID on systems (such as VMWare VMs with hardware version 13) # where dmidecode -s system-uuid shows the wrong UUID. Some such VMWare VMs also show the # wrong UUID in sysfs, which is why we prefer the "dmidecode | awk" version to sysfs for UUID. # (We still need to check sysfs for UUID to handle hosts without dmidecode such as CoreOS.) "dmi[system-uuid]" string => execresult( "$(decoder) -u -t1 | $(paths.awk) ' BEGIN { in1 = 0; hd = 0} /, DMI type / { in1 = 0 } /Strings:/ { hd = 0 } { if (hd == 2) { printf \"%s-%s\n\", $1 $2, $3 $4 $5 $6 $7 $8; hd = 0 } } { if (hd == 1) { printf \"%s-%s-%s-\", $9 $10 $11 $12, $13 $14, $15 $16; hd = 2 } } /, DMI type 1,/ { in1 = 1 } /Header and Data:/ { if (in1 != 0) { hd = 1 } } '", "useshell" ), if => isvariable("dmidefs[system-uuid]"), # Only run this if system-uuid is marked for collection in dmidefs meta => { "inventory", "attribute_name=$(dmidefs[system-uuid])" }; !disable_inventory_dmidecode.!windows:: # The reason disable_inventory_dmidecode is referenced here but not in the other context lines # is because those vars depend on have_dmidecode which won't be set during pre-eval (and won't # be set at all if this bundle isn't called). Without this guard here, we would attempt to # read sysfs even if dmi inventory were turned off on the host via disable_inventory_dmidecode, # which would be undesirable. "dmi[$(dmivars)]" unless => isvariable("dmi[$(dmivars)]"), # This is just for system-uuid really, which we get from the awk script above by preference. if => fileexists( "/sys/devices/virtual/dmi/id/$(sysfs_name_for[$(dmivars)])" ), string => readfile( "/sys/devices/virtual/dmi/id/$(sysfs_name_for[$(dmivars)])", 0 ), meta => { "inventory", "attribute_name=$(dmidefs[$(dmivars)])" }; # Redhat 4 can support the -s option to dmidecode if # kernel-utils-2.4-15.el4 or greater is installed. have_dmidecode.!(redhat_4|redhat_3).!have_proc_device_tree:: "dmi[$(dmivars)]" string => execresult("$(decoder) -s $(dmivars)", "useshell"), unless => isvariable("dmi[$(dmivars)]"), # If already defined from sysfs, don't run dmidecode meta => { "inventory", "attribute_name=$(dmidefs[$(dmivars)])" }; # We do not want to inventory the model name from here, as inventory for # CPU info has been abstracted away from DMI so we just collect it # manually. "dmi[processor-version]" string => execresult("$(decoder) -s processor-version", "useshell"); windows.powershell:: "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]); "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.powershell:: "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" ); # BEGIN Inventory Total Physical Memory MB vars: "total_physical_memory_MB" -> { "CFE-2896" } string => readfile( "$(sys.statedir)/inventory-$(this.bundle)-total-physical-memory-MB.txt", 100 ), meta => { "inventory", "attribute_name=Physical memory (MB)" }, if => fileexists( "$(sys.statedir)/inventory-$(this.bundle)-total-physical-memory-MB.txt" ); commands: have_dmidecode:: "$(decoder) -t 17 | $(paths.awk) '/^\tSize:.*MB/ {a+=$2} /^\tSize:.*GB/ {b+=$2*1024} END {print a+b}' > '$(sys.statedir)/inventory-$(this.bundle)-total-physical-memory-MB.txt'" -> { "CFE-2896", "ENT-7714" } contain => in_shell, if => not( fileexists( "$(sys.statedir)/inventory-$(this.bundle)-total-physical-memory-MB.txt" ) ); files: "$(sys.statedir)/inventory-$(this.bundle)-total-physical-memory-MB.txt" -> { "CFE-2896" } delete => tidy, file_select => older_than(0, 0, 1, 0, 0, 0), comment => "Clear the cached value for total physical memory MB once a day."; # END Inventory Total Physical Memory MB reports: DEBUG|DEBUG_cfe_autorun_inventory_dmidecode:: "DEBUG $(this.bundle): Obtained $(dmidefs[$(dmivars)]) = '$(dmi[$(dmivars)])'"; "DEBUG $(this.bundle): Obtained Physical memory (MB) = '$(total_physical_memory_MB)'"; } 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: "lldpctl_exec_exists" expression => fileexists($(inventory_control.lldpctl_exec)); vars: !disable_inventory_LLDP.lldpctl_exec_exists:: # TODO When CFE-3108 is DONE, migrate to capturing only stdout "info" -> { "CFE-3109", "CFE-3108" } data => parsejson( execresult( "$(inventory_control.lldpctl_json) 2>/dev/null", "useshell" ) ), if => not(isvariable("def.lldpctl_json")), comment => "Not all versions of lldpctl support json, and because an absent lldpd will result in an error on stderr resulting noisy logs and failure to parse the json we redirect to dev null"; "info" -> { "CFE-3109" } data => parsejson( execresult($(inventory_control.lldpctl_json), "noshell") ), if => isvariable("def.lldpctl_json"), comment => "For safety, we do not run lldpctl in a shell if the path to lldpctl is customized via augments"; } 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"), }; "use_package_module_for_inventory" or => { "redhat", "debian", "suse", "sles", "alpinelinux", "windows" }; "use_package_method_for_inventory" or => { "gentoo", "aix" }; "use_package_method_generic_for_inventory" not => "use_package_module_for_inventory|use_package_method_for_inventory"; vars: # if we have the patches, 7 days; otherwise keep trying "refresh" string => ifelse("have_inventory", "10080", "0"); packages: # The legacy implementation (package_method) of the packages type promise # requires a packages promise to be triggered in order to generate package # inventory. The following promises ensure that package inventory data # exists. As package modules become available the package_methods should be # removed. aix:: "cfe_internal_non_existing_package" package_policy => "add", package_method => inventory_lslpp($(refresh)), action => if_elapsed_day; gentoo:: "cfe_internal_non_existing_package" package_policy => "add", package_method => emerge, action => if_elapsed_day; use_package_method_generic_for_inventory:: "cfe_internal_non_existing_package" package_policy => "add", package_method => generic, action => if_elapsed_day; reports: DEBUG|DEBUG_cfe_autorun_inventory_packages:: "DEBUG $(this.bundle): refresh interval is $(refresh)"; "DEBUG $(this.bundle): we have the inventory files." if => "have_inventory"; "DEBUG $(this.bundle): we don't have the inventory files." if => "!have_inventory"; } bundle agent cfe_autorun_inventory_policy_servers # @brief Inventory policy servers { vars: !disable_inventory_policy_servers:: "_primary_policy_server" -> { "ENT-6212" } string => "$(sys.policy_hub)", meta => { "inventory", "attribute_name=Primary Policy Server" }; "_policy_servers" -> { "ENT-6212" } slist => { @(def.policy_servers) }, if => isgreaterthan(length("def.policy_servers"), 0), meta => { "inventory", "attribute_name=Policy Servers" }; } 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_version_regex => "[^:]+:[^:]+:([^:]+):.*"; # Make sure version is not included in the name, that indicates RPM # packages, which we should ignore. package_list_name_regex => "[^:]+:(([^-:]|-[^0-9])+):.*"; package_installed_regex => "[^:]+:(([^-:]|-[^0-9])+):[^:]+:[^:]+:.*"; 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 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. { # canonical "useshell" but this is backwards-compatible useshell => "true"; } cfengine-masterfiles-3.27.3/inventory/debian.cf0000644000000000000000000000761114735102600017662 0ustar0000000000000000bundle 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 => { isvariable("sys.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:: "lmde" expression => regcmp('.*LMDE.*', "$(sys.os_release[NAME])"), comment => "this is a Linux Mint Debian Edition", meta => { "inventory", "attribute_name=none", "derived-from=sys.os_release[NAME]", }; 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"; } cfengine-masterfiles-3.27.3/inventory/freebsd.cf0000644000000000000000000000017414735102600020047 0ustar0000000000000000bundle common inventory_freebsd # @brief FreeBSD inventory bundle # # This common bundle is for FreeBSD inventory work. { } cfengine-masterfiles-3.27.3/inventory/generic.cf0000644000000000000000000000025014735102600020044 0ustar0000000000000000bundle common inventory_generic # @brief Generic (unknown OS) inventory # # This common bundle is for unknown operating systems, not handled by # specific bundles. { } cfengine-masterfiles-3.27.3/inventory/linux.cf0000644000000000000000000001005714735102600017575 0ustar0000000000000000bundle common inventory_linux # @brief Linux inventory # # This common bundle is for Linux inventory work. # # Provides: # systemd class based on linktarget of /proc/1/cmdline { vars: have_proc_device_tree:: "_model_path" string => "/proc/device-tree/model"; "proc_device_tree_model" string => readfile("$(_model_path)"), if => fileexists("$(_model_path)"), comment => "Read model from $(_model_path) because it's not available from DMI", meta => { "inventory", "attribute_name=System version" }; "_serial_number_path" string => "/proc/device-tree/serial-number"; "proc_device_tree_serial_number" string => readfile("$(_serial_number_path)"), if => fileexists("$(_serial_number_path)"), comment => "Read serial number from $(_serial_number_path) because it's not available from DMI", meta => { "inventory", "attribute_name=System serial number" }; 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"); any:: "proc_routes" data => data_readstringarrayidx( "/proc/$(this.promiser_pid)/net/route", "#[^\n]*", "\s+", 40, 4k ), if => fileexists("/proc/$(this.promiser_pid)/net/route"); "routeidx" slist => getindices("proc_routes"); "dgw_ipv4_iface" string => "$(proc_routes[$(routeidx)][0])", comment => "Name of the interface where default gateway is routed", if => strcmp("$(proc_routes[$(routeidx)][1])", "00000000"); linux:: "mounts" string => "/proc/$(this.promiser_pid)/mounts"; "nfs_mounts" slist => grep( ".* nfs .*", readstringlist("$(mounts)", "", "\n", inf, inf) ), if => and(not(isvariable("$(this.promiser)")), fileexists("$(mounts)")); "nfs_server[$(with)]" -> { "CFE-3259", "ENT-13210", "ENT-13223" } with => regex_replace("$(nfs_mounts)", ":.*", "", "g"), handle => "cfe_internal_inventory_mounted_nfs_server", string => "$(with)", meta => { "inventory", "attribute_name=NFS Server" }, if => not(isvariable("$(this.promiser)")); classes: any:: "has_proc_1_cmdline" expression => fileexists("/proc/1/cmdline"), comment => "Check if we can read /proc/1/cmdline"; "inventory_have_python_symlink" expression => fileexists("$(sys.bindir)/cfengine-selected-python"); has_proc_1_cmdline:: "systemd" expression => strcmp(lastnode($(proc_1_process), "/"), "systemd"), comment => "Check if (the link target of) /proc/1/cmdline is systemd"; inventory_have_python_symlink:: "cfe_python_for_package_modules_supported" -> { "CFE-2602", "CFE-3512", "ENT-10248" } comment => concat( "Here we see if the version of python found is", " acceptable ( 3.x or 2.4 or greater ) for package", " modules. We use this guard to prevent errors", " related to missing python modules." ), expression => returnszero( "$(sys.bindir)/cfengine-selected-python -c 'import sys; exit(sys.version_info < (2, 4))'", noshell ); } bundle monitor measure_entropy_available # @brief Measure amount of entropy available { measurements: linux:: # A lack of entropy can cause agents to hang "/proc/sys/kernel/random/entropy_avail" -> { "ENT-6495", "ENT-6494" } if => fileexists("/proc/sys/kernel/random/entropy_avail"), handle => "entropy_avail", stream_type => "file", data_type => "int", units => "bits", history_type => "weekly", match_value => single_value("\d+"), comment => "Amount of entropy available"; } cfengine-masterfiles-3.27.3/inventory/lsb.cf0000644000000000000000000000560414735102600017220 0ustar0000000000000000bundle 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: (DEBUG|DEBUG_inventory_lsb)._inventory_lsb_found:: "DEBUG $(this.bundle): OS = $(os), codename = $(codename), release = $(release), flavor = $(flavor), description = $(description)"; "DEBUG $(this.bundle): got $(dim) LSB keys"; "DEBUG $(this.bundle): prepared LSB key $(lsb_keys) = '$(lsb[$(lsb_keys)][1])'"; (DEBUG|DEBUG_inventory_lsb).!_inventory_lsb_found:: "DEBUG $(this.bundle): LSB inventory not found"; } cfengine-masterfiles-3.27.3/inventory/macos.cf0000644000000000000000000000017414735102600017537 0ustar0000000000000000bundle common inventory_macos # @brief Mac OS X inventory bundle # # This common bundle is for Mac OS X inventory work. { } cfengine-masterfiles-3.27.3/inventory/os.cf0000644000000000000000000001436014735102600017060 0ustar0000000000000000bundle common inventory_os { vars: # NOTE TODO: This first part is the old implementation # scroll down to the @if minimum_version part for the # current implementation. # This bundle uses variable overwriting, so the definitions further # down are prioritized. # Fall back to old LSB based implementation (Lowest priority): _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" }; # Hard coded values for exceptions / platforms without os-release: (redhat_5|redhat_6).redhat_pure:: "description" string => regex_replace( "$(inventory_lsb.description)", " release ", " ", "g" ), if => isvariable("inventory_lsb.description"), meta => { "inventory", "attribute_name=OS", "derived-from=inventory_lsb.description", }; centos_5:: "description" string => "CentOS Linux 5", # Matches format of os-release on 7+ meta => { "inventory", "attribute_name=OS", "derived-from=centos_5" }; centos_6:: "description" string => "CentOS Linux 6", # Matches format of os-release on 7+ meta => { "inventory", "attribute_name=OS", "derived-from=centos_6" }; # os-release PRETTY_NAME preferred whenever available (Highest priority): any:: "description" string => "$(sys.os_release[PRETTY_NAME])", if => isvariable("sys.os_release[PRETTY_NAME]"), meta => { "inventory", "attribute_name=OS", "derived-from=sys.os_release" }; # TODO: Remove promises above this line once 3.15+ is what we care about # New style for Inventory OS variable: # As short and human-friendly as possible, and consistent across platforms(!) # Examples: CentOS 7, Ubuntu 18, Debian 9, SUSE 12, etc. @if minimum_version(3.15) !_inventory_lsb_found.!windows:: "description" string => "$(sys.flavor) (LSB missing)", meta => { "inventory", "attribute_name=OS" }; _inventory_lsb_found:: "description" string => "$(inventory_lsb.os) $(inventory_lsb.release)", meta => { "inventory", "attribute_name=OS" }; windows:: "description" string => string_replace( string_replace("$(sys.release)", "Windows Server", "Windows"), "2012 R2", "2012" ), meta => { "inventory", "attribute_name=OS" }; # os-release is preferred over LSB: any:: # os-release PRETTY_NAME "description" string => string_replace( string_replace( string_replace( string_replace( "$(sys.os_release[PRETTY_NAME])", "Red Hat Enterprise Linux Server", "RHEL" ), "Debian GNU/Linux", "Debian" ), "CentOS Linux", "CentOS" ), "Rocky Linux", "Rocky" ), if => isvariable("sys.os_release[PRETTY_NAME]"), meta => { "inventory", "attribute_name=OS", "derived-from=sys.os_release" }; "major_version_from_os_release" string => nth( string_split("$(sys.os_release[VERSION_ID])", "\.", 2), 0 ), if => isvariable("sys.os_release[VERSION_ID]"); # os-release NAME VERSION_ID - preferred when available "description" string => string_replace( string_replace( string_replace( string_replace( string_replace( string_replace( "$(sys.os_release[NAME]) $(major_version_from_os_release)", "Red Hat Enterprise Linux Server", "RHEL" ), # Seen on RHEL 7... "Red Hat Enterprise Linux", "RHEL" ), # On RHEL 8 they changed their mind "Debian GNU/Linux", "Debian" ), "CentOS Linux", "CentOS" ), "Rocky Linux", "Rocky" ), "SLES", "SUSE" ), if => and( isvariable("sys.os_release[NAME]"), isvariable("major_version_from_os_release") ), meta => { "inventory", "attribute_name=OS", "derived-from=sys.os_release" }; # Hard coded values for exceptions / platforms without os-release: redhat_5.redhat_pure:: "description" string => "RHEL 5", meta => { "inventory", "attribute_name=OS", "derived-from=redhat_5" }; redhat_6.redhat_pure:: "description" string => "RHEL 6", meta => { "inventory", "attribute_name=OS", "derived-from=redhat_6" }; centos_5:: "description" string => "CentOS 5", meta => { "inventory", "attribute_name=OS", "derived-from=centos_5" }; centos_6:: "description" string => "CentOS 6", meta => { "inventory", "attribute_name=OS", "derived-from=centos_6" }; @endif # TODO: Remove all of the logic above once 3.18 clients are expected everywhere @if minimum_version(3.18) any:: "description" string => "$(sys.os_name_human) $(sys.os_version_major)", meta => { "inventory", "attribute_name=OS" }; rocky:: "description" -> { "ENT-8292" } string => "Rocky $(sys.os_version_major)", meta => { "inventory", "attribute_name=OS" }; amzn_2:: "description" -> { "ENT-10817" } string => "Amazon 2", meta => { "inventory", "attribute_name=OS" }; any:: "description" string => "$(sys.os_release[PRETTY_NAME])", if => and( strcmp("$(sys.os_name_human)", "Unknown"), isvariable("sys.os_release[PRETTY_NAME]") ), meta => { "inventory", "attribute_name=OS", "derived-from=sys.os_release" }; @endif } cfengine-masterfiles-3.27.3/inventory/redhat.cf0000644000000000000000000000165414735102600017710 0ustar0000000000000000bundle common inventory_redhat # @brief Red Hat inventory bundle # # This common bundle is for Red Hat Linux inventory work. { classes: "redhat_pure" or => { strcmp("$(sys.os_release[ID])", "rhel"), # Red Hat > 7 have /etc/os-release and the ID field is set to rhel strcmp( "any", and( "redhat.!(centos|oracle|fedora|rocky|almalinux)", # Red Hat < 7 does not have /etc/os-release, and is pure if we don't find another known derivative not(isvariable("sys.os_release")) ) ), }, 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" }; "inventory_redhat_have_python_symlink" expression => fileexists("$(sys.bindir)/cfengine-selected-python"); } cfengine-masterfiles-3.27.3/inventory/suse.cf0000644000000000000000000000066014735102600017414 0ustar0000000000000000bundle 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" }; } cfengine-masterfiles-3.27.3/inventory/windows.cf0000644000000000000000000000017414735102600020127 0ustar0000000000000000bundle common inventory_windows # @brief Windows inventory bundle # # This common bundle is for Windows inventory work. { } cfengine-masterfiles-3.27.3/PaxHeaders/lib0000644000000000000000000000003615266337437015472 xustar0030 mtime=1792655135.245800218 cfengine-masterfiles-3.27.3/lib/0000755000000000000000000000000015266337437014654 5ustar0000000000000000cfengine-masterfiles-3.27.3/lib/README.md0000644000000000000000000000622414735102600016115 0ustar0000000000000000This directory contains the CFEngine Standard Library, previously referred to as the Common Open Promise Body Library. Layout of this `lib` directory: * `lib/*.cf`: Re-unified library compatible with 3.7+ - *autorun.cf*: This file contains bundles that support automatic activation of bundles based on tags as well as automatically adding policy files found in services/autorun to inputs. - *bundles.cf*: This file contains bundles that are generically useful. For example manage cron entries, recursively deleting directories, checking if a url is repsonding, and merging multiple data containers together. - *cfe_internal.cf*: This file defines bodies and bundles that are related to general CFEngine management. For example purging old log files. - *cfe_internal_hub.cf*: This file defines bodies and bundles that are releated to CFEngine Enterprise Hub management. - *cfengine_enterprise_hub_ha.cf*: This file defines bodies and bundles that are related to managing High Availability on CFEngine Enterprise Hubs. - *commands.cf*: This file contains bodies and bundles that are useful when running commands. For example suppressing command output, or controlling which user or group should be executing the command. - *common.cf*: This file contains bodies and bundles that are useful across the board. For example bodies that help to define classes based on promise outcomes, bodies to control logging for specific promsies, and bodies to help control how frequently promises get activated. - *databases.cf*: This file contains bodies and bundles useful when managing databases like Postgres and the Windows Registry. - *edit_xml.cf*: This file contains bodies and bundles useful when managing xml files. - *examples.cf*: This file contains examples of other useful bundles like activating a bundle based on probability. - *feature.cf*: This file defines a bundle to help manage classes to identify contexts that should be set or not set. It can be useful for turning certain aspects of policy on or off for a given amount of time. - *files.cf*: This file defines bodies and bundles that are useful for managing files. - *guest_environments.cf*: This file defines bodies and bundles useful for manageing guest environments (Virtual Machines). - *monitor.cf*: This file defines bodies and bundles useful when measuring values with cf-monitord (Enterprise only) - *packages.cf*: This file defines bodies and bundles releated to package management. - *paths.cf*: This file defines paths to well known binaries for various platforms. - *processes.cf*: This file defines bodies and bundles useful for managing processes. - *services.cf*: This file defines service methods for use with services type promises. - *stdlib.cf*: This file includes the commonly used library files - *storage.cf*: This file defines storage related bodies and bundles for working with mounts and volumes. - *users.cf*: This file defines bodies and bundles related to local user management - *vcs.cf*: This file defines bodies and bundles useful for interacting with version control systems. cfengine-masterfiles-3.27.3/lib/autorun.cf0000644000000000000000000000123614735102600016643 0ustar0000000000000000body file control { services_autorun|services_autorun_inputs:: inputs => { @(services_autorun.found_inputs) }; } bundle agent autorun { vars: services_autorun|services_autorun_bundles:: "sorted_bundles" slist => sort(bundlesmatching(".*", "autorun"), "lex"), comment => "Lexicographically sorted bundles for predictable order"; methods: services_autorun|services_autorun_bundles:: "autorun" -> { "CFE-3795" } usebundle => $(sorted_bundles), action => immediate; reports: DEBUG|DEBUG_autorun|DEBUG_services_autorun:: "DEBUG $(this.bundle): found bundle $(sorted_bundles) with tag 'autorun'"; } cfengine-masterfiles-3.27.3/lib/bundles.cf0000644000000000000000000003605114735102600016605 0ustar0000000000000000# Bundles bundle common bundles_common # @brief Enumerate policy files used by this policy file for inclusion to inputs { vars: "inputs" slist => { "$(this.promise_dirname)/paths.cf", "$(this.promise_dirname)/files.cf", "$(this.promise_dirname)/commands.cf", }; } body file control # @brief Include policy files used by this policy file as part of inputs { 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|sles:: "crontab" string => "/var/spool/cron/tabs"; redhat|fedora:: "crontab" string => "/var/spool/cron"; freebsd:: "crontab" string => "/var/cron/tabs"; !(suse|sles|redhat|fedora|freebsd):: "crontab" string => "/var/spool/cron/crontabs"; any:: # We escape the user supplied values so that we can search to see if the # entry already exists with slightly different spacing. "e_mins" string => escape("$(mins)"); "e_hours" string => escape("$(hours)"); "e_commands" string => escape("$(commands)"); classes: !windows:: # We tolerate existing entries that differ only in whitespace and avoid # entering duplicate entries. "present_with_potentially_different_spacing" expression => regline( "^$(e_mins)\s+$(e_hours)\s+\*\s+\*\s+\*\s+$(e_commands)", "$(crontab)/$(user)" ), if => fileexists("$(crontab)/$(user)"); files: !windows.!present_with_potentially_different_spacing:: "$(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; "$(name)/." 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)"), if => fileexists($(log_files)); } 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 prunetree(dir, depth, max_days) # @brief Delete files and directories inside "dir" up to "depth" older than "max_days". # @depends delete tidy # @depends depth_search recurse_with_base # @depends file_select days_old # @param dir directory to examine for files # @param depth How many levels to descend # @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: # "prunetree" usebundle => prunetree( @(dirs), inf, "1" ); # } # ``` { files: "$(dir)" comment => "Delete files and directories under $(dir) up to $(depth) depth older than $(max_days)", delete => tidy, file_select => days_old($(max_days)), depth_search => recurse_with_base($(depth)); } 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" if => "url_ok_$(chost)"; "$(this.bundle): $(method) $(host):$(port)/$(uri) did *not* get 200 OK" if => "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"; } bundle agent collect_vars(name, tag, flatten) # @brief bundle to collect tagged variables into a data container # @param name the variable name to create inside `collect_vars` # @param tag the tag regex string to match e.g. "beta,gamma=.*" # @param flatten to flatten variable values, set to "any" or "true" or "1" # # The result will be a map in `collect.$(name)`. You can also use # `cmerge.$(name)_str` for a string version of the merged containers # (if it fits in a CFEngine string). # # The name is variable so you can call this bundle for more than one # collection. # # Every found variable will be a key in the map, unless you specify # `flatten`, in which case they'll be flattened into a top-level array # of data. # # The `flatten` parameter can be "any" or "true" or "1" to be true. # # **Example:** # # ```cf3 # body common control # { # inputs => { "$(sys.libdir)/stdlib.cf" }; # } # # bundle agent main # { # vars: # # the "mymerge" tag is user-defined # "a" data => parsejson('{ "mark": "burgess" }'), meta => { "mymerge" }; # "b" data => parsejson('{ "volker": "hilsheimer" }'), meta => { "mymerge" }; # # methods: # # merge a, b into container collect_vars.all # "go" usebundle => collect_vars("all", "mymerge", ""); # # flatten a, b into container collect_vars.flattened # "go_flatten" usebundle => collect_vars("flattened", "mymerge", "true"); # # reports: # # merged = {"default:main.a":{"mark":"burgess"},"default:main.b":{"volker":"hilsheimer"}} # "merged = $(collect_vars.all_str)"; # # flattened = {"mark":"burgess","volker":"hilsheimer"} # "flattened = $(collect_vars.flattened_str)"; # } # ``` { classes: "flatten" expression => strcmp($(flatten), "any"); "flatten" expression => strcmp($(flatten), "1"); "flatten" expression => strcmp($(flatten), "true"); vars: "todo_$(name)" slist => variablesmatching(".*", $(tag)); !flatten:: "$(name)" data => parsejson('{}'), policy => "free"; # this iterates! "$(name)" data => mergedata($(name), '{ "$(todo_$(name))": $(todo_$(name)) }'), policy => "free"; flatten:: "$(name)" data => parsejson('[]'), policy => "free"; # this iterates! "$(name)" data => mergedata($(name), "$(todo_$(name))"), policy => "free"; any:: "$(name)_str" string => format("%S", $(name)), policy => "free"; } bundle agent run_ifdefined(namespace, mybundle) # @brief bundle to maybe run another bundle dynamically # @param namespace the namespace, usually `$(this.namespace)` # @param mybundle the bundle to maybe run # # This bundle simply is a way to run another bundle only if it's defined. # # **Example:** # # ```cf3 # bundle agent run # { # methods: # # does nothing if bundle "runthis" is not defined # "go" usebundle => run_ifdefined($(this.namespace), runthis); # } # ``` { vars: "bundlesfound" slist => bundlesmatching("^$(namespace):$(mybundle)$"); "count" int => length(bundlesfound); methods: "any" usebundle => $(bundlesfound), if => strcmp(1, $(count)); reports: verbose_mode:: "$(this.bundle): found matching bundles $(bundlesfound) for namespace '$(namespace)' and bundle '$(mybundle)'"; } cfengine-masterfiles-3.27.3/lib/cfe_internal.cf0000644000000000000000000000563114735102600017602 0ustar0000000000000000bundle common cfe_internal_common # @brief Select parts of the standard library that are dependant { vars: "inputs" slist => { "$(this.promise_dirname)/common.cf", "$(this.promise_dirname)/commands.cf", }; } body file control # @brief Include necessary parts of stdlib { inputs => { @(cfe_internal_common.inputs) }; } bundle agent cfe_internal_cleanup_agent_reports # @brief Cleanup accumulated agent reports { vars: any:: # To avoid unnecessary work, we only findfiles if there is not already a # variable defined. "diff_files" slist => findfiles("$(sys.workdir)/state/diff/*.diff"), unless => isvariable($(this.promiser)); "promise_log_files" slist => findfiles("$(sys.workdir)/state/promise_log/*.csv"), unless => isvariable($(this.promiser)); "previous_state_files" -> { "ENT-3161" } slist => findfiles("$(sys.workdir)/state/previous_state/*.cache"), unless => isvariable($(this.promiser)), comment => "The files in this directory record the state at the end of the previous agent run. They are used in concert with the promise logs to derive delta reports."; "untracked_files" -> { "ENT-3161" } slist => findfiles("$(sys.workdir)/state/untracked/*.idx"), unless => isvariable($(this.promiser)), comment => "The files in this directory are used in support of the report_data_select filters. This is a record of all promises that should not be collected"; "files" slist => { @(diff_files), @(promise_log_files), @(previous_state_files), @(untracked_files), }; "reports_size[$(files)]" int => filesize("$(files)"), unless => isvariable($(this.promiser)); "tmpmap" slist => maparray("$(this.v)", reports_size); # We need to make sure that we have files before summing or errors are # produced in the log have_files:: "total_report_size" real => sum(tmpmap); classes: "cfe_internal_purge_reports" expression => isgreaterthan( "$(total_report_size)", "$(def.max_client_history_size)" ), comment => "Determine if the current sum of reports exceeds the max desired"; "have_files" expression => isgreaterthan(length(tmpmap), 0); files: cfe_internal_purge_reports:: "$(files)" delete => tidy, handle => "cf_cleanup_agent_reports_$(files)"; reports: DEBUG|DEBUG_cfe_internal_cleanup_agent_reports:: "DEBUG $(this.bundle): Size of '$(files)' = '$(reports_size[$(files)])'"; "DEBUG $(this.bundle): Size of all reports = '$(total_report_size)'"; "DEBUG $(this.bundle): Purge threshold = '$(def.max_client_history_size)'"; "DEBUG $(this.bundle): Client history purge triggered" if => "cfe_internal_purge_reports"; } cfengine-masterfiles-3.27.3/lib/cfe_internal_hub.cf0000644000000000000000000002550014735102600020435 0ustar0000000000000000bundle common cfe_internal_hub_common # @brief Enumerate policy files used by this policy file for inclusion to inputs { vars: "inputs" slist => { "$(this.promise_dirname)/common.cf", "$(this.promise_dirname)/commands.cf", }; } body file control # @brief Include policy files used by this policy file as part of inputs { inputs => { @(cfe_internal_hub_common.inputs) }; } bundle agent cfe_internal_hub_maintain # @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": 1, "time_key": "CheckTimeStamp" } ]' ); "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" } ]' ); classes: "enable_cfe_internal_reporting_database_purge_old_history" -> { "postgres", "CFEngine Enterprise" } expression => "enterprise_edition.Hr00"; "enable_cfe_internal_parition_creation_job" -> { "postgres", "CFEngine Enterprise" } expression => "enterprise_edition.Hr00"; methods: enable_cfe_internal_reporting_database_purge_old_history:: "Remove old report history" usebundle => cfe_internal_database_cleanup_reports(@(report_settings)), action => if_elapsed_day; "Remove cf-hub status history" usebundle => cfe_internal_database_cleanup_cf_hub_status("3"), action => if_elapsed_day; "Remove diagnostics history" usebundle => cfe_internal_database_cleanup_diagnostics( @(diagnostics_settings) ), action => if_elapsed_day; "Remove promise log history" usebundle => cfe_internal_database_cleanup_promise_log("7"), action => if_elapsed_day; enable_cfe_internal_parition_creation_job:: "Create new partitions for partitioned tables" usebundle => cfe_internal_database_partitioning(), action => if_elapsed_day; } bundle agent cfe_internal_database_cleanup_reports(settings) # @brief clean up the reporting tables { vars: "index" slist => getindices(settings); "remove_query_$(settings[$(index)][report])" comment => "This query will delete rows that have a changetimestamp $(settings[$(index)][history_length_days]) older than the hosts most recent changetimestamp in the table.", string => "WITH z AS ( SELECT hostkey, Max($(settings[$(index)][time_key])) AS latest FROM $(settings[$(index)][table]) GROUP BY hostkey) DELETE FROM $(settings[$(index)][table]) t using z WHERE z.hostkey = t.hostkey AND t.$(settings[$(index)][time_key]) <= (z.latest - '$(settings[$(index)][history_length_days]) day'::interval);"; commands: "$(sys.bindir)/psql cfdb -c \"$(remove_query_$(settings[$(index)][report]))\"" @if minimum_version(3.15.0) inform => "false", @endif contain => default:silent, handle => "cf_database_maintain_report_$(settings[$(index)][report])"; } bundle agent cfe_internal_database_cleanup_cf_hub_status(row_count) # @brief keep up to row_count entries in the database { classes: # We probe the database to see if the function is defined "has_sql_function_cleanup_historical_data" expression => returnszero( "$(sys.bindir)/psql cfdb -c \"SELECT 'cleanup_historical_data'::regproc;\" > /dev/null 2>&1", useshell ), if => isexecutable("$(sys.bindir)/psql"); "has_sql_table___status" -> { "ENT-4331" } expression => returnszero( "$(sys.bindir)/psql cfdb -c \"SELECT 'public.__status'::regclass;\" > /dev/null 2>&1", useshell ), if => isexecutable("$(sys.bindir)/psql"); vars: any:: # TODO Redact after 3.15.x is no longer under standard support. Since this # is used in 3.12.x and 3.12.x was supported at the time 3.15.0 was # released we need to maintain the path for people upgrading from 3.12.x # The status table changed it's name for 3.12.2 and 3.10.6, this handles # using the proper table name in the cleanup query "status_table_name" -> { "ENT-4331" } string => ifelse("has_sql_table___status", "__status", "status"); any:: # This is the fallback query to use in case the cleanup_historical_data # function is not present. "remove_query" -> { "ENT-4365" } string => "DELETE FROM $(status_table_name) WHERE ts IN (SELECT ts FROM $(status_table_name) ORDER BY ts DESC OFFSET 50000);"; "delete_future_ts_query" -> { "ENT-4362", "ENT-4992" } string => "DELETE FROM $(status_table_name) WHERE to_timestamp(ts::bigint) > (now() + interval '2 days')::timestamp;"; has_sql_function_cleanup_historical_data:: "remove_query" string => "SELECT * FROM cleanup_historical_data('$(status_table_name)', 'ts', $(row_count), 'host');"; commands: "$(sys.bindir)/psql cfdb -c \"$(remove_query)\"" @if minimum_version(3.15.0) inform => "false", @endif contain => default:silent, handle => "cf_database_maintain_consumer_status"; "$(sys.bindir)/psql cfdb -c \"$(delete_future_ts_query)\"" -> { "ENT-4362" } @if minimum_version(3.15.0) inform => "false", @endif contain => default:silent, handle => "cf_database_maintain_consumer_status_no_future_timestamps"; } 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]))\"" @if minimum_version(3.15.0) inform => "false", @endif contain => default:silent, handle => "cf_database_maintain_diagnostics_$(settings[$(index)][report])"; } bundle agent cfe_internal_database_cleanup_promise_log(history_length_days) # @brief clean up promise log files older than `history_length_days` # @param history_length_days Number of days after which promise logs should be deleted { vars: "cleanup_query_repaired" string => "SELECT promise_log_partition_cleanup('REPAIRED', '$(history_length_days) day');"; "cleanup_query_notkept" string => "SELECT promise_log_partition_cleanup('NOTKEPT', '$(history_length_days) day');"; commands: "$(sys.bindir)/psql cfdb -c \"$(cleanup_query_repaired)\"" @if minimum_version(3.15.0) inform => "false", @endif contain => default:silent, handle => "cf_database_maintain_promise_log_repaired"; "$(sys.bindir)/psql cfdb -c \"$(cleanup_query_notkept)\"" @if minimum_version(3.15.0) inform => "false", @endif contain => default:silent, handle => "cf_database_maintain_promise_log_notkept"; } bundle agent cfe_internal_database_partitioning() # @brief create any nesesary table partitions for database { vars: "promise_outcome" slist => { "REPAIRED", "NOTKEPT" }; "query_create_promise_log_$(promise_outcome)" string => "SELECT promise_log_partition_create(NOW() - INTERVAL '7 day', 7 + 3, '$(promise_outcome)');"; commands: "$(sys.bindir)/psql cfdb -c \"$(query_create_promise_log_$(promise_outcome))\"" @if minimum_version(3.15.0) inform => "false", @endif contain => default:silent, handle => "cf_database_create_partition_promise_log_$(promise_outcome)"; } bundle agent cfe_internal_postgresql_maintenance #@brief Vacuum Full PostgreSQL for maintenance { vars: "vacuum_cfdb_cmd" string => "$(sys.bindir)/vacuumdb --full --dbname=cfdb", comment => "Vacuum Full PostgreSQL (database: cfdb)", handle => "cfe_internal_postgresql_maintenance_vacuum_full"; processes: any:: "cf-hub" signals => { "term" }, comment => "Terminate cf-hub while doing PostgreSQL maintenance", handle => "cfe_internal_postgresql_maintenance_processes_term_cf_hub"; commands: any:: "$(vacuum_cfdb_cmd)" comment => "Run vacuum db full command (database: cfdb)", classes => kept_successful_command, handle => "cfe_internal_postgresql_maintenance_commands_run_vacuumdb_cmd_full"; } bundle agent cfe_internal_postgresql_vacuum #@brief Vacuum (with analyze) over cfdb database. { vars: "vacuum_cfdb_cmd" string => "$(sys.bindir)/vacuumdb --analyze --quiet --dbname=cfdb", comment => "Vacuum command with update statistics enabled"; commands: "$(vacuum_cfdb_cmd)" comment => "Run vacuum db command (database: cfdb)", handle => "cfe_internal_postgresql_maintenance_commands_run_vacuumdb"; } bundle monitor measure_psql { measurements: policy_server|am_policy_hub:: # We average the time for all entries in /var/log/postgresql.log that # PostgreSQL waited before acquiring a lock and measure that over time. "/var/log/postgresql.log" if => fileexists("/var/log/postgresql.log"), handle => "psql_lock_wait_before_acquisition", stream_type => "file", data_type => "real", history_type => "weekly", units => "ms", match_value => acquired_lock, comment => "Approximate length of time PostgreSQL waits before acquiring lock"; } body match_value acquired_lock { # Example log line # 2019-06-11 18:49:39 GMT LOG: process 10427 acquired AccessShareLock on relation 17949 of database 16384 after 1122 select_line_matching => ".*acquired.*Lock.*"; extraction_regex => ".*after (\d+)"; track_growing_file => "true"; select_multiline_policy => "average"; # average, sum, first, last } cfengine-masterfiles-3.27.3/lib/cfengine_enterprise_hub_ha.cf0000644000000000000000000000164614735102600022477 0ustar0000000000000000################################################# # CFEngine Enterprise Hub HA policy inclusion ################################################# bundle common cfengine_enterprise_hub_ha # @brief Inputs specific to CFEngine Enterprise High Availability { vars: enable_cfengine_enterprise_hub_ha:: "input[ha_main]" string => "cfe_internal/enterprise/ha/ha.cf"; "input[ha_def]" string => "cfe_internal/enterprise/ha/ha_def.cf"; "classification_bundles" slist => { "ha_def" }; "management_bundles" slist => { "ha_main" }; "inputs" slist => getvalues(input); !enable_cfengine_enterprise_hub_ha:: "classification_bundles" slist => { "$(this.bundle)" }; "management_bundles" slist => { "$(this.bundle)" }; "inputs" slist => {}; } body file control # @brief Include policy specific to CFEngine Enterprise High Availability { inputs => { @(cfengine_enterprise_hub_ha.inputs) }; } cfengine-masterfiles-3.27.3/lib/commands.cf0000644000000000000000000001631014735102600016746 0ustar0000000000000000# Commands bodies 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.(DEBUG|DEBUG_$(this.bundle))":: "DEBUG $(this.bundle): This bundle does not support Windows"; } ##------------------------------------------------------- ## contain ##------------------------------------------------------- body contain powershell # @brief Run command with powershell (windows only) # # **Example:** # # ```cf3 # commands: # windows:: # 'schtasks /DELETE /TN "$(_taskname)" /F' # contain => powershell; # ``` # # **History:** # # * Introduced in 3.17.0 { useshell => "powershell"; } 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)"; # canonical "useshell" but this is backwards-compatible useshell => "true"; } ## 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; # ``` { # canonical "useshell" but this is backwards-compatible useshell => "true"; } ## 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. { # canonical "useshell" but this is backwards-compatible useshell => "true"; } ## 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"; # ``` { # canonical "useshell" but this is backwards-compatible useshell => "true"; 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"; # ``` { # canonical "useshell" but this is backwards-compatible useshell => "true"; 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)"; # canonical "useshell" but this is backwards-compatible useshell => "true"; } ## 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)"; # canonical "useshell" but this is backwards-compatible useshell => "true"; } ## 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)"; # canonical "useshell" but this is backwards-compatible useshell => "true"; 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)"; } cfengine-masterfiles-3.27.3/lib/common.cf0000644000000000000000000002733614735102600016447 0ustar0000000000000000# Common bodies ##------------------------------------------------------- ## 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 Evaluate 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 measure_promise_time(identifier) # @brief Performance will be measured and recorded under identifier # # @param identifier Measurement name. { measurement_class => "$(identifier)"; } ## 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 defined if the 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 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 is 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)_reached", }; repair_denied => { "repair_denied_$(x)", "$(x)_denied", "$(x)_not_ok", "$(x)_error", "$(x)_not_kept", "$(x)_reached", }; repair_timeout => { "repair_timeout_$(x)", "$(x)_timeout", "$(x)_not_ok", "$(x)_error", "$(x)_not_kept", "$(x)_reached", }; promise_kept => { "promise_kept_$(x)", "$(x)_kept", "$(x)_ok", "$(x)_reached" }; } body classes results(scope, class_prefix) # @brief Define classes prefixed with `class_prefix` and suffixed with # appropriate outcomes: `_kept`, `_repaired`, `_not_kept`, `_error`, `_failed`, # `_denied`, `_timeout`, `_reached` # # @param scope The scope in which the class should be defined (`bundle` or `namespace`) # @param class_prefix The prefix for the classes defined # # This body can be applied to any promise and sets global # (`namespace`) or local (`bundle`) classes based on its outcome. For # instance, with `class_prefix` set to `abc`: # # * if the promise is to change a file's owner to `nick` and the file # was already owned by `nick`, the classes `abc_reached` and # `abc_kept` will be set. # # * if the promise is to change a file's owner to `nick` and the file # was owned by `adam` and the change succeeded, the classes # `abc_reached` and `abc_repaired` will be set. # # This body is a simpler, more consistent version of the body # `scoped_classes_generic`, which see. The key difference is that # fewer classes are defined, and only for outcomes that we can know. # For example this body does not define "OK"/"not OK" outcome classes, # since a promise can be both kept and failed at the same time. # # It's important to understand that promises may do multiple things, # so a promise is not simply "OK" or "not OK." The best way to # understand what will happen when your specific promises get this # body is to test it in all the possible combinations. # # **Suffix Notes:** # # * `_reached` indicates the promise was tried. Any outcome will result # in a class with this suffix being defined. # # * `_kept` indicates some aspect of the promise was kept # # * `_repaired` indicates some aspect of the promise was repaired # # * `_not_kept` indicates some aspect of the promise was not kept. # error, failed, denied and timeout outcomes will result in a class # with this suffix being defined # # * `_error` indicates the promise repair encountered an error # # * `_failed` indicates the promise failed # # * `_denied` indicates the promise repair was denied # # * `_timeout` indicates the promise timed out # # **Example:** # # ```cf3 # bundle agent example # { # commands: # "/bin/true" # classes => results("bundle", "my_class_prefix"); # # reports: # my_class_prefix_kept:: # "My promise was kept"; # # my_class_prefix_repaired:: # "My promise was repaired"; # } # ``` # # **See also:** `scope`, `scoped_classes_generic`, `classes_generic` { scope => "$(scope)"; promise_kept => { "$(class_prefix)_reached", "$(class_prefix)_kept" }; promise_repaired => { "$(class_prefix)_reached", "$(class_prefix)_repaired" }; repair_failed => { "$(class_prefix)_reached", "$(class_prefix)_error", "$(class_prefix)_not_kept", "$(class_prefix)_failed", }; repair_denied => { "$(class_prefix)_reached", "$(class_prefix)_error", "$(class_prefix)_not_kept", "$(class_prefix)_denied", }; repair_timeout => { "$(class_prefix)_reached", "$(class_prefix)_error", "$(class_prefix)_not_kept", "$(class_prefix)_timeout", }; } @if minimum_version(3.8) body classes diff_results(scope, x) # @brief Define `x` prefixed/suffixed with promise outcome with command return codes adjusted to align with `diff`. # @param scope The scope the class should be defined with (`bundle` or `namespace`). # @param x The unique part of the classes to be defined. # # From man diff: # Exit status is 0 if inputs are the same, 1 if # different, 2 if trouble. # # **Example:** # # ```cf3 # bundle agent example # { # commands: # "/usr/bin/diff" # args => "/tmp/file1 /tmp/file2", # classes => diff_results("diff"); # # vars: # "c" slist => classesmatching("diff_.*"); # # reports: # "Found class '$(c)'"; # "Files Differ!" # if => "diff_failed|diff_error|diff_not_kept"; # "Files are the same." # if => "diff_kept"; # } # ``` { inherit_from => results($(scope), $(x)); kept_returncodes => { "0" }; failed_returncodes => { "1", "2" }; } @endif body classes 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 { 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)_reached", }; repair_denied => { "repair_denied_$(x)", "$(x)_denied", "$(x)_not_ok", "$(x)_error", "$(x)_not_kept", "$(x)_reached", }; repair_timeout => { "repair_timeout_$(x)", "$(x)_timeout", "$(x)_not_ok", "$(x)_error", "$(x)_not_kept", "$(x)_reached", }; promise_kept => { "promise_kept_$(x)", "$(x)_kept", "$(x)_ok", "$(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"; scope => "namespace"; } ## 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 unique part of the class that should be defined # The class defined is prefixed with `mXC_` { promise_repaired => { "mXC_$(x)" }; promise_kept => { "mXC_$(x)" }; persist_time => "15"; scope => "namespace"; } ## 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" }; } cfengine-masterfiles-3.27.3/lib/databases.cf0000644000000000000000000000167114735102600017100 0ustar0000000000000000# Databases bodies 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"; } cfengine-masterfiles-3.27.3/lib/edit_xml.cf0000644000000000000000000000354614735102600016761 0ustar0000000000000000# 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)' 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)"; } cfengine-masterfiles-3.27.3/lib/event.cf0000644000000000000000000001516614735102600016276 0ustar0000000000000000# Event handling bundles and bodies @if minimum_version(3.9) bundle agent event_register(prefix, type, name, persistence, metadata) # @brief Register a `event_$(prefix)_$(type)_$(name)` class with meta=`metadata` # @param prefix The prefix (usually the issuing bundle name) # @param type The event type # @param name The event name # @param persistence the time, in minutes, the class should persist on disk (unless collected) # @param metadata A slist with the event metadata # # This bundle creates a class that conforms to the ad-hoc event protocol defined # herein. # # **See also:** `event_handle` { vars: "e" string => "event_$(prefix)_$(type)_$(name)"; "metadata_string" string => format("%S", metadata); classes: "$(e)" scope => "namespace", persistence => $(persistence), meta => { "event", "prefix=$(prefix)", "type=$(type)", "name=$(name)", @(metadata), }; reports: inform_mode:: "$(this.bundle): creating event $(e) persistent for $(persistence) minutes with metadata $(metadata_string)"; } body classes event_cancel_events(events) # @brief Cancel any `events` # @param events A slist of events to cancel { cancel_notkept => { @(events) }; cancel_kept => { @(events) }; cancel_repaired => { @(events) }; } bundle agent event_handle(prefix, type) # @brief Handle all the events matching `prefix` and `type` through delegation # @param prefix A prefix for the event, can be `.*` for all # @param type A type for the event, can be `.*` for all # # This bundle looks for all the event classes matching `prefix` and `type`, then # for all the bundles that have declared they can handle that prefix and type, # and then passes the corresponding event classes to each bundle. # # **See also:** `event_register` { vars: "events_prefix" slist => classesmatching("event_.*", "prefix=$(prefix)"); "events_type" slist => classesmatching("event_.*", "type=$(type)"); "events" slist => intersection(events_prefix, events_type); "events_string" string => format("%S", events); "handlers_prefix" slist => bundlesmatching( "default:event_.*", format("event_prefix=(%s|ALL)", escape($(prefix))) ); "handlers_type" slist => bundlesmatching( "default:event_.*", format("event_type=(%s|ALL)", escape($(type))) ); "handlers" slist => intersection(handlers_prefix, handlers_type); "handlers_string" string => format("%S", handlers); methods: "" usebundle => $(handlers)(@(events)), classes => event_cancel_events(@(events)); reports: inform_mode:: "$(this.bundle): with prefix $(prefix) and type $(type) found events $(events_string)"; "$(this.bundle): with prefix $(prefix) and type $(type) found handlers $(handlers_string)"; } bundle agent event_debug_handler(events) # @brief Debug all the events matching the meta tags `event_prefix` and `event_type` # @param events The list of events, passed from `event_handle` # # This is an event handler that just prints out all the events it finds. To be # registered as a handler, it must have the `meta tags` indicated below. # # **See also:** `event_handle`, `event_register` { meta: "tags" slist => { "event_handler", "event_prefix=.*", "event_type=.*" }; vars: "events_string" string => format("%S", events); "tags_string" string => format("%S", "$(this.bundle)_meta.tags"); reports: inform_mode:: "$(this.bundle): with tags $(tags_string) got events $(events_string)"; } bundle agent event_install_handler(events) # @brief Handle all the install events matching the meta tags `event_prefix` and `event_type` # @param events The list of events, passed from `event_handle` # # This is an event handler that just prints out all the install events it finds. # To be registered as a handler, it must have the `meta tags` indicated below. # The subtlety in `event_prefix=ALL` is that we want to match only # `event_handle(ANYTHING, "install")` but not `event_handle(".*", ANYTHING)`. If # you're confused, just remember: debug handlers use `event_prefix=.*` and # everything else uses `event_prefix=ALL`. # # **See also:** `event_handle`, `event_register` { meta: "tags" slist => { "event_handler", "event_prefix=ALL", "event_type=install" }; vars: "events_string" string => format("%S", events); "tags_string" string => format("%S", "$(this.bundle)_meta.tags"); reports: inform_mode:: "$(this.bundle): with tags $(tags_string) got events $(events_string)"; } bundle agent event_usage_example # @brief Simple demo of event_register and event_handle usage # # You can run it like this: `cf-agent -K ./event.cf -b event_usage_example` # Or for extra debugging, you can run it like this: `cf-agent -KI ./event.cf -b event_usage_example` # # **See also:** `event_handle`, `event_register` # # Expected output with `-KI`: # # ``` # R: event_register: creating event event_event_usage_example_restart_apache persistent for 1440 minutes with metadata { } # R: event_register: creating event event_event_usage_example_install_php persistent for 2880 minutes with metadata { } # R: event_install_handler: with tags { "event_handler", "event_prefix=ALL", "event_type=install" } got events { "event_event_usage_example_install_php" } # R: event_handle: with prefix event_usage_example and type install found events { "event_event_usage_example_install_php" } # R: event_handle: with prefix event_usage_example and type install found handlers { "default:event_install_handler" } # R: event_debug_handler: with tags { "event_handler", "event_prefix=.*", "event_type=.*" } got events { "event_event_usage_example_restart_apache", "event_event_usage_example_install_php" } # R: event_handle: with prefix .* and type .* found events { "event_event_usage_example_restart_apache", "event_event_usage_example_install_php" } # R: event_handle: with prefix .* and type .* found handlers { "default:event_debug_handler" } # ``` { vars: "empty" slist => {}; methods: # register a restart event named "apache" with persistence = 1 day "" usebundle => event_register( $(this.bundle), "restart", "apache", 1440, @(empty) ); # 1 day # register an install event named "php" with persistence = 2 days "" usebundle => event_register( $(this.bundle), "install", "php", 2880, @(empty) ); # the following can be run immediately, or up to 2 days later to collect # the install event above "" usebundle => event_handle($(this.bundle), "install"); # the following can be run immediately, or up to 1 day later to collect # the restart event above "" usebundle => event_handle(".*", ".*"); } @endif cfengine-masterfiles-3.27.3/lib/examples.cf0000644000000000000000000000453114735102600016765 0ustar0000000000000000bundle 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), if => "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), if => "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" if => "activate_bundle_$(probability)000"; "$(this.bundle) activate_bundle_$(probability)001" if => "activate_bundle_$(probability)001"; } cfengine-masterfiles-3.27.3/lib/feature.cf0000644000000000000000000000614414735102600016604 0ustar0000000000000000bundle 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: "DEBUG|DEBUG_$(this.bundle)":: "DEBUG $(this.bundle): $(on) => SET class '$(extract_$(on)[2]) for '$(extract_$(on)[1])'" if => "parsed_$(on)"; "DEBUG $(this.bundle): $(off) => UNSET class '$(extract_$(off)[1])'" if => "parsed_$(off)"; "DEBUG $(this.bundle): have $(extract_$(on)[2])" if => "$(extract_$(on)[2])"; "DEBUG $(this.bundle): have no $(extract_$(on)[2])" if => "!$(extract_$(on)[2])"; "DEBUG $(this.bundle): have $(extract_$(off)[1])" if => "$(extract_$(off)[1])"; "DEBUG $(this.bundle): have no $(extract_$(off)[1])" if => "!$(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])" if => "$(extract_$(on)[2])"; "$(this.bundle): have no $(extract_$(on)[2])" if => "!$(extract_$(on)[2])"; "$(this.bundle): have $(extract_$(off)[1])" if => "$(extract_$(off)[1])"; "$(this.bundle): have no $(extract_$(off)[1])" if => "!$(extract_$(off)[1])"; } body classes feature_cancel(x) # @brief Undefine class `x` when promise is kept or repaired # # Used internally by bundle `feature` { cancel_kept => { "$(x)" }; cancel_repaired => { "$(x)" }; } cfengine-masterfiles-3.27.3/lib/files.cf0000644000000000000000000021007014735102600016246 0ustar0000000000000000# Files bodies bundle common files_common # @brief Enumerate policy files used by this policy file for inclusion to inputs { vars: "inputs" slist => { "$(this.promise_dirname)/common.cf" }; } body file control # @brief Include policy files used by this policy file as part of inputs { inputs => { @(files_common.inputs) }; } ################################################### # edit_line bundles ################################################### bundle edit_line insert_before_if_no_line(before, string) # @brief Insert `string` before `before` if `string` is not found in the file # @param before The regular expression matching the line which `string` will be # inserted before # @param string The string to be prepended { insert_lines: "$(string)" location => before($(before)), comment => "Prepend a line to the file if it doesn't already 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 lines_present(lines) # @brief Ensure `lines` are present in the file. Lines that do not exist are appended to the file # @param lines List or string that should be present in the file # # **Example:** # # ```cf3 # bundle agent example # { # vars: # "nameservers" slist => { "8.8.8.8", "8.8.4.4" }; # # files: # "/etc/resolv.conf" edit_line => lines_present( @(nameservers) ); # "/etc/ssh/sshd_config" edit_line => lines_present( "PermitRootLogin no" ); # } # ``` { insert_lines: "$(lines)" comment => "Append lines if they don't exist"; } bundle edit_line insert_lines(lines) # @brief Alias for `lines_present` # @param lines List or string that should be present in the file { insert_lines: "$(lines)" comment => "Append lines if they don't exist"; } bundle edit_line append_if_no_line(lines) # @brief Alias for `lines_present` # @param lines List or string that should be present in the file { insert_lines: "$(lines)" comment => "Append lines if they don't exist"; } bundle edit_line append_if_no_lines(lines) # @brief Alias for `lines_present` # @param lines List or string that should be present in the file { insert_lines: "$(lines)" comment => "Append lines if they don't exist"; } ## 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 contains_literal_string(string) # @brief Ensure the literal string is present in the promised file # @description If the string is not found in the file it is inserted according # to CFEngine defaults. # @param string The string (potentially multiline) to ensure exists in the # promised file. { insert_lines: "$(string)" insert_type => "preserve_block", expand_scalars => "false", whitespace_policy => { "exact_match" }; } ## 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` promise type][insert_lines] # * [`edit_line` bundles][edit_line] { insert_lines: "$(string)" location => start, comment => "Prepend a line to the file if it doesn'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 replace_uncommented_substrings(_comment, _find, _replace) # @brief Replace all occurrences of `_find` with `_replace` on lines that do not follow a `_comment` # @param _comment Sequence of characters, each indicating the start of a comment. # @param _find String matching substring to replace # @param _replace String to substitute `_find` with # # **Example:** # # ```cf3 # bundle agent example_replace_uncommented_substrings # { # files: # "/tmp/file.txt" # edit_line => replace_uncommented_substrings( "#", "ME", "YOU"); # } # ``` # # **Notes:** # # * Only single character comments are supported as `_comment` is used in the PCRE character group (`[^...]`). # * `-` in `_comment` is interpreted as a range unless it's used as the first or last character. For example, setting `_comment` to `0-9` means any digit starts a comment. # # **History:** # # * Introduced 3.17.0, 3.15.3 { vars: "_reg_match_uncommented_lines_containing_find" string => "^([^$(_comment)]*)\Q$(_find)\E(.*$)"; replace_patterns: "$(_reg_match_uncommented_lines_containing_find)" replace_with => text_between_match1_and_match2($(_replace)); } ## 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)]"); delete_lines: ".*" select_region => INI_section(escape("$(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(escape("$(sectionName)")); } ## 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:** `manage_variable_values_ini()` { vars: "index" slist => getindices("$(tab)[$(sectionName)]"); # Be careful if the index string contains funny chars "cindex[$(index)]" string => canonify("$(index)"); "_escaped_section" string => escape("$(sectionName)"); classes: "edit_$(cindex[$(index)])" not => strcmp("$($(tab)[$(sectionName)][$(index)])", "dontchange"), comment => "Create conditions to make changes"; "section_$(sectionName)_exists" expression => regline("^\[$(_escaped_section)\]", "$(edit.filename)"), if => fileexists("$(edit.filename)"), comment => "Check if the section header already exists in the file"; field_edits: # If the line is there, but commented out, first uncomment it "#+\s*$(index)\s*=.*" select_region => INI_section(escape("$(sectionName)")), edit_field => col("\s*=\s*", "1", "$(index)", "set"), if => and( "edit_$(cindex[$(index)])", canonify("section_$(sectionName)_exists") ); # match a line starting like the key something "\s*$(index)\s*=.*" edit_field => col( "\s*=\s*", "2", "$($(tab)[$(sectionName)][$(index)])", "set" ), select_region => INI_section(escape("$(sectionName)")), classes => results( "bundle", "set_variable_values_ini_not_$(cindex[$(index)])" ), if => and( "edit_$(cindex[$(index)])", canonify("section_$(sectionName)_exists") ); insert_lines: "[$(sectionName)]" location => start, comment => "Insert lines"; "$(index)=$($(tab)[$(sectionName)][$(index)])" select_region => INI_section(escape("$(sectionName)")), if => and( "!(set_variable_values_ini_not_$(cindex[$(index)])_kept|set_variable_values_ini_not_$(cindex[$(index)])_repaired)", "edit_$(cindex[$(index)])", canonify("section_$(sectionName)_exists") ), handle => "insert_key_in_existing_section_$(sectionName)_$(cindex[$(index)])"; "$(index)=$($(tab)[$(sectionName)][$(index)])" location => after("^\[$(_escaped_section)\]"), if => and( "edit_$(cindex[$(index)])", not(canonify("section_$(sectionName)_exists")) ), handle => "insert_key_in_new_section_$(sectionName)_$(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_ini_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: # TODO: refactor once 3.7.x is EOL "indices" slist => getindices($(config)); "k" slist => sort("indices", lex); insert_lines: "[$(name)]" location => start, comment => "Insert an ini section with values if not present"; "$(k)=$($(config)[$(k)])" location => after("[$(name)]"); } 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 => results("bundle", "$(cindex[$(index)])_in_file"), comment => "Match a line starting like key = something"; insert_lines: '$(index)="$($(v)[$(index)])"' comment => "Insert a variable definition", if => "!($(cindex[$(index)])_in_file_kept|$(cindex[$(index)])_in_file_repaired)"; } ## 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_variable_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 => results("bundle", "$(cv)_$(cindex[$(index)])_in_file"), comment => "Match a line starting like key = something"; insert_lines: "$(index)=$($(v)[$(index)])" comment => "Insert a variable definition", if => "!($(cv)_$(cindex[$(index)])_in_file_kept|$(cv)_$(cindex[$(index)])_in_file_repaired)"; } 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)"), scope => "bundle"; # 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" ), scope => "bundle"; replace_patterns: # If the line is commented out, uncomment and replace with # the correct value "^\s*#\s*($(index)\s+.*|$(index))$" comment => "If we find a single commented entry we can uncomment it to keep the settings near any inline documentation. If there are multiple comments, then we don't try to replace them and instead will later append the new value after the first commented occurrence of $(index).", handle => "set_config_values_replace_commented_line", replace_with => value("$(index) $($(v)[$(index)])"), if => "!line_exists_$(cindex[$(index)]).!replace_attempted_$(cindex[$(index)])_reached.!multiple_comments_$(cindex[$(index)])", classes => results("bundle", "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 => results("bundle", "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))$"), if => "replace_attempted_$(cindex[$(index)])_reached.multiple_comments_$(cindex[$(index)])"; # If the line doesn't exist and there are no occurrences # of the LHS commented out, insert a new line at the eof "$(index) $($(v)[$(index)])" comment => "Insert the value, marker doesn't exist $(index)", if => "replace_attempted_$(cindex[$(index)])_reached.!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. # **Note:** If the data structure being used for the first parameter is in the current bundle, you can use `$(this.bundle).variable`. # # Originally `set_config_values` by Ed King. # # @param v The fully-qualified name (`bundlename.variable`) 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: # 3.21.0 and greater know about a file being emptied before editing and # skip this check since it does not make sense. @if minimum_version(3.21) # Check to see if this line exists "exists_$(ci[$(i)])" expression => regline("^\s*($(i)$(bp).*|$(i))$", $(edit.filename)), unless => strcmp("true", $(edit.empty_before_use)); @endif @if minimum_version(3.18) !(cfengine_3_18_0|cfengine_3_18_1|cfengine_3_18_2):: "exists_$(ci[$(i)])" expression => regline("^\s*($(i)$(bp).*|$(i))$", $(edit.filename)), unless => strcmp("true", $(edit.empty_before_use)); @endif (cfengine_3_15|cfengine_3_16|cfengine_3_17|cfengine_3_18_0|cfengine_3_18_1|cfengine_3_18_2|cfengine_3_19|cfengine_3_20):: # Version 3.15.0 does not know about the before_version macro, so we keep the same behavior # TODO Remove after 3.21 is no longer supported. (3.15.0 was supported when 3.21 was released) # Check to see if this line exists "exists_$(ci[$(i)])" expression => regline("^\s*($(i)$(bp).*|$(i))$", $(edit.filename)); any:: # 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)])"), if => "!exists_$(ci[$(i)]).!replace_attempted_$(ci[$(i)])_reached.!multiple_comments_$(ci[$(i)])", classes => results("bundle", "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 => results("bundle", "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))$"), if => "replace_attempted_$(ci[$(i)])_reached.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", if => "replace_attempted_$(ci[$(i)])_reached.!multiple_comments_$(ci[$(i)]).!exists_$(ci[$(i)])"; reports: verbose_mode|EXTRA:: "$(this.bundle): Line for '$(i)' exists" if => "exists_$(ci[$(i)])"; "$(this.bundle): Line for '$(i)' does not exist" if => "!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 => results("bundle", "replace_attempted_$(cindex[$(index)])"); insert_lines: "$(index) $($(v)[$(index)])" if => "replace_attempted_$(cindex[$(index)])_reached"; } ## bundle edit_line maintain_key_values(v, sep) # @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)", if => "!$(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", if => "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", if => "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 A regular expression matching the user(s) 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. # # **See also:** # # * [bundle edit_line set_escaped_user_field][lib/files.cf#set_escaped_user_field] # * [edit_line field_edits][field_edits] { field_edits: "$(user):.*" comment => "Edit a user attribute in the password file", edit_field => col(":", "$(field)", "$(val)", "set"); } ## bundle edit_line set_escaped_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. # # **See also:** # # * [bundle edit_line set_user_field][lib/files.cf#set_user_field] # * [edit_line field_edits][field_edits] { vars: "escaped_user" string => escape("$(user)"); field_edits: "$(escaped_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. { field_edits: "$(group):.*" comment => "Append users into a password file format", edit_field => col(":", "$(field)", "$(allusers)", "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 => results("bundle", "replace_$(cline)"); insert_lines: "$(line)" if => "replace_$(cline)_reached"; } 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` # # **Example:** # # ```cf3 # bundle agent pam_d_su_include # #@brief Ensure /etc/pam.d/su has includes configured properly # { # files: # ubuntu:: # "/etc/pam.d/su" # edit_line => converge( "@include", "@include common-auth # @include common-account # @include common-session"); # } # ``` # # **History:** # # * Introduced in 3.6.0 { 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 converge_prepend(marker, lines) # @brief Converge `lines` marked with `marker` to start of content # # Any content marked with `marker` is removed, then `lines` are # inserted at *start* of content. 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` # # **Example:** # # ```cf3 # bundle agent pam_d_su_session # #@brief Ensure /etc/pam.d/su has session configured properly # { # files: # ubuntu:: # "/etc/pam.d/su" # edit_line => converge_prepend( "session", "session required pam_env.so readenv=1 envfile=/etc/default/locale # session optional pam_mail.so nopen # session required pam_limits.so" ); # } # ``` # # **History:** # # * Introduced in 3.17.0, 3.15.3, 3.12.6 { vars: "regex" string => escape($(marker)); delete_lines: ".*$(regex).*" comment => "Delete lines matching the marker"; insert_lines: "$(lines)" location => start, 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 (append|prepend|alphanum|set|delete) # Ref https://docs.cfengine.com/latest/reference-promise-types-files-edit_line-field_edits.html#field_operation { 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 text_between_match1_and_match2(_text) # @brief Replace matched line with substituted string # @param _text String to substitute between first and second match { replace_value => "$(match.1)$(_text)$(match.2)"; occurrences => "all"; } 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*"; @if minimum_version(3.10) select_end_match_eof => "true"; @endif } ##------------------------------------------------------- ## 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 # # **See Also:** `local_dcp()` { servers => { "$(server)" }; source => "$(from)"; compare => "digest"; } ## body copy_from local_cp(from) # @brief Copy a file if the modification time or creation time of the source # file is newer (the default comparison mechanism). # @param from The path to the source file. # # **Example:** # # ```cf3 # bundle agent example # { # files: # "/tmp/file.bak" # copy_from => local_cp("/tmp/file"); # } # ``` # # **See Also:** `local_dcp()` { source => "$(from)"; } ## body copy_from local_dcp(from) # @brief Copy a local file if the hash on the source file differs. # @param from The path to the source file. # # **Example:** # # ```cf3 # bundle agent example # { # files: # "/tmp/file.bak" # copy_from => local_dcp("/tmp/file"); # } # ``` # # **See Also:** `local_cp()`, `remote_dcp()` { 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. # # **Example:** # # ```cf3 # bundle agent home_dir_init # { # files: # "/home/mark.burgess/." # copy_from => seed_cp("/etc/skel"), # depth_search => recurse(inf), # file_select => all, # comment => "We want to be sure that the home directory has files that are # present in the skeleton."; # } # ``` { source => "$(from)"; compare => "exists"; } ## body copy_from sync_cp(from, server) # @brief Synchronize a file with a remote server. # # * If the file does not exist on the remote server then it should be purged. # * Allow types to change (directories to files and vice versa). # * The mode of the remote file should be preserved. # * Files are compared using the default comparison (mtime or ctime). # # @param from The location of the file on the remote server # @param server The hostname or IP of the server from which to download # # **Example**: # # ```cf3 # files: # "/tmp/masterfiles/." # copy_from => sync_cp( "/var/cfengine/masterfiles", $(sys.policy_server) ), # depth_search => recurse(inf), # file_select => all, # comment => "Mirror masterfiles from the hub to a temporary directory"; # ``` # # **See Also:** `dir_sync()`, `copyfrom_sync()` { 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_cp_compare(from, comparison) # @brief Copy a local file (`from`) based on comparison (`comparison`) and don't make any backup of the previous version # # @param from The path to the source file. # @param comparison The comparison to use. (mtime|ctime|atime|exists|binary|hash|digest) { source => "$(from)"; copy_backup => "false"; compare => "$(comparison)"; } ## 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)"; #+begin_ENT-951 # Remove after 3.20 is not supported rxdirs => "true"; @if minimum_version(3.20) rxdirs => "false"; @endif #+end } ## 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)"; #+begin_ENT-951 # Remove after 3.20 is not supported rxdirs => "true"; @if minimum_version(3.20) rxdirs => "false"; @endif #+end } ## 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)"; #+begin_ENT-951 # Remove after 3.20 is not supported rxdirs => "true"; @if minimum_version(3.20) rxdirs => "false"; @endif #+end } ## 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)"; #+begin_ENT-951 # Remove after 3.20 is not supported rxdirs => "true"; @if minimum_version(3.20) rxdirs => "false"; @endif #+end !windows:: owners => { "root" }; windows:: # NOTE: Setting owners will generate an error if the policy is not being # executed as the user who's ownership is being targeted. While it seems # that should typically be Administrator or SYSTEM, both are reported to # result in errors by users, thus owners is currently omitted for Windows. # ENT-9778 groups => { "Administrators" }; freebsd|openbsd|netbsd|darwin:: groups => { "wheel" }; linux:: groups => { "root" }; solaris:: groups => { "sys" }; aix:: groups => { "system" }; } ##------------------------------------------------------- ## 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 excluded. # # @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 excluding 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"; } @if minimum_version(3.27) ##------------------------------------------------------- ## fsattrs ##------------------------------------------------------- body fsattrs immutable(state) # @brief Ensure promised file is immutable or is not immutable # @param state A string representing a boolean choice in the range `(true|yes|on)` for true and `(false|no|off)` for false.. When true file immutability is enforced, when false file immutability is removed. # # **Example:** # # ```cf3 # files: # "/etc/motd" # content => "There are, in fact, rules. You have been notified.", # fsattrs => immutable("true"), # perms => mog( "644", "root", "root" ); # ```` { # When true the end state of the file is immutable. If the promise # necessitates a change in the file, the agent will handle immutability # transparently with the bit being removed just before modification # and restored immediately after the atomic change is made. immutable => "$(state)"; # The i attribute supported by chattr } body fsattrs is_immutable # @brief Ensure promised file is immutable # # **Example:** # # ```cf3 # files: # "/etc/motd" # content => "There are, in fact, rules. You have been notified.", # fsattrs => is_immutable, # perms => mog( "644", "root", "root" ); # ```` { # The end state of the file should be immutable. If the promise # necessitates a change in the file, the agent will handle immutability # transparently with the bit being removed just before modification and # restored immediately after the atomic change is made. immutable => "true"; # The i attribute supported by chattr } body fsattrs is_not_immutable # @brief Ensure promised file is immutable # # **Example:** # # ```cf3 # files: # "/etc/motd" # content => "There are, in fact, rules. You have been notified.", # fsattrs => is_not_immutable, # perms => mog( "644", "root", "root" ); # ```` { # The end state of the file should be mutable. If the immutable bit is set # it will be removed. immutable => "false"; # The i attribute supported by chattr } @endif ##------------------------------------------------------- ## 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 not_dir # @brief Select all files that are not directories { file_types => { "dir" }; file_result => "!file_types"; } 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"; } body file_select symlinked_to(target) # @brief Select symlinks that point to $(target) # @param target The file the symlink should point to in order to be selected { file_types => { "symlink" }; issymlinkto => { "$(target)" }; file_result => "issymlinkto"; } ##------------------------------------------------------- ## 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: "DEBUG|DEBUG_$(this.bundle)":: "DEBUG $(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: "DEBUG|DEBUG_$(this.bundle)":: "DEBUG $(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: "DEBUG|DEBUG_$(this.bundle)":: "DEBUG $(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"); # ``` { vars: "len" int => string_length($(str)); summarize:: "summary" string => format( "%s...%s", string_head($(str), 18), string_tail($(str), 18) ); classes: "summarize" expression => isgreaterthan($(len), 40); files: "$(file)" create => "true", edit_line => insert_lines($(str)), edit_defaults => empty; reports: "DEBUG|DEBUG_$(this.bundle)":: "DEBUG $(this.bundle): creating $(file) with contents '$(str)'" if => "!summarize"; "DEBUG $(this.bundle): creating $(file) with contents '$(summary)'" if => "summarize"; } bundle agent file_make_mog(file, str, mode, owner, group) # @brief Make a file from a string with mode, owner, group # @param file target # @param str the string data # @param mode the file permissions in octal # @param owner the file owner as a name or UID # @param group the file group as a name or GID # # **Example:** # # ```cf3 # methods: # "" usebundle => file_make_mog("/tmp/z.txt", "Some text # and some more text here", "0644", "root", "root"); # ``` { vars: "len" int => string_length($(str)); summarize:: "summary" string => format( "%s...%s", string_head($(str), 18), string_tail($(str), 18) ); classes: "summarize" expression => isgreaterthan($(len), 40); files: "$(file)" create => "true", edit_line => insert_lines($(str)), perms => mog($(mode), $(owner), $(group)), edit_defaults => empty; reports: "DEBUG|DEBUG_$(this.bundle)":: "DEBUG $(this.bundle): creating $(file) with contents '$(str)', mode '$(mode)', owner '$(owner)' and group '$(group)'" if => "!summarize"; "DEBUG $(this.bundle): creating $(file) with contents '$(summary)', mode '$(mode)', owner '$(owner)' and group '$(group)'" if => "summarize"; } bundle agent file_make_mustache(file, template, data) # @brief Make a file from a mustache template # @param file Target file to render # @param template Path to mustache template # @param data Data container to use # # **Example:** # # ```cf3 # vars: # "state" data => datastate(); # # methods: # "" usebundle => file_make_mustache( "/tmp/z.txt", "/tmp/z.mustache", @(state) ); # ``` { files: "$(file)" create => "true", edit_template => "$(template)", template_method => "mustache", template_data => @(data); reports: "DEBUG|DEBUG_$(this.bundle)":: "DEBUG $(this.bundle): rendering $(file) with template '$(template)'"; } bundle agent file_make_mustache_with_perms(file, template, data, mode, owner, group) # @brief Make a file from a mustache template # @param file Target file to render # @param template Path to mustache template # @param data Data container to use # @param mode File permissions # @param owner Target file owner # @param group Target file group # # **Example:** # # ```cf3 # vars: # "state" data => datastate(); # # methods: # "" usebundle => file_make_mustache( "/tmp/z.txt", "/tmp/z.mustache", @(state), # 600, "root", "root" ); # ``` { files: "$(file)" create => "true", edit_template => "$(template)", template_method => "mustache", perms => mog($(mode), $(owner), $(group)), template_data => @(data); reports: "DEBUG|DEBUG_$(this.bundle)":: "DEBUG $(this.bundle): rendering $(file) with template '$(template)'"; } 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: "DEBUG|DEBUG_$(this.bundle)":: "DEBUG $(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: "DEBUG|DEBUG_$(this.bundle)":: "DEBUG $(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: "DEBUG|DEBUG_$(this.bundle)":: "DEBUG $(this.bundle): $(link) will be a symlink to $(target)"; } cfengine-masterfiles-3.27.3/lib/guest_environments.cf0000644000000000000000000000311014735102600021075 0ustar0000000000000000# Guest environments bodies 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 "; } cfengine-masterfiles-3.27.3/lib/monitor.cf0000644000000000000000000000362014735102600016634 0ustar0000000000000000# Monitor bodies 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`, `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`, `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`, `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`, `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)"; } cfengine-masterfiles-3.27.3/lib/packages-ENT-3719.cf0000644000000000000000000000040114735102600017742 0ustar0000000000000000body package_module msiexec { query_installed_ifelapsed => "60"; query_updates_ifelapsed => "1440"; interpreter => "$(sys.winsysdir)$(const.dirsep)cmd.exe /c "; module_path => "$(def.dir_modules)$(const.dirsep)packages$(const.dirsep)msiexec.bat"; } cfengine-masterfiles-3.27.3/lib/packages.cf0000644000000000000000000025347114735102600016736 0ustar0000000000000000# Packages bodies bundle common package_module_knowledge # @brief common package_module_knowledge bundle # # This common bundle defines which package modules are the defaults on different # platforms. { vars: # First we set the default package manager based on the platform: # TODO Refactor to use ifelse()? debian:: "platform_default" string => "apt_get"; freebsd:: "platform_default" string => "pkg"; redhat|amazon_linux:: "platform_default" string => "yum"; suse|sles|opensuse:: "platform_default" string => "zypper"; aix:: "platform_default" string => "nimclient"; slackware:: "platform_default" string => "slackpkg"; windows:: "platform_default" string => "msiexec"; alpinelinux:: "platform_default" string => "apk"; termux:: "platform_default" string => "apt_get"; any:: # By default, we don't want additional package managers inventoried, but # we need the variable to be defined, so we initialize it to an empty # list. "additional_inventory" slist => {}; # We look to see if additional package inventory modules should be used. # `default:def.additional_package_inventory_modules` is expected to be a data # structure keyed with values expected to match the value of `sys.flavor`. # For example: { "aix_7": [ "yum"], "ubuntu_20: [ "snap" ] } # If there is additional inventory defined for the platform we want to use them "additional_inventory" -> { "CFE-3612" } slist => getvalues( "default:def.additional_package_inventory_modules[$(sys.flavor)]" ), if => isvariable( "default:def.additional_package_inventory_modules[$(sys.flavor)]" ); # Package inventory refresh "query_installed_ifelapsed" -> { "CFE-2771", "CFE-3504" } string => ifelse( isvariable("def.package_module_$(this.promiser)"), "$(def.package_module_$(this.promiser))", "0" ); # Always refresh local package inventory "query_updates_ifelapsed" -> { "CFE-2771", "CFE-3504" } string => ifelse( isvariable("def.package_module_$(this.promiser)"), "$(def.package_module_$(this.promiser))", "1440" ); # Refresh software updates available once a day # It's possible that a user wants to use a different default package # manager. To support that we look at # `default:def.default_package_module`, a data structure keyed # with values expected to match the value of `sys.flavor` "platform_default" -> { "CFE-3612" } string => "$(default:def.default_package_module[$(sys.flavor)])", if => isvariable("default:def.default_package_module[$(sys.flavor)]"), comment => concat( "default:def.default_package_module[$(sys.flavor)] has been defined.", "This overrides the default package manager." ); } body package_module apk { query_installed_ifelapsed => "$(package_module_knowledge.query_installed_ifelapsed)"; query_updates_ifelapsed => "$(package_module_knowledge.query_updates_ifelapsed)"; } body package_module apt_get { query_installed_ifelapsed => "$(package_module_knowledge.query_installed_ifelapsed)"; query_updates_ifelapsed => "$(package_module_knowledge.query_updates_ifelapsed)"; #default_options => {}; @if minimum_version(3.12.2) termux:: interpreter => "$(paths.bin_path)/python"; !termux:: interpreter => "$(sys.bindir)/cfengine-selected-python"; @endif } body package_module dnf_group # @brief manage dnf package groups # # **Example:** # # ```cf3 # "development" # policy => "present", # package_module => dnf_group, # options => { "group_package_types=optional", # "install_weak_deps=false" }, # version => "latest"; # Upgrade group packages # ``` { query_installed_ifelapsed => "$(package_module_knowledge.query_installed_ifelapsed)"; query_updates_ifelapsed => "$(package_module_knowledge.query_updates_ifelapsed)"; interpreter => "$(sys.bindir)/cfengine-selected-python"; } body package_module zypper { query_installed_ifelapsed => "$(package_module_knowledge.query_installed_ifelapsed)"; query_updates_ifelapsed => "$(package_module_knowledge.query_updates_ifelapsed)"; #default_options => {}; @if minimum_version(3.12.2) interpreter => "$(sys.bindir)/cfengine-selected-python"; @endif } body package_module nimclient # @brief Define details used when interfacing with nimclient package # module # # **Example:** # # ```cf3 # bundle agent example_nimclient # { # packages: # "expect.base" # policy => "present", # options => { "lpp_source=lppaix71034" }, # package_module => nimclient; # } # ``` { query_installed_ifelapsed => "$(package_module_knowledge.query_installed_ifelapsed)"; query_updates_ifelapsed => "$(package_module_knowledge.query_updates_ifelapsed)"; # This would likey be customized based on your infrastructure specifics # you may for example want to default the lpp_source based on something # like `oslevel -s` output. #default_options => {}; } body package_module pkgsrc # @brief Define details used when interfacing with the pkgsrc package # module. # # **Example:** # ```cf3 # bundle agent main # { # packages: # "vim" # policy => "present", # package_module => pkgsrc; # } # ``` { query_installed_ifelapsed => "$(package_module_knowledge.query_installed_ifelapsed)"; query_updates_ifelapsed => "$(package_module_knowledge.query_updates_ifelapsed)"; } body package_module yum # @brief Define details used when interfacing with yum { query_installed_ifelapsed => "$(package_module_knowledge.query_installed_ifelapsed)"; query_updates_ifelapsed => "$(package_module_knowledge.query_updates_ifelapsed)"; #default_options => {}; @if minimum_version(3.12.2) interpreter => "$(sys.bindir)/cfengine-selected-python"; @endif } body package_module dnf # @brief Define details used when interfacing with dnf { query_installed_ifelapsed => "$(package_module_knowledge.query_installed_ifelapsed)"; query_updates_ifelapsed => "$(package_module_knowledge.query_updates_ifelapsed)"; #default_options => {}; @if minimum_version(3.12.2) interpreter => "$(sys.bindir)/cfengine-selected-python"; @endif } body package_module slackpkg # @brief Define details used when interfacing with slackpkg { query_installed_ifelapsed => "$(package_module_knowledge.query_installed_ifelapsed)"; query_updates_ifelapsed => "$(package_module_knowledge.query_updates_ifelapsed)"; #default_options => {}; } body package_module pkg # @brief Define details used when interfacing with pkg { query_installed_ifelapsed => "$(package_module_knowledge.query_installed_ifelapsed)"; query_updates_ifelapsed => "$(package_module_knowledge.query_updates_ifelapsed)"; #default_options => {}; } body package_module snap # @brief Define details used when interfacing with snapcraft { query_installed_ifelapsed => "$(package_module_knowledge.query_installed_ifelapsed)"; query_updates_ifelapsed => "$(package_module_knowledge.query_updates_ifelapsed)"; #default_options => {}; } body package_module freebsd_ports # @brief Define details used when interfacing with the freebsd ports package # module. # # **Note:** Ports are expected to be setup prior to trying to use the packages # promise. You may need to ensure that `portsnap extract` has been run, e.g. # fileexists("/usr/ports/Mk/bsd.port.mk") # # **Example:** # ```cf3 # bundle agent main # { # packages: # freebsd:: # "vim" # policy => "present", # package_module => freebsd_ports; # } # ``` { query_installed_ifelapsed => "$(package_module_knowledge.query_installed_ifelapsed)"; query_updates_ifelapsed => "$(package_module_knowledge.query_updates_ifelapsed)"; } bundle common packages_common # @brief Define inputs required for this policy file { vars: "inputs" slist => { "$(this.promise_dirname)/paths.cf", "$(this.promise_dirname)/files.cf", "$(this.promise_dirname)/common.cf", }; } body file control # @brief include policy needed by this file { inputs => { @(packages_common.inputs) }; } ##-------------------------------------------------------------- ## Packages promises ##-------------------------------------------------------------- bundle common common_knowledge # @brief common packages knowledge bundle # # This common bundle defines general things about platforms. { vars: # This variable can be customized via augments: # { "variables": { "default:common_knowledge.list_update_ifelapsed": { "value": "0" } } } "list_update_ifelapsed" string => "240", if => not(isvariable("list_update_ifelapsed")), comment => concat( "The number of minutes to wait before updating the", " package cache. Note this controls both the software", " installed and the software updates available." ); } 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_no_locking_knowledge { vars: # Option was introduced in rhel 6.1 (amazon_linux|redhat|centos).!(redhat_3|redhat_4|redhat_5|redhat_6_0|centos_3|centos_4|centos_5|centos_6_0):: "no_locking_option" string => "--setopt=exit_on_lock=True"; redhat_3|redhat_4|redhat_5|redhat_6_0|centos_3|centos_4|centos_5|centos_6_0:: "no_locking_option" string => ""; } 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])"; "call_rpmvercmp" string => "$(sys.bindir)/rpmvercmp"; # on RHEL 3/4, Yum doesn't know how to be --quiet "yum_options" string => ifelse( "centos_4|redhat_4|centos_3|redhat_3", "", "--quiet ${redhat_no_locking_knowledge.no_locking_option}" ); "yum_offline_options" string => "$(yum_options) -C"; "rpm_compare_equal" string => "$(call_rpmvercmp) '$(v1)' eq '$(v2)'"; "rpm_compare_less" string => "$(call_rpmvercmp) '$(v1)' lt '$(v2)'"; # yum check-update prints a lot of extra useless lines, but the format of # the actual package lines is: # # . # # 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 performs recursive upgrade (of dependencies) by # default. Set $flags to "--no-deps" to perform non-recursive upgrade. # http://www.pip-installer.org/en/latest/cookbook.html#non-recursive-upgrades # # **Example:** # # ```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`. # # Normally you have to specify the package version, and it defaults to # `*`, which then triggers the bug of installing `xyz-abc` when you ask for `xyz`. # # This "permissive" body sets # # package_name_convention => "$(name)"; # # which is permissive in the sense of not requiring the version. # # **Example:** # # ```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].*"; package_version_less_command => "$(redhat_knowledge.rpm_compare_less)"; package_version_equal_command => "$(redhat_knowledge.rpm_compare_equal)"; } ## 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_offline_options) check-update $(redhat_knowledge.check_update_postproc)"; package_list_name_regex => "$(rpm_knowledge.rpm3_name_regex)"; package_list_version_regex => "$(rpm_knowledge.rpm3_version_regex)"; package_list_arch_regex => "$(rpm_knowledge.rpm3_arch_regex)"; package_installed_regex => ".*"; package_name_convention => "$(name)-$(version).$(arch)"; # just give the package name to rpm to delete, otherwise it gets "name.*" (from package_name_convention above) package_delete_convention => "$(name)"; # set it to "0" to avoid caching of list during upgrade package_list_update_command => "$(redhat_knowledge.call_yum) $(redhat_knowledge.yum_options) check-update $(redhat_knowledge.check_update_postproc)"; package_list_update_ifelapsed => "$(common_knowledge.list_update_ifelapsed)"; package_patch_name_regex => "$(redhat_knowledge.patch_name_regex)"; package_patch_version_regex => "$(redhat_knowledge.patch_version_regex)"; package_patch_arch_regex => "$(redhat_knowledge.patch_arch_regex)"; package_add_command => "$(redhat_knowledge.call_yum) $(redhat_knowledge.yum_options) -y install"; package_update_command => "$(redhat_knowledge.call_yum) $(redhat_knowledge.yum_options) -y update"; package_patch_command => "$(redhat_knowledge.call_yum) $(redhat_knowledge.yum_options) -y update"; package_delete_command => "$(rpm_knowledge.call_rpm) -e --nodeps"; package_verify_command => "$(rpm_knowledge.call_rpm) -V"; package_noverify_returncode => "1"; package_version_less_command => "$(redhat_knowledge.rpm_compare_less)"; package_version_equal_command => "$(redhat_knowledge.rpm_compare_equal)"; } ## 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_offline_options) check-update $(redhat_knowledge.check_update_postproc)"; package_list_name_regex => "$(rpm_knowledge.rpm3_name_regex)"; package_list_version_regex => "$(rpm_knowledge.rpm3_version_regex)"; package_list_arch_regex => "$(rpm_knowledge.rpm3_arch_regex)"; package_installed_regex => ".*"; package_name_convention => "$(name)-$(version).$(arch)"; # just give the package name to rpm to delete, otherwise it gets "name.*" (from package_name_convention above) package_delete_convention => "$(name)"; # set it to "0" to avoid caching of list during upgrade package_list_update_command => "$(redhat_knowledge.call_yum) $(redhat_knowledge.yum_options) check-update $(redhat_knowledge.check_update_postproc)"; package_list_update_ifelapsed => "$(common_knowledge.list_update_ifelapsed)"; package_patch_name_regex => "$(redhat_knowledge.patch_name_regex)"; package_patch_version_regex => "$(redhat_knowledge.patch_version_regex)"; package_patch_arch_regex => "$(redhat_knowledge.patch_arch_regex)"; package_add_command => "$(redhat_knowledge.call_yum) $(redhat_knowledge.yum_options) -y install"; package_update_command => "$(redhat_knowledge.call_yum) $(redhat_knowledge.yum_options) -y update"; package_patch_command => "$(redhat_knowledge.call_yum) $(redhat_knowledge.yum_options) -y update"; package_delete_command => "$(rpm_knowledge.call_rpm) -e --nodeps"; package_verify_command => "$(rpm_knowledge.call_rpm) -V"; package_noverify_returncode => "1"; package_version_less_command => "$(redhat_knowledge.rpm_compare_less)"; package_version_equal_command => "$(redhat_knowledge.rpm_compare_equal)"; } 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. # # Normally you have to specify the package version, and it defaults to # `*`, which then triggers the bug of installing `xyz-abc` when you ask for `xyz`. # # This "permissive" body sets # # package_name_convention => "$(name)"; # # which is permissive in the sense of not requiring the version. # # **Example:** # # ```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_offline_options) check-update $(redhat_knowledge.check_update_postproc)"; package_list_name_regex => "$(rpm_knowledge.rpm3_name_regex)"; package_list_version_regex => "$(rpm_knowledge.rpm3_version_regex)"; package_list_arch_regex => "$(rpm_knowledge.rpm3_arch_regex)"; package_installed_regex => ".*"; package_name_convention => "$(name)"; # not needed, same as package_name_convention above package_delete_convention => "$(name)"; # set it to "0" to avoid caching of list during upgrade package_list_update_command => "$(redhat_knowledge.call_yum) $(redhat_knowledge.yum_options) check-update $(redhat_knowledge.check_update_postproc)"; package_list_update_ifelapsed => "$(common_knowledge.list_update_ifelapsed)"; package_patch_name_regex => "$(redhat_knowledge.patch_name_regex)"; package_patch_version_regex => "$(redhat_knowledge.patch_version_regex)"; package_patch_arch_regex => "$(redhat_knowledge.patch_arch_regex)"; package_add_command => "$(redhat_knowledge.call_yum) $(redhat_knowledge.yum_options) -y install"; package_update_command => "$(redhat_knowledge.call_yum) $(redhat_knowledge.yum_options) -y update"; package_patch_command => "$(redhat_knowledge.call_yum) $(redhat_knowledge.yum_options) -y update"; package_delete_command => "$(rpm_knowledge.call_rpm) -e --nodeps"; package_verify_command => "$(rpm_knowledge.call_rpm) -V"; package_noverify_returncode => "1"; package_version_less_command => "$(redhat_knowledge.rpm_compare_less)"; package_version_equal_command => "$(redhat_knowledge.rpm_compare_equal)"; } ## 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_offline_options) check-update $(redhat_knowledge.check_update_postproc)"; package_list_name_regex => "$(rpm_knowledge.rpm2_name_regex)"; package_list_version_regex => "$(rpm_knowledge.rpm2_version_regex)"; package_list_arch_regex => "$(rpm_knowledge.rpm2_arch_regex)"; package_installed_regex => ".*"; package_name_convention => "$(name)"; # set it to "0" to avoid caching of list during upgrade package_list_update_command => "$(redhat_knowledge.call_yum) $(redhat_knowledge.yum_options) check-update $(redhat_knowledge.check_update_postproc)"; package_list_update_ifelapsed => "$(common_knowledge.list_update_ifelapsed)"; package_patch_name_regex => "$(redhat_knowledge.patch_name_regex)"; package_patch_version_regex => "$(redhat_knowledge.patch_version_regex)"; package_patch_arch_regex => "$(redhat_knowledge.patch_arch_regex)"; package_add_command => "$(redhat_knowledge.call_yum) $(redhat_knowledge.yum_options) --enablerepo=$(repoid) -y install"; package_update_command => "$(redhat_knowledge.call_yum) $(redhat_knowledge.yum_options) --enablerepo=$(repoid) -y update"; package_patch_command => "$(redhat_knowledge.call_yum) $(redhat_knowledge.yum_options) -y update"; package_delete_command => "$(rpm_knowledge.call_rpm) -e --nodeps --allmatches"; package_verify_command => "$(rpm_knowledge.call_rpm) -V"; package_noverify_returncode => "1"; package_version_less_command => "$(redhat_knowledge.rpm_compare_less)"; package_version_equal_command => "$(redhat_knowledge.rpm_compare_equal)"; } ## 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"; package_version_less_command => "$(redhat_knowledge.rpm_compare_less)"; package_version_equal_command => "$(redhat_knowledge.rpm_compare_equal)"; } ## 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;]+.*[\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 smartos_pkg_add(repo) # @brief SmartOS pkg_add installation package method # # This package method interacts with SmartOS pkg_add to install from local # or remote repositories. It is slightly different than the FreeBSD pkg_add. # # This example installs "perl5" from a remote repository: # # ```cf3 # ---------------------------- # packages: # "perl5" # package_policy => "add", # package_method => smartos_pkg_add("http://pkg.example.com/packages/"); # # ``` { package_changes => "individual"; package_list_command => "/opt/local/sbin/pkg_info"; package_list_name_regex => "([^\s]+)\-[0-9]+.*\s"; package_list_version_regex => "[^\s]+\-([0-9][^\s]+)\s"; package_installed_regex => ".*"; # all reported are installed package_add_command => "/usr/bin/env PKG_PATH=$(repo) /opt/local/sbin/pkg_add"; package_delete_command => "/opt/local/sbin/pkg_delete"; package_update_command => "/usr/bin/env PKG_PATH=$(repo) /opt/local/sbin/pkg_add"; } 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 install -y"; package_delete_command => "/usr/sbin/pkg delete -y"; } 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|sles|opensuse:: package_changes => "bulk"; package_list_command => "$(rpm_knowledge.call_rpm) -qa --queryformat \"$(rpm_knowledge.rpm_output_format)\""; # set it to "0" to avoid caching of list during upgrade package_list_update_command => "$(suse_knowledge.call_zypper) list-updates"; package_list_update_ifelapsed => "$(common_knowledge.list_update_ifelapsed)"; package_patch_list_command => "$(suse_knowledge.call_zypper) patches"; package_installed_regex => "i.*"; package_list_name_regex => "$(rpm_knowledge.rpm_name_regex)"; package_list_version_regex => "$(rpm_knowledge.rpm_version_regex)"; package_list_arch_regex => "$(rpm_knowledge.rpm_arch_regex)"; package_patch_installed_regex => ".*Installed.*|.*Not Applicable.*"; package_patch_name_regex => "[^|]+\|\s+([^\s]+).*"; package_patch_version_regex => "[^|]+\|[^|]+\|\s+([^\s]+).*"; package_name_convention => "$(name)"; package_add_command => "$(suse_knowledge.call_zypper) --non-interactive install"; package_delete_command => "$(suse_knowledge.call_zypper) --non-interactive remove --force-resolution"; package_update_command => "$(suse_knowledge.call_zypper) --non-interactive update"; package_patch_command => "$(suse_knowledge.call_zypper) --non-interactive patch$"; # $ means no args package_verify_command => "$(suse_knowledge.call_zypper) --non-interactive verify$"; redhat:: package_changes => "bulk"; package_list_command => "$(rpm_knowledge.call_rpm) -qa --qf '$(rpm_knowledge.rpm3_output_format)'"; package_patch_list_command => "$(redhat_knowledge.call_yum) $(redhat_knowledge.yum_offline_options) check-update $(redhat_knowledge.check_update_postproc)"; package_list_name_regex => "$(rpm_knowledge.rpm3_name_regex)"; package_list_version_regex => "$(rpm_knowledge.rpm3_version_regex)"; package_list_arch_regex => "$(rpm_knowledge.rpm3_arch_regex)"; package_installed_regex => ".*"; package_name_convention => "$(name)-$(version).$(arch)"; # just give the package name to rpm to delete, otherwise it gets "name.*" (from package_name_convention above) package_delete_convention => "$(name)"; # set it to "0" to avoid caching of list during upgrade package_list_update_command => "$(redhat_knowledge.call_yum) $(redhat_knowledge.yum_options) check-update $(redhat_knowledge.check_update_postproc)"; package_list_update_ifelapsed => "$(common_knowledge.list_update_ifelapsed)"; package_patch_name_regex => "$(redhat_knowledge.patch_name_regex)"; package_patch_version_regex => "$(redhat_knowledge.patch_version_regex)"; package_patch_arch_regex => "$(redhat_knowledge.patch_arch_regex)"; package_add_command => "$(redhat_knowledge.call_yum) $(redhat_knowledge.yum_options) -y install"; package_update_command => "$(redhat_knowledge.call_yum) $(redhat_knowledge.yum_options) -y update"; package_patch_command => "$(redhat_knowledge.call_yum) $(redhat_knowledge.yum_options) -y update"; package_delete_command => "$(rpm_knowledge.call_rpm) -e --nodeps"; package_verify_command => "$(rpm_knowledge.call_rpm) -V"; package_noverify_returncode => "1"; package_version_less_command => "$(redhat_knowledge.rpm_compare_less)"; package_version_equal_command => "$(redhat_knowledge.rpm_compare_equal)"; debian:: package_changes => "bulk"; package_list_command => "$(debian_knowledge.call_dpkg) -l"; package_list_name_regex => "$(debian_knowledge.list_name_regex)"; package_list_version_regex => "$(debian_knowledge.list_version_regex)"; package_installed_regex => ".i.*"; # packages that have been uninstalled may be listed package_name_convention => "$(name)"; package_list_update_ifelapsed => "$(common_knowledge.list_update_ifelapsed)"; # make correct version comparisons package_version_less_command => "$(debian_knowledge.dpkg_compare_less)"; package_version_equal_command => "$(debian_knowledge.dpkg_compare_equal)"; debian.have_aptitude:: package_add_command => "$(debian_knowledge.call_aptitude) $(debian_knowledge.dpkg_options) --assume-yes install"; package_list_update_command => "$(debian_knowledge.call_aptitude) update"; package_delete_command => "$(debian_knowledge.call_aptitude) $(debian_knowledge.dpkg_options) --assume-yes remove"; package_update_command => "$(debian_knowledge.call_aptitude) $(debian_knowledge.dpkg_options) --assume-yes install"; package_patch_command => "$(debian_knowledge.call_aptitude) $(debian_knowledge.dpkg_options) --assume-yes install"; package_verify_command => "$(debian_knowledge.call_aptitude) show"; package_noverify_regex => "(State: not installed|E: Unable to locate package .*)"; package_patch_list_command => "$(debian_knowledge.call_aptitude) --assume-yes --simulate --verbose full-upgrade"; package_patch_name_regex => "$(debian_knowledge.patch_name_regex)"; package_patch_version_regex => "$(debian_knowledge.patch_version_regex)"; debian.!have_aptitude:: package_add_command => "$(debian_knowledge.call_apt_get) $(debian_knowledge.dpkg_options) --yes install"; package_list_update_command => "$(debian_knowledge.call_apt_get) update"; package_delete_command => "$(debian_knowledge.call_apt_get) $(debian_knowledge.dpkg_options) --yes remove"; package_update_command => "$(debian_knowledge.call_apt_get) $(debian_knowledge.dpkg_options) --yes install"; package_patch_command => "$(debian_knowledge.call_apt_get) $(debian_knowledge.dpkg_options) --yes install"; package_verify_command => "$(debian_knowledge.call_dpkg) -s"; package_noverify_returncode => "1"; package_patch_list_command => "$(debian_knowledge.call_apt_get) --just-print dist-upgrade"; package_patch_name_regex => "$(debian_knowledge.patch_name_regex)"; package_patch_version_regex => "$(debian_knowledge.patch_version_regex)"; freebsd:: package_changes => "individual"; package_list_command => "/usr/sbin/pkg info"; package_list_name_regex => "([^\s]+)-.*"; package_list_version_regex => "[^\s]+-([^\s]+).*"; package_name_regex => "([^\s]+)-.*"; package_version_regex => "[^\s]+-([^\s]+).*"; package_installed_regex => ".*"; package_name_convention => "$(name)-$(version)"; package_add_command => "/usr/sbin/pkg install -y"; package_delete_command => "/usr/sbin/pkg delete"; alpinelinux:: package_changes => "bulk"; package_list_command => "/sbin/apk info -v"; package_list_name_regex => "([^\s]+)-.*"; package_list_version_regex => "[^\s]+-([^\s]+).*"; package_name_regex => ".*"; package_installed_regex => ".*"; package_name_convention => "$(name)"; package_add_command => "/sbin/apk add"; package_delete_command => "/sbin/apk del"; gentoo:: package_changes => "individual"; package_list_command => "/bin/sh -c '/bin/ls -d /var/db/pkg/*/* | cut -c 13-'"; package_list_name_regex => "([^/]+/(?:(?!-\d).)+)-\d.*"; package_list_version_regex => "[^/]+/(?:(?!-\d).)+-(\d.*)"; package_installed_regex => ".*"; # all reported are installed package_name_convention => "$(name)"; package_list_update_command => "/bin/true"; # I prefer manual syncing #package_list_update_command => "/usr/bin/emerge --sync"; # if you like automatic package_list_update_ifelapsed => "$(common_knowledge.list_update_ifelapsed)"; package_add_command => "/usr/bin/emerge -q --quiet-build"; package_delete_command => "/usr/bin/emerge --depclean"; package_update_command => "/usr/bin/emerge --update"; package_patch_command => "/usr/bin/emerge --update"; package_verify_command => "/usr/bin/emerge -s"; package_noverify_regex => ".*(Not Installed|Applications found : 0).*"; archlinux:: package_changes => "bulk"; package_list_command => "/usr/bin/pacman -Q"; package_verify_command => "/usr/bin/pacman -Q"; package_noverify_regex => "error:\b.*\bwas not found"; package_list_name_regex => "(.*)\s+.*"; package_list_version_regex => ".*\s+(.*)"; package_installed_regex => ".*"; package_name_convention => "$(name)"; package_list_update_ifelapsed => "$(common_knowledge.list_update_ifelapsed)"; package_add_command => "/usr/bin/pacman -S --noconfirm --noprogressbar --needed"; package_delete_command => "/usr/bin/pacman -Rs --noconfirm"; package_update_command => "/usr/bin/pacman -S --noconfirm --noprogressbar --needed"; } ## 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|sles|opensuse:: "$(package)" package_policy => "delete", package_method => zypper; !debian.!redhat.!(suse|sles|opensuse):: "$(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|sles|opensuse:: "$(package)" package_policy => "add", package_method => zypper; !debian.!redhat.!(suse|sles|opensuse):: "$(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:9999999999", package_method => apt_get_permissive; redhat:: "$(package)" package_policy => "addupdate", package_version => "999999999", package_method => yum_rpm_permissive; suse|sles|opensuse:: "$(package)" package_policy => "addupdate", package_version => "999999999", package_method => zypper; !debian.!redhat.!(suse|sles|opensuse):: "$(package)" package_policy => "addupdate", package_method => generic; } 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|sles|opensuse:: "$(package_name)" package_policy => $(desired), package_select => '>=', # see verify_packages.c package_version => $(package_version), package_architectures => { $(package_arch) }, package_method => zypper; (redhat|aix).filebased:: "$(package_basename)" package_policy => $(desired), package_select => '>=', package_version => $(package_version), package_architectures => { $(package_arch) }, package_method => rpm_version($(dir)); solaris_adminfile_ok:: "$(package_name)" package_policy => $(desired), package_select => '>=', package_version => $(package_version), package_method => solaris_install($(solaris_admin_file)); !filebased.!debian.!redhat.!(suse|sles|opensuse):: "$(package_name)" package_policy => $(desired), package_method => generic; reports: "(DEBUG|DEBUG_$(this.bundle)).filebased.!(suse|sles|opensuse).!debian.!redhat.!aix.!solaris_pkgadd":: "DEBUG $(this.bundle): sorry, can't do file-based installs on $(sys.os)"; } cfengine-masterfiles-3.27.3/lib/paths.cf0000644000000000000000000006664414735102600016303 0ustar0000000000000000# Paths bundle (used by other bodies) bundle common paths # @brief Defines an array `path` with common paths to standard binaries and # directories as well as 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 no_carriage_returns(filename) # { # commands: # _stdlib_path_exists_sed:: # "$(paths.sed)" -> { "CFE-3216" } # args => "-i 's/^M//' $(filename)", # comment => "Preferred reference style"; # # "$(paths[sed])" # args => "-i 's/^M//' $(filename)", # comment => "Alternate array reference style"; # } # ``` # # The paths bundle can be extended with custom paths by tagging *classic array* variables with `paths.cf`. # # **Example:** # # ```cf3 # bundle agent extended_paths_example # { # meta: # "tags" slist => { "autorun" }; # # vars: # # NOTE: the key will be canonified when it's pulled in to the paths bundle. # "path[orange]" string => "/bin/true", meta => { "paths.cf" }; # "path[true-blue]" string => "/bin/true", meta => { "paths.cf" }; # "foo[bar]" string => "/bin/true", meta => { "paths.cf" }; # # this_context_isnt_defined_so_no_path:: # "path[red]" string => "/bin/true", meta => { "paths.cf" }; # # reports: # _stdlib_path_exists_orange:: # "path paths.orange == $(paths.orange)"; # "path paths.path[orange] == $(paths.path[orange])"; # # _stdlib_path_exists_bar:: # "path paths.bar == $(paths.bar)"; # "path paths.path[bar] == $(paths.path[bar])"; # # _stdlib_path_exists_true_blue:: # "path paths.true_blue == $(paths.true_blue)"; # "path paths.path[true_blue] == $(paths.path[true_blue])"; # # _stdlib_path_exists_red:: # "path paths.red == $(paths.red)"; # "path paths.path[red] == $(paths.path[red])"; # # !_stdlib_path_exists_red:: # "path paths.red was not found"; # "path paths.path[red] was not found"; # } # ``` # # Additionally several path entries are present to aid in policy sharing between # unix systems and Android Termux environments. # # **Example:** # # ```cf3 # bundle agent track_sshd_config # { # files: # "$(paths.etc_path)/sshd/sshd_config" # changes => detect_all_change; # } # ``` # # In case of termux, `paths.etc_path` will be `/data/data/com.termux/files/usr/etc`. # # **History:** # # - Ability to extend paths by tagging classic array variables added 3.17.0 (works with binary version 3.11.0 and greater) { 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"; !(freebsd|darwin|smartos):: "path[npm]" string => "/usr/bin/npm"; "path[pip]" string => "/usr/bin/pip"; "path[virtualenv]" string => "/usr/bin/virtualenv"; !(freebsd|darwin):: "path[getfacl]" string => "/usr/bin/getfacl"; "path[setfacl]" string => "/usr/bin/setfacl"; freebsd|darwin:: "path[npm]" string => "/usr/local/bin/npm"; "path[pip]" string => "/usr/local/bin/pip"; "path[virtualenv]" string => "/usr/local/bin/virtualenv"; "path[automount]" string => "/usr/sbin/automount"; _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"; _have_bin_journalctl:: "path[journalctl]" string => "/bin/journalctl"; !_have_bin_journalctl:: "path[journalctl]" string => "/usr/bin/journalctl"; _have_bin_timedatectl:: "path[timedatectl]" string => "/bin/timedatectl"; !_have_bin_timedatectl:: "path[timedatectl]" string => "/usr/bin/timedatectl"; linux:: "path[date]" string => "/usr/bin/date"; "path[lsattr]" string => "/usr/bin/lsattr"; "path[lsmod]" string => "/sbin/lsmod"; "path[tar]" string => "/bin/tar"; "path[true]" string => "/bin/true"; "path[false]" string => "/bin/false"; "path[pgrep]" string => "/usr/bin/pgrep"; "path[getent]" string => "/usr/bin/getent"; "path[mailx]" string => "/usr/bin/mailx"; "path[prelink]" string => "/usr/sbin/prelink"; "path[ssh]" string => "/usr/bin/ssh"; "path[ss]" string => "/usr/bin/ss"; 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[lssrc]" string => "/usr/bin/lssrc"; "path[netstat]" string => "/usr/bin/netstat"; "path[oslevel]" string => "/usr/bin/oslevel"; "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[startsrc]" string => "/usr/bin/startsrc"; "path[stopsrc]" string => "/usr/bin/stopsrc"; "path[tr]" string => "/usr/bin/tr"; "path[yum]" string => "/usr/bin/yum"; archlinux|manjaro:: "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[pamac]" string => "/usr/bin/pamac"; "path[yaourt]" string => "/usr/bin/yaourt"; "path[useradd]" string => "/usr/bin/useradd"; "path[userdel]" string => "/usr/bin/userdel"; "path[usermod]" string => "/usr/bin/usermod"; "path[groupadd]" string => "/usr/bin/groupadd"; "path[groupdel]" string => "/usr/bin/groupdel"; "path[groupmod]" string => "/usr/bin/groupmod"; "path[ip]" string => "/usr/bin/ip"; "path[ifconfig]" string => "/usr/bin/ifconfig"; "path[journalctl]" string => "/usr/bin/journalctl"; "path[netctl]" string => "/usr/bin/netctl"; coreos:: "path[awk]" string => "/usr/bin/awk"; "path[cat]" string => "/usr/bin/cat"; "path[cksum]" string => "/usr/bin/cksum"; "path[curl]" string => "/usr/bin/curl"; "path[cut]" string => "/usr/bin/cut"; "path[diff]" string => "/usr/bin/diff"; "path[dig]" string => "/usr/bin/dig"; "path[echo]" string => "/usr/bin/echo"; "path[ip]" string => "/usr/bin/ip"; "path[lsof]" string => "/usr/bin/lsof"; "path[netstat]" string => "/usr/bin/netstat"; "path[ping]" string => "/usr/bin/ping"; "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[wget]" string => "/usr/bin/wget"; 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[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.!(freebsd_9_3|freebsd_10|freebsd_11)|netbsd|openbsd:: "path[ping]" string => "/usr/bin/ping"; freebsd_9_3|freebsd_10|freebsd_11:: "path[ping]" string => "/sbin/ping"; freebsd|netbsd:: "path[cksum]" string => "/usr/bin/cksum"; "path[realpath]" string => "/bin/realpath"; freebsd:: "path[bhyvectl]" string => "/usr/sbin/bhyvectl"; "path[getfacl]" string => "/bin/getfacl"; "path[setfacl]" string => "/bin/setfacl"; "path[dtrace]" string => "/usr/sbin/dtrace"; "path[service]" string => "/usr/sbin/service"; "path[zpool]" string => "/sbin/zpool"; "path[zfs]" string => "/sbin/zfs"; openbsd:: "path[cksum]" string => "/bin/cksum"; smartos:: "path[npm]" string => "/opt/local/bin/npm"; "path[pip]" string => "/opt/local/bin/pip"; solaris:: "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[diff]" string => "/usr/bin/diff"; "path[dig]" string => "/usr/sbin/dig"; "path[echo]" string => "/usr/bin/echo"; "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[wget]" string => "/usr/bin/wget"; "path[svcs]" string => "/usr/bin/svcs"; "path[svcadm]" string => "/usr/sbin/svcadm"; "path[svccfg]" string => "/usr/sbin/svccfg"; "path[svcprop]" string => "/usr/bin/svcprop"; "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"; solaris.(mpf_stdlib_use_posix_utils.!disable_mpf_stdlib_use_posix_utils):: "path[awk]" string => "/usr/xpg4/bin/awk"; "path[df]" string => "/usr/xpg4/bin/df"; "path[egrep]" string => "/usr/xpg4/bin/egrep"; "path[find]" string => "/usr/xpg4/bin/find"; "path[grep]" string => "/usr/xpg4/bin/grep"; "path[ls]" string => "/usr/xpg4/bin/ls"; "path[sed]" string => "/usr/xpg4/bin/sed"; "path[sort]" string => "/usr/xpg4/bin/sort"; "path[tr]" string => "/usr/xpg4/bin/tr"; solaris.!(mpf_stdlib_use_posix_utils.!disable_mpf_stdlib_use_posix_utils):: "path[awk]" string => "/usr/bin/awk"; "path[df]" string => "/usr/bin/df"; "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[sed]" string => "/usr/bin/sed"; "path[sort]" string => "/usr/bin/sort"; "path[tr]" string => "/usr/bin/tr"; 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[dmidecode]" string => "/usr/sbin/dmidecode"; "path[dmsetup]" string => "/usr/sbin/dmsetup"; "path[domainname]" string => "/bin/domainname"; "path[echo]" string => "/bin/echo"; "path[egrep]" string => "/bin/egrep"; "path[ethtool]" string => "/usr/sbin/ethtool"; "path[fdisk]" string => "/usr/sbin/fdisk"; "path[find]" string => "/usr/bin/find"; "path[free]" string => "/usr/bin/free"; "path[getenforce]" string => "/usr/sbin/getenforce"; "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[lshw]" string => "/usr/sbin/lshw"; "path[lsof]" string => ifelse( "redhat_7|redhat_6", "/usr/sbin/lsof", "/usr/bin/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[restorecon]" string => "/sbin/restorecon"; "path[sed]" string => "/bin/sed"; "path[semanage]" string => "/usr/sbin/semanage"; "path[sort]" string => "/bin/sort"; "path[test]" string => "/usr/bin/test"; "path[tr]" string => "/usr/bin/tr"; "path[wc]" string => "/usr/bin/wc"; "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[usermod]" string => "/usr/sbin/usermod"; "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[dscl]" string => "/usr/bin/dscl"; "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[dmsetup]" string => "/usr/sbin/dmsetup"; "path[domainname]" string => "/bin/domainname"; "path[echo]" string => "/bin/echo"; "path[egrep]" string => "/bin/egrep"; "path[ethtool]" string => "/sbin/ethtool"; "path[fdisk]" string => "/usr/sbin/fdisk"; "path[find]" string => "/usr/bin/find"; "path[free]" string => "/usr/bin/free"; "path[getenforce]" string => "/usr/sbin/getenforce"; "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[lshw]" string => "/usr/bin/lshw"; "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[restorecon]" string => "/sbin/restorecon"; "path[sed]" string => "/bin/sed"; "path[semanage]" string => "/usr/sbin/semanage"; "path[sort]" string => "/usr/bin/sort"; "path[test]" string => "/usr/bin/test"; "path[tr]" string => "/usr/bin/tr"; "path[wc]" string => "/usr/bin/wc"; "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[dpkg_divert]" string => "/usr/bin/dpkg-divert"; "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[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"; "path[userdel]" string => "/usr/sbin/userdel"; "path[usermod]" string => "/usr/sbin/usermod"; archlinux||darwin:: "path[sysctl]" string => "/usr/bin/sysctl"; !(archlinux||darwin):: "path[sysctl]" string => "/sbin/sysctl"; !(suse|sles):: "path[logger]" string => "/usr/bin/logger"; opensuse:: "path[awk]" string => "/usr/bin/awk"; "path[cat]" string => "/usr/bin/cat"; "path[cksum]" string => "/usr/bin/cksum"; "path[crontab]" string => "/usr/bin/crontab"; "path[curl]" string => "/usr/bin/curl"; "path[cut]" string => "/usr/bin/cut"; "path[df]" string => "/usr/bin/df"; "path[diff]" string => "/usr/bin/diff"; "path[dig]" string => "/usr/bin/dig"; "path[dmidecode]" string => "/usr/sbin/dmidecode"; "path[echo]" string => "/usr/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 => "/usr/bin/hostname"; "path[init]" string => "/sbin/init"; "path[iptables]" string => "/usr/sbin/iptables"; "path[ls]" string => "/usr/bin/ls"; "path[lsof]" string => "/usr/bin/lsof"; "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 => "/usr/bin/sed"; "path[sort]" string => "/usr/bin/sort"; "path[test]" string => "/usr/bin/test"; "path[tr]" string => "/usr/bin/tr"; "path[logger]" string => "/usr/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[ip]" string => "/sbin/ip"; "path[rpm]" string => "/usr/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"; suse|sles:: "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"; "path[mailx]" string => "/usr/bin/mailx"; aix:: "path[shadow]" string => "/etc/security/passwd"; termux:: "path[tar]" string => "/usr/bin/tar"; "path[true]" string => "/usr/bin/true"; "path[false]" string => "/usr/bin/false"; "path[cat]" string => "/usr/bin/cat"; "path[sysctl]" string => "/usr/bin/sysctl"; "path[env]" string => "/usr/bin/env"; # now, mangle the values by prepending the TERMUX_PREFIX "files_path" string => "/data/data/com.termux/files"; "etc_path" string => "$(files_path)/usr/etc"; "tmp_path" string => "$(files_path)/usr/tmp"; "bin_path" string => "$(files_path)/usr/bin"; "var_path" string => "$(files_path)/usr/var"; "tmp_paths" slist => getindices("path"); "tmp_path[$(tmp_paths)]" string => "$(files_path)$(path[$(tmp_paths)])"; "path[$(tmp_paths)]" string => "$(tmp_path[$(tmp_paths)])"; !(termux|windows):: # reasonable defaults for unix systems to allow for writing # more portable paths between termux and other systems "etc_path" string => "/etc"; "tmp_path" string => "/tmp"; "bin_path" string => "/bin"; "var_path" string => "/var"; any:: @if minimum_version(3.11.0) # Pull in variables tagged with `paths.cf` "_extended_path_data" -> { "CFE-3426" } data => variablesmatching_as_data(".*", "paths.cf"); "_i" -> { "CFE-3426" } slist => getindices(_extended_path_data); "path[$(with)]" -> { "CFE-3426" } string => "$(_extended_path_data[$(_i)])", with => canonify(regex_replace($(_i), ".*\[(.*)\]", "$1", "")); @endif "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"); "_have_bin_timedatectl" expression => fileexists("/bin/timedatectl"); "_have_bin_journalctl" expression => fileexists("/bin/journalctl"); "_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"; } cfengine-masterfiles-3.27.3/lib/processes.cf0000644000000000000000000000421414735102600017153 0ustar0000000000000000# Processes bodies 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" }; } cfengine-masterfiles-3.27.3/lib/reports.cf0000644000000000000000000000215014735102600016640 0ustar0000000000000000body printfile cat(file) # @brief Report the contents of a file # @param file The full path of the file to report { file_to_print => "$(file)"; number_of_lines => "inf"; } body printfile head(file) # @brief Report the first 10 lines of a file # @param file The full path of the file to report { file_to_print => "$(file)"; # GNU head defaults to 10 number_of_lines => "10"; } body printfile head_n(file, n) # @brief Report the first `n` lines of a file # @param file The full path of the file to report # @param n The number of lines to report { file_to_print => "$(file)"; number_of_lines => "$(n)"; } @if minimum_version(3.18) body printfile tail(file) # @brief Report the last 10 lines of a file # @param file The full path of the file to report { file_to_print => "$(file)"; # GNU tail defaults to 10 number_of_lines => "-10"; } @endif @if minimum_version(3.18) body printfile tail_n(file, n) # @brief Report the last `n` lines of a file # @param file The full path of the file to report # @param n The number of lines to report { file_to_print => "$(file)"; number_of_lines => "-$(n)"; } @endif cfengine-masterfiles-3.27.3/lib/service_config.cf0000644000000000000000000000457614735102600020145 0ustar0000000000000000# - service_started_file - a file which should have the timestamp of when the service was last started, typically a pid file or maybe /proc/ directory. # todo, maybe chmod, user, group for config_final_path bundle agent service_config(service_name, config_template_path, config_final_path, validate_config_command, template_data, service_started_file) { vars: "staged_config" string => "$(config_final_path).staged"; methods: "staged config rendered" usebundle => file_make_mustache( $(staged_config), $(config_template_path), @(template_data) ); "final config and restart" usebundle => validate_config_and_restart_service( $(staged_config), $(validate_config_command), $(config_final_path), $(service_name), $(service_started_file) ); reports: DEBUG:: "template_data is ${with}" with => storejson(template_data); } bundle agent validate_config_and_restart_service(staged_config, validate_config_command, config_final_path, service_name, service_started_file) { vars: "validation_output" string => "$(staged_config)-validation.log"; classes: "config_validated" expression => returnszero( "$(validate_config_command) $(staged_config) >$(validation_output) 2>&1", "useshell" ); "config_final_exists" expression => fileexists("$(config_final_path)"); "config_newer_than_started_file" expression => isnewerthan( "$(config_final_path)", "$(service_started_file)" ), if => canonify("$(service_name)_config_ok"); files: "$(config_final_path)" copy_from => local_dcp($(staged_config)), if => "config_validated", classes => scoped_classes_generic("bundle", "$(service_name)_config"); services: "$(service_name)" service_policy => "restart", if => and( "config_validated", or(not("config_final_exists"), "config_newer_than_started_file") ); reports: DEBUG:: "service_started_file is $(service_started_file)"; "$(staged_config) validated" if => "config_validated"; "$(config_final_path) exists" if => "config_final_exists"; "$(config_final_path) is newer than service started file $(service_started_file)" if => "config_newer_than_started_file"; !config_validated:: "validation output ${with}" with => readfile("${validation_output}"); } cfengine-masterfiles-3.27.3/lib/services.cf0000644000000000000000000013730314735102600016776 0ustar0000000000000000# Services bodies bundle common services_common # @brief Enumerate policy files used by this policy file for inclusion to inputs { vars: "inputs" slist => { "$(this.promise_dirname)/common.cf", "$(this.promise_dirname)/paths.cf" }; } body file control # @brief Include policy files used by this policy file as part of inputs { 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"; } body service_method standard_services # @brief Default services_method for when you wan't to call it explicitly # # By default this service_method is *not* used. The call for standard_services # is within the core and not here. In case you use a promise like: # # ```cf3 # services: # "ssh" # service_policy => "start"; # ``` # # Then this method is skipped and CFEngine calls standard_services bundle # directly. This is here as a helper in case you wan't to be explicit # with your service promise and point it to standard_services (for readability, # documentation, etc). # # Do note that any options defined in this method does not apply to service # promises without explicit template_method call for standard_services. # # **Example:** # # ```cf3 # services: # "ssh" # service_policy => "start", # service_method => standard_services; # ``` { service_bundle => default:standard_services( $(this.promiser), $(this.service_policy) ); } body service_method systemd_services # @brief systemd service method # # **Example:** # # ```cf3 # services: # "ssh" # service_policy => "enabled", # service_method => systemd_services; # ``` { service_bundle => default:systemd_services( $(this.promiser), $(this.service_policy) ); } 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". "enable", "enabled", and "disabled" are also able to be used when systemd is detected. "active" and "inactive" states are supported for systemd managed hosts and can be used for controlling the services currently running state, but make no promises about the service state on boot. # # 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 via `systemd_services`. # # Else, if chkconfig is present, it will be used. # # Else, if the service command is available, it will be used. # # Else, if the svcadm command is available, it will be used. Note you # have to supply the full SMF service identifier. # # Else, if lssrc command is available (AIX), it will be used. # # 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 # ``` # # Alternatively, since services promises are an abstraction around bundles, the service state can be promised via a methods type promise. # # ```cf3 # # methods: # "SSHD should be running" usebundle => standard_services("sshd", "start"); # ``` # # **Notes:** # FreeBSD uses "one" prefixed commands, e.g. onestatus, onestart, onestop so that services that are not enabled can still be managed { vars: "c_service" string => canonify("$(service)"); freebsd:: "init" string => ifelse( fileexists("/usr/local/etc/rc.d/$(service)"), "/usr/local/etc/rc.d/$(service)", "/etc/rc.d/$(service)" ); !freebsd:: "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"; # AIX System Resource Controller https://www.ibm.com/docs/en/aix/7.2?topic=concepts-system-resource-controller "aix_src" expression => "_stdlib_path_exists_lssrc"; "fallback" expression => "!systemd.!chkconfig.!sysvservice.!smf.!aix_src"; "have_init" expression => fileexists($(init)); chkconfig.have_init:: "running" expression => returnszero("$(init) status > /dev/null", "useshell"); sysvservice.have_init:: # We use one prefixed service commands on freebsd so that service # management works even when the service is not enabled in /etc/rc.conf. "running" -> { "CFE-4323" } with => ifelse("freebsd", "one", ""), expression => returnszero( "$(paths.service) $(service) $(with)status > /dev/null", "useshell" ); chkconfig.SuSE:: "onboot" expression => returnszero( "$(paths.chkconfig) $(service) | $(paths.grep) 'on$' >/dev/null", "useshell" ), comment => "SuSE chkconfig outputs current state to stdout rather than as an exit code"; chkconfig.!SuSE:: "onboot" expression => returnszero("$(paths.chkconfig) $(service)", "noshell"), comment => "We need to know if the service is configured to start at boot or not"; # We redirect stderr and stdout to dev null so that we do not create noise in the logs "chkconfig_$(c_service)_unregistered" not => returnszero( "$(paths.chkconfig) --list $(service) &> /dev/null", "useshell" ), comment => "We need to know if the service is registered with chkconfig so that we can perform other chkconfig operations, if the service is not registered it must be added. Note we do not automatically try to add the service at this time."; commands: 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, and if its a registered chkconfig service "$(paths.chkconfig) $(service) $(chkconfig_mode)" if => "!chkconfig_$(c_service)_unregistered", classes => kept_successful_command, contain => silent; chkconfig.have_init.(((start|restart).!running)|((stop|restart|reload).running)).non_disabling:: "$(init) $(state)" contain => silent; sysvservice.start.!running:: # We use one prefixed service commands on freebsd so that service # management works even when the service is not enabled in /etc/rc.conf. "$(paths.service) $(service) $(with)start" -> { "CFE-4323" } handle => "standard_services_sysvservice_not_running_start", classes => kept_successful_command, with => ifelse("freebsd", "one", ""); sysvservice.restart:: # We use one prefixed service commands on freebsd so that service # management works even when the service is not enabled in /etc/rc.conf. "$(paths.service) $(service) $(with)restart" -> { "CFE-4323" } handle => "standard_services_sysvservice_restart", classes => kept_successful_command, with => ifelse("freebsd", "one", ""); sysvservice.reload.running:: # If the service should be reloaded we issue the standard service command # to reload the service, but only if it's currently running as to not # start a service that was not already running. This may not be triggered # as service state parameters are limited and translated to the closest # meaning. "$(paths.service) $(service) $(with)reload" -> { "CFE-4323" } handle => "standard_services_sysvservice_reload", classes => kept_successful_command, with => ifelse("freebsd", "one", ""); sysvservice.((stop|disable).running):: # If the service should be stopped or disabled and it is currently running # then we should issue the standard service command to stop the service "$(paths.service) $(service) $(with)stop" -> { "CFE-4323" } handle => "standard_services_sysvservice_not_freebsd stop", classes => kept_successful_command, with => ifelse("freebsd", "one", ""); smf:: "$(paths.svcadm) $(svcadm_mode) $(service)" classes => kept_successful_command; methods: aix_src:: "aix_service" usebundle => aix_services($(service), $(state)); fallback:: "classic" usebundle => classic_services($(service), $(state)); systemd:: "systemd" usebundle => systemd_services($(service), $(state)); reports: verbose_mode.systemd:: "$(this.bundle): using systemd layer to $(state) $(service)"; verbose_mode.systemd.!service_loaded:: "$(this.bundle): Service $(service) unit file is not loaded; doing nothing"; verbose_mode.chkconfig:: "$(this.bundle): using chkconfig layer to $(state) $(service) (chkconfig mode $(chkconfig_mode))" if => "!chkconfig_$(c_service)_unregistered.((start.!onboot)|(stop.onboot))"; verbose_mode.chkconfig:: "$(this.bundle): skipping chkconfig layer to $(state) $(service) because $(service) is not registered with chkconfig (chkconfig --list $(service))" if => "chkconfig_$(c_service)_unregistered"; verbose_mode.sysvservice:: "$(this.bundle): using System V service / Upstart layer to $(state) $(service)"; verbose_mode.smf:: "$(this.bundle): using Solaris SMF to $(state) $(service) (svcadm mode $(svcadm_mode))"; verbose_mode.fallback:: "$(this.bundle): falling back to classic_services to $(state) $(service)"; } body action fresh_systemd_state # @brief An 'action' body ensuring the state information for a systemd service is always fresh # # This 'action' body disables caching for functions, in particular the # execresult*() family of functions. # # Although it's now the same as the 'immediate' action body, this may change in # the future. { cfengine:: # ^Needed for versions 3.15.x and older that did not # support empty bodies. When 3.15.x is no longer # supported, this can be removed. @if minimum_version(3.18.1) # Beginning with 3.18.1 ifelapsed being set to 0 results in bypassing of # function caching. In versions prior to 3.18, if an action body with # ifelapsed set to 0 was used in a vars type promise a warning was # emitted. This is guarded to suppress that warning in older versions # where this setting would not change the behavior. ifelapsed => "0"; @endif } bundle agent systemd_services(service, state) # @brief Manage systemd service state # @author Bryan Burke # @param service specific service to control # @param state The desired state for that service: "active", "inactive", "restart", "reload", "enabled", "disabled", "start", and "stop" are specifically understood states. Any other custom state will be passed through to systemctl. # # **State descriptions:** # # * active - Service should be running, no promise about state on boot made. # * inactive - Service should not be running, no promise about state on boot made. # * restart - Service should be restarted, no promise about state on boot made. # * reload - Service should be reloaded, no promise about state on boot made. # * enabled - Service should be enabled, no promise about state on boot made. # * disabled - Service should be disabled, no promise about state on boot made. # * start - Service should be running, service should be started on boot (active + enabled). # * stop - Service should not be running, service should not be started on boot (inactive + disabled). # # **Example:** # # ```cf3 # services: # # Uses `standard_services`, dynamic decision about init subsystem # "sshd" # service_policy => "enabled"; # # # Explicitly use `systemd_services` # "sshd" # service_policy => "enabled", # service_method => systemd_services; # ``` # # Alternatively, since services promises are an abstraction around bundles, the service state can be promised via a methods type promise. # # ```cf3 # # methods: # "SSHD should be running" usebundle => systemd_services("sshd", "enabled"); # ``` { vars: systemd:: "call_systemctl" string => "$(paths.systemctl) --no-ask-password --system"; "systemd_properties" string => "-pLoadState,CanStop,UnitFileState,ActiveState,LoadState,CanStart,CanReload"; "systemd_service_info" slist => string_split( execresult( "$(call_systemctl) $(systemd_properties) show $(service)", "noshell" ), "\n", "10" ), action => fresh_systemd_state; # Ensure this info is always fresh and not cached [CFE-3753] classes: systemd:: "service_enabled" expression => reglist(@(systemd_service_info), "UnitFileState=enabled"); "service_enabled" -> { "CFE-2923" } expression => returnszero( "$(call_systemctl) is-enabled $(service) > /dev/null 2>&1", useshell ); "service_active" -> { "CFE-3238" } expression => reglist( @(systemd_service_info), "ActiveState=(active|activating)" ); "service_loaded" expression => reglist(@(systemd_service_info), "LoadState=loaded"); "service_notfound" expression => reglist(@(systemd_service_info), "LoadState=not-found"); "can_stop_service" expression => reglist(@(systemd_service_info), "CanStop=yes"); "can_start_service" expression => reglist(@(systemd_service_info), "CanStart=yes"); "can_reload_service" expression => reglist(@(systemd_service_info), "CanReload=yes"); "request_start" expression => strcmp("start", "$(state)"); "request_stop" expression => strcmp("stop", "$(state)"); "request_reload" expression => strcmp("reload", "$(state)"); "request_restart" expression => strcmp("restart", "$(state)"); "request_disable" expression => strcmp("disable", "$(state)"); "request_disabled" expression => strcmp("disabled", "$(state)"); "request_enable" expression => strcmp("enable", "$(state)"); "request_enabled" expression => strcmp("enabled", "$(state)"); "request_active" expression => strcmp("active", "$(state)"); "request_inactive" expression => strcmp("inactive", "$(state)"); "action_custom" expression => "!(request_start|request_stop|request_reload|request_restart|request_disable|request_disabled|request_enable|request_enabled|request_active|request_inactive)"; "action_start" expression => "(request_start|request_active).!service_active.can_start_service"; "action_stop" expression => "(request_stop|request_inactive).service_active.can_stop_service"; "action_reload" expression => "request_reload.service_active.can_reload_service"; "action_restart" or => { "request_restart", # Possibly undesirable... if a reload is # requested, and the service "can't" be # reloaded, then we restart it instead. "request_reload.!can_reload_service.service_active", }; # Starting a service implicitly enables it "action_enable" expression => "(request_start|request_enable|request_enabled).!service_enabled"; # Respectively, stopping it implicitly disables it "action_disable" expression => "(request_disable|request_disabled|request_stop).service_enabled"; commands: systemd.service_loaded:: # note this class is defined in `inventory/linux.cf` # conveniently, systemd states map to `services` states, except # for `enable` "$(call_systemctl) -q start $(service)" if => "action_start"; "$(call_systemctl) -q stop $(service)" if => "action_stop"; "$(call_systemctl) -q reload $(service)" if => "action_reload"; "$(call_systemctl) -q restart $(service)" if => "action_restart"; "$(call_systemctl) -q enable $(service)" if => "action_enable"; "$(call_systemctl) -q disable $(service)" if => "action_disable"; # Custom action for any of the non-standard systemd actions such a # status, try-restart, isolate, et al. "$(call_systemctl) $(state) $(service)" if => "action_custom"; reports: systemd.service_notfound.(action_start|action_restart|action_reload).(inform_mode|verbose_mode):: "$(this.bundle): Could not find service: $(service)"; } bundle agent classic_services(service, state) # @brief Classic services bundle # @author CFEngine AS # @author Tero Kantonen # @param service specific service to control # @param state desired state for that service # # This bundle is used by `standard_services` if it doesn't have an # automatic driver for the current service manager. # # 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/