diff --git a/.gitignore b/.gitignore index 7515e5993b..c4b29bd763 100644 --- a/.gitignore +++ b/.gitignore @@ -1,354 +1,356 @@ # # Copyright 2011-2023 the Pacemaker project contributors # # The version control history for this file may have further details. # # This source code is licensed under the GNU General Public License version 2 # or later (GPLv2+) WITHOUT ANY WARRANTY. # # Common conventions for files that should be ignored *~ *.bz2 *.diff *.orig *.patch *.rej *.sed *.swp *.tar.gz *.tgz \#* .\#* logs # libtool artifacts *.la *.lo .libs libltdl libtool libtool.m4 ltdl.m4 /m4/argz.m4 /m4/ltargz.m4 /m4/ltoptions.m4 /m4/ltsugar.m4 /m4/ltversion.m4 /m4/lt~obsolete.m4 # autotools artifacts .deps .dirstamp Makefile Makefile.in aclocal.m4 autoconf autoheader autom4te.cache/ automake /confdefs.h config.log config.status configure /conftest* # gettext artifacts /ABOUT-NLS /m4/codeset.m4 /m4/fcntl-o.m4 /m4/gettext.m4 /m4/glibc2.m4 /m4/glibc21.m4 /m4/iconv.m4 /m4/intdiv0.m4 /m4/intl.m4 /m4/intldir.m4 /m4/intlmacosx.m4 /m4/intmax.m4 /m4/inttypes-pri.m4 /m4/inttypes_h.m4 /m4/lcmessage.m4 /m4/lib-ld.m4 /m4/lib-link.m4 /m4/lib-prefix.m4 /m4/lock.m4 /m4/longlong.m4 /m4/nls.m4 /m4/po.m4 /m4/printf-posix.m4 /m4/progtest.m4 /m4/size_max.m4 /m4/stdint_h.m4 /m4/threadlib.m4 /m4/uintmax_t.m4 /m4/visibility.m4 /m4/wchar_t.m4 /m4/wint_t.m4 /m4/xsize.m4 /po/*.gmo /po/*.header /po/*.pot /po/*.sin /po/Makefile.in.in /po/Makevars.template /po/POTFILES /po/Rules-quot /po/stamp-po # configure targets /agents/ocf/ClusterMon /agents/ocf/Dummy /agents/ocf/HealthCPU /agents/ocf/HealthIOWait /agents/ocf/HealthSMART /agents/ocf/Stateful /agents/ocf/SysInfo /agents/ocf/attribute /agents/ocf/controld /agents/ocf/ifspeed /agents/ocf/ping /agents/ocf/remote /agents/stonith/fence_legacy /agents/stonith/fence_watchdog /cts/benchmark/clubench /cts/cluster_test /cts/cts /cts/cts-attrd /cts/cts-cli /cts/cts-exec /cts/cts-fencing /cts/cts-lab /cts/cts-regression /cts/cts-scheduler +/cts/cts-schemas /cts/lab/CTS.py /cts/support/LSBDummy /cts/support/cts-support /cts/support/fence_dummy /cts/support/pacemaker-cts-dummyd /cts/support/pacemaker-cts-dummyd@.service /daemons/execd/pacemaker_remote /daemons/execd/pacemaker_remote.service /daemons/fenced/fence_legacy /daemons/fenced/fence_watchdog /daemons/pacemakerd/pacemaker.combined.upstart /daemons/pacemakerd/pacemaker.service /daemons/pacemakerd/pacemaker.upstart /doc/Doxyfile /etc/init.d/pacemaker /etc/logrotate.d/pacemaker /etc/sysconfig/pacemaker /include/config.h /include/config.h.in /include/crm_config.h /maint/bumplibs /python/pacemaker/buildoptions.py /python/setup.py /tools/cluster-clean /tools/cluster-helper /tools/cluster-init /tools/cibsecret /tools/crm_error /tools/crm_failcount /tools/crm_master /tools/crm_mon.service /tools/crm_mon.upstart /tools/crm_report /tools/crm_rule /tools/crm_standby /tools/pcmk_simtimes /tools/report.collector /tools/report.common /xml/rng-helper # Compiled targets and intermediary files *.o *.pc *.pyc /daemons/attrd/pacemaker-attrd /daemons/based/pacemaker-based /daemons/controld/pacemaker-controld /daemons/execd/cts-exec-helper /daemons/execd/pacemaker-execd /daemons/execd/pacemaker-remoted /daemons/fenced/cts-fence-helper /daemons/fenced/pacemaker-fenced /daemons/pacemakerd/pacemakerd /daemons/schedulerd/pacemaker-schedulerd /devel/scratch /lib/gnu/stdalign.h /tools/attrd_updater /tools/cibadmin /tools/crmadmin /tools/crm_attribute /tools/crm_diff /tools/crm_mon /tools/crm_node /tools/crm_resource /tools/crm_shadow /tools/crm_simulate /tools/crm_ticket /tools/crm_verify /tools/iso8601 /tools/stonith_admin # Generated XML schema files /xml/crm_mon.rng /xml/pacemaker*.rng /xml/versions.rng /xml/api/api-result*.rng # Working directories for make dist and make export /pacemaker-[a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9] # Documentation build targets and intermediary files *.7 *.7.xml *.7.html *.8 *.8.xml *.8.html GPATH GRTAGS GTAGS TAGS /daemons/fenced/pacemaker-fenced.xml /daemons/schedulerd/pacemaker-schedulerd.xml /doc/.ABI-build /doc/HTML /doc/abi_dumps /doc/abi-check /doc/api/ /doc/compat_reports /doc/crm_fencing.html /doc/sphinx/*/_build /doc/sphinx/*/conf.py /doc/sphinx/*/generated /doc/sphinx/build-2.1.txt /doc/sphinx/shared/images/*.png # Test artifacts (from unit tests, regression tests, static analysis, etc.) *.coverity *.gcda *.gcno coverity-* pacemaker_*.info /coverage /cppcheck.out -/cts/scheduler/*.ref -/cts/scheduler/*.up -/cts/scheduler/*.up.err /cts/scheduler/bug-rh-1097457.log /cts/scheduler/bug-rh-1097457.trs /cts/scheduler/shadow.* +/cts/scheduler/xml/*.ref +/cts/scheduler/xml/*.ref.err +/cts/scheduler/xml/*.up +/cts/scheduler/xml/*.up.err +/cts/schemas/test-*/*.up +/cts/schemas/test-*/*.up.err /cts/test-suite.log /lib/*/tests/*/*.log /lib/*/tests/*/*_test /lib/*/tests/*/*.trs /lib/common/tests/schemas/schemas -/xml/test-*/*.up -/xml/test-*/*.up.err /test/_test_file.c # Packaging artifacts *.rpm /pacemaker.spec /rpm/[A-LN-Z]* /rpm/build.counter /rpm/mock # Project maintainer artifacts /maint/gnulib /maint/mocked/based /maint/testcc_helper.cc /maint/testcc_*_h # Formerly built files (helps when jumping back and forth in checkout) /.ABI-build /Doxyfile /HTML /abi_dumps /abi-check /agents/ocf/o2cb /build.counter /compat_reports /compile /cts/.regression.failed.diff /attrd /cib /config.guess /config.sub /coverage.sh /crmd /cts/CTS.py /cts/CTSlab.py /cts/CTSvars.py /cts/HBDummy /cts/LSBDummy /cts/OCFIPraTest.py /cts/cts-coverage /cts/cts-log-watcher /cts/cts-support /cts/fence_dummy /cts/lab/CTSlab.py /cts/lab/CTSvars.py /cts/lab/OCFIPraTest.py /cts/lab/cluster_test /cts/lab/cts /cts/lab/cts-log-watcher /cts/lxc_autogen.sh /cts/pacemaker-cts-dummyd /cts/pacemaker-cts-dummyd@.service /daemons/based/cibmon /daemons/fenced/fence_legacy /daemons/fenced/fence_watchdog /daemons/pacemakerd/pacemaker /depcomp /doc/*.build /doc/*/en-US/Ap-*.xml /doc/*/en-US/Ch-*.xml /doc/*/publican.cfg /doc/*/publish /doc/*/tmp/** /doc/Clusters_from_Scratch.txt /doc/Pacemaker_Explained.txt /doc/acls.html /doc/publican-catalog* /doc/shared/en-US/*.xml /doc/shared/en-US/images/pcmk-*.png /doc/shared/en-US/images/Policy-Engine-*.png /extra/*/* /fencing /include/stamp-* /install-sh /lib/common/md5.c /lib/common/tests/flags/pcmk__clear_flags_as /lib/common/tests/flags/pcmk__set_flags_as /lib/common/tests/flags/pcmk_all_flags_set /lib/common/tests/flags/pcmk_any_flags_set /lib/common/tests/operations/parse_op_key /lib/common/tests/strings/pcmk__btoa /lib/common/tests/strings/pcmk__parse_ll_range /lib/common/tests/strings/pcmk__scan_double /lib/common/tests/strings/pcmk__str_any_of /lib/common/tests/strings/pcmk__strcmp /lib/common/tests/strings/pcmk__char_in_any_str /lib/common/tests/utils/pcmk_str_is_infinity /lib/common/tests/utils/pcmk_str_is_minus_infinity /lib/gnu/libgnu.a /lib/pengine/tests/rules/ /lrmd /ltmain.sh /mcp /missing /mock /pacemaker-*.spec /pengine /py-compile /scratch /tools/cluster-init /test-driver /xml/assets /xml/crm.dtd /xml/version-diff.sh ylwrap diff --git a/configure.ac b/configure.ac index 9dfb7554f2..7b298f3d31 100644 --- a/configure.ac +++ b/configure.ac @@ -1,2186 +1,2187 @@ dnl dnl autoconf for Pacemaker dnl dnl Copyright 2009-2024 the Pacemaker project contributors dnl dnl The version control history for this file may have further details. dnl dnl This source code is licensed under the GNU General Public License version 2 dnl or later (GPLv2+) WITHOUT ANY WARRANTY. dnl ============================================== dnl Bootstrap autotools dnl ============================================== # Require a minimum version of autoconf itself AC_PREREQ(2.64) dnl AC_CONFIG_MACRO_DIR is deprecated as of autoconf 2.70 (2020-12-08). dnl Once we can require that version, we can simplify this, and no longer dnl need ACLOCAL_AMFLAGS in Makefile.am. m4_ifdef([AC_CONFIG_MACRO_DIRS], [AC_CONFIG_MACRO_DIRS([m4])], [AC_CONFIG_MACRO_DIR([m4])]) m4_include([m4/version.m4]) AC_INIT([pacemaker], VERSION_NUMBER, [users@clusterlabs.org], [pacemaker], PCMK_URL) LT_CONFIG_LTDL_DIR([libltdl]) AC_CONFIG_AUX_DIR([libltdl/config]) dnl Where #defines that autoconf makes (e.g. HAVE_whatever) go dnl dnl include/config.h dnl - Internal API dnl - Contains all defines dnl - include/config.h.in is generated automatically by autoheader dnl - Not to be included in any header files except crm_internal.h dnl (which is also not to be included in any other header files) dnl dnl include/crm_config.h dnl - External API dnl - Contains a subset of defines dnl - include/crm_config.h.in is manually edited to select the subset dnl - Should not include HAVE_* defines dnl - Safe to include anywhere AC_CONFIG_HEADERS([include/config.h include/crm_config.h]) dnl 1.13: minimum automake version required dnl foreign: don't require GNU-standard top-level files dnl tar-ustar: use (older) POSIX variant of generated tar rather than v7 dnl subdir-objects: keep .o's with their .c's (no-op in 2.0+) AM_INIT_AUTOMAKE([1.13 foreign tar-ustar subdir-objects]) dnl Require minimum version of pkg-config PKG_PROG_PKG_CONFIG(0.28) AS_IF([test x"${PKG_CONFIG}" != x""], [], [AC_MSG_FAILURE([Could not find required build tool pkg-config (0.28 or later)])]) PKG_INSTALLDIR PKG_NOARCH_INSTALLDIR dnl ============================================== dnl Compiler checks and helpers dnl ============================================== dnl A particular compiler can be forced by setting the CC environment variable AC_PROG_CC dnl C++ is needed only to run maintainer utilities, not to build AC_PROG_CXX dnl Use at least C99 if possible (automatic for autoconf >= 2.70) m4_version_prereq([2.70], [:], [AC_PROG_CC_STDC]) # cc_supports_flag # Return success if the C compiler supports the given flag cc_supports_flag() { local CFLAGS="-Werror $@" AC_MSG_CHECKING([whether $CC supports $@]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ ]], [[ ]])], [RC=0; AC_MSG_RESULT([yes])], [RC=1; AC_MSG_RESULT([no])]) return $RC } # cc_temp_flags # Use the given flags for subsequent C compilation. These can be reverted to # what was used previously with cc_restore_flags. This allows certain tests to # use specific flags without affecting anything else. cc_temp_flags() { ac_save_CFLAGS="$CFLAGS" CFLAGS="$*" } # cc_restore_flags # Restore C compiler flags to what they were before the last cc_temp_flags # call. cc_restore_flags() { CFLAGS=$ac_save_CFLAGS } # Check for fatal warning support AS_IF([test $enable_fatal_warnings -ne $DISABLED dnl && test x"$GCC" = x"yes" && cc_supports_flag -Werror], [WERROR="-Werror"], [ WERROR="" AS_CASE([$enable_fatal_warnings], [$REQUIRED], [AC_MSG_ERROR([Compiler does not support fatal warnings])], [$OPTIONAL], [enable_fatal_warnings=$DISABLED]) ]) dnl ============================================== dnl Linker checks dnl ============================================== # Check whether linker supports --enable-new-dtags to use RUNPATH instead of # RPATH. It is necessary to do this before libtool does linker detection. # See also: https://github.com/kronosnet/kronosnet/issues/107 AX_CHECK_LINK_FLAG([-Wl,--enable-new-dtags], [AM_LDFLAGS=-Wl,--enable-new-dtags], [AC_MSG_ERROR(["Linker support for --enable-new-dtags is required"])]) AC_SUBST([AM_LDFLAGS]) saved_LDFLAGS="$LDFLAGS" LDFLAGS="$AM_LDFLAGS $LDFLAGS" LT_INIT([dlopen]) LDFLAGS="$saved_LDFLAGS" LTDL_INIT([convenience]) dnl ============================================== dnl Define configure options dnl ============================================== # yes_no_try # Map a yes/no/try user selection to $REQUIRED for yes, $DISABLED for no, and # $OPTIONAL for try. DISABLED=0 REQUIRED=1 OPTIONAL=2 yes_no_try() { local value AS_IF([test x"$1" = x""], [value="$2"], [value="$1"]) AS_CASE(["`echo "$value" | tr '[A-Z]' '[a-z]'`"], [0|no|false|disable], [return $DISABLED], [1|yes|true|enable], [return $REQUIRED], [try|check], [return $OPTIONAL] ) AC_MSG_ERROR([Invalid option value "$value"]) } # # Fix the defaults of certain built-in variables so they can be used in the # defaults for our custom arguments # AC_MSG_NOTICE([Sanitizing prefix: ${prefix}]) AS_IF([test x"$prefix" = x"NONE"], [ prefix=/usr dnl Fix default variables - "prefix" variable if not specified AS_IF([test x"$localstatedir" = x"\${prefix}/var"], [localstatedir="/var"]) AS_IF([test x"$sysconfdir" = x"\${prefix}/etc"], [sysconfdir="/etc"]) ]) AC_MSG_NOTICE([Sanitizing exec_prefix: ${exec_prefix}]) AS_CASE([$exec_prefix], [prefix|NONE], [exec_prefix=$prefix]) AC_MSG_NOTICE([Sanitizing libdir: ${libdir}]) AS_CASE([$libdir], [prefix|NONE], [ AC_MSG_CHECKING([which lib directory to use]) for aDir in lib64 lib do trydir="${exec_prefix}/${aDir}" AS_IF([test -d ${trydir}], [ libdir=${trydir} break ]) done AC_MSG_RESULT([$libdir]) ]) # Start a list of optional features this build supports PCMK_FEATURES="" dnl This section should include only the definition of configure script dnl options and determining their values. Processing should be done later when dnl possible, other than what's needed to determine values and defaults. dnl Per the autoconf docs, --enable-*/--disable-* options should control dnl features inherent to Pacemaker, while --with-*/--without-* options should dnl control the use of external software. However, --enable-*/--disable-* may dnl implicitly require additional external dependencies, and dnl --with-*/--without-* may implicitly enable or disable features, so the dnl line is blurry. dnl dnl We also use --with-* options for custom file, directory, and path dnl locations, since autoconf does not provide an option type for those. dnl --enable-* options: build process AC_ARG_ENABLE([quiet], [AS_HELP_STRING([--enable-quiet], [suppress make output unless there is an error @<:@no@:>@])] ) yes_no_try "$enable_quiet" "no" enable_quiet=$? AC_ARG_ENABLE([fatal-warnings], [AS_HELP_STRING([--enable-fatal-warnings], [enable pedantic and fatal warnings for gcc @<:@try@:>@])], ) yes_no_try "$enable_fatal_warnings" "try" enable_fatal_warnings=$? AC_ARG_ENABLE([hardening], [AS_HELP_STRING([--enable-hardening], [harden the resulting executables/libraries @<:@try@:>@])] ) yes_no_try "$enable_hardening" "try" enable_hardening=$? dnl --enable-* options: features AC_ARG_ENABLE([systemd], [AS_HELP_STRING([--enable-systemd], [enable support for managing resources via systemd @<:@try@:>@])] ) yes_no_try "$enable_systemd" "try" enable_systemd=$? AC_ARG_ENABLE([upstart], [AS_HELP_STRING([--enable-upstart], [enable support for managing resources via Upstart (deprecated) @<:@try@:>@])] ) yes_no_try "$enable_upstart" "try" enable_upstart=$? dnl --enable-* options: features inherent to Pacemaker # AM_GNU_GETTEXT calls AM_NLS which defines the nls option, but it defaults # to enabled. We override the definition of AM_NLS to flip the default and mark # it as experimental in the help text. AC_DEFUN([AM_NLS], [AC_MSG_CHECKING([whether NLS is requested]) AC_ARG_ENABLE([nls], [AS_HELP_STRING([--enable-nls], [use Native Language Support (experimental)])], USE_NLS=$enableval, USE_NLS=no) AC_MSG_RESULT([$USE_NLS]) AC_SUBST([USE_NLS])] ) AM_GNU_GETTEXT([external]) AM_GNU_GETTEXT_VERSION([0.18]) dnl --with-* options: external software support, and custom locations dnl This argument is defined via an M4 macro so default can be a variable AC_DEFUN([VERSION_ARG], [AC_ARG_WITH([version], [AS_HELP_STRING([--with-version=VERSION], [override package version @<:@$1@:>@])], [ PACEMAKER_VERSION="$withval" ], [ PACEMAKER_VERSION="$PACKAGE_VERSION" ])] ) VERSION_ARG(VERSION_NUMBER) CRM_DAEMON_USER="" AC_ARG_WITH([daemon-user], [AS_HELP_STRING([--with-daemon-user=USER], [user to run unprivileged Pacemaker daemons as (advanced option: changing this may break other cluster components unless similarly configured) @<:@hacluster@:>@])], [ CRM_DAEMON_USER="$withval" ] ) AS_IF([test x"${CRM_DAEMON_USER}" = x""], [CRM_DAEMON_USER="hacluster"]) CRM_DAEMON_GROUP="" AC_ARG_WITH([daemon-group], [AS_HELP_STRING([--with-daemon-group=GROUP], [group to run unprivileged Pacemaker daemons as (advanced option: changing this may break other cluster components unless similarly configured) @<:@haclient@:>@])], [ CRM_DAEMON_GROUP="$withval" ] ) AS_IF([test x"${CRM_DAEMON_GROUP}" = x""], [CRM_DAEMON_GROUP="haclient"]) BUG_URL="" AC_ARG_WITH([bug-url], [AS_HELP_STRING([--with-bug-url=DIR], m4_normalize([ address where users should submit bug reports @<:@https://bugs.clusterlabs.org/enter_bug.cgi?product=Pacemaker@:>@]))], [ BUG_URL="$withval" ] ) AS_IF([test x"${BUG_URL}" = x""], [BUG_URL="https://bugs.clusterlabs.org/enter_bug.cgi?product=Pacemaker"]) dnl --with-* options: features AC_ARG_WITH([cibsecrets], [AS_HELP_STRING([--with-cibsecrets], [support separate file for CIB secrets @<:@no@:>@])] ) yes_no_try "$with_cibsecrets" "no" with_cibsecrets=$? PCMK_GNUTLS_PRIORITIES="NORMAL" AC_ARG_WITH([gnutls-priorities], [AS_HELP_STRING([--with-gnutls-priorities], [default GnuTLS cipher priorities @<:@NORMAL@:>@])], [ test x"$withval" = x"no" || PCMK_GNUTLS_PRIORITIES="$withval" ] ) AC_ARG_WITH([concurrent-fencing-default], [AS_HELP_STRING([--with-concurrent-fencing-default], [default value for concurrent-fencing cluster option @<:@false@:>@])], ) AS_CASE([$with_concurrent_fencing_default], [""], [with_concurrent_fencing_default="false"], [false], [], [true], [PCMK_FEATURES="$PCMK_FEATURES default-concurrent-fencing"], [AC_MSG_ERROR([Invalid value "$with_concurrent_fencing_default" for --with-concurrent-fencing-default])] ) AC_ARG_WITH([sbd-sync-default], [AS_HELP_STRING([--with-sbd-sync-default], m4_normalize([ default value used by sbd if SBD_SYNC_RESOURCE_STARTUP environment variable is not set @<:@false@:>@]))], ) AS_CASE([$with_sbd_sync_default], [""], [with_sbd_sync_default=false], [false], [], [true], [PCMK_FEATURES="$PCMK_FEATURES default-sbd-sync"], [AC_MSG_ERROR([Invalid value "$with_sbd_sync_default" for --with-sbd-sync-default])] ) AC_ARG_WITH([resource-stickiness-default], [AS_HELP_STRING([--with-resource-stickiness-default], [If positive, value to add to new CIBs as explicit resource default for resource-stickiness @<:@0@:>@])], ) errmsg="Invalid value \"$with_resource_stickiness_default\" for --with-resource-stickiness-default" AS_CASE([$with_resource_stickiness_default], [0|""], [with_resource_stickiness_default="0"], [*[[!0-9]]*], [AC_MSG_ERROR([$errmsg])], [PCMK_FEATURES="$PCMK_FEATURES default-resource-stickiness"] ) AC_ARG_WITH([corosync], [AS_HELP_STRING([--with-corosync], [support the Corosync messaging and membership layer @<:@try@:>@])] ) yes_no_try "$with_corosync" "try" with_corosync=$? dnl Get default from Corosync if possible PKG_CHECK_VAR([PCMK__COROSYNC_CONF], [corosync], [corosysconfdir], [PCMK__COROSYNC_CONF="$PCMK__COROSYNC_CONF/corosync.conf"], [PCMK__COROSYNC_CONF="${sysconfdir}/corosync/corosync.conf"]) AC_ARG_WITH([corosync-conf], [AS_HELP_STRING([--with-corosync-conf], m4_normalize([ location of Corosync configuration file @<:@value from Corosync package if available otherwise SYSCONFDIR/corosync/corosync.conf@:>@]))], [ PCMK__COROSYNC_CONF="$withval" ] ) AC_ARG_WITH([nagios], [AS_HELP_STRING([--with-nagios], [support nagios resources (deprecated)])] ) yes_no_try "$with_nagios" "try" with_nagios=$? dnl --with-* options: directory locations AC_ARG_WITH([nagios-plugin-dir], [AS_HELP_STRING([--with-nagios-plugin-dir=DIR], [directory for nagios plugins (deprecated) @<:@LIBEXECDIR/nagios/plugins@:>@])], [ NAGIOS_PLUGIN_DIR="$withval" ] ) AC_ARG_WITH([nagios-metadata-dir], [AS_HELP_STRING([--with-nagios-metadata-dir=DIR], [directory for nagios plugins metadata (deprecated) @<:@DATADIR/nagios/plugins-metadata@:>@])], [ NAGIOS_METADATA_DIR="$withval" ] ) INITDIR="" AC_ARG_WITH([initdir], [AS_HELP_STRING([--with-initdir=DIR], [directory for init (rc) scripts])], [ INITDIR="$withval" ] ) systemdsystemunitdir="${systemdsystemunitdir-}" AC_ARG_WITH([systemdsystemunitdir], [AS_HELP_STRING([--with-systemdsystemunitdir=DIR], [directory for systemd unit files (advanced option: must match what systemd uses)])], [ systemdsystemunitdir="$withval" ] ) CONFIGDIR="" AC_ARG_WITH([configdir], [AS_HELP_STRING([--with-configdir=DIR], [directory for Pacemaker configuration file @<:@SYSCONFDIR/sysconfig@:>@])], [ CONFIGDIR="$withval" ] ) dnl --runstatedir is available as of autoconf 2.70 (2020-12-08). When users dnl have an older version, they can use our --with-runstatedir. pcmk_runstatedir="" AC_ARG_WITH([runstatedir], [AS_HELP_STRING([--with-runstatedir=DIR], [modifiable per-process data @<:@LOCALSTATEDIR/run@:>@ (ignored if --runstatedir is available)])], [ pcmk_runstatedir="$withval" ] ) CRM_LOG_DIR="" AC_ARG_WITH([logdir], [AS_HELP_STRING([--with-logdir=DIR], [directory for Pacemaker log file @<:@LOCALSTATEDIR/log/pacemaker@:>@])], [ CRM_LOG_DIR="$withval" ] ) CRM_BUNDLE_DIR="" AC_ARG_WITH([bundledir], [AS_HELP_STRING([--with-bundledir=DIR], [directory for Pacemaker bundle logs @<:@LOCALSTATEDIR/log/pacemaker/bundles@:>@])], [ CRM_BUNDLE_DIR="$withval" ] ) dnl Get default from resource-agents if possible. Otherwise, the default uses dnl /usr/lib rather than libdir because it's determined by the OCF project and dnl not Pacemaker. Even if a user wants to install Pacemaker to /usr/local or dnl such, the OCF agents will be expected in their usual location. However, we dnl do give the user the option to override it. PKG_CHECK_VAR([OCF_ROOT_DIR], [resource-agents], [ocfrootdir], [], [OCF_ROOT_DIR="/usr/lib/ocf"]) AC_ARG_WITH([ocfdir], [AS_HELP_STRING([--with-ocfdir=DIR], m4_normalize([ OCF resource agent root directory (advanced option: changing this may break other cluster components unless similarly configured) @<:@value from resource-agents package if available otherwise /usr/lib/ocf@:>@]))], [ OCF_ROOT_DIR="$withval" ] ) dnl Get default from resource-agents if possible PKG_CHECK_VAR([OCF_RA_PATH], [resource-agents], [ocfrapath], [], [OCF_RA_PATH="$OCF_ROOT_DIR/resource.d"]) AC_ARG_WITH([ocfrapath], [AS_HELP_STRING([--with-ocfrapath=DIR], m4_normalize([ OCF resource agent directories (colon-separated) to search @<:@value from resource-agents package if available otherwise OCFDIR/resource.d@:>@]))], [ OCF_RA_PATH="$withval" ] ) OCF_RA_INSTALL_DIR="$OCF_ROOT_DIR/resource.d" AC_ARG_WITH([ocfrainstalldir], [AS_HELP_STRING([--with-ocfrainstalldir=DIR], m4_normalize([ OCF installation directory for Pacemakers resource agents @<:@OCFDIR/resource.d@:>@]))], [ OCF_RA_INSTALL_DIR="$withval" ] ) dnl Get default from fence-agents if available PKG_CHECK_VAR([FA_PREFIX], [fence-agents], [prefix], [PCMK__FENCE_BINDIR="${FA_PREFIX}/sbin"], [PCMK__FENCE_BINDIR="$sbindir"]) AC_ARG_WITH([fence-bindir], [AS_HELP_STRING([--with-fence-bindir=DIR], m4_normalize([ directory for executable fence agents @<:@value from fence-agents package if available otherwise SBINDIR@:>@]))], [ PCMK__FENCE_BINDIR="$withval" ] ) dnl --with-* options: non-production testing AC_ARG_WITH([profiling], [AS_HELP_STRING([--with-profiling], [disable optimizations, for effective profiling @<:@no@:>@])] ) yes_no_try "$with_profiling" "no" with_profiling=$? AC_ARG_WITH([coverage], [AS_HELP_STRING([--with-coverage], [disable optimizations, for effective profiling and coverage testing @<:@no@:>@])] ) yes_no_try "$with_coverage" "no" with_coverage=$? AC_DEFINE_UNQUOTED([PCMK__WITH_COVERAGE], [$with_coverage], [Build with code coverage]) AM_CONDITIONAL([BUILD_COVERAGE], [test $with_coverage -ne $DISABLED]) AC_ARG_WITH([sanitizers], [AS_HELP_STRING([--with-sanitizers=...,...], [enable SANitizer build, do *NOT* use for production. Only ASAN/UBSAN/TSAN are currently supported])], [ SANITIZERS="$withval" ], [ SANITIZERS="" ]) dnl Environment variable options AC_ARG_VAR([CFLAGS_HARDENED_LIB], [extra C compiler flags for hardened libraries]) AC_ARG_VAR([LDFLAGS_HARDENED_LIB], [extra linker flags for hardened libraries]) AC_ARG_VAR([CFLAGS_HARDENED_EXE], [extra C compiler flags for hardened executables]) AC_ARG_VAR([LDFLAGS_HARDENED_EXE], [extra linker flags for hardened executables]) dnl ============================================== dnl Locate essential tools dnl ============================================== PATH="$PATH:/sbin:/usr/sbin:/usr/local/sbin:/usr/local/bin" export PATH dnl Pacemaker's executable python scripts will invoke the python specified by dnl configure's PYTHON variable. If not specified, AM_PATH_PYTHON will check a dnl built-in list with (unversioned) "python" having precedence. To configure dnl Pacemaker to use a specific python interpreter version, define PYTHON dnl when calling configure, for example: ./configure PYTHON=/usr/bin/python3.6 dnl If PYTHON was specified, ensure it is an absolute path AS_IF([test x"${PYTHON}" != x""], [AC_PATH_PROG([PYTHON], [$PYTHON])]) dnl Require a minimum Python version AM_PATH_PYTHON([3.6]) AC_PROG_LN_S AC_PROG_MKDIR_P AC_PATH_PROG([GIT], [git], [false]) dnl Bash is needed for building man pages and running regression tests. dnl We set "BASH_PATH" because "BASH" is already an environment variable. REQUIRE_PROG([BASH_PATH], [bash]) AC_PATH_PROGS(VALGRIND_BIN, valgrind, /usr/bin/valgrind) AC_DEFINE_UNQUOTED(VALGRIND_BIN, "$VALGRIND_BIN", Valgrind command) dnl ============================================== dnl Package and schema versioning dnl ============================================== # Redefine PACKAGE_VERSION and VERSION according to PACEMAKER_VERSION in case # the user used --with-version. Unfortunately, this can only affect the # substitution variables and later uses in this file, not the config.h # constants, so we have to be careful to use only PACEMAKER_VERSION in C code. PACKAGE_VERSION=$PACEMAKER_VERSION VERSION=$PACEMAKER_VERSION AC_DEFINE_UNQUOTED(PACEMAKER_VERSION, "$VERSION", [Version number of this Pacemaker build]) AC_MSG_CHECKING([build version]) AS_IF([test "$GIT" != "false" && test -d .git], [ BUILD_VERSION=`"$GIT" log --pretty="format:%h" -n 1` AC_MSG_RESULT([$BUILD_VERSION (git hash)]) ], [ # The current directory name make a reasonable default # Most generated archives will include the hash or tag BASE=`basename $PWD` BUILD_VERSION=`echo $BASE | sed s:.*[[Pp]]acemaker-::` AC_MSG_RESULT([$BUILD_VERSION (directory name)]) ]) AC_DEFINE_UNQUOTED(BUILD_VERSION, "$BUILD_VERSION", Build version) AC_SUBST(BUILD_VERSION) # schema_files # List all manually edited RNG schemas (as opposed to auto-generated via make) # in the given directory. Use git if available to list managed RNGs, in case # there are leftover schema files from an earlier build of a different # version. Otherwise, check all RNGs. schema_files() { local files="$("$GIT" ls-files "$1"/*.rng 2>/dev/null)" AS_IF([test x"$files" = x""], [ files="$(ls -1 "$1"/*.rng | grep -E -v \ '/(pacemaker|api-result|crm_mon|versions)[^/]*\.rng')" ]) echo "$files" } # latest_schema_version # Determine highest RNG version in the given schema directory. latest_schema_version() { schema_files "$1" | sed -n -e 's/^.*-\([[0-9]][[0-9.]]*\).rng$/\1/p' dnl | sort -V | tail -1 } # schemas_for_make # Like schema_files, but suitable for use in make variables. schemas_for_make() { local file for file in $(schema_files "$1"); do AS_ECHO_N(["\$(top_srcdir)/$file "]) done } # Detect highest API schema version API_VERSION=$(latest_schema_version "xml/api") AC_DEFINE_UNQUOTED([PCMK__API_VERSION], ["$API_VERSION"], [Highest API schema version]) # Detect highest CIB schema version CIB_VERSION=$(latest_schema_version "xml") AC_SUBST(CIB_VERSION) # Re-run configure at next make if schema files change, to re-detect versions cib_schemas="$(schemas_for_make "xml")" api_schemas="$(schemas_for_make "xml/api")" CONFIG_STATUS_DEPENDENCIES="$cib_schemas $api_schemas" AC_SUBST(CONFIG_STATUS_DEPENDENCIES) dnl ============================================== dnl Process simple options dnl ============================================== AS_IF([test x"$enable_nls" = x"yes"], [PCMK_FEATURES="$PCMK_FEATURES nls"]) AC_DEFINE_UNQUOTED([PCMK__CONCURRENT_FENCING_DEFAULT], ["$with_concurrent_fencing_default"], [Default value for concurrent-fencing cluster option]) AC_DEFINE_UNQUOTED([PCMK__SBD_SYNC_DEFAULT], [$with_sbd_sync_default], [Default value for SBD_SYNC_RESOURCE_STARTUP environment variable]) AC_DEFINE_UNQUOTED([PCMK__RESOURCE_STICKINESS_DEFAULT], [$with_resource_stickiness_default], [Default value for resource-stickiness resource meta-attribute]) AS_IF([test x"${PCMK_GNUTLS_PRIORITIES}" != x""], [], [AC_MSG_ERROR([--with-gnutls-priorities value must not be empty])]) AC_DEFINE_UNQUOTED([PCMK_GNUTLS_PRIORITIES], ["$PCMK_GNUTLS_PRIORITIES"], [GnuTLS cipher priorities]) AC_SUBST(PCMK_GNUTLS_PRIORITIES) AC_SUBST(BUG_URL) AC_DEFINE_UNQUOTED([PCMK__BUG_URL], ["$BUG_URL"], [Where bugs should be reported]) AC_DEFINE_UNQUOTED([CRM_DAEMON_USER], ["$CRM_DAEMON_USER"], [User to run Pacemaker daemons as]) AC_SUBST(CRM_DAEMON_USER) AC_DEFINE_UNQUOTED([CRM_DAEMON_GROUP], ["$CRM_DAEMON_GROUP"], [Group to run Pacemaker daemons as]) AC_SUBST(CRM_DAEMON_GROUP) dnl ============================================== dnl Process file paths dnl ============================================== # expand_path_option [] # Given the name of a file path variable, expand any variable references # inside it, use the specified default if it is not specified, and ensure it # is a full path. expand_path_option() { # The first argument is the variable *name* (not value) ac_path_varname="$1" # Get the original value of the variable ac_path_value=$(eval echo "\${${ac_path_varname}}") # Expand any literal variable expressions in the value so that we don't # end up with something like '${prefix}' in #defines etc. # # Autoconf deliberately leaves values unexpanded to allow overriding # the configure script choices in make commands (for example, # "make exec_prefix=/foo install"). No longer being able to do this seems # like no great loss. eval ac_path_value=$(eval echo "${ac_path_value}") # Use (expanded) default if necessary AS_IF([test x"${ac_path_value}" = x""], [eval ac_path_value=$(eval echo "$2")]) # Require a full path AS_CASE(["$ac_path_value"], [/*], [eval ${ac_path_varname}="$ac_path_value"], [*], [AC_MSG_ERROR([$ac_path_varname value "$ac_path_value" is not a full path])] ) } AC_MSG_NOTICE([Sanitizing INITDIR: ${INITDIR}]) AS_CASE([$INITDIR], [prefix], [INITDIR=$prefix], [""], [ AC_MSG_CHECKING([which init (rc) directory to use]) for initdir in /etc/init.d /etc/rc.d/init.d /sbin/init.d \ /usr/local/etc/rc.d /etc/rc.d do AS_IF([test -d $initdir], [ INITDIR=$initdir break ]) done AC_MSG_RESULT([$INITDIR]) ]) AC_SUBST(INITDIR) dnl Expand values of autoconf-provided directory options expand_path_option prefix expand_path_option exec_prefix expand_path_option bindir expand_path_option sbindir expand_path_option libexecdir expand_path_option datarootdir expand_path_option datadir expand_path_option sysconfdir expand_path_option sharedstatedir expand_path_option localstatedir expand_path_option libdir expand_path_option includedir expand_path_option oldincludedir expand_path_option infodir expand_path_option mandir AC_DEFUN([AC_DATAROOTDIR_CHECKED]) dnl Expand values of custom directory options expand_path_option localedir "${datadir}/locale" AC_DEFINE_UNQUOTED([PCMK__LOCALE_DIR],["$localedir"], [Base directory for message catalogs]) AS_IF([test x"${runstatedir}" = x""], [runstatedir="${pcmk_runstatedir}"]) expand_path_option runstatedir "${localstatedir}/run" AC_DEFINE_UNQUOTED([PCMK_RUN_DIR], ["$runstatedir"], [Location for modifiable per-process data]) AC_SUBST(runstatedir) expand_path_option INITDIR AC_DEFINE_UNQUOTED([PCMK__LSB_INIT_DIR], ["$INITDIR"], [Location for LSB init scripts]) expand_path_option docdir "${datadir}/doc/${PACKAGE}-${VERSION}" AC_SUBST(docdir) expand_path_option CONFIGDIR "${sysconfdir}/sysconfig" AC_SUBST(CONFIGDIR) expand_path_option PCMK__COROSYNC_CONF "${sysconfdir}/corosync/corosync.conf" AC_SUBST(PCMK__COROSYNC_CONF) expand_path_option CRM_LOG_DIR "${localstatedir}/log/pacemaker" AC_DEFINE_UNQUOTED([CRM_LOG_DIR], ["$CRM_LOG_DIR"], [Location for Pacemaker log file]) AC_SUBST(CRM_LOG_DIR) expand_path_option CRM_BUNDLE_DIR "${localstatedir}/log/pacemaker/bundles" AC_DEFINE_UNQUOTED([CRM_BUNDLE_DIR], ["$CRM_BUNDLE_DIR"], [Location for Pacemaker bundle logs]) AC_SUBST(CRM_BUNDLE_DIR) expand_path_option PCMK__FENCE_BINDIR AC_SUBST(PCMK__FENCE_BINDIR) AC_DEFINE_UNQUOTED([PCMK__FENCE_BINDIR], ["$PCMK__FENCE_BINDIR"], [Location for executable fence agents]) expand_path_option OCF_ROOT_DIR AC_SUBST(OCF_ROOT_DIR) AC_DEFINE_UNQUOTED([OCF_ROOT_DIR], ["$OCF_ROOT_DIR"], [OCF root directory for resource agents and libraries]) expand_path_option OCF_RA_PATH AC_SUBST(OCF_RA_PATH) AC_DEFINE_UNQUOTED([OCF_RA_PATH], ["$OCF_RA_PATH"], [OCF directories to search for resource agents ]) expand_path_option OCF_RA_INSTALL_DIR AC_SUBST(OCF_RA_INSTALL_DIR) # Derived paths CRM_SCHEMA_DIRECTORY="${datadir}/pacemaker" AC_DEFINE_UNQUOTED([CRM_SCHEMA_DIRECTORY], ["$CRM_SCHEMA_DIRECTORY"], [Location for the Pacemaker Relax-NG Schema]) AC_SUBST(CRM_SCHEMA_DIRECTORY) PCMK__REMOTE_SCHEMA_DIR="${localstatedir}/lib/pacemaker/schemas" AC_DEFINE_UNQUOTED([PCMK__REMOTE_SCHEMA_DIR], ["$PCMK__REMOTE_SCHEMA_DIR"], [Location to store Relax-NG Schema files on remote nodes]) AC_SUBST(PCMK__REMOTE_SCHEMA_DIR) CRM_CORE_DIR="${localstatedir}/lib/pacemaker/cores" AC_DEFINE_UNQUOTED([CRM_CORE_DIR], ["$CRM_CORE_DIR"], [Directory Pacemaker daemons should change to (without systemd, core files will go here)]) AC_SUBST(CRM_CORE_DIR) CRM_PACEMAKER_DIR="${localstatedir}/lib/pacemaker" AC_DEFINE_UNQUOTED([CRM_PACEMAKER_DIR], ["$CRM_PACEMAKER_DIR"], [Location to store directory produced by Pacemaker daemons]) AC_SUBST(CRM_PACEMAKER_DIR) CRM_BLACKBOX_DIR="${localstatedir}/lib/pacemaker/blackbox" AC_DEFINE_UNQUOTED([CRM_BLACKBOX_DIR], ["$CRM_BLACKBOX_DIR"], [Where to keep blackbox dumps]) AC_SUBST(CRM_BLACKBOX_DIR) PE_STATE_DIR="${localstatedir}/lib/pacemaker/pengine" AC_DEFINE_UNQUOTED([PE_STATE_DIR], ["$PE_STATE_DIR"], [Where to keep scheduler outputs]) AC_SUBST(PE_STATE_DIR) CRM_CONFIG_DIR="${localstatedir}/lib/pacemaker/cib" AC_DEFINE_UNQUOTED([CRM_CONFIG_DIR], ["$CRM_CONFIG_DIR"], [Where to keep configuration files]) AC_SUBST(CRM_CONFIG_DIR) CRM_DAEMON_DIR="${libexecdir}/pacemaker" AC_DEFINE_UNQUOTED([CRM_DAEMON_DIR], ["$CRM_DAEMON_DIR"], [Location for Pacemaker daemons]) AC_SUBST(CRM_DAEMON_DIR) CRM_STATE_DIR="${runstatedir}/crm" AC_DEFINE_UNQUOTED([CRM_STATE_DIR], ["$CRM_STATE_DIR"], [Where to keep state files and sockets]) AC_SUBST(CRM_STATE_DIR) CRM_RSCTMP_DIR="${runstatedir}/resource-agents" AC_DEFINE_UNQUOTED([CRM_RSCTMP_DIR], ["$CRM_RSCTMP_DIR"], [Where resource agents should keep state files]) AC_SUBST(CRM_RSCTMP_DIR) PACEMAKER_CONFIG_DIR="${sysconfdir}/pacemaker" AC_DEFINE_UNQUOTED([PACEMAKER_CONFIG_DIR], ["$PACEMAKER_CONFIG_DIR"], [Where to keep configuration files like authkey]) AC_SUBST(PACEMAKER_CONFIG_DIR) AC_DEFINE_UNQUOTED([SBIN_DIR], ["$sbindir"], [Location for system binaries]) # Warn about any directories that don't exist (which may be OK) for j in prefix exec_prefix bindir sbindir libexecdir datadir sysconfdir \ sharedstatedir localstatedir libdir includedir oldincludedir infodir \ mandir INITDIR docdir CONFIGDIR localedir do dirname=`eval echo '${'${j}'}'` AS_IF([test ! -d "$dirname"], [AC_MSG_WARN([$j directory ($dirname) does not exist (yet)])]) done dnl =============================================== dnl General Processing dnl =============================================== us_auth= AC_CHECK_HEADER([sys/socket.h], [ AC_CHECK_DECL([SO_PEERCRED], [ # Linux AC_CHECK_TYPE([struct ucred], [ us_auth=peercred_ucred; AC_DEFINE([HAVE_UCRED], [1], [Define if Unix socket auth method is getsockopt(s, SO_PEERCRED, &ucred, ...)]) ], [ # OpenBSD AC_CHECK_TYPE([struct sockpeercred], [ us_auth=localpeercred_sockepeercred; AC_DEFINE([HAVE_SOCKPEERCRED], [1], [Define if Unix socket auth method is getsockopt(s, SO_PEERCRED, &sockpeercred, ...)]) ], [], [[#include ]]) ], [[#define _GNU_SOURCE #include ]]) ], [], [[#include ]]) ]) AS_IF([test -z "${us_auth}"], [ # FreeBSD AC_CHECK_DECL([getpeereid], [ us_auth=getpeereid; AC_DEFINE([HAVE_GETPEEREID], [1], [Define if Unix socket auth method is getpeereid(s, &uid, &gid)]) ], [ # Solaris/OpenIndiana AC_CHECK_DECL([getpeerucred], [ us_auth=getpeerucred; AC_DEFINE([HAVE_GETPEERUCRED], [1], [Define if Unix socket auth method is getpeercred(s, &ucred)]) ], [ AC_MSG_FAILURE([No way to authenticate a Unix socket peer]) ], [[#include ]]) ]) ]) dnl OS-based decision-making is poor autotools practice; feature-based dnl mechanisms are strongly preferred. Keep this section to a bare minimum; dnl regard as a "necessary evil". dnl Set host_os and host_cpu AC_CANONICAL_HOST INIT_EXT="" PROCFS=0 dnl Solaris and some *BSD versions support procfs but not files we need AS_CASE(["$host_os"], [*bsd*], [INIT_EXT=".sh"], [*linux*], [PROCFS=1], [darwin*], [ LIBS="$LIBS -L${prefix}/lib" CFLAGS="$CFLAGS -I${prefix}/include" ]) AC_SUBST(INIT_EXT) AM_CONDITIONAL([SUPPORT_PROCFS], [test $PROCFS -eq 1]) AC_DEFINE_UNQUOTED([HAVE_LINUX_PROCFS], [$PROCFS], [Define to 1 if procfs is supported]) AS_CASE(["$host_cpu"], [ppc64|powerpc64], [ AS_CASE([$CFLAGS], [*powerpc64*], [], [*], [AS_IF([test x"$GCC" = x"yes"], [CFLAGS="$CFLAGS -m64"]) ]) ]) dnl ============================================== dnl Documentation build dependencies and checks dnl ============================================== AC_PATH_PROGS([ASCIIDOC_CONV], [asciidoc asciidoctor]) AC_PATH_PROG([HELP2MAN], [help2man]) AC_PATH_PROG([SPHINX], [sphinx-build]) AC_PATH_PROG([INKSCAPE], [inkscape]) AC_PATH_PROG([XSLTPROC], [xsltproc]) AC_PATH_PROG([XMLCATALOG], [xmlcatalog]) AM_CONDITIONAL(BUILD_HELP, test x"${HELP2MAN}" != x"") AS_IF([test x"${HELP2MAN}" != x""], [PCMK_FEATURES="$PCMK_FEATURES generated-manpages"]) MANPAGE_XSLT="" AS_IF([test x"${XSLTPROC}" != x""], [ AC_MSG_CHECKING([for DocBook-to-manpage transform]) # first try to figure out correct template using xmlcatalog query, # resort to extensive (semi-deterministic) file search if that fails DOCBOOK_XSL_URI='http://docbook.sourceforge.net/release/xsl/current' DOCBOOK_XSL_PATH='manpages/docbook.xsl' MANPAGE_XSLT=$(${XMLCATALOG} "" ${DOCBOOK_XSL_URI}/${DOCBOOK_XSL_PATH} \ | sed -n 's|^file://||p;q') AS_IF([test x"${MANPAGE_XSLT}" = x""], [ DIRS=$(find "${datadir}" -name $(basename $(dirname ${DOCBOOK_XSL_PATH})) \ -type d 2>/dev/null | LC_ALL=C sort) XSLT=$(basename ${DOCBOOK_XSL_PATH}) for d in ${DIRS} do AS_IF([test -f "${d}/${XSLT}"], [ MANPAGE_XSLT="${d}/${XSLT}" break ]) done ]) ]) AC_MSG_RESULT([$MANPAGE_XSLT]) AC_SUBST(MANPAGE_XSLT) AM_CONDITIONAL(BUILD_XML_HELP, test x"${MANPAGE_XSLT}" != x"") AS_IF([test x"${MANPAGE_XSLT}" != x""], [PCMK_FEATURES="$PCMK_FEATURES agent-manpages"]) AM_CONDITIONAL([IS_ASCIIDOC], [echo "${ASCIIDOC_CONV}" | grep -Eq 'asciidoc$']) AM_CONDITIONAL([BUILD_ASCIIDOC], [test "x${ASCIIDOC_CONV}" != x]) AS_IF([test x"${ASCIIDOC_CONV}" != x""], [PCMK_FEATURES="$PCMK_FEATURES ascii-docs"]) AM_CONDITIONAL([BUILD_SPHINX_DOCS], [test x"${SPHINX}" != x"" && test x"${INKSCAPE}" != x""]) AM_COND_IF([BUILD_SPHINX_DOCS], [PCMK_FEATURES="$PCMK_FEATURES books"]) dnl Pacemaker's shell scripts (and thus man page builders) rely on GNU getopt AC_MSG_CHECKING([for GNU-compatible getopt]) IFS_orig=$IFS IFS=: for PATH_DIR in $PATH do IFS=$IFS_orig GETOPT_PATH="${PATH_DIR}/getopt" AS_IF([test -f "$GETOPT_PATH" && test -x "$GETOPT_PATH"], [ $GETOPT_PATH -T >/dev/null 2>/dev/null AS_IF([test $? -eq 4], [break]) ]) GETOPT_PATH="" done IFS=$IFS_orig AS_IF([test -n "$GETOPT_PATH"], [AC_MSG_RESULT([$GETOPT_PATH])], [ AC_MSG_RESULT([no]) AC_MSG_ERROR([Could not find required build tool GNU-compatible getopt]) ]) AC_SUBST([GETOPT_PATH]) dnl =============================================== dnl Libraries dnl =============================================== AC_CHECK_LIB(socket, socket) dnl -lsocket AC_CHECK_LIB(c, dlopen) dnl if dlopen is in libc... AC_CHECK_LIB(dl, dlopen) dnl -ldl (for Linux) AC_CHECK_LIB(rt, sched_getscheduler) dnl -lrt (for Tru64) AC_CHECK_LIB(gnugetopt, getopt_long) dnl -lgnugetopt ( if available ) AC_CHECK_LIB(pam, pam_start) dnl -lpam (if available) PKG_CHECK_MODULES([UUID], [uuid], [CPPFLAGS="${CPPFLAGS} ${UUID_CFLAGS}" LIBS="${LIBS} ${UUID_LIBS}"]) AC_CHECK_FUNCS([sched_setscheduler]) AS_IF([test x"$ac_cv_func_sched_setscheduler" != x"yes"], [PC_LIBS_RT=""], [PC_LIBS_RT="-lrt"]) AC_SUBST(PC_LIBS_RT) # Require minimum glib version PKG_CHECK_MODULES([GLIB], [glib-2.0 >= 2.42.0], [CPPFLAGS="${CPPFLAGS} ${GLIB_CFLAGS}" LIBS="${LIBS} ${GLIB_LIBS}"]) # Check whether high-resolution sleep function is available AC_CHECK_FUNCS([nanosleep usleep]) # # Where is dlopen? # AS_IF([test x"$ac_cv_lib_c_dlopen" = x"yes"], [LIBADD_DL=""], [test x"$ac_cv_lib_dl_dlopen" = x"yes"], [LIBADD_DL=-ldl], [LIBADD_DL=${lt_cv_dlopen_libs}]) PKG_CHECK_MODULES(LIBXML2, [libxml-2.0 >= 2.9.2], [CPPFLAGS="${CPPFLAGS} ${LIBXML2_CFLAGS}" LIBS="${LIBS} ${LIBXML2_LIBS}"]) REQUIRE_LIB([xslt], [xsltApplyStylesheet]) AC_MSG_CHECKING([whether __progname and __progname_full are available]) AC_LINK_IFELSE([AC_LANG_PROGRAM([[extern char *__progname, *__progname_full;]], [[__progname = "foo"; __progname_full = "foo bar";]])], [ have_progname="yes" AC_DEFINE(HAVE_PROGNAME, 1, [Define to 1 if processes can change their name]) ], [have_progname="no"]) AC_MSG_RESULT([$have_progname]) dnl ======================================================================== dnl Headers dnl ======================================================================== # Some distributions insert #warnings into deprecated headers. If we will # enable fatal warnings for the build, then enable them for the header checks # as well, otherwise the build could fail even though the header check # succeeds. (We should probably be doing this in more places.) cc_temp_flags "$CFLAGS $WERROR" # Optional headers (inclusion of these should be conditional in C code) AC_CHECK_HEADERS([linux/swab.h]) AC_CHECK_HEADERS([stddef.h]) AC_CHECK_HEADERS([sys/signalfd.h]) AC_CHECK_HEADERS([uuid/uuid.h]) AC_CHECK_HEADERS([security/pam_appl.h pam/pam_appl.h]) # Required headers REQUIRE_HEADER([arpa/inet.h]) REQUIRE_HEADER([ctype.h]) REQUIRE_HEADER([dirent.h]) REQUIRE_HEADER([dlfcn.h]) REQUIRE_HEADER([errno.h]) REQUIRE_HEADER([fcntl.h]) REQUIRE_HEADER([float.h]) REQUIRE_HEADER([glib.h]) REQUIRE_HEADER([grp.h]) REQUIRE_HEADER([inttypes.h]) REQUIRE_HEADER([libgen.h]) REQUIRE_HEADER([limits.h]) REQUIRE_HEADER([locale.h]) REQUIRE_HEADER([netdb.h]) REQUIRE_HEADER([netinet/in.h]) REQUIRE_HEADER([netinet/ip.h], [ #include #include ]) REQUIRE_HEADER([netinet/tcp.h]) REQUIRE_HEADER([pwd.h]) REQUIRE_HEADER([regex.h]) REQUIRE_HEADER([sched.h]) REQUIRE_HEADER([signal.h]) REQUIRE_HEADER([stdarg.h]) REQUIRE_HEADER([stdbool.h]) REQUIRE_HEADER([stdint.h]) REQUIRE_HEADER([stdio.h]) REQUIRE_HEADER([stdlib.h]) REQUIRE_HEADER([string.h]) REQUIRE_HEADER([strings.h]) REQUIRE_HEADER([sys/ioctl.h]) REQUIRE_HEADER([sys/param.h]) REQUIRE_HEADER([sys/reboot.h]) REQUIRE_HEADER([sys/resource.h]) REQUIRE_HEADER([sys/socket.h]) REQUIRE_HEADER([sys/stat.h]) REQUIRE_HEADER([sys/time.h]) REQUIRE_HEADER([sys/types.h]) REQUIRE_HEADER([sys/uio.h]) REQUIRE_HEADER([sys/utsname.h]) REQUIRE_HEADER([sys/wait.h]) REQUIRE_HEADER([termios.h]) REQUIRE_HEADER([time.h]) REQUIRE_HEADER([unistd.h]) REQUIRE_HEADER([libxml/xpath.h]) REQUIRE_HEADER([libxslt/xslt.h]) cc_restore_flags dnl ======================================================================== dnl Generic declarations dnl ======================================================================== AC_CHECK_DECLS([CLOCK_MONOTONIC], [PCMK_FEATURES="$PCMK_FEATURES monotonic"], [], [[ #include ]]) dnl ======================================================================== dnl Unit test declarations dnl ======================================================================== AC_CHECK_DECLS([assert_float_equal], [], [], [[ #include #include #include #include ]]) dnl ======================================================================== dnl Byte size dnl ======================================================================== # Compile-time assert hack # https://jonjagger.blogspot.com/2017/07/compile-time-assertions-in-c.html AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[ switch (0) { case 0: case (CHAR_BIT == 8): break; } ]])], [], [AC_MSG_FAILURE(m4_normalize([Pacemaker is not supported on platforms where char is not 8 bits]))]) dnl ======================================================================== dnl Structures dnl ======================================================================== AC_CHECK_MEMBERS([struct tm.tm_gmtoff],,,[[#include ]]) AC_CHECK_MEMBER([struct dirent.d_type], AC_DEFINE(HAVE_STRUCT_DIRENT_D_TYPE,1,[Define this if struct dirent has d_type]),, [#include ]) dnl ======================================================================== dnl Functions dnl ======================================================================== REQUIRE_FUNC([alphasort]) REQUIRE_FUNC([getopt]) REQUIRE_FUNC([scandir]) REQUIRE_FUNC([setenv]) REQUIRE_FUNC([strndup]) REQUIRE_FUNC([strnlen]) REQUIRE_FUNC([unsetenv]) REQUIRE_FUNC([uuid_unparse]) REQUIRE_FUNC([vasprintf]) AC_CHECK_FUNCS([strchrnul]) AC_CHECK_FUNCS([fopen64]) AM_CONDITIONAL([WRAPPABLE_FOPEN64], [test x"$ac_cv_func_fopen64" = x"yes"]) AC_MSG_CHECKING([whether strerror always returns non-NULL]) AC_RUN_IFELSE([AC_LANG_PROGRAM([[ #include #include ]], [[ return strerror(-1) == NULL; ]])], [AC_MSG_RESULT([yes])], [AC_MSG_ERROR([strerror() is not C99-compliant])], [AC_MSG_ERROR([strerror() is not C99-compliant])]) AC_RUN_IFELSE([AC_LANG_PROGRAM([[#include ]], [[ const char *s = "some-command-line-arg"; char *name = NULL; int n = sscanf(s, "%ms", &name); return n != 1; ]])], [have_sscanf_m="yes"], [have_sscanf_m="no"], [have_sscanf_m="no"]) AS_IF([test x"$have_sscanf_m" = x"yes"], [AC_DEFINE([HAVE_SSCANF_M], [1], [Define to 1 if sscanf %m modifier is available])]) dnl ======================================================================== dnl bzip2 dnl ======================================================================== REQUIRE_HEADER([bzlib.h]) REQUIRE_LIB([bz2], [BZ2_bzBuffToBuffCompress]) dnl ======================================================================== dnl sighandler_t is missing from Illumos, Solaris11 systems dnl ======================================================================== AC_MSG_CHECKING([for sighandler_t]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[sighandler_t *f;]])], [ AC_MSG_RESULT([yes]) AC_DEFINE([HAVE_SIGHANDLER_T], [1], [Define to 1 if sighandler_t is available]) ], [AC_MSG_RESULT([no])]) dnl ======================================================================== dnl ncurses dnl ======================================================================== dnl dnl A few OSes (e.g. Linux) deliver a default "ncurses" alongside "curses". dnl Many non-Linux deliver "curses"; sites may add "ncurses". dnl dnl However, the source-code recommendation for both is to #include "curses.h" dnl (i.e. "ncurses" still wants the include to be simple, no-'n', "curses.h"). dnl dnl ncurses takes precedence. dnl AC_CHECK_HEADERS([curses.h curses/curses.h ncurses.h ncurses/ncurses.h]) dnl Although n-library is preferred, only look for it if the n-header was found. CURSESLIBS='' PC_NAME_CURSES="" PC_LIBS_CURSES="" AS_IF([test x"$ac_cv_header_ncurses_h" = x"yes"], [ AC_CHECK_LIB(ncurses, printw, [AC_DEFINE(HAVE_LIBNCURSES,1, have ncurses library)]) CURSESLIBS=`$PKG_CONFIG --libs ncurses` || CURSESLIBS='-lncurses' PC_NAME_CURSES="ncurses" ]) AS_IF([test x"$ac_cv_header_ncurses_ncurses_h" = x"yes"], [ AC_CHECK_LIB(ncurses, printw, [AC_DEFINE(HAVE_LIBNCURSES,1, have ncurses library)]) CURSESLIBS=`$PKG_CONFIG --libs ncurses` || CURSESLIBS='-lncurses' PC_NAME_CURSES="ncurses" ]) dnl Only look for non-n-library if there was no n-library. AS_IF([test x"$CURSESLIBS" = x"" && test x"$ac_cv_header_curses_h" = x"yes"], [ AC_CHECK_LIB(curses, printw, [CURSESLIBS='-lcurses'; AC_DEFINE(HAVE_LIBCURSES,1, have curses library)]) PC_LIBS_CURSES="$CURSESLIBS" ]) dnl Only look for non-n-library if there was no n-library. AS_IF([test x"$CURSESLIBS" = x"" && test x"$ac_cv_header_curses_curses_h" = x"yes"], [ AC_CHECK_LIB(curses, printw, [CURSESLIBS='-lcurses'; AC_DEFINE(HAVE_LIBCURSES,1, have curses library)]) PC_LIBS_CURSES="$CURSESLIBS" ]) AS_IF([test x"$CURSESLIBS" != x""], [PCMK_FEATURES="$PCMK_FEATURES ncurses"]) dnl Check for printw() prototype compatibility AS_IF([test x"$CURSESLIBS" != x"" && cc_supports_flag -Wcast-qual], [ ac_save_LIBS=$LIBS LIBS="$CURSESLIBS" # avoid broken test because of hardened build environment in Fedora 23+ # - https://fedoraproject.org/wiki/Changes/Harden_All_Packages # - https://bugzilla.redhat.com/1297985 AS_IF([cc_supports_flag -fPIC], [cc_temp_flags "-Wcast-qual $WERROR -fPIC"], [cc_temp_flags "-Wcast-qual $WERROR"]) AC_MSG_CHECKING([whether curses library is compatible]) AC_LINK_IFELSE( [AC_LANG_PROGRAM([ #if defined(HAVE_NCURSES_H) # include #elif defined(HAVE_NCURSES_NCURSES_H) # include #elif defined(HAVE_CURSES_H) # include #endif ], [printw((const char *)"Test");] )], [AC_MSG_RESULT([yes])], [ AC_MSG_RESULT([no]) AC_MSG_WARN(m4_normalize([Disabling curses because the printw() function of your (n)curses library is old. If you wish to enable curses, update to a newer version (ncurses 5.4 or later is recommended, available from https://invisible-island.net/ncurses/) ])) AC_DEFINE([HAVE_INCOMPATIBLE_PRINTW], [1], [Define to 1 if curses library has incompatible printw()]) ] ) LIBS=$ac_save_LIBS cc_restore_flags ]) AC_SUBST(CURSESLIBS) AC_SUBST(PC_NAME_CURSES) AC_SUBST(PC_LIBS_CURSES) dnl ======================================================================== dnl Profiling and GProf dnl ======================================================================== CFLAGS_ORIG="$CFLAGS" AS_IF([test $with_coverage -ne $DISABLED], [ with_profiling=$REQUIRED PCMK_FEATURES="$PCMK_FEATURES coverage" CFLAGS="$CFLAGS -fprofile-arcs -ftest-coverage" dnl During linking, make sure to specify -lgcov or -coverage ] ) AS_IF([test $with_profiling -ne $DISABLED], [ with_profiling=$REQUIRED PCMK_FEATURES="$PCMK_FEATURES profile" dnl Disable various compiler optimizations CFLAGS="$CFLAGS -fno-omit-frame-pointer -fno-inline -fno-builtin" dnl CFLAGS="$CFLAGS -fno-inline-functions" dnl CFLAGS="$CFLAGS -fno-default-inline" dnl CFLAGS="$CFLAGS -fno-inline-functions-called-once" dnl CFLAGS="$CFLAGS -fno-optimize-sibling-calls" dnl Turn off optimization so tools can get accurate line numbers CFLAGS=`echo $CFLAGS | sed \ -e 's/-O.\ //g' \ -e 's/-Wp,-D_FORTIFY_SOURCE=.\ //g' \ -e 's/-D_FORTIFY_SOURCE=.\ //g'` CFLAGS="$CFLAGS -O0 -g3 -gdwarf-2" AC_MSG_NOTICE([CFLAGS before adding profiling options: $CFLAGS_ORIG]) AC_MSG_NOTICE([CFLAGS after: $CFLAGS]) ] ) AC_DEFINE_UNQUOTED([SUPPORT_PROFILING], [$with_profiling], [Support profiling]) AM_CONDITIONAL([BUILD_PROFILING], [test "$with_profiling" = "$REQUIRED"]) dnl ======================================================================== dnl Cluster infrastructure - LibQB dnl ======================================================================== PKG_CHECK_MODULES([libqb], [libqb >= 1.0.1]) CPPFLAGS="$libqb_CFLAGS $CPPFLAGS" LIBS="$libqb_LIBS $LIBS" dnl libqb 2.0.5+ (2022-03) AC_CHECK_FUNCS([qb_ipcc_connect_async]) dnl libqb 2.0.2+ (2020-10) AC_CHECK_FUNCS([qb_ipcc_auth_get]) dnl libqb 2.0.0+ (2020-05) dnl also defines QB_FEATURE_LOG_HIRES_TIMESTAMPS CHECK_ENUM_VALUE([qb/qblog.h],[qb_log_conf],[QB_LOG_CONF_MAX_LINE_LEN]) CHECK_ENUM_VALUE([qb/qblog.h],[qb_log_conf],[QB_LOG_CONF_ELLIPSIS]) dnl Support Linux-HA fence agents if available AS_IF([test x"$cross_compiling" != x"yes"], [CPPFLAGS="$CPPFLAGS -I${prefix}/include/heartbeat"]) AC_CHECK_HEADERS([stonith/stonith.h], [ AC_CHECK_LIB([pils], [PILLoadPlugin]) AC_CHECK_LIB([plumb], [G_main_add_IPC_Channel]) PCMK_FEATURES="$PCMK_FEATURES lha" ]) AM_CONDITIONAL([BUILD_LHA_SUPPORT], [test x"$ac_cv_header_stonith_stonith_h" = x"yes"]) dnl =============================================== dnl Detect DBus, systemd, and Upstart support dnl =============================================== HAVE_dbus=0 PC_NAME_DBUS="" PKG_CHECK_MODULES([DBUS],[dbus-1 >= 1.5.12], [ HAVE_dbus=1 PC_NAME_DBUS="dbus-1" CPPFLAGS="${CPPFLAGS} ${DBUS_CFLAGS}" ],[]) AC_DEFINE_UNQUOTED(HAVE_DBUS, $HAVE_dbus, Support dbus) AM_CONDITIONAL(BUILD_DBUS, test $HAVE_dbus = 1) AC_SUBST(PC_NAME_DBUS) check_systemdsystemunitdir() { AC_MSG_CHECKING([which system unit file directory to use]) PKG_CHECK_VAR([systemdsystemunitdir], [systemd], [systemdsystemunitdir]) AC_MSG_RESULT([${systemdsystemunitdir}]) test x"$systemdsystemunitdir" != x"" return $? } AS_CASE([$enable_systemd], [$REQUIRED], [ AS_IF([test $HAVE_dbus = 0], [AC_MSG_FAILURE([Cannot support systemd resources without DBus])]) AS_IF([test "$ac_cv_have_decl_CLOCK_MONOTONIC" = "no"], [AC_MSG_FAILURE([Cannot support systemd resources without monotonic clock])]) AS_IF([check_systemdsystemunitdir], [], [AC_MSG_FAILURE([Cannot support systemd resources without systemdsystemunitdir])]) ], [$OPTIONAL], [ AS_IF([test $HAVE_dbus = 0 \ || test x"$ac_cv_have_decl_CLOCK_MONOTONIC" = x"no"], [enable_systemd=$DISABLED], [ AC_MSG_CHECKING([for systemd version (using dbus-send)]) ret=$({ dbus-send --system --print-reply \ --dest=org.freedesktop.systemd1 \ /org/freedesktop/systemd1 \ org.freedesktop.DBus.Properties.Get \ string:org.freedesktop.systemd1.Manager \ string:Version 2>/dev/null \ || echo "version unavailable"; } | tail -n1) # sanitize output a bit (interested just in value, not type), # ret is intentionally unenquoted so as to normalize whitespace ret=$(echo ${ret} | cut -d' ' -f2-) AC_MSG_RESULT([${ret}]) AS_IF([test x"$ret" != x"unavailable" \ || systemctl --version 2>/dev/null | grep -q systemd], [ AS_IF([check_systemdsystemunitdir], [enable_systemd=$REQUIRED], [enable_systemd=$DISABLED]) ], [enable_systemd=$DISABLED] ) ]) ], ) AC_MSG_CHECKING([whether to enable support for managing resources via systemd]) AS_IF([test $enable_systemd -eq $DISABLED], [AC_MSG_RESULT([no])], [ AC_MSG_RESULT([yes]) PCMK_FEATURES="$PCMK_FEATURES systemd" ] ) AC_SUBST([systemdsystemunitdir]) AC_DEFINE_UNQUOTED([SUPPORT_SYSTEMD], [$enable_systemd], [Support systemd resources]) AM_CONDITIONAL([BUILD_SYSTEMD], [test $enable_systemd = $REQUIRED]) AC_SUBST(SUPPORT_SYSTEMD) AS_CASE([$enable_upstart], [$REQUIRED], [ AS_IF([test $HAVE_dbus = 0], [AC_MSG_FAILURE([Cannot support Upstart resources without DBus])]) ], [$OPTIONAL], [ AS_IF([test $HAVE_dbus = 0], [enable_upstart=$DISABLED], [ AC_MSG_CHECKING([for Upstart version (using dbus-send)]) ret=$({ dbus-send --system --print-reply \ --dest=com.ubuntu.Upstart \ /com/ubuntu/Upstart org.freedesktop.DBus.Properties.Get \ string:com.ubuntu.Upstart0_6 string:version 2>/dev/null \ || echo "version unavailable"; } | tail -n1) # sanitize output a bit (interested just in value, not type), # ret is intentionally unenquoted so as to normalize whitespace ret=$(echo ${ret} | cut -d' ' -f2-) AC_MSG_RESULT([${ret}]) AS_IF([test x"$ret" != x"unavailable" \ || initctl --version 2>/dev/null | grep -q upstart], [enable_upstart=$REQUIRED], [enable_upstart=$DISABLED] ) ]) ], ) AC_MSG_CHECKING([whether to enable support for managing resources via Upstart]) AS_IF([test $enable_upstart -eq $DISABLED], [AC_MSG_RESULT([no])], [ AC_MSG_RESULT([yes]) PCMK_FEATURES="$PCMK_FEATURES upstart" ] ) AC_DEFINE_UNQUOTED([SUPPORT_UPSTART], [$enable_upstart], [Support Upstart resources]) AM_CONDITIONAL([BUILD_UPSTART], [test $enable_upstart -eq $REQUIRED]) AC_SUBST(SUPPORT_UPSTART) dnl ======================================================================== dnl Detect Nagios support dnl ======================================================================== AS_CASE([$with_nagios], [$REQUIRED], [ AS_IF([test x"$ac_cv_have_decl_CLOCK_MONOTONIC" = x"no"], [AC_MSG_FAILURE([Cannot support nagios resources without monotonic clock])]) ], [$OPTIONAL], [ AS_IF([test x"$ac_cv_have_decl_CLOCK_MONOTONIC" = x"no"], [with_nagios=$DISABLED], [with_nagios=$REQUIRED]) ] ) AS_IF([test $with_nagios -eq $REQUIRED], [PCMK_FEATURES="$PCMK_FEATURES nagios"]) AC_DEFINE_UNQUOTED([SUPPORT_NAGIOS], [$with_nagios], [Support nagios plugins]) AM_CONDITIONAL([BUILD_NAGIOS], [test $with_nagios -eq $REQUIRED]) AS_IF([test x"$NAGIOS_PLUGIN_DIR" = x""], [NAGIOS_PLUGIN_DIR="${libexecdir}/nagios/plugins"]) AC_DEFINE_UNQUOTED(NAGIOS_PLUGIN_DIR, "$NAGIOS_PLUGIN_DIR", Directory for nagios plugins) AC_SUBST(NAGIOS_PLUGIN_DIR) AS_IF([test x"$NAGIOS_METADATA_DIR" = x""], [NAGIOS_METADATA_DIR="${datadir}/nagios/plugins-metadata"]) AC_DEFINE_UNQUOTED(NAGIOS_METADATA_DIR, "$NAGIOS_METADATA_DIR", Directory for nagios plugins metadata) AC_SUBST(NAGIOS_METADATA_DIR) STACKS="" CLUSTERLIBS="" PC_NAME_CLUSTER="" dnl ======================================================================== dnl Cluster stack - Corosync dnl ======================================================================== COROSYNC_LIBS="" AS_CASE([$with_corosync], [$REQUIRED], [ # These will be fatal if unavailable PKG_CHECK_MODULES([cpg], [libcpg]) PKG_CHECK_MODULES([cfg], [libcfg]) PKG_CHECK_MODULES([cmap], [libcmap]) PKG_CHECK_MODULES([quorum], [libquorum]) PKG_CHECK_MODULES([libcorosync_common], [libcorosync_common]) ] [$OPTIONAL], [ PKG_CHECK_MODULES([cpg], [libcpg], [], [with_corosync=$DISABLED]) PKG_CHECK_MODULES([cfg], [libcfg], [], [with_corosync=$DISABLED]) PKG_CHECK_MODULES([cmap], [libcmap], [], [with_corosync=$DISABLED]) PKG_CHECK_MODULES([quorum], [libquorum], [], [with_corosync=$DISABLED]) PKG_CHECK_MODULES([libcorosync_common], [libcorosync_common], [], [with_corosync=$DISABLED]) AS_IF([test $with_corosync -ne $DISABLED], [with_corosync=$REQUIRED]) ] ) AS_IF([test $with_corosync -ne $DISABLED], [ AC_MSG_CHECKING([for Corosync 2 or later]) AC_MSG_RESULT([yes]) CFLAGS="$CFLAGS $libqb_CFLAGS $cpg_CFLAGS $cfg_CFLAGS $cmap_CFLAGS $quorum_CFLAGS $libcorosync_common_CFLAGS" CPPFLAGS="$CPPFLAGS `$PKG_CONFIG --cflags-only-I corosync`" COROSYNC_LIBS="$COROSYNC_LIBS $cpg_LIBS $cfg_LIBS $cmap_LIBS $quorum_LIBS $libcorosync_common_LIBS" CLUSTERLIBS="$CLUSTERLIBS $COROSYNC_LIBS" PC_NAME_CLUSTER="$PC_CLUSTER_NAME libcfg libcmap libcorosync_common libcpg libquorum" STACKS="$STACKS corosync-ge-2" dnl Shutdown tracking added (back) to corosync Jan 2021 saved_LIBS="$LIBS" LIBS="$LIBS $COROSYNC_LIBS" AC_CHECK_FUNCS([corosync_cfg_trackstart]) LIBS="$saved_LIBS" ] ) AC_DEFINE_UNQUOTED([SUPPORT_COROSYNC], [$with_corosync], [Support the Corosync messaging and membership layer]) AM_CONDITIONAL([BUILD_CS_SUPPORT], [test $with_corosync -eq $REQUIRED]) AC_SUBST([SUPPORT_COROSYNC]) dnl dnl Cluster stack - Sanity dnl AS_IF([test x"$STACKS" != x""], [AC_MSG_NOTICE([Supported stacks:${STACKS}])], [AC_MSG_FAILURE([At least one cluster stack must be supported])]) PCMK_FEATURES="${PCMK_FEATURES}${STACKS}" AC_SUBST(CLUSTERLIBS) AC_SUBST(PC_NAME_CLUSTER) dnl ======================================================================== dnl CIB secrets dnl ======================================================================== AS_IF([test $with_cibsecrets -ne $DISABLED], [ with_cibsecrets=$REQUIRED PCMK_FEATURES="$PCMK_FEATURES cibsecrets" LRM_CIBSECRETS_DIR="${localstatedir}/lib/pacemaker/lrm/secrets" AC_DEFINE_UNQUOTED([LRM_CIBSECRETS_DIR], ["$LRM_CIBSECRETS_DIR"], [Location for CIB secrets]) AC_SUBST([LRM_CIBSECRETS_DIR]) ] ) AC_DEFINE_UNQUOTED([SUPPORT_CIBSECRETS], [$with_cibsecrets], [Support CIB secrets]) AM_CONDITIONAL([BUILD_CIBSECRETS], [test $with_cibsecrets -eq $REQUIRED]) dnl ======================================================================== dnl GnuTLS dnl ======================================================================== PKG_CHECK_MODULES(GNUTLS, [gnutls >= 3.1.7], [CPPFLAGS="${CPPFLAGS} ${GNUTLS_CFLAGS}" LIBS="${LIBS} ${GNUTLS_LIBS}"]) # --- ASAN/UBSAN/TSAN (see man gcc) --- # when using SANitizers, we need to pass the -fsanitize.. # to both CFLAGS and LDFLAGS. The CFLAGS/LDFLAGS must be # specified as first in the list or there will be runtime # issues (for example user has to LD_PRELOAD asan for it to work # properly). AS_IF([test -n "${SANITIZERS}"], [ SANITIZERS=$(echo $SANITIZERS | sed -e 's/,/ /g') for SANITIZER in $SANITIZERS do AS_CASE([$SANITIZER], [asan|ASAN], [ SANITIZERS_CFLAGS="$SANITIZERS_CFLAGS -fsanitize=address" SANITIZERS_LDFLAGS="$SANITIZERS_LDFLAGS -fsanitize=address -lasan" PCMK_FEATURES="$PCMK_FEATURES asan" REQUIRE_LIB([asan],[main]) ], [ubsan|UBSAN], [ SANITIZERS_CFLAGS="$SANITIZERS_CFLAGS -fsanitize=undefined" SANITIZERS_LDFLAGS="$SANITIZERS_LDFLAGS -fsanitize=undefined -lubsan" PCMK_FEATURES="$PCMK_FEATURES ubsan" REQUIRE_LIB([ubsan],[main]) ], [tsan|TSAN], [ SANITIZERS_CFLAGS="$SANITIZERS_CFLAGS -fsanitize=thread" SANITIZERS_LDFLAGS="$SANITIZERS_LDFLAGS -fsanitize=thread -ltsan" PCMK_FEATURES="$PCMK_FEATURES tsan" REQUIRE_LIB([tsan],[main]) ]) done ]) dnl ======================================================================== dnl Compiler flags dnl ======================================================================== dnl Make sure that CFLAGS is not exported. If the user did dnl not have CFLAGS in their environment then this should have dnl no effect. However if CFLAGS was exported from the user's dnl environment, then the new CFLAGS will also be exported dnl to sub processes. AS_IF([export | fgrep " CFLAGS=" > /dev/null], [ SAVED_CFLAGS="$CFLAGS" unset CFLAGS CFLAGS="$SAVED_CFLAGS" unset SAVED_CFLAGS ]) CC_EXTRAS="" AS_IF([test x"$GCC" != x"yes"], [CFLAGS="$CFLAGS -g"], [ CFLAGS="$CFLAGS -ggdb" dnl When we don't have diagnostic push / pull, we can't explicitly disable dnl checking for nonliteral formats in the places where they occur on purpose dnl thus we disable nonliteral format checking globally as we are aborting dnl on warnings. dnl what makes the things really ugly is that nonliteral format checking is dnl obviously available as an extra switch in very modern gcc but for older dnl gcc this is part of -Wformat=2 dnl so if we have push/pull we can enable -Wformat=2 -Wformat-nonliteral dnl if we don't have push/pull but -Wformat-nonliteral we can enable -Wformat=2 dnl otherwise none of both gcc_diagnostic_push_pull=no cc_temp_flags "$CFLAGS $WERROR" AC_MSG_CHECKING([for gcc diagnostic push / pull]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #pragma GCC diagnostic push #pragma GCC diagnostic pop ]])], [ AC_MSG_RESULT([yes]) gcc_diagnostic_push_pull=yes ], AC_MSG_RESULT([no])) cc_restore_flags AS_IF([cc_supports_flag "-Wformat-nonliteral"], [gcc_format_nonliteral=yes], [gcc_format_nonliteral=no]) # We had to eliminate -Wnested-externs because of libtool changes # Make sure to order options so that the former stand for prerequisites # of the latter (e.g., -Wformat-nonliteral requires -Wformat). EXTRA_FLAGS="-fgnu89-inline" EXTRA_FLAGS="$EXTRA_FLAGS -Wall" EXTRA_FLAGS="$EXTRA_FLAGS -Waggregate-return" EXTRA_FLAGS="$EXTRA_FLAGS -Wbad-function-cast" EXTRA_FLAGS="$EXTRA_FLAGS -Wcast-align" EXTRA_FLAGS="$EXTRA_FLAGS -Wdeclaration-after-statement" EXTRA_FLAGS="$EXTRA_FLAGS -Wendif-labels" EXTRA_FLAGS="$EXTRA_FLAGS -Wfloat-equal" EXTRA_FLAGS="$EXTRA_FLAGS -Wformat-security" EXTRA_FLAGS="$EXTRA_FLAGS -Wimplicit-fallthrough" EXTRA_FLAGS="$EXTRA_FLAGS -Wmissing-prototypes" EXTRA_FLAGS="$EXTRA_FLAGS -Wmissing-declarations" EXTRA_FLAGS="$EXTRA_FLAGS -Wnested-externs" EXTRA_FLAGS="$EXTRA_FLAGS -Wno-long-long" EXTRA_FLAGS="$EXTRA_FLAGS -Wno-strict-aliasing" EXTRA_FLAGS="$EXTRA_FLAGS -Wpointer-arith" EXTRA_FLAGS="$EXTRA_FLAGS -Wstrict-prototypes" EXTRA_FLAGS="$EXTRA_FLAGS -Wwrite-strings" EXTRA_FLAGS="$EXTRA_FLAGS -Wunused-but-set-variable" EXTRA_FLAGS="$EXTRA_FLAGS -Wunsigned-char" AS_IF([test x"$gcc_diagnostic_push_pull" = x"yes"], [ AC_DEFINE([HAVE_FORMAT_NONLITERAL], [], [gcc can complain about nonliterals in format]) EXTRA_FLAGS="$EXTRA_FLAGS -Wformat=2 -Wformat-nonliteral" ], [test x"$gcc_format_nonliteral" = x"yes"], [EXTRA_FLAGS="$EXTRA_FLAGS -Wformat=2"]) # Additional warnings it might be nice to enable one day # -Wshadow # -Wunreachable-code for j in $EXTRA_FLAGS do AS_IF([cc_supports_flag $CC_EXTRAS $j], [CC_EXTRAS="$CC_EXTRAS $j"]) done AC_MSG_NOTICE([Using additional gcc flags: ${CC_EXTRAS}]) ]) dnl dnl Hardening flags dnl dnl The prime control of whether to apply (targeted) hardening build flags and dnl which ones is --{enable,disable}-hardening option passed to ./configure: dnl dnl --enable-hardening=try (default): dnl depending on whether any of CFLAGS_HARDENED_EXE, LDFLAGS_HARDENED_EXE, dnl CFLAGS_HARDENED_LIB or LDFLAGS_HARDENED_LIB environment variables dnl (see below) is set and non-null, all these custom flags (even if not dnl set) are used as are, otherwise the best effort is made to offer dnl reasonably strong hardening in several categories (RELRO, PIE, dnl "bind now", stack protector) according to what the selected toolchain dnl can offer dnl dnl --enable-hardening: dnl same effect as --enable-hardening=try when the environment variables dnl in question are suppressed dnl dnl --disable-hardening: dnl do not apply any targeted hardening measures at all dnl dnl The user-injected environment variables that regulate the hardening in dnl default case are as follows: dnl dnl * CFLAGS_HARDENED_EXE, LDFLAGS_HARDENED_EXE dnl compiler and linker flags (respectively) for daemon programs dnl (pacemakerd, pacemaker-attrd, pacemaker-controld, pacemaker-execd, dnl pacemaker-based, pacemaker-fenced, pacemaker-remoted, dnl pacemaker-schedulerd) dnl dnl * CFLAGS_HARDENED_LIB, LDFLAGS_HARDENED_LIB dnl compiler and linker flags (respectively) for libraries linked dnl with the daemon programs dnl dnl Note that these are purposedly targeted variables (addressing particular dnl targets all over the scattered Makefiles) and have no effect outside of dnl the predestined scope (e.g., CLI utilities). For a global reach, dnl use CFLAGS, LDFLAGS, etc. as usual. dnl dnl For guidance on the suitable flags consult, for instance: dnl https://fedoraproject.org/wiki/Changes/Harden_All_Packages#Detailed_Harden_Flags_Description dnl https://owasp.org/index.php/C-Based_Toolchain_Hardening#GCC.2FBinutils dnl AS_IF([test $enable_hardening -eq $OPTIONAL], [ AS_IF([test "$(env | grep -Ec '^(C|LD)FLAGS_HARDENED_(EXE|LIB)=.')" = 0], [enable_hardening=$REQUIRED], [AC_MSG_NOTICE([Hardening: using custom flags from environment])] ) ], [ unset CFLAGS_HARDENED_EXE unset CFLAGS_HARDENED_LIB unset LDFLAGS_HARDENED_EXE unset LDFLAGS_HARDENED_LIB ] ) AS_CASE([$enable_hardening], [$DISABLED], [AC_MSG_NOTICE([Hardening: explicitly disabled])], [$REQUIRED], [ CFLAGS_HARDENED_EXE= CFLAGS_HARDENED_LIB= LDFLAGS_HARDENED_EXE= LDFLAGS_HARDENED_LIB= relro=0 pie=0 bindnow=0 stackprot="none" # daemons incl. libs: partial RELRO flag="-Wl,-z,relro" CC_CHECK_LDFLAGS(["${flag}"], [ LDFLAGS_HARDENED_EXE="${LDFLAGS_HARDENED_EXE} ${flag}" LDFLAGS_HARDENED_LIB="${LDFLAGS_HARDENED_LIB} ${flag}" relro=1 ]) # daemons: PIE for both CFLAGS and LDFLAGS AS_IF([cc_supports_flag -fPIE], [ flag="-pie" CC_CHECK_LDFLAGS(["${flag}"], [ CFLAGS_HARDENED_EXE="${CFLAGS_HARDENED_EXE} -fPIE" LDFLAGS_HARDENED_EXE="${LDFLAGS_HARDENED_EXE} ${flag}" pie=1 ]) ] ) # daemons incl. libs: full RELRO if sensible + as-needed linking # so as to possibly mitigate startup performance # hit caused by excessive linking with unneeded # libraries AS_IF([test "${relro}" = 1 && test "${pie}" = 1], [ flag="-Wl,-z,now" CC_CHECK_LDFLAGS(["${flag}"], [ LDFLAGS_HARDENED_EXE="${LDFLAGS_HARDENED_EXE} ${flag}" LDFLAGS_HARDENED_LIB="${LDFLAGS_HARDENED_LIB} ${flag}" bindnow=1 ]) ] ) AS_IF([test "${bindnow}" = 1], [ flag="-Wl,--as-needed" CC_CHECK_LDFLAGS(["${flag}"], [ LDFLAGS_HARDENED_EXE="${LDFLAGS_HARDENED_EXE} ${flag}" LDFLAGS_HARDENED_LIB="${LDFLAGS_HARDENED_LIB} ${flag}" ]) ]) # universal: prefer strong > all > default stack protector if possible flag= AS_IF([cc_supports_flag -fstack-protector-strong], [ flag="-fstack-protector-strong" stackprot="strong" ], [cc_supports_flag -fstack-protector-all], [ flag="-fstack-protector-all" stackprot="all" ], [cc_supports_flag -fstack-protector], [ flag="-fstack-protector" stackprot="default" ] ) AS_IF([test -n "${flag}"], [CC_EXTRAS="${CC_EXTRAS} ${flag}"]) # universal: enable stack clash protection if possible AS_IF([cc_supports_flag -fstack-clash-protection], [ CC_EXTRAS="${CC_EXTRAS} -fstack-clash-protection" AS_IF([test "${stackprot}" = "none"], [stackprot="clash-only"], [stackprot="${stackprot}+clash"] ) ] ) # Log a summary AS_IF([test "${relro}" = 1 || test "${pie}" = 1 || test x"${stackprot}" != x"none"], [AC_MSG_NOTICE(m4_normalize([Hardening: relro=${relro} pie=${pie} bindnow=${bindnow} stackprot=${stackprot}])) ], [AC_MSG_WARN([Hardening: no suitable features in the toolchain detected])] ) ], ) CFLAGS="$SANITIZERS_CFLAGS $CFLAGS $CC_EXTRAS" LDFLAGS="$SANITIZERS_LDFLAGS $LDFLAGS" CFLAGS_HARDENED_EXE="$SANITIZERS_CFLAGS $CFLAGS_HARDENED_EXE" LDFLAGS_HARDENED_EXE="$SANITIZERS_LDFLAGS $LDFLAGS_HARDENED_EXE" NON_FATAL_CFLAGS="$CFLAGS" AC_SUBST(NON_FATAL_CFLAGS) dnl dnl We reset CFLAGS to include our warnings *after* all function dnl checking goes on, so that our warning flags don't keep the dnl AC_*FUNCS() calls above from working. In particular, -Werror will dnl *always* cause us troubles if we set it before here. dnl dnl AS_IF([test $enable_fatal_warnings -ne $DISABLED], [ AC_MSG_NOTICE([Enabling fatal compiler warnings]) CFLAGS="$CFLAGS $WERROR" ]) AC_SUBST(CFLAGS) dnl This is useful for use in Makefiles that need to remove one specific flag CFLAGS_COPY="$CFLAGS" AC_SUBST(CFLAGS_COPY) AC_SUBST(LIBADD_DL) dnl extra flags for dynamic linking libraries AC_SUBST(LOCALE) dnl Options for cleaning up the compiler output AS_IF([test $enable_quiet -ne $DISABLED], [ AC_MSG_NOTICE([Suppressing make details]) QUIET_LIBTOOL_OPTS="--silent" QUIET_MAKE_OPTS="-s" # POSIX compliant ], [ QUIET_LIBTOOL_OPTS="" QUIET_MAKE_OPTS="" ] ) dnl Put the above variables to use LIBTOOL="${LIBTOOL} --tag=CC \$(QUIET_LIBTOOL_OPTS)" MAKEFLAGS="${MAKEFLAGS} ${QUIET_MAKE_OPTS}" # Make features list available (sorted alphabetically, without leading space) PCMK_FEATURES=`echo "$PCMK_FEATURES" | sed -e 's/^ //' -e 's/ /\n/g' | sort | xargs` AC_DEFINE_UNQUOTED(CRM_FEATURES, "$PCMK_FEATURES", Set of enabled features) AC_SUBST(PCMK_FEATURES) AC_SUBST(CC) AC_SUBST(MAKEFLAGS) AC_SUBST(LIBTOOL) AC_SUBST(QUIET_LIBTOOL_OPTS) dnl Files we output that need to be executable CONFIG_FILES_EXEC([agents/ocf/ClusterMon], [agents/ocf/Dummy], [agents/ocf/HealthCPU], [agents/ocf/HealthIOWait], [agents/ocf/HealthSMART], [agents/ocf/Stateful], [agents/ocf/SysInfo], [agents/ocf/attribute], [agents/ocf/controld], [agents/ocf/ifspeed], [agents/ocf/ping], [agents/ocf/remote], [agents/stonith/fence_legacy], [agents/stonith/fence_watchdog], [cts/cluster_test], [cts/cts], [cts/cts-attrd], [cts/cts-cli], [cts/cts-exec], [cts/cts-fencing], [cts/cts-lab], [cts/cts-regression], [cts/cts-scheduler], + [cts/cts-schemas], [cts/benchmark/clubench], [cts/support/LSBDummy], [cts/support/cts-support], [cts/support/fence_dummy], [cts/support/pacemaker-cts-dummyd], [doc/abi-check], [maint/bumplibs], [tools/cluster-clean], [tools/cluster-helper], [tools/crm_failcount], [tools/crm_master], [tools/crm_report], [tools/crm_standby], [tools/cibsecret], [tools/pcmk_simtimes], [xml/rng-helper]) dnl Other files we output AC_CONFIG_FILES(Makefile \ agents/Makefile \ agents/alerts/Makefile \ agents/ocf/Makefile \ agents/stonith/Makefile \ cts/Makefile \ cts/benchmark/Makefile \ cts/scheduler/Makefile \ cts/scheduler/dot/Makefile \ cts/scheduler/exp/Makefile \ cts/scheduler/scores/Makefile \ cts/scheduler/stderr/Makefile \ cts/scheduler/summary/Makefile \ cts/scheduler/xml/Makefile \ cts/support/Makefile \ cts/support/pacemaker-cts-dummyd@.service \ daemons/Makefile \ daemons/attrd/Makefile \ daemons/based/Makefile \ daemons/controld/Makefile \ daemons/execd/Makefile \ daemons/execd/pacemaker_remote \ daemons/execd/pacemaker_remote.service \ daemons/fenced/Makefile \ daemons/pacemakerd/Makefile \ daemons/pacemakerd/pacemaker.combined.upstart \ daemons/pacemakerd/pacemaker.service \ daemons/pacemakerd/pacemaker.upstart \ daemons/schedulerd/Makefile \ devel/Makefile \ doc/Doxyfile \ doc/Makefile \ doc/sphinx/Makefile \ etc/Makefile \ etc/init.d/pacemaker \ etc/logrotate.d/pacemaker \ etc/sysconfig/pacemaker \ include/Makefile \ include/crm/Makefile \ include/crm/cib/Makefile \ include/crm/common/Makefile \ include/crm/cluster/Makefile \ include/crm/fencing/Makefile \ include/crm/pengine/Makefile \ include/pcmki/Makefile \ lib/Makefile \ lib/cib/Makefile \ lib/cluster/Makefile \ lib/cluster/tests/Makefile \ lib/cluster/tests/cluster/Makefile \ lib/cluster/tests/cpg/Makefile \ lib/common/Makefile \ lib/common/tests/Makefile \ lib/common/tests/acl/Makefile \ lib/common/tests/actions/Makefile \ lib/common/tests/agents/Makefile \ lib/common/tests/cmdline/Makefile \ lib/common/tests/digest/Makefile \ lib/common/tests/flags/Makefile \ lib/common/tests/health/Makefile \ lib/common/tests/io/Makefile \ lib/common/tests/iso8601/Makefile \ lib/common/tests/lists/Makefile \ lib/common/tests/nodes/Makefile \ lib/common/tests/nvpair/Makefile \ lib/common/tests/options/Makefile \ lib/common/tests/output/Makefile \ lib/common/tests/probes/Makefile \ lib/common/tests/procfs/Makefile \ lib/common/tests/resources/Makefile \ lib/common/tests/results/Makefile \ lib/common/tests/rules/Makefile \ lib/common/tests/scheduler/Makefile \ lib/common/tests/schemas/Makefile \ lib/common/tests/scores/Makefile \ lib/common/tests/strings/Makefile \ lib/common/tests/utils/Makefile \ lib/common/tests/xml/Makefile \ lib/common/tests/xpath/Makefile \ lib/fencing/Makefile \ lib/libpacemaker.pc \ lib/lrmd/Makefile \ lib/pacemaker/Makefile \ lib/pacemaker/tests/Makefile \ lib/pacemaker/tests/pcmk_resource/Makefile \ lib/pacemaker/tests/pcmk_ticket/Makefile \ lib/pacemaker.pc \ lib/pacemaker-cib.pc \ lib/pacemaker-cluster.pc \ lib/pacemaker-fencing.pc \ lib/pacemaker-lrmd.pc \ lib/pacemaker-service.pc \ lib/pacemaker-pe_rules.pc \ lib/pacemaker-pe_status.pc \ lib/pengine/Makefile \ lib/pengine/tests/Makefile \ lib/pengine/tests/native/Makefile \ lib/pengine/tests/status/Makefile \ lib/pengine/tests/unpack/Makefile \ lib/pengine/tests/utils/Makefile \ lib/services/Makefile \ maint/Makefile \ po/Makefile.in \ python/Makefile \ python/setup.py \ python/pacemaker/Makefile \ python/pacemaker/_cts/Makefile \ python/pacemaker/_cts/tests/Makefile \ python/pacemaker/buildoptions.py \ python/tests/Makefile \ rpm/Makefile \ tests/Makefile \ tools/Makefile \ tools/crm_mon.service \ tools/crm_mon.upstart \ tools/report.collector \ tools/report.common \ xml/Makefile \ xml/pacemaker-schemas.pc \ ) dnl Now process the entire list of files added by previous dnl calls to AC_CONFIG_FILES() AC_OUTPUT() dnl ***************** dnl Configure summary dnl ***************** AC_MSG_NOTICE([]) AC_MSG_NOTICE([$PACKAGE configuration:]) AC_MSG_NOTICE([ Version = ${VERSION} (Build: $BUILD_VERSION)]) AC_MSG_NOTICE([ Features = ${PCMK_FEATURES}]) AC_MSG_NOTICE([]) AC_MSG_NOTICE([ Prefix = ${prefix}]) AC_MSG_NOTICE([ Executables = ${sbindir}]) AC_MSG_NOTICE([ Man pages = ${mandir}]) AC_MSG_NOTICE([ Libraries = ${libdir}]) AC_MSG_NOTICE([ Header files = ${includedir}]) AC_MSG_NOTICE([ Arch-independent files = ${datadir}]) AC_MSG_NOTICE([ State information = ${localstatedir}]) AC_MSG_NOTICE([ System configuration = ${sysconfdir}]) AC_MSG_NOTICE([ OCF agents = ${OCF_ROOT_DIR}]) AC_MSG_NOTICE([]) AC_MSG_NOTICE([ HA group name = ${CRM_DAEMON_GROUP}]) AC_MSG_NOTICE([ HA user name = ${CRM_DAEMON_USER}]) AC_MSG_NOTICE([]) AC_MSG_NOTICE([ CFLAGS = ${CFLAGS}]) AC_MSG_NOTICE([ CFLAGS_HARDENED_EXE = ${CFLAGS_HARDENED_EXE}]) AC_MSG_NOTICE([ CFLAGS_HARDENED_LIB = ${CFLAGS_HARDENED_LIB}]) AC_MSG_NOTICE([ LDFLAGS_HARDENED_EXE = ${LDFLAGS_HARDENED_EXE}]) AC_MSG_NOTICE([ LDFLAGS_HARDENED_LIB = ${LDFLAGS_HARDENED_LIB}]) AC_MSG_NOTICE([ Libraries = ${LIBS}]) AC_MSG_NOTICE([ Stack Libraries = ${CLUSTERLIBS}]) AC_MSG_NOTICE([ Unix socket auth method = ${us_auth}]) diff --git a/cts/Makefile.am b/cts/Makefile.am index 9a97a5a53d..c2ce308c85 100644 --- a/cts/Makefile.am +++ b/cts/Makefile.am @@ -1,71 +1,78 @@ # # Copyright 2001-2024 the Pacemaker project contributors # # The version control history for this file may have further details. # # This source code is licensed under the GNU General Public License version 2 # or later (GPLv2+) WITHOUT ANY WARRANTY. # include $(top_srcdir)/mk/python.mk MAINTAINERCLEANFILES = Makefile.in # Test commands and globally applicable test files should be in $(testdir), # and command-specific test data should be in a command-specific subdirectory. testdir = $(datadir)/$(PACKAGE)/tests test_SCRIPTS = cts-attrd \ cts-cli \ cts-exec \ cts-fencing \ cts-lab \ cts-regression \ - cts-scheduler + cts-scheduler \ + cts-schemas dist_test_DATA = README.md \ valgrind-pcmk.suppressions clidir = $(testdir)/cli dist_cli_DATA = $(wildcard cli/*.xml cli/*.exp) ctsdir = $(datadir)/$(PACKAGE)/tests/cts cts_SCRIPTS = cts +schemasdir = $(testdir)/schemas +dist_schemas_DATA = $(wildcard schemas/*/*.ref) \ + $(wildcard schemas/*/*.ref.err) \ + $(wildcard schemas/*/*.xml) + noinst_SCRIPTS = cluster_test .PHONY: scheduler-list scheduler-list: @for T in "$(srcdir)"/scheduler/xml/*.xml; do \ echo $$(basename $$T .xml); \ done CLEANFILES = $(builddir)/.regression.failed.diff .PHONY: clean-local clean-local: rm -f scheduler/*/*.pe + rm -f schemas/*/*.up{,.err} SUBDIRS = benchmark \ scheduler \ support .PHONY: cts-support-install cts-support-install: $(MAKE) $(AM_MAKEFLAGS) -C support cts-support $(builddir)/support/cts-support install .PHONY: cts-support-uninstall cts-support-uninstall: $(MAKE) $(AM_MAKEFLAGS) -C support cts-support $(builddir)/support/cts-support uninstall # Everything listed here is a python script, typically generated from a .in file # (though that is not a requirement). We want to run pylint on all of these # things after they've been built. python_files = cts-attrd \ cts-exec \ cts-fencing \ cts-lab \ cts-regression \ cts-scheduler PYCHECKFILES ?= $(python_files) diff --git a/xml/regression.sh b/cts/cts-schemas.in similarity index 81% rename from xml/regression.sh rename to cts/cts-schemas.in index 5add49f822..f355a37a51 100755 --- a/xml/regression.sh +++ b/cts/cts-schemas.in @@ -1,703 +1,759 @@ -#!/bin/sh +#!@BASH_PATH@ # # Copyright 2018-2024 the Pacemaker project contributors # # The version control history for this file may have further details. # # This source code is licensed under the GNU General Public License version 2 # or later (GPLv2+) WITHOUT ANY WARRANTY. +# Note on portable usage of sed: GNU/POSIX/*BSD sed have a limited subset of +# compatible functionality. Do not use the -i option, alternation (\|), +# \0, or character sequences such as \n or \s. + +# Exit immediately if a command fails, with some exceptions (for example, when +# part of an if or while condition). Treat unset variables as errors during +# expansion. See bash(1) man page for details. set -eu -if [ ! -d "test-2" ]; then - echo "$0 must be run from the xml subdirectory of a source tree" - exit 1 +# If readlink supports -e, use it +readlink -e / >/dev/null 2>/dev/null +if [ $? -eq 0 ]; then + test_home=$(dirname "$(readlink -e "$0")") +else + test_home=$(dirname "$0") +fi + +suites_dir="$test_home/schemas" +src_dir=$(dirname "$test_home") + +if [ -d "$src_dir/xml" ]; then + export PCMK_schema_directory="$src_dir/xml" + echo "Using local schemas from: $PCMK_schema_directory" +else + export PCMK_schema_directory=@CRM_SCHEMA_DIRECTORY@ fi DIFF="diff -u" DIFF_PAGER="less -LRX" RNG_VALIDATOR="xmllint --noout --relaxng" XSLT_PROCESSOR="xsltproc --nonet" -# Default tests +# Available test suites tests="test2to3 test2to3enter test2to3leave test2to3roundtrip cts_scheduler" # # commons # emit_result() { _er_howmany=${1:?} # how many errors (0/anything else incl. strings) _er_subject=${2:?} _er_prefix=${3-} if [ -n "$_er_prefix" ]; then _er_prefix="${_er_prefix}: " fi if [ "$_er_howmany" = "0" ]; then printf "%s%s finished OK\n" "${_er_prefix}" "${_er_subject}" else printf "%s%s encountered ${_er_howmany} errors\n" \ "${_er_prefix}" "${_er_subject}" fi } emit_error() { _ee_msg=${1:?} printf "%s\n" "${_ee_msg}" >&2 } # returns 1 + floor of base 2 logaritm for _lo0r_i in 1...255, # or 0 for _lo0r_i = 0 log2_or_0_return() { _lo0r_i=${1:?} return $(((!(_lo0r_i >> 1) && _lo0r_i) * 1 \ + (!(_lo0r_i >> 2) && _lo0r_i & (1 << 1)) * 2 \ + (!(_lo0r_i >> 3) && _lo0r_i & (1 << 2)) * 3 \ + (!(_lo0r_i >> 4) && _lo0r_i & (1 << 3)) * 4 \ + (!(_lo0r_i >> 5) && _lo0r_i & (1 << 4)) * 5 \ + (!(_lo0r_i >> 6) && _lo0r_i & (1 << 5)) * 6 \ + (!(_lo0r_i >> 7) && _lo0r_i & (1 << 6)) * 7 \ + !!(_lo0r_i >> 7) * 7 )) } # rough addition of two base 2 logarithms log2_or_0_add() { _lo0a_op1=${1:?} _lo0a_op2=${2:?} if [ "$_lo0a_op1" -gt "$_lo0a_op2" ]; then return ${_lo0a_op1} elif [ "$_lo0a_op2" -gt "$_lo0a_op1" ]; then return ${_lo0a_op2} elif [ "$_lo0a_op1" -gt 0 ]; then return $((_lo0a_op1 + 1)) else return ${_lo0a_op1} fi } # # test phases # # -r ... whether to remove referential files as well # stdin: input file per line test_cleaner() { _tc_cleanref=0 while [ $# -gt 0 ]; do case "$1" in -r) _tc_cleanref=1;; esac shift done while read _tc_origin; do _tc_origin=${_tc_origin%.*} rm -f "${_tc_origin}.up" "${_tc_origin}.up.err" rm -f "$(dirname "${_tc_origin}")/.$(basename "${_tc_origin}").up" if [ "$_tc_cleanref" -eq 1 ]; then rm -f "${_tc_origin}.ref" "${_tc_origin}.ref.err" fi done } test_explanation() { _tsc_template= while [ $# -gt 0 ]; do case "$1" in - -o=*) _tsc_template="upgrade-${1#-o=}.xsl";; + -o=*) _tsc_template="$PCMK_schema_directory/upgrade-${1#-o=}.xsl";; esac shift done - ${XSLT_PROCESSOR} upgrade-detail.xsl "${_tsc_template}" + $XSLT_PROCESSOR "$PCMK_schema_directory/upgrade-detail.xsl" "$_tsc_template" } cleanup_module_error() { # Work around a libxml2 bug. At least as of libxslt-1.1.41 and # libxml2-2.10.4, if the stylesheet contains a user-defined top-level # element (that is, one with a namespace other than the XSL namespace), # libxslt tries to load the namespace URI as an XML module. If this fails, # libxml2 logs a "module error: failed to open ..." message. # # This appears to be fixed in libxml2 v2.13 with commit ecb4c9fb. sed "/module error/d" "$1" > "$1.new" mv -- "$1.new" "$1" } # stdout: filename of the transformed file test_runner_upgrade() { _tru_template=${1:?} _tru_source=${2:?} # filename _tru_mode=${3:?} # extra modes wrt. "referential" outcome, see below _tru_ref="${_tru_source%.*}.ref" if [ "$((_tru_mode & (1 << 0)))" -ne 0 ] || [ -f "${_tru_ref}.err" ]; then _tru_ref_err="${_tru_ref}.err" else _tru_ref_err=/dev/null fi _tru_proc_rc=0 _tru_diff_rc=0 _tru_target="${_tru_source%.*}.up" _tru_target_err="${_tru_target}.err" if [ "$((_tru_mode & (1 << 2)))" -eq 0 ]; then ${XSLT_PROCESSOR} "${_tru_template}" "${_tru_source}" \ > "${_tru_target}" 2> "${_tru_target_err}" \ || _tru_proc_rc=$? cleanup_module_error "$_tru_target_err" if [ "$_tru_proc_rc" -ne 0 ]; then echo "$_tru_target_err" return "$_tru_proc_rc" fi else # when -B (deblanked outcomes handling) requested, we: # - drop blanks from the source XML # (effectively emulating pacemaker handling) # - re-drop blanks from the XSLT outcome, # which is compared with referential outcome # processed with even greedier custom deblanking # (extraneous inter-element whitespace like blank # lines will not get removed otherwise, see lower) xmllint --noblanks "${_tru_source}" \ | ${XSLT_PROCESSOR} "${_tru_template}" - \ > "${_tru_target}" 2> "${_tru_target_err}" \ || _tru_proc_rc=$? cleanup_module_error "$_tru_target_err" if [ "$_tru_proc_rc" -ne 0 ]; then echo "$_tru_target_err" return "$_tru_proc_rc" fi # reusing variable no longer needed _tru_template="$(dirname "${_tru_target}")" _tru_template="${_tru_template}/.$(basename "${_tru_target}")" mv "${_tru_target}" "${_tru_template}" ${XSLT_PROCESSOR} - "${_tru_template}" > "${_tru_target}" < EOF fi # only respond with the flags except for "-B", i.e., when both: # - _tru_mode non-zero # - "-B" in _tru_mode is zero (hence non-zero when flipped with XOR) if [ "$((_tru_mode * ((_tru_mode ^ (1 << 2)) & (1 << 2))))" -ne 0 ]; then if [ "$((_tru_mode & (1 << 0)))" -ne 0 ]; then cp -a "${_tru_target}" "${_tru_ref}" cp -a "${_tru_target_err}" "${_tru_ref_err}" fi if [ "$((_tru_mode & (1 << 1)))" -ne 0 ]; then { ${DIFF} "${_tru_source}" "${_tru_ref}" \ && printf '\n(files match)\n'; } | ${DIFF_PAGER} >&2 if [ $? -ne 0 ]; then printf "\npager failure\n" >&2 return 1 fi printf '\nIs comparison OK? ' >&2 if read _tru_answer &2; return 1;; esac else return 1 fi fi elif [ -f "$_tru_ref" ] && [ -e "$_tru_ref_err" ]; then if [ "$((_tru_mode & (1 << 2)))" -eq 0 ]; then _output=$(cat "$_tru_ref") else _output=$($XSLT_PROCESSOR - "$_tru_ref" < EOF ) fi echo "$_output" | $DIFF - "$_tru_target" >&2 || _tru_diff_rc=$? if [ "$_tru_diff_rc" -eq 0 ]; then $DIFF "$_tru_ref_err" "$_tru_target_err" >&2 || _tru_diff_rc=$? fi if [ "$_tru_diff_rc" -ne 0 ]; then emit_error "Outputs differ from referential ones" echo "/dev/null" return 1 fi else emit_error "Referential file(s) missing: ${_tru_ref}" echo "/dev/null" return 1 fi echo "${_tru_target}" } test_runner_validate() { _trv_schema=${1:?} _trv_target=${2:?} # filename if ! ${RNG_VALIDATOR} "${_trv_schema}" "${_trv_target}" \ 2>/dev/null; then ${RNG_VALIDATOR} "${_trv_schema}" "${_trv_target}" fi } # -a= ... action modifier completing template name (e.g. 2.10-(enter|leave)) # -o= ... which conventional version to deem as the transform origin # -t= ... which conventional version to deem as the transform target # -B # -D # -G ... see usage # stdin: input file per line test_runner() { _tr_mode=0 _tr_ret=0 _tr_action= _tr_schema_o= _tr_schema_t= _tr_target= _tr_template= while [ $# -gt 0 ]; do case "$1" in -a=*) _tr_action="${1#-a=}";; -o=*) _tr_template="${1#-o=}" - _tr_schema_o="pacemaker-${1#-o=}.rng";; - -t=*) _tr_schema_t="pacemaker-${1#-t=}.rng";; + _tr_schema_o="$PCMK_schema_directory/pacemaker-${1#-o=}.rng";; + -t=*) _tr_schema_t="$PCMK_schema_directory/pacemaker-${1#-t=}.rng";; -G) _tr_mode=$((_tr_mode | (1 << 0)));; -D) _tr_mode=$((_tr_mode | (1 << 1)));; -B) _tr_mode=$((_tr_mode | (1 << 2)));; esac shift done - _tr_template="upgrade-${_tr_action:-${_tr_template:?}}.xsl" + _tr_template="$PCMK_schema_directory/upgrade-${_tr_action:-${_tr_template:?}}.xsl" if [ ! -f "${_tr_schema_o:?}" ] || [ ! -f "${_tr_schema_t:?}" ]; then emit_error "Origin and/or target schema missing, rerun make" return 1 fi while read _tr_origin; do printf '%-60s' "${_tr_origin}... " # pre-validate if ! test_runner_validate "${_tr_schema_o}" "${_tr_origin}"; then _tr_ret=$((_tr_ret + 1)); echo "E:pre-validate"; continue fi # upgrade if ! _tr_target=$(test_runner_upgrade "${_tr_template}" \ "${_tr_origin}" "${_tr_mode}"); then _tr_ret=$((_tr_ret + 1)); if [ -z "$_tr_target" ]; then break fi echo "E:upgrade" if [ -s "$_tr_target" ]; then echo --- cat "$_tr_target" || : echo --- fi continue fi # post-validate if ! test_runner_validate "${_tr_schema_t}" "${_tr_target}"; then _tr_ret=$((_tr_ret + 1)); echo "E:post-validate"; continue fi echo "OK" done log2_or_0_return ${_tr_ret} } # # particular test variations # -C # -X # stdin: granular test specification(s) if any # test2to3() { _t23_pattern= while read _t23_spec; do _t23_spec=${_t23_spec%.xml} _t23_spec=${_t23_spec%\*} _t23_pattern="${_t23_pattern} -name ${_t23_spec}*.xml -o" done if [ -n "$_t23_pattern" ]; then _t23_pattern="( ${_t23_pattern%-o} )" fi - find test-2 -name test-2 -o -type d -prune \ + find "$suites_dir/test-2" -name test-2 -o -type d -prune \ -o -name '*.xml' ${_t23_pattern} -print \ | env LC_ALL=C sort \ | { case " $* " in *\ -C\ *) test_cleaner;; *\ -X\ *) test_explanation -o=2.10;; *) test_runner -o=2.10 -t=3.0 "$@" || return $?;; esac; } } test2to3enter() { _t23e_pattern= while read _t23e_spec; do _t23e_spec=${_t23e_spec%.xml} _t23e_spec=${_t23e_spec%\*} _t23e_pattern="${_t23e_pattern} -name ${_t23e_spec}*.xml -o" done if [ -n "$_t23e_pattern" ]; then _t23e_pattern="( ${_t23e_pattern%-o} )" fi - find test-2-enter -name test-2-enter -o -type d -prune \ + find "$suites_dir/test-2-enter" -name test-2-enter -o -type d -prune \ -o -name '*.xml' ${_t23e_pattern} -print \ | env LC_ALL=C sort \ | { case " $* " in *\ -C\ *) test_cleaner;; *\ -X\ *) emit_result "not implemented" "option -X";; *) test_runner -a=2.10-enter -o=2.10 -t=2.10 "$@" || return $?;; esac; } } test2to3leave() { _t23l_pattern= while read _t23l_spec; do _t23l_spec=${_t23l_spec%.xml} _t23l_spec=${_t23l_spec%\*} _t23l_pattern="${_t23l_pattern} -name ${_t23l_spec}*.xml -o" done if [ -n "$_t23l_pattern" ]; then _t23l_pattern="( ${_t23l_pattern%-o} )" fi - find test-2-leave -name test-2-leave -o -type d -prune \ + find "$suites_dir/test-2-leave" -name test-2-leave -o -type d -prune \ -o -name '*.xml' ${_t23l_pattern} -print \ | env LC_ALL=C sort \ | { case " $* " in *\ -C\ *) test_cleaner;; *\ -X\ *) emit_result "not implemented" "option -X";; *) test_runner -a=2.10-leave -o=3.0 -t=3.0 "$@" || return $?;; esac; } } test2to3roundtrip() { _t23rt_pattern= while read _t23tr_spec; do _t23rt_spec=${_t23rt_spec%.xml} _t23rt_spec=${_t23rt_spec%\*} _t23rt_pattern="${_t23rt_pattern} -name ${_t23rt_spec}*.xml -o" done if [ -n "$_t23rt_pattern" ]; then _t23rt_pattern="( ${_t23rt_pattern%-o} )" fi - find test-2-roundtrip -name test-2-roundtrip -o -type d -prune \ + find "$suites_dir/test-2-roundtrip" \ + -name test-2-roundtrip -o -type d -prune \ -o -name '*.xml' ${_t23rt_pattern} -print \ | env LC_ALL=C sort \ | { case " $* " in *\ -C\ *) test_cleaner;; *\ -X\ *) emit_result "not implemented" "option -X";; *) test_runner -a=2.10-roundtrip -o=2.10 -t=3.0 "$@" \ || return $?;; esac; } } # -B # -D # -G ... see usage cts_scheduler() { + # @TODO This test suite yields a great many errors with -G. With some effort + # we could fix it, but it may be better to drop it. + # + # The cts_scheduler suite doesn't run by default. Rather, the user can + # explicitly request to generate reference outputs from cts/scheduler/xml, + # and then test against those reference. Nothing actually requires that we + # do this. We can create regression tests specifically for these schema + # upgrades: in fact, that's what the other test suites are. + _tcp_mode=0 _tcp_ret=0 _tcp_validatewith= _tcp_schema_o= _tcp_schema_t= _tcp_template= - find ../cts/scheduler/xml -name '*.xml' | env LC_ALL=C sort \ + find "$test_home/scheduler/xml" -name '*.xml' | env LC_ALL=C sort \ | { case " $* " in *\ -C\ *) test_cleaner -r;; *\ -X\ *) emit_result "not implemented" "option -X";; *) while [ $# -gt 0 ]; do case "$1" in -G) _tcp_mode=$((_tcp_mode | (1 << 0)));; -D) _tcp_mode=$((_tcp_mode | (1 << 1)));; -B) _tcp_mode=$((_tcp_mode | (1 << 2)));; esac shift done while read _tcp_origin; do _tcp_validatewith=$(${XSLT_PROCESSOR} - "${_tcp_origin}" < EOF ) _tcp_schema_t=${_tcp_validatewith} case "${_tcp_validatewith}" in 1) _tcp_schema_o=1.3;; 2) _tcp_schema_o=2.10;; # only for gradual refinement as upgrade-2.10.xsl under # active development, move to 3.x when schema v4 emerges 3) _tcp_schema_o=2.10 _tcp_schema_t=2;; *) emit_error \ "need to skip ${_tcp_origin} (schema: ${_tcp_validatewith})" continue;; esac - _tcp_template="upgrade-${_tcp_schema_o}.xsl" - _tcp_schema_t="pacemaker-$((_tcp_schema_t + 1)).0.rng" + _tcp_template="$PCMK_schema_directory/upgrade-${_tcp_schema_o}.xsl" + _tcp_schema_t="$PCMK_schema_directory/pacemaker-$((_tcp_schema_t + 1)).0.rng" if [ "${_tcp_schema_o%%.*}" = "${_tcp_validatewith}" ]; then - _tcp_schema_o="pacemaker-${_tcp_schema_o}.rng" + _tcp_schema_o="$PCMK_schema_directory/pacemaker-${_tcp_schema_o}.rng" else _tcp_schema_o="${_tcp_schema_t}" fi # pre-validate if [ "$_tcp_schema_o" != "$_tcp_schema_t" ] \ && ! test_runner_validate "$_tcp_schema_o" "$_tcp_origin"; then _tcp_ret=$((_tcp_ret + 1)) echo "E:pre-validate" continue fi # upgrade if [ "$((_tcp_mode & (1 << 0)))" -eq 0 ]; then ln -fs "$(pwd)/$_tcp_origin" "${_tcp_origin%.*}.ref" fi if ! _tcp_target=$(test_runner_upgrade "${_tcp_template}" \ "${_tcp_origin}" "${_tcp_mode}"); then _tcp_ret=$((_tcp_ret + 1)); if [ -z "$_tcp_target" ]; then break fi echo "E:upgrade" if [ -s "$_tcp_target" ]; then echo --- cat "$_tcp_target" || : echo --- fi continue fi if [ "$((_tcp_mode & (1 << 0)))" -eq 0 ]; then rm -f "${_tcp_origin%.*}.ref" fi # post-validate if ! test_runner_validate "${_tcp_schema_t}" "${_tcp_target}"; then _tcp_ret=$((_tcp_ret + 1)); echo "E:post-validate"; continue fi if [ "$((_tcp_mode & (1 << 0)))" -ne 0 ]; then mv "$_tcp_target" "$_tcp_origin" fi done; log2_or_0_return ${_tcp_ret};; esac; } } # # "framework" # # option-likes ... options to be passed down # argument-likes ... drives a test selection test_suite() { _ts_pass= _ts_select= _ts_select_full= _ts_test_specs= _ts_global_ret=0 _ts_ret=0 while [ $# -gt 0 ]; do case "$1" in -) printf '%s\n' 'waiting for tests specified at stdin...'; while read _ts_spec; do _ts_select="${_ts_spec}@$1" done;; -*) _ts_pass="${_ts_pass} $1";; *) _ts_select_full="${_ts_select_full}@$1" _ts_select="${_ts_select}@${1%%/*}";; esac shift done + + # _ts_select contains a '@'-delimited list of test suite names from CLI _ts_select="${_ts_select}@" + + # _ts_select_full contains a '@'-delimited list of test names _ts_select_full="${_ts_select_full}@" for _ts_test in ${tests}; do _ts_test_specs= while true; do case "${_ts_select}" in - *@${_ts_test}@*) - _ts_test_specs="${_ts_select%%@${_ts_test}@*}"\ + *@${_ts_test}@*) + # A known test suite _ts_test was found in the list of + # requested test suites _ts_select. Strip it out of + # _ts_select. + # + # The purpose of this seems to be to prevent the later + # _ts_select_full loop from selecting specific tests from + # this suite, if the user also requested the entire suite. + + _ts_test_specs="${_ts_select%%@${_ts_test}@*}"\ "@${_ts_select#*@${_ts_test}@}" - if [ "$_ts_test_specs" = "@" ]; then - _ts_select= # nothing left - else - _ts_select="${_ts_test_specs}" - fi - continue - ;; - @) case "${_ts_test}" in test*) break;; esac # filter - ;; + + if [ "$_ts_test_specs" = "@" ]; then + _ts_select= # nothing left + else + _ts_select="$_ts_test_specs" + fi + continue + ;; + @) + case "${_ts_test}" in test*) break;; esac # filter + ;; esac + if [ -n "$_ts_test_specs" ]; then break fi continue 2 # move on to matching with next local test done _ts_test_specs= while true; do case "${_ts_select_full}" in - *@${_ts_test}/*) - _ts_test_full="${_ts_test}/${_ts_select_full#*@${_ts_test}/}" - _ts_test_full="${_ts_test_full%%@*}" - _ts_select_full="${_ts_select_full%%@${_ts_test_full}@*}"\ + *@${_ts_test}/*) + # A test was requested from a known test suite. This does + # not mean the requested test actually exists, but rather + # that it was requested as the form "/...". + + # Strip extraneous data from test path + _ts_test_full="${_ts_test}/${_ts_select_full#*@${_ts_test}/}" + _ts_test_full="${_ts_test_full%%@*}" + + # Strip the requested test out of _ts_select_full + _ts_select_full="${_ts_select_full%%@${_ts_test_full}@*}"\ "@${_ts_select_full#*@${_ts_test_full}@}" - _ts_test_specs="${_ts_test_specs} ${_ts_test_full#*/}" - ;; - *) - break - ;; + + # Strip the test suite name and slash from the test spec + _ts_test_specs="${_ts_test_specs} ${_ts_test_full#*/}" + ;; + *) + break + ;; esac done + # Feed the test specs (if any) as stdin to the respective test suite + # function _ts_test() for _ts_test_spec in ${_ts_test_specs}; do printf '%s\n' "${_ts_test_spec}" done | "${_ts_test}" ${_ts_pass} || _ts_ret=$? if [ "$_ts_ret" = 0 ]; then emit_result "$_ts_ret" "$_ts_test" else emit_result "at least 2^$((_ts_ret - 1))" "$_ts_test" fi log2_or_0_add ${_ts_global_ret} ${_ts_ret} _ts_global_ret=$? done if [ -n "${_ts_select#@}" ]; then emit_error "Non-existing test(s):$(echo "${_ts_select}" \ | tr '@' ' ')" log2_or_0_add ${_ts_global_ret} 1 || _ts_global_ret=$? fi return ${_ts_global_ret} } # NOTE: big letters are dedicated for per-test-set behaviour, # small ones for generic/global behaviour usage() { printf \ '%s\n%s\n %s\n %s\n %s\n %s\n %s\n %s\n %s\n %s\n' \ "usage: $0 [-{B,C,D,G,X}]* \\" \ " [-|{${tests## }}*]" \ "- when no suites (arguments) provided, \"test*\" ones get used" \ "- with '-' suite specification the actual ones grabbed on stdin" \ "- use '-B' to run validate-only check suppressing blanks first" \ "- use '-C' to only cleanup ephemeral byproducts" \ "- use '-D' to review originals vs. \"referential\" outcomes" \ "- use '-G' to generate \"referential\" outcomes" \ "- use '-X' to show explanatory details about the upgrade" \ "- test specification can be granular, e.g. 'test2to3/022'" } main() { _main_pass= _main_bailout=0 _main_ret=0 while [ $# -gt 0 ]; do case "$1" in -h) usage; exit;; -C|-G|-X) _main_bailout=1;; esac _main_pass="${_main_pass} $1" shift done test_suite ${_main_pass} || _main_ret=$? if [ "$_main_bailout" -eq 0 ]; then test_suite -C $_main_pass >/dev/null || true fi if [ "$_main_ret" = 0 ]; then emit_result "$_main_ret" "Overall suite" else emit_result "at least 2^$((_main_ret - 1))" "Overall suite" fi return ${_main_ret} } main "$@" diff --git a/xml/test-2-enter/010-clu-props.ref b/cts/schemas/test-2-enter/010-clu-props.ref similarity index 100% rename from xml/test-2-enter/010-clu-props.ref rename to cts/schemas/test-2-enter/010-clu-props.ref diff --git a/xml/test-2-enter/010-clu-props.ref.err b/cts/schemas/test-2-enter/010-clu-props.ref.err similarity index 100% rename from xml/test-2-enter/010-clu-props.ref.err rename to cts/schemas/test-2-enter/010-clu-props.ref.err diff --git a/xml/test-2-enter/010-clu-props.xml b/cts/schemas/test-2-enter/010-clu-props.xml similarity index 100% rename from xml/test-2-enter/010-clu-props.xml rename to cts/schemas/test-2-enter/010-clu-props.xml diff --git a/xml/test-2-enter/020-instance_atributes-rsc.ref b/cts/schemas/test-2-enter/020-instance_atributes-rsc.ref similarity index 100% rename from xml/test-2-enter/020-instance_atributes-rsc.ref rename to cts/schemas/test-2-enter/020-instance_atributes-rsc.ref diff --git a/xml/test-2-enter/020-instance_atributes-rsc.ref.err b/cts/schemas/test-2-enter/020-instance_atributes-rsc.ref.err similarity index 100% rename from xml/test-2-enter/020-instance_atributes-rsc.ref.err rename to cts/schemas/test-2-enter/020-instance_atributes-rsc.ref.err diff --git a/xml/test-2-enter/020-instance_atributes-rsc.xml b/cts/schemas/test-2-enter/020-instance_atributes-rsc.xml similarity index 100% rename from xml/test-2-enter/020-instance_atributes-rsc.xml rename to cts/schemas/test-2-enter/020-instance_atributes-rsc.xml diff --git a/xml/test-2-enter/021-instance_atributes-rsc-nonbijective.ref b/cts/schemas/test-2-enter/021-instance_atributes-rsc-nonbijective.ref similarity index 100% rename from xml/test-2-enter/021-instance_atributes-rsc-nonbijective.ref rename to cts/schemas/test-2-enter/021-instance_atributes-rsc-nonbijective.ref diff --git a/xml/test-2-enter/021-instance_atributes-rsc-nonbijective.ref.err b/cts/schemas/test-2-enter/021-instance_atributes-rsc-nonbijective.ref.err similarity index 100% rename from xml/test-2-enter/021-instance_atributes-rsc-nonbijective.ref.err rename to cts/schemas/test-2-enter/021-instance_atributes-rsc-nonbijective.ref.err diff --git a/xml/test-2-enter/021-instance_atributes-rsc-nonbijective.xml b/cts/schemas/test-2-enter/021-instance_atributes-rsc-nonbijective.xml similarity index 100% rename from xml/test-2-enter/021-instance_atributes-rsc-nonbijective.xml rename to cts/schemas/test-2-enter/021-instance_atributes-rsc-nonbijective.xml diff --git a/xml/test-2-leave/010-clu-props-can.ref b/cts/schemas/test-2-leave/010-clu-props-can.ref similarity index 100% rename from xml/test-2-leave/010-clu-props-can.ref rename to cts/schemas/test-2-leave/010-clu-props-can.ref diff --git a/xml/test-2-leave/010-clu-props-can.ref.err b/cts/schemas/test-2-leave/010-clu-props-can.ref.err similarity index 100% rename from xml/test-2-leave/010-clu-props-can.ref.err rename to cts/schemas/test-2-leave/010-clu-props-can.ref.err diff --git a/xml/test-2-leave/010-clu-props-can.xml b/cts/schemas/test-2-leave/010-clu-props-can.xml similarity index 100% rename from xml/test-2-leave/010-clu-props-can.xml rename to cts/schemas/test-2-leave/010-clu-props-can.xml diff --git a/xml/test-2-leave/011-clu-props-cannot.ref b/cts/schemas/test-2-leave/011-clu-props-cannot.ref similarity index 100% rename from xml/test-2-leave/011-clu-props-cannot.ref rename to cts/schemas/test-2-leave/011-clu-props-cannot.ref diff --git a/xml/test-2-leave/011-clu-props-cannot.ref.err b/cts/schemas/test-2-leave/011-clu-props-cannot.ref.err similarity index 100% rename from xml/test-2-leave/011-clu-props-cannot.ref.err rename to cts/schemas/test-2-leave/011-clu-props-cannot.ref.err diff --git a/xml/test-2-leave/011-clu-props-cannot.xml b/cts/schemas/test-2-leave/011-clu-props-cannot.xml similarity index 100% rename from xml/test-2-leave/011-clu-props-cannot.xml rename to cts/schemas/test-2-leave/011-clu-props-cannot.xml diff --git a/xml/test-2-leave/021-instance_atributes-rsc-nonbijective.ref b/cts/schemas/test-2-leave/021-instance_atributes-rsc-nonbijective.ref similarity index 100% rename from xml/test-2-leave/021-instance_atributes-rsc-nonbijective.ref rename to cts/schemas/test-2-leave/021-instance_atributes-rsc-nonbijective.ref diff --git a/xml/test-2-leave/021-instance_atributes-rsc-nonbijective.ref.err b/cts/schemas/test-2-leave/021-instance_atributes-rsc-nonbijective.ref.err similarity index 100% rename from xml/test-2-leave/021-instance_atributes-rsc-nonbijective.ref.err rename to cts/schemas/test-2-leave/021-instance_atributes-rsc-nonbijective.ref.err diff --git a/xml/test-2-leave/021-instance_atributes-rsc-nonbijective.xml b/cts/schemas/test-2-leave/021-instance_atributes-rsc-nonbijective.xml similarity index 100% rename from xml/test-2-leave/021-instance_atributes-rsc-nonbijective.xml rename to cts/schemas/test-2-leave/021-instance_atributes-rsc-nonbijective.xml diff --git a/xml/test-2-roundtrip/021-instance_atributes-rsc-nonbijective.ref b/cts/schemas/test-2-roundtrip/021-instance_atributes-rsc-nonbijective.ref similarity index 100% rename from xml/test-2-roundtrip/021-instance_atributes-rsc-nonbijective.ref rename to cts/schemas/test-2-roundtrip/021-instance_atributes-rsc-nonbijective.ref diff --git a/xml/test-2-roundtrip/021-instance_atributes-rsc-nonbijective.ref.err b/cts/schemas/test-2-roundtrip/021-instance_atributes-rsc-nonbijective.ref.err similarity index 100% rename from xml/test-2-roundtrip/021-instance_atributes-rsc-nonbijective.ref.err rename to cts/schemas/test-2-roundtrip/021-instance_atributes-rsc-nonbijective.ref.err diff --git a/xml/test-2-roundtrip/021-instance_atributes-rsc-nonbijective.xml b/cts/schemas/test-2-roundtrip/021-instance_atributes-rsc-nonbijective.xml similarity index 100% rename from xml/test-2-roundtrip/021-instance_atributes-rsc-nonbijective.xml rename to cts/schemas/test-2-roundtrip/021-instance_atributes-rsc-nonbijective.xml diff --git a/xml/test-2/010-rsc_colocation-dropped-for-noop-sa.ref b/cts/schemas/test-2/010-rsc_colocation-dropped-for-noop-sa.ref similarity index 100% rename from xml/test-2/010-rsc_colocation-dropped-for-noop-sa.ref rename to cts/schemas/test-2/010-rsc_colocation-dropped-for-noop-sa.ref diff --git a/xml/test-2/010-rsc_colocation-dropped-for-noop-sa.ref.err b/cts/schemas/test-2/010-rsc_colocation-dropped-for-noop-sa.ref.err similarity index 100% rename from xml/test-2/010-rsc_colocation-dropped-for-noop-sa.ref.err rename to cts/schemas/test-2/010-rsc_colocation-dropped-for-noop-sa.ref.err diff --git a/xml/test-2/010-rsc_colocation-dropped-for-noop-sa.xml b/cts/schemas/test-2/010-rsc_colocation-dropped-for-noop-sa.xml similarity index 100% rename from xml/test-2/010-rsc_colocation-dropped-for-noop-sa.xml rename to cts/schemas/test-2/010-rsc_colocation-dropped-for-noop-sa.xml diff --git a/xml/test-2/020-rsc-requires-inline.ref b/cts/schemas/test-2/020-rsc-requires-inline.ref similarity index 100% rename from xml/test-2/020-rsc-requires-inline.ref rename to cts/schemas/test-2/020-rsc-requires-inline.ref diff --git a/xml/test-2/020-rsc-requires-inline.ref.err b/cts/schemas/test-2/020-rsc-requires-inline.ref.err similarity index 100% rename from xml/test-2/020-rsc-requires-inline.ref.err rename to cts/schemas/test-2/020-rsc-requires-inline.ref.err diff --git a/xml/test-2/020-rsc-requires-inline.xml b/cts/schemas/test-2/020-rsc-requires-inline.xml similarity index 100% rename from xml/test-2/020-rsc-requires-inline.xml rename to cts/schemas/test-2/020-rsc-requires-inline.xml diff --git a/xml/test-2/021-rsc-requires-nvpair.ref b/cts/schemas/test-2/021-rsc-requires-nvpair.ref similarity index 100% rename from xml/test-2/021-rsc-requires-nvpair.ref rename to cts/schemas/test-2/021-rsc-requires-nvpair.ref diff --git a/xml/test-2/021-rsc-requires-nvpair.ref.err b/cts/schemas/test-2/021-rsc-requires-nvpair.ref.err similarity index 100% rename from xml/test-2/021-rsc-requires-nvpair.ref.err rename to cts/schemas/test-2/021-rsc-requires-nvpair.ref.err diff --git a/xml/test-2/021-rsc-requires-nvpair.xml b/cts/schemas/test-2/021-rsc-requires-nvpair.xml similarity index 100% rename from xml/test-2/021-rsc-requires-nvpair.xml rename to cts/schemas/test-2/021-rsc-requires-nvpair.xml diff --git a/xml/test-2/022-rsc-requires-counterexamples.ref b/cts/schemas/test-2/022-rsc-requires-counterexamples.ref similarity index 100% rename from xml/test-2/022-rsc-requires-counterexamples.ref rename to cts/schemas/test-2/022-rsc-requires-counterexamples.ref diff --git a/xml/test-2/022-rsc-requires-counterexamples.ref.err b/cts/schemas/test-2/022-rsc-requires-counterexamples.ref.err similarity index 100% rename from xml/test-2/022-rsc-requires-counterexamples.ref.err rename to cts/schemas/test-2/022-rsc-requires-counterexamples.ref.err diff --git a/xml/test-2/022-rsc-requires-counterexamples.xml b/cts/schemas/test-2/022-rsc-requires-counterexamples.xml similarity index 100% rename from xml/test-2/022-rsc-requires-counterexamples.xml rename to cts/schemas/test-2/022-rsc-requires-counterexamples.xml diff --git a/xml/test-2/023-rsc-requires-no-override.ref b/cts/schemas/test-2/023-rsc-requires-no-override.ref similarity index 100% rename from xml/test-2/023-rsc-requires-no-override.ref rename to cts/schemas/test-2/023-rsc-requires-no-override.ref diff --git a/xml/test-2/023-rsc-requires-no-override.ref.err b/cts/schemas/test-2/023-rsc-requires-no-override.ref.err similarity index 100% rename from xml/test-2/023-rsc-requires-no-override.ref.err rename to cts/schemas/test-2/023-rsc-requires-no-override.ref.err diff --git a/xml/test-2/023-rsc-requires-no-override.xml b/cts/schemas/test-2/023-rsc-requires-no-override.xml similarity index 100% rename from xml/test-2/023-rsc-requires-no-override.xml rename to cts/schemas/test-2/023-rsc-requires-no-override.xml diff --git a/xml/test-2/024-rsc-requires-no-selfclash.ref b/cts/schemas/test-2/024-rsc-requires-no-selfclash.ref similarity index 100% rename from xml/test-2/024-rsc-requires-no-selfclash.ref rename to cts/schemas/test-2/024-rsc-requires-no-selfclash.ref diff --git a/xml/test-2/024-rsc-requires-no-selfclash.ref.err b/cts/schemas/test-2/024-rsc-requires-no-selfclash.ref.err similarity index 100% rename from xml/test-2/024-rsc-requires-no-selfclash.ref.err rename to cts/schemas/test-2/024-rsc-requires-no-selfclash.ref.err diff --git a/xml/test-2/024-rsc-requires-no-selfclash.xml b/cts/schemas/test-2/024-rsc-requires-no-selfclash.xml similarity index 100% rename from xml/test-2/024-rsc-requires-no-selfclash.xml rename to cts/schemas/test-2/024-rsc-requires-no-selfclash.xml diff --git a/xml/test-2/030-clu-props-plain-rename.ref b/cts/schemas/test-2/030-clu-props-plain-rename.ref similarity index 100% rename from xml/test-2/030-clu-props-plain-rename.ref rename to cts/schemas/test-2/030-clu-props-plain-rename.ref diff --git a/xml/test-2/030-clu-props-plain-rename.ref.err b/cts/schemas/test-2/030-clu-props-plain-rename.ref.err similarity index 100% rename from xml/test-2/030-clu-props-plain-rename.ref.err rename to cts/schemas/test-2/030-clu-props-plain-rename.ref.err diff --git a/xml/test-2/030-clu-props-plain-rename.xml b/cts/schemas/test-2/030-clu-props-plain-rename.xml similarity index 100% rename from xml/test-2/030-clu-props-plain-rename.xml rename to cts/schemas/test-2/030-clu-props-plain-rename.xml diff --git a/xml/test-2/031-clu-props-drop.ref b/cts/schemas/test-2/031-clu-props-drop.ref similarity index 100% rename from xml/test-2/031-clu-props-drop.ref rename to cts/schemas/test-2/031-clu-props-drop.ref diff --git a/xml/test-2/031-clu-props-drop.ref.err b/cts/schemas/test-2/031-clu-props-drop.ref.err similarity index 100% rename from xml/test-2/031-clu-props-drop.ref.err rename to cts/schemas/test-2/031-clu-props-drop.ref.err diff --git a/xml/test-2/031-clu-props-drop.xml b/cts/schemas/test-2/031-clu-props-drop.xml similarity index 100% rename from xml/test-2/031-clu-props-drop.xml rename to cts/schemas/test-2/031-clu-props-drop.xml diff --git a/xml/test-2/032-clu-props-move.ref b/cts/schemas/test-2/032-clu-props-move.ref similarity index 100% rename from xml/test-2/032-clu-props-move.ref rename to cts/schemas/test-2/032-clu-props-move.ref diff --git a/xml/test-2/032-clu-props-move.ref.err b/cts/schemas/test-2/032-clu-props-move.ref.err similarity index 100% rename from xml/test-2/032-clu-props-move.ref.err rename to cts/schemas/test-2/032-clu-props-move.ref.err diff --git a/xml/test-2/032-clu-props-move.xml b/cts/schemas/test-2/032-clu-props-move.xml similarity index 100% rename from xml/test-2/032-clu-props-move.xml rename to cts/schemas/test-2/032-clu-props-move.xml diff --git a/xml/test-2/033-clu-props-move-merge.ref b/cts/schemas/test-2/033-clu-props-move-merge.ref similarity index 100% rename from xml/test-2/033-clu-props-move-merge.ref rename to cts/schemas/test-2/033-clu-props-move-merge.ref diff --git a/xml/test-2/033-clu-props-move-merge.ref.err b/cts/schemas/test-2/033-clu-props-move-merge.ref.err similarity index 100% rename from xml/test-2/033-clu-props-move-merge.ref.err rename to cts/schemas/test-2/033-clu-props-move-merge.ref.err diff --git a/xml/test-2/033-clu-props-move-merge.xml b/cts/schemas/test-2/033-clu-props-move-merge.xml similarity index 100% rename from xml/test-2/033-clu-props-move-merge.xml rename to cts/schemas/test-2/033-clu-props-move-merge.xml diff --git a/xml/test-2/034-clu-props-move-redef.ref b/cts/schemas/test-2/034-clu-props-move-redef.ref similarity index 100% rename from xml/test-2/034-clu-props-move-redef.ref rename to cts/schemas/test-2/034-clu-props-move-redef.ref diff --git a/xml/test-2/034-clu-props-move-redef.ref.err b/cts/schemas/test-2/034-clu-props-move-redef.ref.err similarity index 100% rename from xml/test-2/034-clu-props-move-redef.ref.err rename to cts/schemas/test-2/034-clu-props-move-redef.ref.err diff --git a/xml/test-2/034-clu-props-move-redef.xml b/cts/schemas/test-2/034-clu-props-move-redef.xml similarity index 100% rename from xml/test-2/034-clu-props-move-redef.xml rename to cts/schemas/test-2/034-clu-props-move-redef.xml diff --git a/xml/test-2/040-nodes-rename-type.ref b/cts/schemas/test-2/040-nodes-rename-type.ref similarity index 100% rename from xml/test-2/040-nodes-rename-type.ref rename to cts/schemas/test-2/040-nodes-rename-type.ref diff --git a/xml/test-2/040-nodes-rename-type.ref.err b/cts/schemas/test-2/040-nodes-rename-type.ref.err similarity index 100% rename from xml/test-2/040-nodes-rename-type.ref.err rename to cts/schemas/test-2/040-nodes-rename-type.ref.err diff --git a/xml/test-2/040-nodes-rename-type.xml b/cts/schemas/test-2/040-nodes-rename-type.xml similarity index 100% rename from xml/test-2/040-nodes-rename-type.xml rename to cts/schemas/test-2/040-nodes-rename-type.xml diff --git a/xml/test-2/050-rsc-attrs-instance-plain-rename.ref b/cts/schemas/test-2/050-rsc-attrs-instance-plain-rename.ref similarity index 100% rename from xml/test-2/050-rsc-attrs-instance-plain-rename.ref rename to cts/schemas/test-2/050-rsc-attrs-instance-plain-rename.ref diff --git a/xml/test-2/050-rsc-attrs-instance-plain-rename.ref.err b/cts/schemas/test-2/050-rsc-attrs-instance-plain-rename.ref.err similarity index 100% rename from xml/test-2/050-rsc-attrs-instance-plain-rename.ref.err rename to cts/schemas/test-2/050-rsc-attrs-instance-plain-rename.ref.err diff --git a/xml/test-2/050-rsc-attrs-instance-plain-rename.xml b/cts/schemas/test-2/050-rsc-attrs-instance-plain-rename.xml similarity index 100% rename from xml/test-2/050-rsc-attrs-instance-plain-rename.xml rename to cts/schemas/test-2/050-rsc-attrs-instance-plain-rename.xml diff --git a/xml/test-2/051-rsc-attrs-instance-pcmk_arg_map.ref b/cts/schemas/test-2/051-rsc-attrs-instance-pcmk_arg_map.ref similarity index 100% rename from xml/test-2/051-rsc-attrs-instance-pcmk_arg_map.ref rename to cts/schemas/test-2/051-rsc-attrs-instance-pcmk_arg_map.ref diff --git a/xml/test-2/051-rsc-attrs-instance-pcmk_arg_map.ref.err b/cts/schemas/test-2/051-rsc-attrs-instance-pcmk_arg_map.ref.err similarity index 100% rename from xml/test-2/051-rsc-attrs-instance-pcmk_arg_map.ref.err rename to cts/schemas/test-2/051-rsc-attrs-instance-pcmk_arg_map.ref.err diff --git a/xml/test-2/051-rsc-attrs-instance-pcmk_arg_map.xml b/cts/schemas/test-2/051-rsc-attrs-instance-pcmk_arg_map.xml similarity index 100% rename from xml/test-2/051-rsc-attrs-instance-pcmk_arg_map.xml rename to cts/schemas/test-2/051-rsc-attrs-instance-pcmk_arg_map.xml diff --git a/xml/test-2/060-rsc-attrs-meta-isolation.ref b/cts/schemas/test-2/060-rsc-attrs-meta-isolation.ref similarity index 100% rename from xml/test-2/060-rsc-attrs-meta-isolation.ref rename to cts/schemas/test-2/060-rsc-attrs-meta-isolation.ref diff --git a/xml/test-2/060-rsc-attrs-meta-isolation.ref.err b/cts/schemas/test-2/060-rsc-attrs-meta-isolation.ref.err similarity index 100% rename from xml/test-2/060-rsc-attrs-meta-isolation.ref.err rename to cts/schemas/test-2/060-rsc-attrs-meta-isolation.ref.err diff --git a/xml/test-2/060-rsc-attrs-meta-isolation.xml b/cts/schemas/test-2/060-rsc-attrs-meta-isolation.xml similarity index 100% rename from xml/test-2/060-rsc-attrs-meta-isolation.xml rename to cts/schemas/test-2/060-rsc-attrs-meta-isolation.xml diff --git a/xml/test-2/061-rsc-attrs-meta-exchange.ref b/cts/schemas/test-2/061-rsc-attrs-meta-exchange.ref similarity index 100% rename from xml/test-2/061-rsc-attrs-meta-exchange.ref rename to cts/schemas/test-2/061-rsc-attrs-meta-exchange.ref diff --git a/xml/test-2/061-rsc-attrs-meta-exchange.ref.err b/cts/schemas/test-2/061-rsc-attrs-meta-exchange.ref.err similarity index 100% rename from xml/test-2/061-rsc-attrs-meta-exchange.ref.err rename to cts/schemas/test-2/061-rsc-attrs-meta-exchange.ref.err diff --git a/xml/test-2/061-rsc-attrs-meta-exchange.xml b/cts/schemas/test-2/061-rsc-attrs-meta-exchange.xml similarity index 100% rename from xml/test-2/061-rsc-attrs-meta-exchange.xml rename to cts/schemas/test-2/061-rsc-attrs-meta-exchange.xml diff --git a/xml/test-2/070-rsc-op-attrs-inst-requires-start.ref b/cts/schemas/test-2/070-rsc-op-attrs-inst-requires-start.ref similarity index 100% rename from xml/test-2/070-rsc-op-attrs-inst-requires-start.ref rename to cts/schemas/test-2/070-rsc-op-attrs-inst-requires-start.ref diff --git a/xml/test-2/070-rsc-op-attrs-inst-requires-start.ref.err b/cts/schemas/test-2/070-rsc-op-attrs-inst-requires-start.ref.err similarity index 100% rename from xml/test-2/070-rsc-op-attrs-inst-requires-start.ref.err rename to cts/schemas/test-2/070-rsc-op-attrs-inst-requires-start.ref.err diff --git a/xml/test-2/070-rsc-op-attrs-inst-requires-start.xml b/cts/schemas/test-2/070-rsc-op-attrs-inst-requires-start.xml similarity index 100% rename from xml/test-2/070-rsc-op-attrs-inst-requires-start.xml rename to cts/schemas/test-2/070-rsc-op-attrs-inst-requires-start.xml diff --git a/xml/test-2/071-rsc-op-attrs-inst-requires-nonstart.ref b/cts/schemas/test-2/071-rsc-op-attrs-inst-requires-nonstart.ref similarity index 100% rename from xml/test-2/071-rsc-op-attrs-inst-requires-nonstart.ref rename to cts/schemas/test-2/071-rsc-op-attrs-inst-requires-nonstart.ref diff --git a/xml/test-2/071-rsc-op-attrs-inst-requires-nonstart.ref.err b/cts/schemas/test-2/071-rsc-op-attrs-inst-requires-nonstart.ref.err similarity index 100% rename from xml/test-2/071-rsc-op-attrs-inst-requires-nonstart.ref.err rename to cts/schemas/test-2/071-rsc-op-attrs-inst-requires-nonstart.ref.err diff --git a/xml/test-2/071-rsc-op-attrs-inst-requires-nonstart.xml b/cts/schemas/test-2/071-rsc-op-attrs-inst-requires-nonstart.xml similarity index 100% rename from xml/test-2/071-rsc-op-attrs-inst-requires-nonstart.xml rename to cts/schemas/test-2/071-rsc-op-attrs-inst-requires-nonstart.xml diff --git a/xml/test-2/072-rsc-op-attrs-inst-requires-no-override.ref b/cts/schemas/test-2/072-rsc-op-attrs-inst-requires-no-override.ref similarity index 100% rename from xml/test-2/072-rsc-op-attrs-inst-requires-no-override.ref rename to cts/schemas/test-2/072-rsc-op-attrs-inst-requires-no-override.ref diff --git a/xml/test-2/072-rsc-op-attrs-inst-requires-no-override.ref.err b/cts/schemas/test-2/072-rsc-op-attrs-inst-requires-no-override.ref.err similarity index 100% rename from xml/test-2/072-rsc-op-attrs-inst-requires-no-override.ref.err rename to cts/schemas/test-2/072-rsc-op-attrs-inst-requires-no-override.ref.err diff --git a/xml/test-2/072-rsc-op-attrs-inst-requires-no-override.xml b/cts/schemas/test-2/072-rsc-op-attrs-inst-requires-no-override.xml similarity index 100% rename from xml/test-2/072-rsc-op-attrs-inst-requires-no-override.xml rename to cts/schemas/test-2/072-rsc-op-attrs-inst-requires-no-override.xml diff --git a/xml/test-2/073-rsc-op-attrs-inst-meta-meaning.ref b/cts/schemas/test-2/073-rsc-op-attrs-inst-meta-meaning.ref similarity index 100% rename from xml/test-2/073-rsc-op-attrs-inst-meta-meaning.ref rename to cts/schemas/test-2/073-rsc-op-attrs-inst-meta-meaning.ref diff --git a/xml/test-2/073-rsc-op-attrs-inst-meta-meaning.ref.err b/cts/schemas/test-2/073-rsc-op-attrs-inst-meta-meaning.ref.err similarity index 100% rename from xml/test-2/073-rsc-op-attrs-inst-meta-meaning.ref.err rename to cts/schemas/test-2/073-rsc-op-attrs-inst-meta-meaning.ref.err diff --git a/xml/test-2/073-rsc-op-attrs-inst-meta-meaning.xml b/cts/schemas/test-2/073-rsc-op-attrs-inst-meta-meaning.xml similarity index 100% rename from xml/test-2/073-rsc-op-attrs-inst-meta-meaning.xml rename to cts/schemas/test-2/073-rsc-op-attrs-inst-meta-meaning.xml diff --git a/xml/Makefile.am b/xml/Makefile.am index 05702e2e5c..1a14df5c13 100644 --- a/xml/Makefile.am +++ b/xml/Makefile.am @@ -1,286 +1,281 @@ # # Copyright 2004-2024 the Pacemaker project contributors # # The version control history for this file may have further details. # # This source code is licensed under the GNU General Public License version 2 # or later (GPLv2+) WITHOUT ANY WARRANTY. # include $(top_srcdir)/mk/common.mk noarch_pkgconfig_DATA = $(builddir)/pacemaker-schemas.pc # Pacemaker has 3 schemas: the CIB schema, the API schema (for command-line # tool XML output), and a legacy schema for crm_mon --as-xml. # # See README.md for details on updating CIB schema files (API is similar) # The CIB and crm_mon schemas are installed directly in CRM_SCHEMA_DIRECTORY # for historical reasons, while the API schema is installed in a subdirectory. APIdir = $(CRM_SCHEMA_DIRECTORY)/api CIBdir = $(CRM_SCHEMA_DIRECTORY) MONdir = $(CRM_SCHEMA_DIRECTORY) basexsltdir = $(CRM_SCHEMA_DIRECTORY)/base dist_basexslt_DATA = $(srcdir)/base/access-render-2.xsl # Extract a sorted list of available numeric schema versions # from filenames like NAME-MAJOR[.MINOR][.MINOR-MINOR].rng numeric_versions = $(shell ls -1 $(1) \ | sed -n -e 's/^.*-\([0-9][0-9.]*\).rng$$/\1/p' \ | sort -u -t. -k 1,1n -k 2,2n -k 3,3n) # @COMPAT: pacemaker-next is deprecated since 2.1.5 version_pairs = $(join \ $(1),$(addprefix \ -,$(wordlist \ 2,$(words $(1)),$(1) \ ) next \ ) \ ) version_pairs_last = $(wordlist \ $(words \ $(wordlist \ 2,$(1),$(2) \ ) \ ),$(1),$(2) \ ) # NOTE: All files in API_request_base, CIB_cfg_base, API_base, and CIB_base # need to start with a unique prefix. These variables all get iterated over # and globbed, and two files starting with the same prefix will cause # problems. # Names of API schemas that form the choices for pacemaker-result content API_request_base = command-output \ crm_attribute \ crm_error \ crm_mon \ crm_node \ crm_resource \ crm_rule \ crm_shadow \ crm_simulate \ crm_ticket \ crmadmin \ digests \ iso8601 \ pacemakerd \ stonith_admin \ version # Names of CIB schemas that form the choices for cib/configuration content CIB_cfg_base = options \ nodes \ resources \ constraints \ fencing \ acls \ tags \ alerts # Names of all schemas (including top level and those included by others) API_base = $(API_request_base) \ any-element \ failure \ fence-event \ generic-list \ instruction \ item \ node-attrs \ node-history \ nodes \ ocf-ra \ options \ patchset \ resources \ status \ subprocess-output \ ticket CIB_base = cib \ $(CIB_cfg_base) \ status \ score \ rule \ nvset # Static schema files and transforms (only CIB has transforms) # # This is more complicated than it should be due to the need to support # VPATH builds and "make distcheck". We need the absolute paths for reliable # substitution back and forth, and relative paths for distributed files. API_abs_files = $(foreach base,$(API_base),$(wildcard $(abs_srcdir)/api/$(base)-*.rng)) CIB_abs_files = $(foreach base,$(CIB_base),$(wildcard $(abs_srcdir)/$(base).rng $(abs_srcdir)/$(base)-*.rng)) CIB_abs_xsl = $(abs_srcdir)/upgrade-1.3-0.xsl \ $(wildcard $(abs_srcdir)/upgrade-2.10-[0-2].xsl) MON_abs_files = $(abs_srcdir)/crm_mon.rng API_files = $(foreach base,$(API_base),$(wildcard $(srcdir)/api/$(base)-*.rng)) CIB_files = $(foreach base,$(CIB_base),$(wildcard $(srcdir)/$(base).rng $(srcdir)/$(base)-*.rng)) CIB_xsl = $(srcdir)/upgrade-1.3-0.xsl \ $(wildcard $(srcdir)/upgrade-2.10-[0-2].xsl) MON_files = $(srcdir)/crm_mon.rng # Sorted lists of all numeric schema versions API_numeric_versions = $(call numeric_versions,${API_files}) CIB_numeric_versions = $(call numeric_versions,${CIB_files}) MON_numeric_versions = $(call numeric_versions,$(wildcard $(srcdir)/api/crm_mon*.rng)) # The highest numeric schema version API_max ?= $(lastword $(API_numeric_versions)) CIB_max ?= $(lastword $(CIB_numeric_versions)) MON_max ?= $(lastword $(MON_numeric_versions)) # Sorted lists of all schema versions (including "next") # @COMPAT: pacemaker-next is deprecated since 2.1.5 API_versions = next $(API_numeric_versions) CIB_versions = next $(CIB_numeric_versions) # Build tree locations of static schema files and transforms (for VPATH builds) API_build_copies = $(foreach f,$(API_abs_files),$(subst $(abs_srcdir),$(abs_builddir),$(f))) CIB_build_copies = $(foreach f,$(CIB_abs_files) $(CIB_abs_xsl),$(subst $(abs_srcdir),$(abs_builddir),$(f))) MON_build_copies = $(foreach f,$(MON_abs_files),$(subst $(abs_srcdir),$(abs_builddir),$(f))) # Dynamically generated schema files API_generated = api/api-result.rng $(foreach base,$(API_versions),api/api-result-$(base).rng) CIB_generated = pacemaker.rng \ $(foreach base,$(CIB_versions),pacemaker-$(base).rng) \ versions.rng MON_generated = crm_mon.rng CIB_version_pairs = $(call version_pairs,${CIB_numeric_versions}) CIB_version_pairs_cnt = $(words ${CIB_version_pairs}) CIB_version_pairs_last = $(call version_pairs_last,${CIB_version_pairs_cnt},${CIB_version_pairs}) dist_API_DATA = $(API_files) dist_CIB_DATA = $(CIB_files) \ $(CIB_xsl) nodist_API_DATA = $(API_generated) nodist_CIB_DATA = $(CIB_generated) nodist_MON_DATA = $(MON_generated) EXTRA_DIST = README.md \ cibtr-2.rng \ context-of.xsl \ rng-helper \ ocf-meta2man.xsl \ - regression.sh \ upgrade-1.3.xsl \ upgrade-2.10.xsl \ upgrade-2.10-enter.xsl \ upgrade-2.10-leave.xsl \ upgrade-2.10-roundtrip.xsl \ upgrade-detail.xsl \ - xslt_cibtr-2.rng \ - test-2 \ - test-2-enter \ - test-2-leave \ - test-2-roundtrip + xslt_cibtr-2.rng .PHONY: cib-versions cib-versions: @echo "Max: $(CIB_max)" @echo "Available: $(CIB_versions)" .PHONY: api-versions api-versions: @echo "Max: $(API_max)" @echo "Available: $(API_versions)" # Dynamically generated top-level API schema api/api-result.rng: api/api-result-$(API_max).rng $(AM_V_at)$(MKDIR_P) api # might not exist in VPATH build $(AM_V_SCHEMA)cp $(top_builddir)/xml/$< $@ api/api-result-%.rng: $(API_build_copies) rng-helper Makefile.am $(AM_V_SCHEMA)$(builddir)/rng-helper build_api_rng "$@" "$*" \ $(API_request_base) crm_mon.rng: api/crm_mon-$(MON_max).rng $(AM_V_at)echo '' > $@ $(AM_V_at)echo '> $@ $(AM_V_at)echo ' datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">' >> $@ $(AM_V_at)echo ' ' >> $@ $(AM_V_at)echo ' ' >> $@ $(AM_V_at)echo ' ' >> $@ $(AM_V_at)echo ' ' >> $@ $(AM_V_at)echo ' ' >> $@ $(AM_V_at)echo ' ' >> $@ $(AM_V_at)echo ' ' >> $@ $(AM_V_at)echo ' ' >> $@ $(AM_V_at)echo ' ' >> $@ $(AM_V_SCHEMA)echo '' >> $@ # Dynamically generated top-level CIB schema pacemaker.rng: pacemaker-$(CIB_max).rng $(AM_V_SCHEMA)cp $(top_builddir)/xml/$< $@ pacemaker-%.rng: $(CIB_build_copies) rng-helper Makefile.am $(AM_V_SCHEMA)$(builddir)/rng-helper build_cib_rng "$@" "$*" \ $(CIB_cfg_base) # Dynamically generated CIB schema listing all pacemaker versions # # @COMPAT none, pacemaker-0.6, pacemaker-0.7, pacemaker-1.1, and # transitional-0.6 are deprecated since 2.1.8, as is validate-with being # optional versions.rng: pacemaker-$(CIB_max).rng Makefile.am $(AM_V_at)echo '' > $@ $(AM_V_at)echo '' >> $@ $(AM_V_at)echo ' ' >> $@ $(AM_V_at)echo ' ' >> $@ $(AM_V_at)echo ' ' >> $@ $(AM_V_at)echo ' ' >> $@ $(AM_V_at)echo ' ' >> $@ $(AM_V_at)echo ' none' >> $@ $(AM_V_at)echo ' pacemaker-0.6' >> $@ $(AM_V_at)echo ' transitional-0.6' >> $@ $(AM_V_at)echo ' pacemaker-0.7' >> $@ $(AM_V_at)echo ' pacemaker-1.1' >> $@ $(AM_V_at)for rng in $(CIB_versions); do echo " pacemaker-$$rng" >> $@; done $(AM_V_at)echo ' ' >> $@ $(AM_V_at)echo ' ' >> $@ $(AM_V_at)echo ' ' >> $@ $(AM_V_at)echo ' ' >> $@ $(AM_V_at)echo ' ' >> $@ $(AM_V_at)echo ' ' >> $@ $(AM_V_at)echo ' ' >> $@ $(AM_V_at)echo ' ' >> $@ $(AM_V_SCHEMA)echo '' >> $@ .PHONY: diff diff: rng-helper @echo "# Comparing changes in + since $(CIB_max)" @$(builddir)/rng-helper diff ${CIB_version_pairs_last} .PHONY: fulldiff fulldiff: rng-helper @echo "# Comparing all changes across all the subsequent increments" @$(builddir)/rng-helper diff ${CIB_version_pairs} CLEANFILES = $(API_generated) \ $(CIB_generated) \ $(MON_generated) # Remove pacemaker schema files generated by *any* source version. This allows # "make -C xml clean" to have the desired effect when checking out an earlier # revision in a source tree. .PHONY: clean-local clean-local: if [ "x$(srcdir)" != "x$(builddir)" ]; then \ rm -f $(API_build_copies) $(CIB_build_copies) $(MON_build_copies); \ fi rm -f $(builddir)/pacemaker-[0-9]*.[0-9]*.rng # Enable ability to use $@ in prerequisite .SECONDEXPANSION: # For VPATH builds, copy the static schema files into the build tree $(API_build_copies) $(CIB_build_copies) $(MON_build_copies): $$(subst $(abs_builddir),$(srcdir),$$(@)) $(AM_V_GEN)if [ "x$(srcdir)" != "x$(builddir)" ]; then \ $(MKDIR_P) "$(dir $(@))"; \ cp "$(<)" "$(@)"; \ fi