diff --git a/.gitignore b/.gitignore index 7887f3abe8..b698574d4f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,352 +1,354 @@ # # 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/o2cb /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-log-watcher /cts/cts-regression /cts/cts-scheduler /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/version-diff.sh # 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/test-suite.log /lib/*/tests/*/*.log /lib/*/tests/*/*_test /lib/*/tests/*/*.trs /xml/test-*/*.up /xml/test-*/*.up.err /xml/assets/*.rng /xml/assets/diffview.js /xml/assets/xmlcatalog /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 /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-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/pe_cron_range_satisfied /lrmd /ltmain.sh /mcp /missing /mock /pacemaker-*.spec /pengine /py-compile /scratch +/tools/cluster-init /test-driver /xml/crm.dtd ylwrap diff --git a/GNUmakefile b/GNUmakefile index 8cb5d3e486..73714b4bce 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -1,61 +1,63 @@ # # Copyright 2008-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. # default: build .PHONY: default -include Makefile # The main purpose of this GNUmakefile is that its targets can be invoked # without having to call autogen.sh and configure first. That means automake # variables may or may not be defined. Here, we use the current working # directory if a relevant variable hasn't been defined. abs_srcdir ?= $(shell pwd) GLIB_CFLAGS ?= $(pkg-config --cflags glib-2.0) PACKAGE ?= pacemaker .PHONY: init init: test -e configure && test -e libltdl || ./autogen.sh test -e Makefile || ./configure .PHONY: build build: init $(MAKE) $(AM_MAKEFLAGS) core ## RPM-related targets (deprecated; use targets in rpm subdirectory instead) # Pass option depending on whether automake has been run or not USE_FILE = $(shell test -e rpm/Makefile || echo "-f Makefile.am") .PHONY: $(PACKAGE).spec chroot dirty export mock rc release rpm rpmlint srpm $(PACKAGE).spec chroot dirty export mock rc release rpm rpmlint srpm: $(MAKE) $(AM_MAKEFLAGS) -C rpm $(USE_FILE) "$@" -.PHONY: mock-% rpm-% spec-% srpm-% -mock-% rpm-% spec-% srpm-%: +mock-% rpm-% spec-% srpm-%: FORCE $(MAKE) $(AM_MAKEFLAGS) -C rpm $(USE_FILE) "$@" ## Development-related targets ## (deprecated; use targets in devel subdirectory instead) COVLEVEL ?= low COVERAGE_TARGETS = coverage coverage-cts coverage-clean COVERITY_TARGETS = coverity coverity-analyze coverity-clean coverity-corp .PHONY: clang $(COVERAGE_TARGETS) $(COVERITY_TARGETS) cppcheck indent clang $(COVERAGE_TARGETS) $(COVERITY_TARGETS) cppcheck indent: @echo 'Deprecated: Use "make -C devel $@" instead' $(MAKE) $(AM_MAKEFLAGS) \ CLANG_checkers=$(CLANG_checkers) \ COVLEVEL=$(COVLEVEL) \ CPPCHECK_ARGS=$(CPPCHECK_ARGS) \ -C devel "$@" + +.PHONY: FORCE +FORCE: diff --git a/Makefile.am b/Makefile.am index a3952ac19b..04346a30cd 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,113 +1,135 @@ # # Copyright 2003-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. # # This directory must be same as in configure.ac's AC_CONFIG_MACRO_DIR ACLOCAL_AMFLAGS = -I m4 -EXTRA_DIST = CONTRIBUTING.md \ - GNUmakefile \ - INSTALL.md \ - README.markdown \ - autogen.sh \ +EXTRA_DIST = CONTRIBUTING.md \ + GNUmakefile \ + INSTALL.md \ + README.markdown \ + autogen.sh \ m4/CC_CHECK_LDFLAGS.m4 \ m4/CHECK_ENUM_VALUE.m4 \ - m4/gnulib-cache.m4 \ - m4/gnulib-tool.m4 \ - m4/PKG_CHECK_VAR.m4 \ - m4/REQUIRE_HEADER.m4 \ + m4/gnulib-cache.m4 \ + m4/gnulib-tool.m4 \ + m4/PKG_CHECK_VAR.m4 \ + m4/REQUIRE_HEADER.m4 \ m4/version.m4 DISTCLEANFILES = config.status -MAINTAINERCLEANFILES = Makefile.in \ - aclocal.m4 \ - config.guess \ - config.sub \ - configure \ - depcomp \ - install-sh \ - ltmain.sh \ - missing \ - py-compile \ +MAINTAINERCLEANFILES = Makefile.in \ + aclocal.m4 \ + config.guess \ + config.sub \ + configure \ + depcomp \ + install-sh \ + ltmain.sh \ + missing \ + py-compile \ test-driver # Don't try to install files outside build directory for "make distcheck". AM_DISTCHECK_CONFIGURE_FLAGS = --prefix="$$dc_install_base/usr" \ --sysconfdir="$$dc_install_base/etc" \ --with-initdir="$$dc_install_base/etc/init.d" \ --with-ocfdir="$$dc_install_base/usr/lib/ocf" \ --with-systemdsystemunitdir="$$dc_install_base$(systemdsystemunitdir)" # Only these will get built with a plain "make" -CORE = include lib daemons tools xml po python cts rpm - -SUBDIRS = $(CORE) agents devel doc etc maint tests +CORE = include \ + lib \ + daemons \ + tools \ + xml \ + po \ + python \ + cts \ + rpm + +SUBDIRS = $(CORE) \ + agents \ + devel \ + doc \ + etc \ + maint \ + tests AM_CPPFLAGS = -I$(top_srcdir)/include -doc_DATA = README.markdown COPYING +doc_DATA = README.markdown \ + COPYING licensedir = $(docdir)/licenses/ dist_license_DATA = $(wildcard licenses/*) # Directories that should be created on install and removed on uninstall ## owned by root:haclient, mode 0750 ROOT_DIRS = $(PACEMAKER_CONFIG_DIR) ## owned by hacluster:haclient, mode 0750 DAEMON_R_DIRS = $(CRM_CONFIG_DIR) \ $(CRM_CORE_DIR) \ $(CRM_BLACKBOX_DIR) ## owned by hacluster:haclient, mode 0770 DAEMON_RW_DIRS = $(CRM_BUNDLE_DIR) \ $(CRM_LOG_DIR) +.PHONY: core core: @echo "Building only core components and tests: $(CORE)" @for subdir in $(CORE); do \ echo "Building $$subdir"; \ $(MAKE) $(AM_MAKEFLAGS) -C $$subdir all || exit 1; \ done +.PHONY: core-clean core-clean: @echo "Cleaning only core components and tests: $(CORE)" @for subdir in $(CORE); do \ echo "Cleaning $$subdir"; \ $(MAKE) $(AM_MAKEFLAGS) -C $$subdir clean || exit 1; \ done +.PHONY: install-exec-local install-exec-local: for DIR in $(ROOT_DIRS) $(DAEMON_R_DIRS); do \ $(INSTALL) -d -m 750 "$(DESTDIR)/$$DIR"; \ done for DIR in $(DAEMON_RW_DIRS); do \ $(INSTALL) -d -m 770 "$(DESTDIR)/$$DIR"; \ done -for DIR in $(ROOT_DIRS); do \ chgrp $(CRM_DAEMON_GROUP) "$(DESTDIR)/$$DIR"; \ done -for DIR in $(DAEMON_R_DIRS) $(DAEMON_RW_DIRS); do \ chown $(CRM_DAEMON_USER):$(CRM_DAEMON_GROUP) "$(DESTDIR)/$$DIR"; \ done # Remove created directories only if they're empty +.PHONY: uninstall-hook uninstall-hook: -for DIR in $(ROOT_DIRS) $(DAEMON_R_DIRS) $(DAEMON_RW_DIRS); do \ rmdir "$(DESTDIR)/$$DIR"; \ done +.PHONY: clean-generic clean-generic: -rm -f *.tar.bz2 *.sed PACKAGE ?= pacemaker +.PHONY: clean-local clean-local: -rm -f $(builddir)/$(PACKAGE)-*.tar.gz +.PHONY: distclean-local distclean-local: -rm -rf libltdl autom4te.cache diff --git a/agents/Makefile.am b/agents/Makefile.am index 3cbd7c6b10..af0d970d24 100644 --- a/agents/Makefile.am +++ b/agents/Makefile.am @@ -1,12 +1,14 @@ # # Copyright 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. # include $(top_srcdir)/mk/common.mk -SUBDIRS = alerts ocf stonith +SUBDIRS = alerts \ + ocf \ + stonith diff --git a/agents/alerts/Makefile.am b/agents/alerts/Makefile.am index fdb294fa80..a3fe8911e7 100644 --- a/agents/alerts/Makefile.am +++ b/agents/alerts/Makefile.am @@ -1,15 +1,13 @@ # # Copyright 2016-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. # include $(top_srcdir)/mk/common.mk samplesdir = $(datadir)/$(PACKAGE)/alerts/ -dist_samples_DATA = alert_file.sh.sample \ - alert_smtp.sh.sample \ - alert_snmp.sh.sample +dist_samples_DATA = $(wildcard *.sample) diff --git a/agents/ocf/Makefile.am b/agents/ocf/Makefile.am index 823e67e911..0b18bb1d43 100644 --- a/agents/ocf/Makefile.am +++ b/agents/ocf/Makefile.am @@ -1,53 +1,58 @@ # # Copyright 2008-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. # include $(top_srcdir)/mk/common.mk include $(top_srcdir)/mk/man.mk ocfdir = @OCF_RA_INSTALL_DIR@/pacemaker dist_ocf_SCRIPTS = attribute \ controld \ Dummy \ HealthCPU \ HealthIOWait \ ping \ remote \ Stateful ocf_SCRIPTS = ClusterMon \ HealthSMART \ ifspeed \ o2cb \ SysInfo if BUILD_XML_HELP -man7_MANS = $(ocf_SCRIPTS:%=ocf_pacemaker_%.7) $(dist_ocf_SCRIPTS:%=ocf_pacemaker_%.7) -DBOOK_OPTS = --stringparam command.prefix ocf_pacemaker_ --stringparam variable.prefix OCF_RESKEY_ --param man.vol 7 +man7_MANS = $(ocf_SCRIPTS:%=ocf_pacemaker_%.7) \ + $(dist_ocf_SCRIPTS:%=ocf_pacemaker_%.7) +DBOOK_OPTS = --stringparam command.prefix ocf_pacemaker_ \ + --stringparam variable.prefix OCF_RESKEY_ \ + --param man.vol 7 ocf_pacemaker_%.xml: % $(AM_V_GEN)OCF_FUNCTIONS=/dev/null OCF_ROOT=$(OCF_ROOT_DIR) $(abs_builddir)/$< meta-data > $@ endif # Pass correct local values to validate target manually RNG := /dev/null OCF_ROOT := /usr/lib/ocf .PHONY: validate validate: all @cat "$(RNG)" >/dev/null 2>/dev/null || { echo "Must specify valid RNG" && false; } @[ -x "$(OCF_ROOT)/lib/heartbeat" ] || { echo "Must specify valid OCF_ROOT" && false; } @for AGENT in $(dist_ocf_SCRIPTS) $(ocf_SCRIPTS); do \ echo -e "\n\n## $$AGENT:"; \ OCF_ROOT="$(OCF_ROOT)" "$(builddir)/$$AGENT" meta-data \ | xmllint --noout --relaxng $(RNG) - || break; \ done -CLEANFILES = $(man7_MANS) $(ocf_SCRIPTS:%=%.xml) $(dist_ocf_SCRIPTS:%=%.xml) +CLEANFILES = $(man7_MANS) \ + $(ocf_SCRIPTS:%=%.xml) \ + $(dist_ocf_SCRIPTS:%=%.xml) diff --git a/agents/stonith/Makefile.am b/agents/stonith/Makefile.am index e231775403..3e074f1656 100644 --- a/agents/stonith/Makefile.am +++ b/agents/stonith/Makefile.am @@ -1,19 +1,20 @@ # # Copyright 2003-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. # include $(top_srcdir)/mk/common.mk include $(top_srcdir)/mk/man.mk sbin_SCRIPTS = fence_watchdog if BUILD_LHA_SUPPORT sbin_SCRIPTS += fence_legacy endif -CLEANFILES = $(man7_MANS) $(man8_MANS) +CLEANFILES = $(man7_MANS) \ + $(man8_MANS) diff --git a/configure.ac b/configure.ac index d4aaec6fa8..4c8d3d7e70 100644 --- a/configure.ac +++ b/configure.ac @@ -1,2235 +1,2235 @@ dnl dnl autoconf for Pacemaker dnl dnl Copyright 2009-2023 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.27) AS_IF([test x"${PKG_CONFIG}" != x""], [], [AC_MSG_FAILURE([Could not find required build tool pkg-config (0.27 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 We use md5.c from gnulib, which has its own m4 macros. Per its docs: dnl "The macro gl_EARLY must be called as soon as possible after verifying that dnl the C compiler is working. ... The core part of the gnulib checks are done dnl by the macro gl_INIT." In addition, prevent gnulib from introducing OpenSSL dnl as a dependency. gl_EARLY gl_SET_CRYPTO_CHECK_DEFAULT([no]) gl_INIT AC_CHECK_SIZEOF(long) 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 AC_ARG_ENABLE([compat-2.0], [AS_HELP_STRING([--enable-compat-2.0], m4_normalize([ preserve certain output as it was in 2.0; this option will be available only for the lifetime of the 2.1 series @<:@no@:>@]))] ) yes_no_try "$enable_compat_2_0" "no" enable_compat_2_0=$? # Add an option to create symlinks at the pre-2.0.0 daemon name locations, so # that users and tools can continue to invoke those names directly (e.g., for # meta-data). This option will be removed in a future release. AC_ARG_ENABLE([legacy-links], [AS_HELP_STRING([--enable-legacy-links], [add symlinks for old daemon names (deprecated) @<:@no@:>@])] ) yes_no_try "$enable_legacy_links" "no" enable_legacy_links=$? # 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=$? AC_ARG_WITH([gnutls], [AS_HELP_STRING([--with-gnutls], [support Pacemaker Remote and remote-tls-port using GnuTLS @<:@try@:>@])] ) yes_no_try "$with_gnutls" "try" with_gnutls=$? 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_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.4]) 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 $enable_compat_2_0 -ne $DISABLED], [ AC_DEFINE_UNQUOTED([PCMK__COMPAT_2_0], [1], [Keep certain output compatible with 2.0 release series]) PCMK_FEATURES="$PCMK_FEATURES compat-2.0" ] ) AM_CONDITIONAL([BUILD_LEGACY_LINKS], [test $enable_legacy_links -ne $DISABLED]) 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) 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], [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 ]]) cc_temp_flags "$CFLAGS -Wl,--wrap=uname" WRAPPABLE_UNAME="no" AC_MSG_CHECKING([if uname() can be wrapped]) AC_RUN_IFELSE([AC_LANG_SOURCE([[ #include int __wrap_uname(struct utsname *buf) { return 100; } int main(int argc, char **argv) { struct utsname x; return uname(&x) == 100 ? 0 : 1; } ]])], [ WRAPPABLE_UNAME="yes" ], [ WRAPPABLE_UNAME="no"]) AC_MSG_RESULT([$WRAPPABLE_UNAME]) AM_CONDITIONAL([WRAPPABLE_UNAME], [test x"$WRAPPABLE_UNAME" = x"yes"]) cc_restore_flags 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 >= 0.17) 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) 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=1 PKG_CHECK_MODULES([DBUS], [dbus-1], [CPPFLAGS="${CPPFLAGS} ${DBUS_CFLAGS}"], [HAVE_dbus=0]) AC_DEFINE_UNQUOTED(HAVE_DBUS, $HAVE_dbus, Support dbus) AM_CONDITIONAL(BUILD_DBUS, test $HAVE_dbus = 1) dnl libdbus 1.5.12+ (2012-03) / 1.6.0+ (2012-06) AC_CHECK_TYPES([DBusBasicValue],,,[[#include ]]) AS_IF([test $HAVE_dbus = 0], [PC_NAME_DBUS=""], [PC_NAME_DBUS="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 ======================================================================== dnl Require GnuTLS >=2.12.0 (2011-03) for Pacemaker Remote support PC_NAME_GNUTLS="" AS_CASE([$with_gnutls], [$REQUIRED], [ REQUIRE_LIB([gnutls], [gnutls_sec_param_to_pk_bits]) REQUIRE_HEADER([gnutls/gnutls.h]) ], [$OPTIONAL], [ AC_CHECK_LIB([gnutls], [gnutls_sec_param_to_pk_bits], [], [with_gnutls=$DISABLED]) AC_CHECK_HEADERS([gnutls/gnutls.h], [], [with_gnutls=$DISABLED]) ] ) AS_IF([test $with_gnutls -ne $DISABLED], [ PC_NAME_GNUTLS="gnutls" PCMK_FEATURES="$PCMK_FEATURES remote" ] ) AC_SUBST([PC_NAME_GNUTLS]) AM_CONDITIONAL([BUILD_REMOTE], [test $with_gnutls -ne $DISABLED]) # --- 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/o2cb], [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-log-watcher], [cts/cts-regression], [cts/cts-scheduler], [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/cluster-init], [tools/crm_failcount], [tools/crm_master], [tools/crm_report], [tools/crm_standby], [tools/cibsecret], - [tools/pcmk_simtimes]) + [tools/pcmk_simtimes], + [xml/version-diff.sh]) 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/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/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/nvpair/Makefile \ lib/common/tests/options/Makefile \ lib/common/tests/output/Makefile \ lib/common/tests/procfs/Makefile \ lib/common/tests/results/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/gnu/Makefile \ lib/libpacemaker.pc \ lib/lrmd/Makefile \ lib/pacemaker/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/rules/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 ac2e8abf82..598ae32b9b 100644 --- a/cts/Makefile.am +++ b/cts/Makefile.am @@ -1,90 +1,76 @@ # # Copyright 2001-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. # 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 \ +test_SCRIPTS = cts-attrd \ cts-cli \ cts-exec \ cts-fencing \ cts-lab \ cts-regression \ cts-scheduler dist_test_DATA = README.md \ valgrind-pcmk.suppressions clidir = $(testdir)/cli -dist_cli_DATA = cli/constraints.xml \ - cli/crmadmin-cluster-remote-guest-nodes.xml \ - cli/crm_diff_new.xml \ - cli/crm_diff_old.xml \ - cli/crm_mon.xml \ - cli/crm_mon-feature_set.xml \ - cli/crm_mon-partial.xml \ - cli/crm_mon-rsc-maint.xml \ - cli/crm_mon-T180.xml \ - cli/crm_mon-unmanaged.xml \ - cli/crm_resource_digests.xml \ - cli/regression.acls.exp \ - cli/regression.crm_mon.exp \ - cli/regression.daemons.exp \ - cli/regression.dates.exp \ - cli/regression.error_codes.exp \ - cli/regression.feature_set.exp \ - cli/regression.rules.exp \ - cli/regression.tools.exp \ - cli/regression.upgrade.exp \ - cli/regression.validity.exp \ - cli/regression.access_render.exp +dist_cli_DATA = $(wildcard cli/*.xml cli/*.exp) ctsdir = $(datadir)/$(PACKAGE)/tests/cts cts_SCRIPTS = cts # Commands intended to be run only via other commands halibdir = $(CRM_DAEMON_DIR) dist_halib_SCRIPTS = cts-log-watcher 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 -SUBDIRS = benchmark scheduler support +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-log-watcher \ - cts-regression \ - cts-scheduler +python_files = cts-attrd \ + cts-exec \ + cts-fencing \ + cts-lab \ + cts-log-watcher \ + cts-regression \ + cts-scheduler +.PHONY: pylint pylint: $(python_files) PYTHONPATH=$(top_builddir)/python pylint --rcfile $(top_srcdir)/python/pylintrc $(python_files) diff --git a/cts/benchmark/Makefile.am b/cts/benchmark/Makefile.am index 532abd2c4e..703f18dcf3 100644 --- a/cts/benchmark/Makefile.am +++ b/cts/benchmark/Makefile.am @@ -1,13 +1,14 @@ # -# Copyright 2001-2017 the Pacemaker project contributors +# Copyright 2001-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. # MAINTAINERCLEANFILES = Makefile.in benchdir = $(datadir)/$(PACKAGE)/tests/cts/benchmark -dist_bench_DATA = README.benchmark control +dist_bench_DATA = README.benchmark \ + control bench_SCRIPTS = clubench diff --git a/cts/cts-cli.in b/cts/cts-cli.in index 72e24355bd..c6cc593a02 100755 --- a/cts/cts-cli.in +++ b/cts/cts-cli.in @@ -1,3419 +1,3419 @@ #!@BASH_PATH@ # -# Copyright 2008-2022 the Pacemaker project contributors +# Copyright 2008-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. # # Set the exit status of a command to the exit code of the last program to # exit non-zero. This is bash-specific. set -o pipefail # # 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. # USAGE_TEXT="Usage: cts-cli [] Options: --help Display this text, then exit -V, --verbose Display any differences from expected output -t 'TEST [...]' Run only specified tests (default: 'daemons dates error_codes tools crm_mon acls validity upgrade rules feature_set'). Other tests: agents (must be run in an installed environment). -p DIR Look for executables in DIR (may be specified multiple times) -v, --valgrind Run all commands under valgrind -s Save actual output as expected output" # If readlink supports -e (i.e. GNU), 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 : ${shadow=cts-cli} shadow_dir=$(mktemp -d ${TMPDIR:-/tmp}/cts-cli.shadow.XXXXXXXXXX) num_errors=0 num_passed=0 verbose=0 tests="daemons dates error_codes tools crm_mon acls validity upgrade rules " tests="$tests feature_set" do_save=0 XMLLINT_CMD= VALGRIND_CMD= VALGRIND_OPTS=" -q --gen-suppressions=all --show-reachable=no --leak-check=full --trace-children=no --time-stamp=yes --num-callers=20 --suppressions=$test_home/valgrind-pcmk.suppressions " # Temp files for saving a command's stdout/stderr in _test_assert() test_assert_outfile=$(mktemp ${TMPDIR:-/tmp}/cts-cli.ta_outfile.XXXXXXXXXX) test_assert_errfile=$(mktemp ${TMPDIR:-/tmp}/cts-cli.ta_errfile.XXXXXXXXXX) xmllint_outfile=$(mktemp ${TMPDIR:-/tmp}/cts-cli.xmllint_outfile.XXXXXXXXXX) # Log test errors to stderr export PCMK_stderr=1 # Output when PCMK_trace_functions is undefined is different from when it's # empty. Later we save the value of PCMK_trace_functions, do work, and restore # the original value. Getting back to the initial state is simplest if we assume # the variable is defined. : ${PCMK_trace_functions=""} export PCMK_trace_functions # These constants must track crm_exit_t values CRM_EX_OK=0 CRM_EX_ERROR=1 CRM_EX_INVALID_PARAM=2 CRM_EX_UNIMPLEMENT_FEATURE=3 CRM_EX_INSUFFICIENT_PRIV=4 CRM_EX_NOT_CONFIGURED=6 CRM_EX_USAGE=64 CRM_EX_DATAERR=65 CRM_EX_CANTCREAT=73 CRM_EX_CONFIG=78 CRM_EX_OLD=103 CRM_EX_DIGEST=104 CRM_EX_NOSUCH=105 CRM_EX_UNSAFE=107 CRM_EX_EXISTS=108 CRM_EX_MULTIPLE=109 CRM_EX_EXPIRED=110 CRM_EX_NOT_YET_IN_EFFECT=111 reset_shadow_cib_version() { local SHADOWPATH SHADOWPATH="$(crm_shadow --file)" # sed -i isn't portable :-( cp -p "$SHADOWPATH" "${SHADOWPATH}.$$" # preserve permissions sed -e 's/epoch="[0-9]*"/epoch="1"/g' \ -e 's/num_updates="[0-9]*"/num_updates="0"/g' \ -e 's/admin_epoch="[0-9]*"/admin_epoch="0"/g' \ "$SHADOWPATH" > "${SHADOWPATH}.$$" mv -- "${SHADOWPATH}.$$" "$SHADOWPATH" } # A newly created empty CIB might or might not have a rsc_defaults section # depending on whether the --with-resource-stickiness-default configure # option was used. To ensure regression tests behave the same either way, # delete any rsc_defaults after creating or erasing a CIB. delete_shadow_resource_defaults() { cibadmin --delete --xml-text '' # The above command might or might not bump the CIB version, so reset it # to ensure future changes result in the same version for comparison. reset_shadow_cib_version } create_shadow_cib() { local VALIDATE_WITH local SHADOW_CMD CREATE_ARG="$1" VALIDATE_WITH="$2" export CIB_shadow_dir="${shadow_dir}" SHADOW_CMD="$VALGRIND_CMD crm_shadow --batch --force $CREATE_ARG" if [ -z "$VALIDATE_WITH" ]; then $SHADOW_CMD "$shadow" 2>&1 else $SHADOW_CMD "$shadow" --validate-with="${VALIDATE_WITH}" 2>&1 fi export CIB_shadow="$shadow" delete_shadow_resource_defaults } function _test_assert() { target=$1; shift validate=$1; shift cib=$1; shift app=`echo "$cmd" | sed 's/\ .*//'` printf "* Running: $app - $desc\n" 1>&2 printf "=#=#=#= Begin test: $desc =#=#=#=\n" # Capture stderr and stdout separately, then print them consecutively eval $VALGRIND_CMD $cmd > "$test_assert_outfile" 2> "$test_assert_errfile" rc=$? cat "$test_assert_errfile" cat "$test_assert_outfile" if [ x$cib != x0 ]; then printf "=#=#=#= Current cib after: $desc =#=#=#=\n" CIB_user=root cibadmin -Q fi # Do not validate if running under valgrind, even if told to do so. Valgrind # will output a lot more stuff that is not XML, so it wouldn't validate anyway. if [ "$validate" = "1" ] && [ "$VALGRIND_CMD" = "" ] && [ $rc = 0 ] && [ "$XMLLINT_CMD" != "" ]; then # The sed command filters out the "- validates" line that xmllint will output # on success. grep cannot be used here because "grep -v 'validates$'" will # return an exit code of 1 if its input consists entirely of "- validates". $XMLLINT_CMD --noout --relaxng \ "$PCMK_schema_directory/api/api-result.rng" "$test_assert_outfile" \ > "$xmllint_outfile" 2>&1 rc=$? sed -n '/validates$/ !p' "$xmllint_outfile" if [ $rc = 0 ]; then printf "=#=#=#= End test: %s - $(crm_error --exit $rc) (%d) =#=#=#=\n" "$desc" $rc else printf "=#=#=#= End test: %s - Failed to validate (%d) =#=#=#=\n" "$desc" $rc fi else printf "=#=#=#= End test: %s - $(crm_error --exit $rc) (%d) =#=#=#=\n" "$desc" $rc fi if [ $rc -ne $target ]; then num_errors=$(( $num_errors + 1 )) printf "* Failed (rc=%.3d): %-14s - %s\n" $rc $app "$desc" printf "* Failed (rc=%.3d): %-14s - %s\n" $rc $app "$desc (`which $app`)" 1>&2 return exit $CRM_EX_ERROR else printf "* Passed: %-14s - %s\n" $app "$desc" num_passed=$(( $num_passed + 1 )) fi } function test_assert() { _test_assert $1 0 $2 } function test_assert_validate() { _test_assert $1 1 $2 } # Tests that depend on resource agents and must be run in an installed # environment function test_agents() { desc="Validate a valid resource configuration" cmd="crm_resource --validate --class ocf --provider pacemaker --agent Dummy" test_assert $CRM_EX_OK 0 desc="Validate a valid resource configuration (XML)" cmd="crm_resource --validate --class ocf --provider pacemaker --agent Dummy" cmd="$cmd --output-as=xml" test_assert_validate $CRM_EX_OK 0 # Make the Dummy configuration invalid (op_sleep can't be a generic string) export OCF_RESKEY_op_sleep=asdf desc="Validate an invalid resource configuration" cmd="crm_resource --validate --class ocf --provider pacemaker --agent Dummy" test_assert $CRM_EX_NOT_CONFIGURED 0 desc="Validate an invalid resource configuration (XML)" cmd="crm_resource --validate --class ocf --provider pacemaker --agent Dummy" cmd="$cmd --output-as=xml" test_assert_validate $CRM_EX_NOT_CONFIGURED 0 unset OCF_RESKEY_op_sleep export OCF_RESKEY_op_sleep } function test_daemons() { desc="Get CIB manager metadata" cmd="pacemaker-based metadata" test_assert $CRM_EX_OK 0 desc="Get controller metadata" cmd="pacemaker-controld metadata" test_assert $CRM_EX_OK 0 desc="Get fencer metadata" cmd="pacemaker-fenced metadata" test_assert $CRM_EX_OK 0 desc="Get scheduler metadata" cmd="pacemaker-schedulerd metadata" test_assert $CRM_EX_OK 0 } function test_crm_mon() { local TMPXML export CIB_file="$test_home/cli/crm_mon.xml" desc="Basic text output" cmd="crm_mon -1" test_assert $CRM_EX_OK 0 desc="XML output" cmd="crm_mon --output-as=xml" test_assert_validate $CRM_EX_OK 0 desc="Basic text output without node section" cmd="crm_mon -1 --exclude=nodes" test_assert $CRM_EX_OK 0 desc="XML output without the node section" cmd="crm_mon --output-as=xml --exclude=nodes" test_assert_validate $CRM_EX_OK 0 desc="Text output with only the node section" cmd="crm_mon -1 --exclude=all --include=nodes" test_assert $CRM_EX_OK 0 # The above test doesn't need to be performed for other output formats. It's # really just a test to make sure that blank lines are correct. desc="Complete text output" cmd="crm_mon -1 --include=all" test_assert $CRM_EX_OK 0 # XML includes everything already so there's no need for a complete test desc="Complete text output with detail" cmd="crm_mon -1R --include=all" test_assert $CRM_EX_OK 0 # XML includes detailed output already desc="Complete brief text output" cmd="crm_mon -1 --include=all --brief" test_assert $CRM_EX_OK 0 desc="Complete text output grouped by node" cmd="crm_mon -1 --include=all --group-by-node" test_assert $CRM_EX_OK 0 # XML does not have a brief output option desc="Complete brief text output grouped by node" cmd="crm_mon -1 --include=all --group-by-node --brief" test_assert $CRM_EX_OK 0 desc="XML output grouped by node" cmd="crm_mon -1 --output-as=xml --group-by-node" test_assert_validate $CRM_EX_OK 0 desc="Complete text output filtered by node" cmd="crm_mon -1 --include=all --node=cluster01" test_assert $CRM_EX_OK 0 desc="XML output filtered by node" cmd="crm_mon --output-as xml --include=all --node=cluster01" test_assert_validate $CRM_EX_OK 0 desc="Complete text output filtered by tag" cmd="crm_mon -1 --include=all --node=even-nodes" test_assert $CRM_EX_OK 0 desc="XML output filtered by tag" cmd="crm_mon --output-as=xml --include=all --node=even-nodes" test_assert_validate $CRM_EX_OK 0 desc="Complete text output filtered by resource tag" cmd="crm_mon -1 --include=all --resource=fencing-rscs" test_assert $CRM_EX_OK 0 desc="XML output filtered by resource tag" cmd="crm_mon --output-as=xml --include=all --resource=fencing-rscs" test_assert_validate $CRM_EX_OK 0 desc="Basic text output filtered by node that doesn't exist" cmd="crm_mon -1 --node=blah" test_assert $CRM_EX_OK 0 desc="XML output filtered by node that doesn't exist" cmd="crm_mon --output-as=xml --node=blah" test_assert_validate $CRM_EX_OK 0 desc="Basic text output with inactive resources" cmd="crm_mon -1 -r" test_assert $CRM_EX_OK 0 # XML already includes inactive resources desc="Basic text output with inactive resources, filtered by node" cmd="crm_mon -1 -r --node=cluster02" test_assert $CRM_EX_OK 0 # XML already includes inactive resources desc="Complete text output filtered by primitive resource" cmd="crm_mon -1 --include=all --resource=Fencing" test_assert $CRM_EX_OK 0 desc="XML output filtered by primitive resource" cmd="crm_mon --output-as=xml --resource=Fencing" test_assert_validate $CRM_EX_OK 0 desc="Complete text output filtered by group resource" cmd="crm_mon -1 --include=all --resource=exim-group" test_assert $CRM_EX_OK 0 desc="XML output filtered by group resource" cmd="crm_mon --output-as=xml --resource=exim-group" test_assert_validate $CRM_EX_OK 0 desc="Complete text output filtered by group resource member" cmd="crm_mon -1 --include=all --resource=Public-IP" test_assert $CRM_EX_OK 0 desc="XML output filtered by group resource member" cmd="crm_mon --output-as=xml --resource=Email" test_assert_validate $CRM_EX_OK 0 desc="Complete text output filtered by clone resource" cmd="crm_mon -1 --include=all --resource=ping-clone" test_assert $CRM_EX_OK 0 desc="XML output filtered by clone resource" cmd="crm_mon --output-as=xml --resource=ping-clone" test_assert_validate $CRM_EX_OK 0 desc="Complete text output filtered by clone resource instance" cmd="crm_mon -1 --include=all --resource=ping" test_assert $CRM_EX_OK 0 desc="XML output filtered by clone resource instance" cmd="crm_mon --output-as=xml --resource=ping" test_assert_validate $CRM_EX_OK 0 desc="Complete text output filtered by exact clone resource instance" cmd="crm_mon -1 --include=all --show-detail --resource=ping:0" test_assert $CRM_EX_OK 0 desc="XML output filtered by exact clone resource instance" cmd="crm_mon --output-as=xml --resource=ping:1" test_assert_validate $CRM_EX_OK 0 desc="Basic text output filtered by resource that doesn't exist" cmd="crm_mon -1 --resource=blah" test_assert $CRM_EX_OK 0 desc="XML output filtered by resource that doesn't exist" cmd="crm_mon --output-as=xml --resource=blah" test_assert_validate $CRM_EX_OK 0 desc="Basic text output with inactive resources, filtered by tag" cmd="crm_mon -1 -r --resource=inactive-rscs" test_assert $CRM_EX_OK 0 desc="Basic text output with inactive resources, filtered by bundle resource" cmd="crm_mon -1 -r --resource=httpd-bundle" test_assert $CRM_EX_OK 0 desc="XML output filtered by inactive bundle resource" cmd="crm_mon --output-as=xml --resource=httpd-bundle" test_assert_validate $CRM_EX_OK 0 desc="Basic text output with inactive resources, filtered by bundled IP address resource" cmd="crm_mon -1 -r --resource=httpd-bundle-ip-192.168.122.131" test_assert $CRM_EX_OK 0 desc="XML output filtered by bundled IP address resource" cmd="crm_mon --output-as=xml --resource=httpd-bundle-ip-192.168.122.132" test_assert_validate $CRM_EX_OK 0 desc="Basic text output with inactive resources, filtered by bundled container" cmd="crm_mon -1 -r --resource=httpd-bundle-docker-1" test_assert $CRM_EX_OK 0 desc="XML output filtered by bundled container" cmd="crm_mon --output-as=xml --resource=httpd-bundle-docker-2" test_assert_validate $CRM_EX_OK 0 desc="Basic text output with inactive resources, filtered by bundle connection" cmd="crm_mon -1 -r --resource=httpd-bundle-0" test_assert $CRM_EX_OK 0 desc="XML output filtered by bundle connection" cmd="crm_mon --output-as=xml --resource=httpd-bundle-0" test_assert_validate $CRM_EX_OK 0 desc="Basic text output with inactive resources, filtered by bundled primitive resource" cmd="crm_mon -1 -r --resource=httpd" test_assert $CRM_EX_OK 0 desc="XML output filtered by bundled primitive resource" cmd="crm_mon --output-as=xml --resource=httpd" test_assert_validate $CRM_EX_OK 0 desc="Complete text output, filtered by clone name in cloned group" cmd="crm_mon -1 --include=all --show-detail --resource=mysql-clone-group" test_assert $CRM_EX_OK 0 desc="XML output, filtered by clone name in cloned group" cmd="crm_mon --output-as=xml --resource=mysql-clone-group" test_assert_validate $CRM_EX_OK 0 desc="Complete text output, filtered by group name in cloned group" cmd="crm_mon -1 --include=all --show-detail --resource=mysql-group" test_assert $CRM_EX_OK 0 desc="XML output, filtered by group name in cloned group" cmd="crm_mon --output-as=xml --resource=mysql-group" test_assert_validate $CRM_EX_OK 0 desc="Complete text output, filtered by exact group instance name in cloned group" cmd="crm_mon -1 --include=all --show-detail --resource=mysql-group:1" test_assert $CRM_EX_OK 0 desc="XML output, filtered by exact group instance name in cloned group" cmd="crm_mon --output-as=xml --resource=mysql-group:1" test_assert_validate $CRM_EX_OK 0 desc="Complete text output, filtered by primitive name in cloned group" cmd="crm_mon -1 --include=all --show-detail --resource=mysql-proxy" test_assert $CRM_EX_OK 0 desc="XML output, filtered by primitive name in cloned group" cmd="crm_mon --output-as=xml --resource=mysql-proxy" test_assert_validate $CRM_EX_OK 0 desc="Complete text output, filtered by exact primitive instance name in cloned group" cmd="crm_mon -1 --include=all --show-detail --resource=mysql-proxy:1" test_assert $CRM_EX_OK 0 desc="XML output, filtered by exact primitive instance name in cloned group" cmd="crm_mon --output-as=xml --resource=mysql-proxy:1" test_assert_validate $CRM_EX_OK 0 unset CIB_file export CIB_file="$test_home/cli/crm_mon-partial.xml" desc="Text output of partially active resources" cmd="crm_mon -1 --show-detail" test_assert $CRM_EX_OK 0 desc="XML output of partially active resources" cmd="crm_mon -1 --output-as=xml" test_assert_validate $CRM_EX_OK 0 desc="Text output of partially active resources, with inactive resources" cmd="crm_mon -1 -r --show-detail" test_assert $CRM_EX_OK 0 # XML already includes inactive resources desc="Complete brief text output, with inactive resources" cmd="crm_mon -1 -r --include=all --brief --show-detail" test_assert $CRM_EX_OK 0 # XML does not have a brief output option desc="Text output of partially active group" cmd="crm_mon -1 --resource=partially-active-group" test_assert $CRM_EX_OK 0 desc="Text output of partially active group, with inactive resources" cmd="crm_mon -1 --resource=partially-active-group -r" test_assert $CRM_EX_OK 0 desc="Text output of active member of partially active group" cmd="crm_mon -1 --resource=dummy-1" test_assert $CRM_EX_OK 0 desc="Text output of inactive member of partially active group" cmd="crm_mon -1 --resource=dummy-2 --show-detail" test_assert $CRM_EX_OK 0 desc="Complete brief text output grouped by node, with inactive resources" cmd="crm_mon -1 -r --include=all --group-by-node --brief --show-detail" test_assert $CRM_EX_OK 0 desc="Text output of partially active resources, with inactive resources, filtered by node" cmd="crm_mon -1 -r --node=cluster01" test_assert $CRM_EX_OK 0 desc="Text output of partially active resources, filtered by node" cmd="crm_mon -1 --output-as=xml --node=cluster01" test_assert_validate $CRM_EX_OK 0 unset CIB_file export CIB_file="$test_home/cli/crm_mon-unmanaged.xml" desc="Text output of active unmanaged resource on offline node" cmd="crm_mon -1" test_assert $CRM_EX_OK 0 desc="XML output of active unmanaged resource on offline node" cmd="crm_mon -1 --output-as=xml" test_assert $CRM_EX_OK 0 desc="Brief text output of active unmanaged resource on offline node" cmd="crm_mon -1 --brief" test_assert $CRM_EX_OK 0 desc="Brief text output of active unmanaged resource on offline node, grouped by node" cmd="crm_mon -1 --brief --group-by-node" test_assert $CRM_EX_OK 0 # Maintenance mode tests export CIB_file=$(mktemp ${TMPDIR:-/tmp}/cts-cli.crm_mon.xml.XXXXXXXXXX) cp "$test_home/cli/crm_mon.xml" "$CIB_file" crm_attribute -n maintenance-mode -v true desc="Text output of all resources with maintenance-mode enabled" cmd="crm_mon -1 -r" test_assert $CRM_EX_OK 0 desc="XML output of all resources with maintenance-mode enabled" cmd="crm_mon -1 -r --output-as=xml" test_assert_validate $CRM_EX_OK 0 crm_attribute -n maintenance-mode -v false crm_attribute -n maintenance -N cluster02 -v true desc="Text output of all resources with maintenance enabled for a node" cmd="crm_mon -1 -r" test_assert $CRM_EX_OK 0 desc="XML output of all resources with maintenance enabled for a node" cmd="crm_mon -1 -r --output-as=xml" test_assert_validate $CRM_EX_OK 0 rm -f "$CIB_file" unset CIB_file export CIB_file="$test_home/cli/crm_mon-rsc-maint.xml" # The fence resource is excluded, for comparison desc="Text output of all resources with maintenance meta attribute true" cmd="crm_mon -1 -r" test_assert $CRM_EX_OK 0 desc="XML output of all resources with maintenance meta attribute true" cmd="crm_mon -1 -r --output-as=xml" test_assert_validate $CRM_EX_OK 0 unset CIB_file export CIB_file="$test_home/cli/crm_mon-T180.xml" desc="Text output of guest node's container on different node from its" desc="$desc remote resource" cmd="crm_mon -1" test_assert $CRM_EX_OK 0 desc="Complete text output of guest node's container on different node from" desc="$desc its remote resource" cmd="crm_mon -1 --show-detail" test_assert $CRM_EX_OK 0 unset CIB_file } function test_error_codes() { # Note: At the time of this writing, crm_error returns success even for # unknown error codes. We don't want to cause a regression by changing that. # Due to the way _test_assert() formats output, we need "crm_error" to be # the first token of cmd. We can't start with a parenthesis or variable # assignment. However, in the "list result codes" tests, we also need to # save some output for later processing. We'll use a temp file for this. local TMPFILE TMPFILE=$(mktemp ${TMPDIR:-/tmp}/cts-cli.crm_error_out.XXXXXXXXXX) # Legacy return codes # # Don't test unknown legacy code. FreeBSD includes a colon in strerror(), # while other distros do not. desc="Get legacy return code" cmd="crm_error -- 201" test_assert $CRM_EX_OK 0 desc="Get legacy return code (XML)" cmd="crm_error --output-as=xml -- 201" test_assert_validate $CRM_EX_OK 0 desc="Get legacy return code (with name)" cmd="crm_error -n -- 201" test_assert $CRM_EX_OK 0 desc="Get legacy return code (with name) (XML)" cmd="crm_error -n --output-as=xml -- 201" test_assert_validate $CRM_EX_OK 0 desc="Get multiple legacy return codes" cmd="crm_error -- 201 202" test_assert $CRM_EX_OK 0 desc="Get multiple legacy return codes (XML)" cmd="crm_error --output-as=xml -- 201 202" test_assert_validate $CRM_EX_OK 0 desc="Get multiple legacy return codes (with names)" cmd="crm_error -n -- 201 202" test_assert $CRM_EX_OK 0 desc="Get multiple legacy return codes (with names) (XML)" cmd="crm_error -n --output-as=xml -- 201 202" test_assert_validate $CRM_EX_OK 0 # We can only rely on our custom codes, so we'll spot-check codes 201-209 desc="List legacy return codes (spot check)" cmd="crm_error -l | grep 20[1-9]" test_assert $CRM_EX_OK 0 desc="List legacy return codes (spot check) (XML)" cmd="crm_error -l --output-as=xml > $TMPFILE; rc=$?" cmd="$cmd; grep -Ev ' "$TMPORIG" desc="Set cluster option" cmd="crm_attribute -n cluster-delay -v 60s" test_assert $CRM_EX_OK desc="Query new cluster option" cmd="cibadmin -Q -o crm_config | grep cib-bootstrap-options-cluster-delay" test_assert $CRM_EX_OK desc="Query cluster options" cmd="cibadmin -Q -o crm_config > $TMPXML" test_assert $CRM_EX_OK desc="Set no-quorum policy" cmd="crm_attribute -n no-quorum-policy -v ignore" test_assert $CRM_EX_OK desc="Delete nvpair" cmd="cibadmin -D -o crm_config --xml-text ''" test_assert $CRM_EX_OK desc="Create operation should fail" cmd="cibadmin -C -o crm_config --xml-file $TMPXML" test_assert $CRM_EX_EXISTS desc="Modify cluster options section" cmd="cibadmin -M -o crm_config --xml-file $TMPXML" test_assert $CRM_EX_OK desc="Query updated cluster option" cmd="cibadmin -Q -o crm_config | grep cib-bootstrap-options-cluster-delay" test_assert $CRM_EX_OK desc="Set duplicate cluster option" cmd="crm_attribute -n cluster-delay -v 40s -s duplicate" test_assert $CRM_EX_OK desc="Setting multiply defined cluster option should fail" cmd="crm_attribute -n cluster-delay -v 30s" test_assert $CRM_EX_MULTIPLE desc="Set cluster option with -s" cmd="crm_attribute -n cluster-delay -v 30s -s duplicate" test_assert $CRM_EX_OK desc="Delete cluster option with -i" cmd="crm_attribute -n cluster-delay -D -i cib-bootstrap-options-cluster-delay" test_assert $CRM_EX_OK desc="Create node1 and bring it online" cmd="crm_simulate --live-check --in-place --node-up=node1" test_assert $CRM_EX_OK desc="Create node attribute" cmd="crm_attribute -n ram -v 1024M -N node1 -t nodes" test_assert $CRM_EX_OK desc="Query new node attribute" cmd="cibadmin -Q -o nodes | grep node1-ram" test_assert $CRM_EX_OK desc="Create second node attribute" cmd="crm_attribute -n rattr -v XYZ -N node1 -t nodes" test_assert $CRM_EX_OK desc="Query node attributes by pattern" cmd="crm_attribute -t nodes -P 'ra.*' -N node1 --query" test_assert $CRM_EX_OK 0 desc="Update node attributes by pattern" cmd="crm_attribute -t nodes -P 'rat.*' -N node1 -v 10" test_assert $CRM_EX_OK desc="Delete node attributes by pattern" cmd="crm_attribute -t nodes -P 'rat.*' -N node1 -D" test_assert $CRM_EX_OK desc="Set a transient (fail-count) node attribute" cmd="crm_attribute -n fail-count-foo -v 3 -N node1 -t status" test_assert $CRM_EX_OK desc="Query a fail count" cmd="crm_failcount --query -r foo -N node1" test_assert $CRM_EX_OK desc="Show node attributes with crm_simulate" cmd="crm_simulate --live-check --show-attrs" test_assert $CRM_EX_OK 0 desc="Set a second transient node attribute" cmd="crm_attribute -n fail-count-bar -v 5 -N node1 -t status" test_assert $CRM_EX_OK desc="Query transient node attributes by pattern" cmd="crm_attribute -t status -P fail-count -N node1 --query" test_assert $CRM_EX_OK 0 desc="Update transient node attributes by pattern" cmd="crm_attribute -t status -P fail-count -N node1 -v 10" test_assert $CRM_EX_OK desc="Delete transient node attributes by pattern" cmd="crm_attribute -t status -P fail-count -N node1 -D" test_assert $CRM_EX_OK desc="crm_attribute given invalid delete usage" cmd="crm_attribute -t nodes -N node1 -D" test_assert $CRM_EX_USAGE 0 desc="Set a utilization node attribute" cmd="crm_attribute -n cpu -v 1 -N node1 -z" test_assert $CRM_EX_OK desc="Query utilization node attribute" cmd="crm_attribute --query -n cpu -N node1 -z" test_assert $CRM_EX_OK 0 desc="Digest calculation" cmd="cibadmin -Q | cibadmin -5 -p 2>&1 > /dev/null" test_assert $CRM_EX_OK # This update will fail because it has version numbers desc="Replace operation should fail" cmd="cibadmin -R --xml-file $TMPORIG" test_assert $CRM_EX_OLD desc="Default standby value" cmd="crm_standby -N node1 -G" test_assert $CRM_EX_OK desc="Set standby status" cmd="crm_standby -N node1 -v true" test_assert $CRM_EX_OK desc="Query standby value" cmd="crm_standby -N node1 -G" test_assert $CRM_EX_OK desc="Delete standby value" cmd="crm_standby -N node1 -D" test_assert $CRM_EX_OK desc="Create a resource" cmd="cibadmin -C -o resources --xml-text ''" test_assert $CRM_EX_OK desc="crm_resource run with extra arguments" cmd="crm_resource foo bar" test_assert $CRM_EX_USAGE 0 desc="crm_resource given both -r and resource config" cmd="crm_resource -r xyz --class ocf --provider pacemaker --agent Dummy" test_assert $CRM_EX_USAGE 0 desc="crm_resource given resource config with invalid action" cmd="crm_resource --class ocf --provider pacemaker --agent Dummy -D" test_assert $CRM_EX_USAGE 0 desc="Create a resource meta attribute" cmd="crm_resource -r dummy --meta -p is-managed -v false" test_assert $CRM_EX_OK desc="Query a resource meta attribute" cmd="crm_resource -r dummy --meta -g is-managed" test_assert $CRM_EX_OK desc="Remove a resource meta attribute" cmd="crm_resource -r dummy --meta -d is-managed" test_assert $CRM_EX_OK desc="Create another resource meta attribute" cmd="crm_resource -r dummy --meta -p target-role -v Stopped --output-as=xml" test_assert_validate $CRM_EX_OK 0 desc="Show why a resource is not running" cmd="crm_resource -Y -r dummy --output-as=xml" test_assert_validate $CRM_EX_OK 0 desc="Remove another resource meta attribute" cmd="crm_resource -r dummy --meta -d target-role --output-as=xml" test_assert_validate $CRM_EX_OK 0 desc="Get a non-existent attribute from a resource element with output-as=xml" cmd="crm_resource -r dummy --get-parameter nonexistent --element --output-as=xml" test_assert_validate $CRM_EX_OK 0 desc="Get a non-existent attribute from a resource element without output-as=xml" cmd="crm_resource -r dummy --get-parameter nonexistent --element" test_assert $CRM_EX_OK desc="Get an existent attribute from a resource element with output-as=xml" cmd="crm_resource -r dummy --get-parameter class --element --output-as=xml" test_assert_validate $CRM_EX_OK 0 desc="Get an existent attribute from a resource element without output-as=xml" cmd="crm_resource -r dummy --get-parameter class --element" test_assert $CRM_EX_OK desc="Set a non-existent attribute for a resource element with output-as=xml" cmd="crm_resource -r dummy --set-parameter=description -v test_description --element --output-as=xml" test_assert $CRM_EX_OK desc="Set an existent attribute for a resource element with output-as=xml" cmd="crm_resource -r dummy --set-parameter=description -v test_description --element --output-as=xml" test_assert $CRM_EX_OK desc="Delete an existent attribute for a resource element with output-as=xml" cmd="crm_resource -r dummy -d description --element --output-as=xml" test_assert $CRM_EX_OK desc="Delete a non-existent attribute for a resource element with output-as=xml" cmd="crm_resource -r dummy -d description --element --output-as=xml" test_assert $CRM_EX_OK desc="Set a non-existent attribute for a resource element without output-as=xml" cmd="crm_resource -r dummy --set-parameter=description -v test_description --element" test_assert $CRM_EX_OK desc="Set an existent attribute for a resource element without output-as=xml" cmd="crm_resource -r dummy --set-parameter=description -v test_description --element" test_assert $CRM_EX_OK desc="Delete an existent attribute for a resource element without output-as=xml" cmd="crm_resource -r dummy -d description --element" test_assert $CRM_EX_OK desc="Delete a non-existent attribute for a resource element without output-as=xml" cmd="crm_resource -r dummy -d description --element" test_assert $CRM_EX_OK desc="Create a resource attribute" cmd="crm_resource -r dummy -p delay -v 10s" test_assert $CRM_EX_OK desc="List the configured resources" cmd="crm_resource -L" test_assert $CRM_EX_OK desc="List the configured resources in XML" cmd="crm_resource -L --output-as=xml" test_assert_validate $CRM_EX_OK 0 desc="Implicitly list the configured resources" cmd="crm_resource" test_assert $CRM_EX_OK 0 desc="List IDs of instantiated resources" cmd="crm_resource -l" test_assert $CRM_EX_OK 0 desc="Show XML configuration of resource" cmd="crm_resource -q -r dummy" test_assert $CRM_EX_OK 0 desc="Show XML configuration of resource, output as XML" cmd="crm_resource -q -r dummy --output-as=xml" test_assert $CRM_EX_OK 0 desc="Require a destination when migrating a resource that is stopped" cmd="crm_resource -r dummy -M" test_assert $CRM_EX_USAGE desc="Don't support migration to non-existent locations" cmd="crm_resource -r dummy -M -N i.do.not.exist" test_assert $CRM_EX_NOSUCH desc="Create a fencing resource" cmd="cibadmin -C -o resources --xml-text ''" test_assert $CRM_EX_OK desc="Bring resources online" cmd="crm_simulate --live-check --in-place -S" test_assert $CRM_EX_OK desc="Try to move a resource to its existing location" cmd="crm_resource -r dummy --move --node node1" test_assert $CRM_EX_EXISTS desc="Try to move a resource that doesn't exist" cmd="crm_resource -r xyz --move --node node1" test_assert $CRM_EX_NOSUCH 0 desc="Move a resource from its existing location" cmd="crm_resource -r dummy --move" test_assert $CRM_EX_OK desc="Clear out constraints generated by --move" cmd="crm_resource -r dummy --clear" test_assert $CRM_EX_OK desc="Default ticket granted state" cmd="crm_ticket -t ticketA -G granted -d false" test_assert $CRM_EX_OK desc="Set ticket granted state" cmd="crm_ticket -t ticketA -r --force" test_assert $CRM_EX_OK desc="Query ticket granted state" cmd="crm_ticket -t ticketA -G granted" test_assert $CRM_EX_OK desc="Delete ticket granted state" cmd="crm_ticket -t ticketA -D granted --force" test_assert $CRM_EX_OK desc="Make a ticket standby" cmd="crm_ticket -t ticketA -s" test_assert $CRM_EX_OK desc="Query ticket standby state" cmd="crm_ticket -t ticketA -G standby" test_assert $CRM_EX_OK desc="Activate a ticket" cmd="crm_ticket -t ticketA -a" test_assert $CRM_EX_OK desc="Delete ticket standby state" cmd="crm_ticket -t ticketA -D standby" test_assert $CRM_EX_OK desc="Ban a resource on unknown node" cmd="crm_resource -r dummy -B -N host1" test_assert $CRM_EX_NOSUCH desc="Create two more nodes and bring them online" cmd="crm_simulate --live-check --in-place --node-up=node2 --node-up=node3" test_assert $CRM_EX_OK desc="Ban dummy from node1" cmd="crm_resource -r dummy -B -N node1" test_assert $CRM_EX_OK desc="Show where a resource is running" cmd="crm_resource -r dummy -W" test_assert $CRM_EX_OK 0 desc="Show constraints on a resource" cmd="crm_resource -a -r dummy" test_assert $CRM_EX_OK 0 desc="Ban dummy from node2" cmd="crm_resource -r dummy -B -N node2 --output-as=xml" test_assert_validate $CRM_EX_OK desc="Relocate resources due to ban" cmd="crm_simulate --live-check --in-place -S" test_assert $CRM_EX_OK desc="Move dummy to node1" cmd="crm_resource -r dummy -M -N node1 --output-as=xml" test_assert_validate $CRM_EX_OK desc="Clear implicit constraints for dummy on node2" cmd="crm_resource -r dummy -U -N node2" test_assert $CRM_EX_OK desc="Drop the status section" cmd="cibadmin -R -o status --xml-text ''" test_assert $CRM_EX_OK 0 desc="Create a clone" cmd="cibadmin -C -o resources --xml-text ''" test_assert $CRM_EX_OK 0 desc="Create a resource meta attribute" cmd="crm_resource -r test-primitive --meta -p is-managed -v false" test_assert $CRM_EX_OK desc="Create a resource meta attribute in the primitive" cmd="crm_resource -r test-primitive --meta -p is-managed -v false --force" test_assert $CRM_EX_OK desc="Update resource meta attribute with duplicates" cmd="crm_resource -r test-clone --meta -p is-managed -v true" test_assert $CRM_EX_OK desc="Update resource meta attribute with duplicates (force clone)" cmd="crm_resource -r test-clone --meta -p is-managed -v true --force" test_assert $CRM_EX_OK desc="Update child resource meta attribute with duplicates" cmd="crm_resource -r test-primitive --meta -p is-managed -v false" test_assert $CRM_EX_OK desc="Delete resource meta attribute with duplicates" cmd="crm_resource -r test-clone --meta -d is-managed" test_assert $CRM_EX_OK desc="Delete resource meta attribute in parent" cmd="crm_resource -r test-primitive --meta -d is-managed" test_assert $CRM_EX_OK desc="Create a resource meta attribute in the primitive" cmd="crm_resource -r test-primitive --meta -p is-managed -v false --force" test_assert $CRM_EX_OK desc="Update existing resource meta attribute" cmd="crm_resource -r test-clone --meta -p is-managed -v true" test_assert $CRM_EX_OK desc="Create a resource meta attribute in the parent" cmd="crm_resource -r test-clone --meta -p is-managed -v true --force" test_assert $CRM_EX_OK desc="Copy resources" cmd="cibadmin -Q -o resources > $TMPXML" test_assert $CRM_EX_OK 0 desc="Delete resource parent meta attribute (force)" cmd="crm_resource -r test-clone --meta -d is-managed --force" test_assert $CRM_EX_OK desc="Restore duplicates" cmd="cibadmin -R -o resources --xml-file $TMPXML" test_assert $CRM_EX_OK desc="Delete resource child meta attribute" cmd="crm_resource -r test-primitive --meta -d is-managed" test_assert $CRM_EX_OK desc="Create the dummy-group resource group" cmd="cibadmin -C -o resources --xml-text '" cmd="$cmd " cmd="$cmd " cmd="$cmd '" test_assert $CRM_EX_OK desc="Create a resource meta attribute in dummy1" cmd="crm_resource -r dummy1 --meta -p is-managed -v true" test_assert $CRM_EX_OK desc="Create a resource meta attribute in dummy-group" cmd="crm_resource -r dummy-group --meta -p is-managed -v false" test_assert $CRM_EX_OK desc="Delete the dummy-group resource group" cmd="cibadmin -D -o resources --xml-text ''" test_assert $CRM_EX_OK desc="Specify a lifetime when moving a resource" cmd="crm_resource -r dummy --move --node node2 --lifetime=PT1H" test_assert $CRM_EX_OK desc="Try to move a resource previously moved with a lifetime" cmd="crm_resource -r dummy --move --node node1" test_assert $CRM_EX_OK desc="Ban dummy from node1 for a short time" cmd="crm_resource -r dummy -B -N node1 --lifetime=PT1S" test_assert $CRM_EX_OK desc="Remove expired constraints" sleep 2 cmd="crm_resource --clear --expired" test_assert $CRM_EX_OK # Clear has already been tested elsewhere, but we need to get rid of the # constraints so testing delete works. It won't delete if there's still # a reference to the resource somewhere. desc="Clear all implicit constraints for dummy" cmd="crm_resource -r dummy -U" test_assert $CRM_EX_OK desc="Set a node health strategy" cmd="crm_attribute -n node-health-strategy -v migrate-on-red" test_assert $CRM_EX_OK desc="Set a node health attribute" cmd="crm_attribute -N node3 -n '#health-cts-cli' -v red" test_assert $CRM_EX_OK desc="Show why a resource is not running on an unhealthy node" cmd="crm_resource -N node3 -Y -r dummy --output-as=xml" test_assert_validate $CRM_EX_OK 0 desc="Delete a resource" cmd="crm_resource -D -r dummy -t primitive" test_assert $CRM_EX_OK unset CIB_shadow unset CIB_shadow_dir desc="Create an XML patchset" cmd="crm_diff -o $test_home/cli/crm_diff_old.xml -n $test_home/cli/crm_diff_new.xml" test_assert $CRM_EX_ERROR 0 export CIB_file="$test_home/cli/constraints.xml" for rsc in prim1 prim2 prim3 prim4 prim5 prim6 prim7 prim8 prim9 \ prim10 prim11 prim12 prim13 group clone; do desc="Check locations and constraints for $rsc" cmd="crm_resource -a -r $rsc" test_assert $CRM_EX_OK 0 desc="Recursively check locations and constraints for $rsc" cmd="crm_resource -A -r $rsc" test_assert $CRM_EX_OK 0 desc="Check locations and constraints for $rsc in XML" cmd="crm_resource -a -r $rsc --output-as=xml" test_assert_validate $CRM_EX_OK 0 desc="Recursively check locations and constraints for $rsc in XML" cmd="crm_resource -A -r $rsc --output-as=xml" test_assert_validate $CRM_EX_OK 0 done desc="Check locations and constraints for group member (referring to group)" cmd="crm_resource -a -r gr2" test_assert $CRM_EX_OK 0 desc="Check locations and constraints for group member (without referring to group)" cmd="crm_resource -a -r gr2 --force" test_assert $CRM_EX_OK 0 # Create a shadow CIB based on constraints.xml create_shadow_cib --create unset CIB_file desc="Set a meta-attribute for primitive and resources colocated with it" cmd="crm_resource -r prim5 --meta --set-parameter=target-role -v Stopped --recursive" test_assert $CRM_EX_OK 0 desc="Set a meta-attribute for group and resource colocated with it" cmd="crm_resource -r group --meta --set-parameter=target-role -v Stopped --recursive" test_assert $CRM_EX_OK 0 desc="Set a meta-attribute for clone and resource colocated with it" cmd="crm_resource -r clone --meta --set-parameter=target-role -v Stopped --recursive" test_assert $CRM_EX_OK 0 unset CIB_shadow unset CIB_shadow_dir export CIB_file="$test_home/cli/crm_resource_digests.xml" desc="Show resource digests" cmd="crm_resource --digests -r rsc1 -N node1 --output-as=xml" test_assert_validate $CRM_EX_OK 0 desc="Show resource digests with overrides" cmd="$cmd CRM_meta_interval=10000 CRM_meta_timeout=20000" test_assert $CRM_EX_OK 0 desc="Show resource operations" cmd="crm_resource --list-operations" test_assert $CRM_EX_OK 0 desc="Show resource operations (XML)" cmd="crm_resource --list-operations --output-as=xml" test_assert_validate $CRM_EX_OK 0 unset CIB_file export CIB_file="$test_home/cli/crmadmin-cluster-remote-guest-nodes.xml" desc="List all nodes" cmd="crmadmin -N" test_assert $CRM_EX_OK 0 desc="Minimally list all nodes" cmd="crmadmin -N -q" test_assert $CRM_EX_OK 0 desc="List all nodes as bash exports" cmd="crmadmin -N -B" test_assert $CRM_EX_OK 0 desc="List cluster nodes" cmd="crmadmin -N cluster | wc -l | grep 6" test_assert $CRM_EX_OK 0 desc="List guest nodes" cmd="crmadmin -N guest | wc -l | grep 2" test_assert $CRM_EX_OK 0 desc="List remote nodes" cmd="crmadmin -N remote | wc -l | grep 3" test_assert $CRM_EX_OK 0 desc="List cluster,remote nodes" cmd="crmadmin -N cluster,remote | wc -l | grep 9" test_assert $CRM_EX_OK 0 desc="List guest,remote nodes" cmd="crmadmin -N guest,remote | wc -l | grep 5" test_assert $CRM_EX_OK 0 unset CIB_file export CIB_file="$test_home/cli/crm_mon.xml" export CIB_shadow_dir="${shadow_dir}" desc="Show allocation scores with crm_simulate" cmd="crm_simulate -x $CIB_file --show-scores --output-as=xml" test_assert_validate $CRM_EX_OK 0 desc="Show utilization with crm_simulate" cmd="crm_simulate -x $CIB_file --show-utilization" test_assert $CRM_EX_OK 0 desc="Simulate injecting a failure" cmd="crm_simulate -x $CIB_file -S -i ping_monitor_10000@cluster02=1" test_assert $CRM_EX_OK 0 desc="Simulate bringing a node down" cmd="crm_simulate -x $CIB_file -S --node-down=cluster01" test_assert $CRM_EX_OK 0 desc="Simulate a node failing" cmd="crm_simulate -x $CIB_file -S --node-fail=cluster02" test_assert $CRM_EX_OK 0 unset CIB_shadow_dir desc="List a promotable clone resource" cmd="crm_resource --locate -r promotable-clone" test_assert $CRM_EX_OK 0 desc="List the primitive of a promotable clone resource" cmd="crm_resource --locate -r promotable-rsc" test_assert $CRM_EX_OK 0 desc="List a single instance of a promotable clone resource" cmd="crm_resource --locate -r promotable-rsc:0" test_assert $CRM_EX_OK 0 desc="List another instance of a promotable clone resource" cmd="crm_resource --locate -r promotable-rsc:1" test_assert $CRM_EX_OK 0 desc="List a promotable clone resource in XML" cmd="crm_resource --locate -r promotable-clone --output-as=xml" test_assert_validate $CRM_EX_OK 0 desc="List the primitive of a promotable clone resource in XML" cmd="crm_resource --locate -r promotable-rsc --output-as=xml" test_assert_validate $CRM_EX_OK 0 desc="List a single instance of a promotable clone resource in XML" cmd="crm_resource --locate -r promotable-rsc:0 --output-as=xml" test_assert_validate $CRM_EX_OK 0 desc="List another instance of a promotable clone resource in XML" cmd="crm_resource --locate -r promotable-rsc:1 --output-as=xml" test_assert_validate $CRM_EX_OK 0 desc="Try to move an instance of a cloned resource" cmd="crm_resource -r promotable-rsc:0 --move --node node1" test_assert $CRM_EX_INVALID_PARAM 0 # Create a sandbox copy of crm_mon.xml cibadmin -Q > "$TMPXML" export CIB_file="$TMPXML" desc="Query a nonexistent promotable score attribute" cmd="crm_attribute -N cluster01 -p promotable-rsc -G" test_assert $CRM_EX_NOSUCH 0 desc="Query a nonexistent promotable score attribute (XML)" cmd="crm_attribute -N cluster01 -p promotable-rsc -G --output-as=xml" test_assert_validate $CRM_EX_NOSUCH 0 desc="Delete a nonexistent promotable score attribute" cmd="crm_attribute -N cluster01 -p promotable-rsc -D" test_assert $CRM_EX_OK 0 desc="Delete a nonexistent promotable score attribute (XML)" cmd="crm_attribute -N cluster01 -p promotable-rsc -D --output-as=xml" test_assert_validate $CRM_EX_OK 0 desc="Query after deleting a nonexistent promotable score attribute" cmd="crm_attribute -N cluster01 -p promotable-rsc -G" test_assert $CRM_EX_NOSUCH 0 desc="Query after deleting a nonexistent promotable score attribute (XML)" cmd="crm_attribute -N cluster01 -p promotable-rsc -G --output-as=xml" test_assert_validate $CRM_EX_NOSUCH 0 desc="Update a nonexistent promotable score attribute" cmd="crm_attribute -N cluster01 -p promotable-rsc -v 1" test_assert $CRM_EX_OK 0 desc="Update a nonexistent promotable score attribute (XML)" cmd="crm_attribute -N cluster01 -p promotable-rsc -v 1 --output-as=xml" test_assert_validate $CRM_EX_OK 0 desc="Query after updating a nonexistent promotable score attribute" cmd="crm_attribute -N cluster01 -p promotable-rsc -G" test_assert $CRM_EX_OK 0 desc="Query after updating a nonexistent promotable score attribute (XML)" cmd="crm_attribute -N cluster01 -p promotable-rsc -G --output-as=xml" test_assert_validate $CRM_EX_OK 0 desc="Update an existing promotable score attribute" cmd="crm_attribute -N cluster01 -p promotable-rsc -v 5" test_assert $CRM_EX_OK 0 desc="Update an existing promotable score attribute (XML)" cmd="crm_attribute -N cluster01 -p promotable-rsc -v 5 --output-as=xml" test_assert_validate $CRM_EX_OK 0 desc="Query after updating an existing promotable score attribute" cmd="crm_attribute -N cluster01 -p promotable-rsc -G" test_assert $CRM_EX_OK 0 desc="Query after updating an existing promotable score attribute (XML)" cmd="crm_attribute -N cluster01 -p promotable-rsc -G --output-as=xml" test_assert_validate $CRM_EX_OK 0 desc="Delete an existing promotable score attribute" cmd="crm_attribute -N cluster01 -p promotable-rsc -D" test_assert $CRM_EX_OK 0 desc="Delete an existing promotable score attribute (XML)" cmd="crm_attribute -N cluster01 -p promotable-rsc -D --output-as=xml" test_assert_validate $CRM_EX_OK 0 desc="Query after deleting an existing promotable score attribute" cmd="crm_attribute -N cluster01 -p promotable-rsc -G" test_assert $CRM_EX_NOSUCH 0 desc="Query after deleting an existing promotable score attribute (XML)" cmd="crm_attribute -N cluster01 -p promotable-rsc -G --output-as=xml" test_assert_validate $CRM_EX_NOSUCH 0 # Test for an issue with legacy command line parsing when the resource is # specified in the environment (CLBZ#5509) export OCF_RESOURCE_INSTANCE=promotable-rsc desc="Update a promotable score attribute to -INFINITY" cmd="crm_attribute -N cluster01 -p -v -INFINITY" test_assert $CRM_EX_OK 0 desc="Update a promotable score attribute to -INFINITY (XML)" cmd="crm_attribute -N cluster01 -p -v -INFINITY --output-as=xml" test_assert $CRM_EX_OK 0 desc="Query after updating a promotable score attribute to -INFINITY" cmd="crm_attribute -N cluster01 -p -G" test_assert $CRM_EX_OK 0 desc="Query after updating a promotable score attribute to -INFINITY (XML)" cmd="crm_attribute -N cluster01 -p -G --output-as=xml" test_assert $CRM_EX_OK 0 desc="Try OCF_RESOURCE_INSTANCE if -p is specified with an empty string" cmd="crm_attribute -N cluster01 -p '' -G" test_assert $CRM_EX_OK 0 export OCF_RESOURCE_INSTANCE="" desc="Return usage error if both -p and OCF_RESOURCE_INSTANCE are empty strings" cmd="crm_attribute -N cluster01 -p '' -G" test_assert $CRM_EX_USAGE 0 unset CIB_file unset OCF_RESOURCE_INSTANCE export CIB_file="-" desc="Check that CIB_file=\"-\" works - crm_mon" cmd="cat $test_home/cli/crm_mon.xml | crm_mon -1" test_assert $CRM_EX_OK 0 desc="Check that CIB_file=\"-\" works - crm_resource" cmd="cat $test_home/cli/crm_resource_digests.xml | crm_resource --digests -r rsc1 -N node1 --output-as=xml" test_assert_validate $CRM_EX_OK 0 desc="Check that CIB_file=\"-\" works - crmadmin" cmd="cat $test_home/cli/crmadmin-cluster-remote-guest-nodes.xml | crmadmin -N | wc -l | grep 11" test_assert $CRM_EX_OK 0 unset CIB_file rm -f "$TMPXML" "$TMPORIG" # crm_shadow tests unset CIB_shadow unset CIB_shadow_dir # Query with no active shadow instance desc="Get active shadow instance (no active instance)" cmd="crm_shadow --which" test_assert $CRM_EX_NOSUCH 0 desc="Get active shadow instance (no active instance) (XML)" cmd="crm_shadow --which --output-as=xml" test_assert_validate $CRM_EX_NOSUCH 0 desc="Get active shadow instance's file name (no active instance)" cmd="crm_shadow --file" test_assert $CRM_EX_NOSUCH 0 desc="Get active shadow instance's file name (no active instance) (XML)" cmd="crm_shadow --file --output-as=xml" test_assert_validate $CRM_EX_NOSUCH 0 desc="Get active shadow instance's contents (no active instance)" cmd="crm_shadow --display" test_assert $CRM_EX_NOSUCH 0 desc="Get active shadow instance's contents (no active instance) (XML)" cmd="crm_shadow --display --output-as=xml" test_assert_validate $CRM_EX_NOSUCH 0 desc="Get active shadow instance's diff (no active instance)" cmd="crm_shadow --diff" test_assert $CRM_EX_NOSUCH 0 desc="Get active shadow instance's diff (no active instance) (XML)" cmd="crm_shadow --diff --output-as=xml" test_assert_validate $CRM_EX_NOSUCH 0 # Create new shadow instance based on active CIB # Don't use create_shadow_cib() here; test explicitly export CIB_file="$test_home/cli/crm_mon.xml" export CIB_shadow="$shadow" export CIB_shadow_dir="$shadow_dir" # Delete the shadow file if it already exists crm_shadow --delete "$shadow" --force >/dev/null 2>&1 desc="Create copied shadow instance" cmd="crm_shadow --create $shadow --batch" test_assert $CRM_EX_OK 0 crm_shadow --delete "$shadow" --force >/dev/null 2>&1 desc="Create copied shadow instance (XML)" cmd="crm_shadow --create $shadow --batch --output-as=xml" test_assert_validate $CRM_EX_OK 0 # Query shadow instance based on active CIB desc="Get active shadow instance (copied)" cmd="crm_shadow --which" test_assert $CRM_EX_OK 0 desc="Get active shadow instance (copied) (XML)" cmd="crm_shadow --which --output-as=xml" test_assert_validate $CRM_EX_OK 0 desc="Get active shadow instance's file name (copied)" cmd="crm_shadow --file" test_assert $CRM_EX_OK 0 desc="Get active shadow instance's file name (copied) (XML)" cmd="crm_shadow --file --output-as=xml" test_assert_validate $CRM_EX_OK 0 desc="Get active shadow instance's contents (copied)" cmd="crm_shadow --display" test_assert $CRM_EX_OK 0 desc="Get active shadow instance's contents (copied) (XML)" cmd="crm_shadow --display --output-as=xml" test_assert_validate $CRM_EX_OK 0 desc="Get active shadow instance's diff (copied)" cmd="crm_shadow --diff" test_assert $CRM_EX_OK 0 desc="Get active shadow instance's diff (copied) (XML)" cmd="crm_shadow --diff --output-as=xml" test_assert_validate $CRM_EX_OK 0 # Make some changes to the shadow file export CIB_file="$(crm_shadow --file)" cibadmin --modify --xml-text '' cibadmin --delete --xml-text '' cibadmin --create -o resources --xml-text \ '' state="" cibadmin --create -o status --xml-text "$state" unset state export CIB_file="$test_home/cli/crm_mon.xml" desc="Get active shadow instance's diff (after changes)" cmd="crm_shadow --diff" test_assert $CRM_EX_ERROR 0 desc="Get active shadow instance's diff (after changes) (XML)" cmd="crm_shadow --diff --output-as=xml" test_assert_validate $CRM_EX_ERROR 0 # Commit the modified shadow CIB to a temp active CIB file cp "$test_home/cli/crm_mon.xml" "$TMPXML" export CIB_file="$TMPXML" desc="Commit shadow instance" cmd="crm_shadow --commit $shadow" test_assert $CRM_EX_USAGE 0 desc="Commit shadow instance (force)" cmd="crm_shadow --commit $shadow --force" test_assert $CRM_EX_OK 0 desc="Get active shadow instance's diff (after commit)" cmd="crm_shadow --diff" test_assert $CRM_EX_ERROR 0 desc="Commit shadow instance (force) (all)" cmd="crm_shadow --commit $shadow --force --all" test_assert $CRM_EX_OK 0 desc="Get active shadow instance's diff (after commit all)" cmd="crm_shadow --diff" test_assert $CRM_EX_ERROR 0 # Repeat sequence with XML output cp "$test_home/cli/crm_mon.xml" "$TMPXML" export CIB_file="$TMPXML" desc="Commit shadow instance (XML)" cmd="crm_shadow --commit $shadow --output-as=xml" test_assert_validate $CRM_EX_USAGE 0 desc="Commit shadow instance (force) (XML)" cmd="crm_shadow --commit $shadow --force --output-as=xml" test_assert_validate $CRM_EX_OK 0 desc="Get active shadow instance's diff (after commit) (XML)" cmd="crm_shadow --diff --output-as=xml" test_assert_validate $CRM_EX_ERROR 0 desc="Commit shadow instance (force) (all) (XML)" cmd="crm_shadow --commit $shadow --force --all --output-as=xml" test_assert_validate $CRM_EX_OK 0 desc="Get active shadow instance's diff (after commit all) (XML)" cmd="crm_shadow --diff --output-as=xml" test_assert_validate $CRM_EX_ERROR 0 # Commit an inactive shadow instance with no active instance unset CIB_shadow desc="Commit shadow instance (no active instance)" cmd="crm_shadow --commit $shadow" test_assert $CRM_EX_USAGE 0 desc="Commit shadow instance (no active instance) (force)" cmd="crm_shadow --commit $shadow --force" test_assert $CRM_EX_OK 0 desc="Commit shadow instance (no active instance) (XML)" cmd="crm_shadow --commit $shadow --output-as=xml" test_assert_validate $CRM_EX_USAGE 0 desc="Commit shadow instance (no active instance) (force) (XML)" cmd="crm_shadow --commit $shadow --force --output-as=xml" test_assert_validate $CRM_EX_OK 0 # Commit an inactive shadow instance with an active instance export CIB_shadow="nonexistent_shadow" desc="Commit shadow instance (mismatch)" cmd="crm_shadow --commit $shadow" test_assert $CRM_EX_USAGE 0 desc="Commit shadow instance (mismatch) (force)" cmd="crm_shadow --commit $shadow --force" test_assert $CRM_EX_OK 0 desc="Commit shadow instance (mismatch) (XML)" cmd="crm_shadow --commit $shadow --output-as=xml" test_assert_validate $CRM_EX_USAGE 0 desc="Commit shadow instance (mismatch) (force) (XML)" cmd="crm_shadow --commit $shadow --force --output-as=xml" test_assert_validate $CRM_EX_OK 0 # Commit an active shadow instance whose shadow file is missing desc="Commit shadow instance (nonexistent shadow file)" cmd="crm_shadow --commit $CIB_shadow" test_assert $CRM_EX_USAGE 0 desc="Commit shadow instance (nonexistent shadow file) (force)" cmd="crm_shadow --commit $CIB_shadow --force" test_assert $CRM_EX_NOSUCH 0 desc="Get active shadow instance's diff (nonexistent shadow file)" cmd="crm_shadow --diff" test_assert $CRM_EX_NOSUCH 0 desc="Commit shadow instance (nonexistent shadow file) (XML)" cmd="crm_shadow --commit $CIB_shadow --output-as=xml" test_assert_validate $CRM_EX_USAGE 0 desc="Commit shadow instance (nonexistent shadow file) (force) (XML)" cmd="crm_shadow --commit $CIB_shadow --force --output-as=xml" test_assert_validate $CRM_EX_NOSUCH 0 desc="Get active shadow instance's diff (nonexistent shadow file) (XML)" cmd="crm_shadow --diff --output-as=xml" test_assert_validate $CRM_EX_NOSUCH 0 # Commit an active shadow instance when the CIB file is missing export CIB_file="$test_home/cli/nonexistent_cib.xml" export CIB_shadow="$shadow" desc="Commit shadow instance (nonexistent CIB file)" cmd="crm_shadow --commit $shadow" test_assert $CRM_EX_USAGE 0 desc="Commit shadow instance (nonexistent CIB file) (force)" cmd="crm_shadow --commit $shadow --force" test_assert $CRM_EX_NOSUCH 0 desc="Get active shadow instance's diff (nonexistent CIB file)" cmd="crm_shadow --diff" test_assert $CRM_EX_NOSUCH 0 desc="Commit shadow instance (nonexistent CIB file) (XML)" cmd="crm_shadow --commit $shadow --output-as=xml" test_assert_validate $CRM_EX_USAGE 0 desc="Commit shadow instance (nonexistent CIB file) (force) (XML)" cmd="crm_shadow --commit $shadow --force --output-as=xml" test_assert_validate $CRM_EX_NOSUCH 0 desc="Get active shadow instance's diff (nonexistent CIB file) (XML)" cmd="crm_shadow --diff --output-as=xml" test_assert_validate $CRM_EX_NOSUCH 0 rm -f "$TMPXML" # Delete an active shadow instance export CIB_file="$test_home/cli/crm_mon.xml" export CIB_shadow="$shadow" desc="Delete shadow instance" cmd="crm_shadow --delete $shadow" test_assert $CRM_EX_USAGE 0 desc="Delete shadow instance (force)" cmd="crm_shadow --delete $shadow --force" test_assert $CRM_EX_OK 0 create_shadow_cib --create desc="Delete shadow instance (XML)" cmd="crm_shadow --delete $shadow --output-as=xml" test_assert_validate $CRM_EX_USAGE 0 desc="Delete shadow instance (force) (XML)" cmd="crm_shadow --delete $shadow --force --output-as=xml" test_assert_validate $CRM_EX_OK 0 # Delete an inactive shadow instance with no active instance create_shadow_cib --create unset CIB_shadow desc="Delete shadow instance (no active instance)" cmd="crm_shadow --delete $shadow" test_assert $CRM_EX_USAGE 0 desc="Delete shadow instance (no active instance) (force)" cmd="crm_shadow --delete $shadow --force" test_assert $CRM_EX_OK 0 create_shadow_cib --create unset CIB_shadow desc="Delete shadow instance (no active instance) (XML)" cmd="crm_shadow --delete $shadow --output-as=xml" test_assert_validate $CRM_EX_USAGE 0 desc="Delete shadow instance (no active instance) (force) (XML)" cmd="crm_shadow --delete $shadow --force --output-as=xml" test_assert_validate $CRM_EX_OK 0 # Delete an inactive shadow instance with an active instance create_shadow_cib --create export CIB_shadow="nonexistent_shadow" desc="Delete shadow instance (mismatch)" cmd="crm_shadow --delete $shadow" test_assert $CRM_EX_USAGE 0 desc="Delete shadow instance (mismatch) (force)" cmd="crm_shadow --delete $shadow --force" test_assert $CRM_EX_OK 0 create_shadow_cib --create export CIB_shadow="nonexistent_shadow" desc="Delete shadow instance (mismatch) (XML)" cmd="crm_shadow --delete $shadow --output-as=xml" test_assert_validate $CRM_EX_USAGE 0 desc="Delete shadow instance (mismatch) (force) (XML)" cmd="crm_shadow --delete $shadow --force --output-as=xml" test_assert_validate $CRM_EX_OK 0 # Delete an active shadow instance whose shadow file is missing desc="Delete shadow instance (nonexistent shadow file)" cmd="crm_shadow --delete $CIB_shadow" test_assert $CRM_EX_USAGE 0 desc="Delete shadow instance (nonexistent shadow file) (force)" cmd="crm_shadow --delete $CIB_shadow --force" test_assert $CRM_EX_OK 0 desc="Delete shadow instance (nonexistent shadow file) (XML)" cmd="crm_shadow --delete $CIB_shadow --output-as=xml" test_assert_validate $CRM_EX_USAGE 0 desc="Delete shadow instance (nonexistent shadow file) (force) (XML)" cmd="crm_shadow --delete $CIB_shadow --force --output-as=xml" test_assert_validate $CRM_EX_OK 0 # Delete an active shadow instance when the CIB file is missing export CIB_file="$test_home/cli/crm_mon.xml" create_shadow_cib --create export CIB_file="$test_home/cli/nonexistent_cib.xml" desc="Delete shadow instance (nonexistent CIB file)" cmd="crm_shadow --delete $shadow" test_assert $CRM_EX_USAGE 0 desc="Delete shadow instance (nonexistent CIB file) (force)" cmd="crm_shadow --delete $shadow --force" test_assert $CRM_EX_OK 0 export CIB_file="$test_home/cli/crm_mon.xml" create_shadow_cib --create export CIB_file="$test_home/cli/nonexistent_cib.xml" desc="Delete shadow instance (nonexistent CIB file) (XML)" cmd="crm_shadow --delete $shadow --output-as=xml" test_assert_validate $CRM_EX_USAGE 0 desc="Delete shadow instance (nonexistent CIB file) (force) (XML)" cmd="crm_shadow --delete $shadow --force --output-as=xml" test_assert_validate $CRM_EX_OK 0 # Create new shadow instance based on active CIB with no instance active export CIB_file="$test_home/cli/crm_mon.xml" crm_shadow --delete "$shadow" --force >/dev/null 2>&1 unset CIB_shadow desc="Create copied shadow instance (no active instance)" cmd="crm_shadow --create $shadow --batch" test_assert $CRM_EX_OK 0 crm_shadow --delete "$shadow" --force >/dev/null 2>&1 unset CIB_shadow desc="Create copied shadow instance (no active instance) (XML)" cmd="crm_shadow --create $shadow --batch --output-as=xml" test_assert_validate $CRM_EX_OK 0 # Create new shadow instance based on active CIB with other instance active export CIB_file="$test_home/cli/crm_mon.xml" export CIB_shadow="nonexistent_shadow" crm_shadow --delete "$shadow" --force >/dev/null 2>&1 desc="Create copied shadow instance (mismatch)" cmd="crm_shadow --create $shadow --batch" test_assert $CRM_EX_OK 0 crm_shadow --delete "$shadow" --force >/dev/null 2>&1 desc="Create copied shadow instance (mismatch) (XML)" cmd="crm_shadow --create $shadow --batch --output-as=xml" test_assert_validate $CRM_EX_OK 0 # Create new shadow instance based on CIB (shadow file already exists) export CIB_file="$test_home/cli/crm_mon.xml" desc="Create copied shadow instance (file already exists)" cmd="crm_shadow --create $shadow --batch" test_assert $CRM_EX_CANTCREAT 0 desc="Create copied shadow instance (file already exists) (force)" cmd="crm_shadow --create $shadow --batch --force" test_assert $CRM_EX_OK 0 desc="Create copied shadow instance (file already exists) (XML)" cmd="crm_shadow --create $shadow --batch --output-as=xml" test_assert_validate $CRM_EX_CANTCREAT 0 desc="Create copied shadow instance (file already exists) (force) (XML)" cmd="crm_shadow --create $shadow --batch --force --output-as=xml" test_assert_validate $CRM_EX_OK 0 # Create new shadow instance based on active CIB when the CIB file is missing export CIB_file="$test_home/cli/nonexistent_cib.xml" export CIB_shadow="$shadow" crm_shadow --delete "$shadow" --force >/dev/null 2>&1 desc="Create copied shadow instance (nonexistent CIB file) (force)" cmd="crm_shadow --create $shadow --batch --force" test_assert $CRM_EX_NOSUCH 0 desc="Create copied shadow instance (nonexistent CIB file) (force) (XML)" cmd="crm_shadow --create $shadow --batch --force --output-as=xml" test_assert_validate $CRM_EX_NOSUCH 0 # Create new empty shadow instance export CIB_shadow="$shadow" crm_shadow --delete "$shadow" --force >/dev/null 2>&1 desc="Create empty shadow instance" cmd="crm_shadow --create-empty $shadow --batch" test_assert $CRM_EX_OK 0 crm_shadow --delete "$shadow" --force >/dev/null 2>&1 desc="Create empty shadow instance (XML)" cmd="crm_shadow --create-empty $shadow --batch --output-as=xml" test_assert_validate $CRM_EX_OK 0 # Create empty shadow instance with no active instance unset CIB_shadow crm_shadow --delete "$shadow" --force >/dev/null 2>&1 desc="Create empty shadow instance (no active instance)" cmd="crm_shadow --create-empty $shadow --batch" test_assert $CRM_EX_OK 0 crm_shadow --delete "$shadow" --force >/dev/null 2>&1 desc="Create empty shadow instance (no active instance) (XML)" cmd="crm_shadow --create-empty $shadow --batch --output-as=xml" test_assert_validate $CRM_EX_OK 0 # Create empty shadow instance with other instance active export CIB_shadow="nonexistent_shadow" crm_shadow --delete "$shadow" --force >/dev/null 2>&1 desc="Create empty shadow instance (mismatch)" cmd="crm_shadow --create-empty $shadow --batch" test_assert $CRM_EX_OK 0 crm_shadow --delete "$shadow" --force >/dev/null 2>&1 desc="Create empty shadow instance (mismatch) (XML)" cmd="crm_shadow --create-empty $shadow --batch --output-as=xml" test_assert_validate $CRM_EX_OK 0 # Create empty shadow instance when the CIB file is missing export CIB_file="$test_home/cli/nonexistent_cib.xml" export CIB_shadow="$shadow" crm_shadow --delete "$shadow" --force >/dev/null 2>&1 desc="Create empty shadow instance (nonexistent CIB file)" cmd="crm_shadow --create-empty $shadow --batch" test_assert $CRM_EX_OK 0 crm_shadow --delete "$shadow" --force >/dev/null 2>&1 desc="Create empty shadow instance (nonexistent CIB file) (XML)" cmd="crm_shadow --create-empty $shadow --batch --force --output-as=xml" test_assert_validate $CRM_EX_OK 0 # Create empty shadow instance (shadow file already exists) export CIB_file="$test_home/cli/crm_mon.xml" desc="Create empty shadow instance (file already exists)" cmd="crm_shadow --create-empty $shadow --batch" test_assert $CRM_EX_CANTCREAT 0 desc="Create empty shadow instance (file already exists) (force)" cmd="crm_shadow --create-empty $shadow --batch --force" test_assert $CRM_EX_OK 0 desc="Create empty shadow instance (file already exists) (XML)" cmd="crm_shadow --create-empty $shadow --batch --output-as=xml" test_assert_validate $CRM_EX_CANTCREAT 0 desc="Create empty shadow instance (file already exists) (force) (XML)" cmd="crm_shadow --create-empty $shadow --batch --force --output-as=xml" test_assert_validate $CRM_EX_OK 0 # Query shadow instance with an empty CIB. # --which and --file queries were done earlier. delete_shadow_resource_defaults desc="Get active shadow instance's contents (empty CIB)" cmd="crm_shadow --display" test_assert $CRM_EX_OK 0 desc="Get active shadow instance's contents (empty CIB) (XML)" cmd="crm_shadow --display --output-as=xml" test_assert_validate $CRM_EX_OK 0 desc="Get active shadow instance's diff (empty CIB)" cmd="crm_shadow --diff" test_assert $CRM_EX_ERROR 0 desc="Get active shadow instance's diff (empty CIB) (XML)" cmd="crm_shadow --diff --output-as=xml" test_assert_validate $CRM_EX_ERROR 0 # Reset shadow instance (overwrite existing shadow file based on active CIB) export CIB_file="$test_home/cli/crm_mon.xml" export CIB_shadow="$shadow" desc="Reset shadow instance" cmd="crm_shadow --reset $shadow --batch" test_assert $CRM_EX_OK 0 desc="Get active shadow instance's diff (after reset)" cmd="crm_shadow --diff" test_assert $CRM_EX_OK 0 create_shadow_cib --create-empty desc="Reset shadow instance (XML)" cmd="crm_shadow --reset $shadow --batch --output-as=xml" test_assert_validate $CRM_EX_OK 0 desc="Get active shadow instance's diff (after reset) (XML)" cmd="crm_shadow --diff --output-as=xml" test_assert_validate $CRM_EX_OK 0 # Reset an inactive shadow instance with no active instance unset CIB_shadow desc="Reset shadow instance (no active instance)" cmd="crm_shadow --reset $shadow --batch" test_assert $CRM_EX_OK 0 create_shadow_cib --create-empty unset CIB_shadow desc="Reset shadow instance (no active instance) (XML)" cmd="crm_shadow --reset $shadow --batch --output-as=xml" test_assert_validate $CRM_EX_OK 0 # Reset an inactive shadow instance with an active instance export CIB_shadow="nonexistent_shadow" desc="Reset shadow instance (mismatch)" cmd="crm_shadow --reset $shadow --batch" test_assert $CRM_EX_USAGE 0 desc="Reset shadow instance (mismatch) (force)" cmd="crm_shadow --reset $shadow --batch --force" test_assert $CRM_EX_OK 0 create_shadow_cib --create-empty export CIB_shadow="nonexistent_shadow" desc="Reset shadow instance (mismatch) (XML)" cmd="crm_shadow --reset $shadow --batch --output-as=xml" test_assert_validate $CRM_EX_USAGE 0 desc="Reset shadow instance (mismatch) (force) (XML)" cmd="crm_shadow --reset $shadow --batch --force --output-as=xml" test_assert_validate $CRM_EX_OK 0 # Reset an active shadow instance when the CIB file is missing create_shadow_cib --create-empty export CIB_file="$test_home/cli/nonexistent_cib.xml" desc="Reset shadow instance (nonexistent CIB file)" cmd="crm_shadow --reset $CIB_shadow --batch" test_assert $CRM_EX_NOSUCH 0 desc="Reset shadow instance (nonexistent CIB file) (XML)" cmd="crm_shadow --reset $CIB_shadow --batch --output-as=xml" test_assert_validate $CRM_EX_NOSUCH 0 desc="Reset shadow instance (nonexistent CIB file) (force)" cmd="crm_shadow --reset $CIB_shadow --batch --force" test_assert $CRM_EX_NOSUCH 0 desc="Reset shadow instance (nonexistent CIB file) (force) (XML)" cmd="crm_shadow --reset $CIB_shadow --batch --force --output-as=xml" test_assert_validate $CRM_EX_NOSUCH 0 # Reset an active shadow instance whose shadow file is missing export CIB_file="$test_home/cli/crm_mon.xml" export CIB_shadow="$shadow" crm_shadow --delete "$shadow" --force >/dev/null 2>&1 desc="Reset shadow instance (nonexistent shadow file)" cmd="crm_shadow --reset $CIB_shadow --batch" test_assert $CRM_EX_NOSUCH 0 desc="Reset shadow instance (nonexistent shadow file) (force)" cmd="crm_shadow --reset $CIB_shadow --batch --force" test_assert $CRM_EX_OK 0 crm_shadow --delete "$shadow" --force >/dev/null 2>&1 desc="Reset shadow instance (nonexistent shadow file) (XML)" cmd="crm_shadow --reset $CIB_shadow --batch --output-as=xml" test_assert_validate $CRM_EX_NOSUCH 0 desc="Reset shadow instance (nonexistent shadow file) (force) (XML)" cmd="crm_shadow --reset $CIB_shadow --batch --force --output-as=xml" test_assert_validate $CRM_EX_OK 0 # Switch shadow instances # In batch mode, this only displays a message create_shadow_cib --create-empty # Makes no difference now, just future-proofing CIB_shadow="nonexistent_shadow" desc="Switch to new shadow instance" cmd="crm_shadow --switch $shadow --batch" test_assert $CRM_EX_OK 0 CIB_shadow="nonexistent_shadow" desc="Switch to new shadow instance (XML)" cmd="crm_shadow --switch $shadow --batch --output-as=xml" test_assert_validate $CRM_EX_OK 0 crm_shadow --delete "$shadow" --force >/dev/null 2>&1 desc="Switch to nonexistent shadow instance" cmd="crm_shadow --switch $shadow --batch" test_assert $CRM_EX_NOSUCH 0 desc="Switch to nonexistent shadow instance (force)" cmd="crm_shadow --switch $shadow --batch --force" test_assert $CRM_EX_NOSUCH 0 desc="Switch to nonexistent shadow instance (XML)" cmd="crm_shadow --switch $shadow --batch --output-as=xml" test_assert_validate $CRM_EX_NOSUCH 0 desc="Switch to nonexistent shadow instance (force) (XML)" cmd="crm_shadow --switch $shadow --batch --force --output-as=xml" test_assert_validate $CRM_EX_NOSUCH 0 unset CIB_file unset CIB_shadow unset CIB_shadow_dir } INVALID_PERIODS=( "2019-01-01 00:00:00Z" # Start with no end "2019-01-01 00:00:00Z/" # Start with only a trailing slash "PT2S/P1M" # Two durations "2019-13-01 00:00:00Z/P1M" # Out-of-range month "20191077T15/P1M" # Out-of-range day "2019-10-01T25:00:00Z/P1M" # Out-of-range hour "2019-10-01T24:00:01Z/P1M" # Hour 24 with anything but :00:00 "PT5H/20191001T007000Z" # Out-of-range minute "2019-10-01 00:00:80Z/P1M" # Out-of-range second "2019-10-01 00:00:10 +25:00/P1M" # Out-of-range offset hour "20191001T000010 -00:61/P1M" # Out-of-range offset minute "P1Y/2019-02-29 00:00:00Z" # Feb. 29 in non-leap-year "2019-01-01 00:00:00Z/P" # Duration with no values "P1Z/2019-02-20 00:00:00Z" # Invalid duration unit "P1YM/2019-02-20 00:00:00Z" # No number for duration unit ) function test_dates() { # Ensure invalid period specifications are rejected for spec in '' "${INVALID_PERIODS[@]}"; do desc="Invalid period - [$spec]" cmd="iso8601 -p \"$spec\"" test_assert $CRM_EX_INVALID_PARAM 0 done desc="2014-01-01 00:30:00 - 1 Hour" cmd="iso8601 -d '2014-01-01 00:30:00Z' -D P-1H -E '2013-12-31 23:30:00Z'" test_assert $CRM_EX_OK 0 desc="Valid date - Feb 29 in leap year" cmd="iso8601 -d '2020-02-29 00:00:00Z' -E '2020-02-29 00:00:00Z'" test_assert $CRM_EX_OK 0 desc="Valid date - using 'T' and offset" cmd="iso8601 -d '20191201T131211 -05:00' -E '2019-12-01 18:12:11Z'" test_assert $CRM_EX_OK 0 desc="24:00:00 equivalent to 00:00:00 of next day" cmd="iso8601 -d '2019-12-31 24:00:00Z' -E '2020-01-01 00:00:00Z'" test_assert $CRM_EX_OK 0 for y in 06 07 08 09 10 11 12 13 14 15 16 17 18 40; do desc="20$y-W01-7" cmd="iso8601 -d '20$y-W01-7 00Z'" test_assert $CRM_EX_OK 0 desc="20$y-W01-7 - round-trip" cmd="iso8601 -d '20$y-W01-7 00Z' -W -E '20$y-W01-7 00:00:00Z'" test_assert $CRM_EX_OK 0 desc="20$y-W01-1" cmd="iso8601 -d '20$y-W01-1 00Z'" test_assert $CRM_EX_OK 0 desc="20$y-W01-1 - round-trip" cmd="iso8601 -d '20$y-W01-1 00Z' -W -E '20$y-W01-1 00:00:00Z'" test_assert $CRM_EX_OK 0 done desc="2009-W53-07" cmd="iso8601 -d '2009-W53-7 00:00:00Z' -W -E '2009-W53-7 00:00:00Z'" test_assert $CRM_EX_OK 0 desc="epoch + 2 Years 5 Months 6 Minutes" cmd="iso8601 -d 'epoch' -D P2Y5MT6M -E '1972-06-01 00:06:00Z'" test_assert $CRM_EX_OK 0 desc="2009-01-31 + 1 Month" cmd="iso8601 -d '20090131T000000Z' -D P1M -E '2009-02-28 00:00:00Z'" test_assert $CRM_EX_OK 0 desc="2009-01-31 + 2 Months" cmd="iso8601 -d '2009-01-31 00:00:00Z' -D P2M -E '2009-03-31 00:00:00Z'" test_assert $CRM_EX_OK 0 desc="2009-01-31 + 3 Months" cmd="iso8601 -d '2009-01-31 00:00:00Z' -D P3M -E '2009-04-30 00:00:00Z'" test_assert $CRM_EX_OK 0 desc="2009-03-31 - 1 Month" cmd="iso8601 -d '2009-03-31 01:00:00 +01:00' -D P-1M -E '2009-02-28 00:00:00Z'" test_assert $CRM_EX_OK 0 desc="2038-01-01 + 3 Months" cmd="iso8601 -d '2038-01-01 00:00:00Z' -D P3M -E '2038-04-01 00:00:00Z'" test_assert $CRM_EX_OK 0 } function test_acl_loop() { local TMPXML TMPXML="$1" # Make sure we're rejecting things for the right reasons orig_trace_fns="$PCMK_trace_functions" export PCMK_trace_functions=pcmk__check_acl,pcmk__apply_creation_acl CIB_user=root cibadmin --replace --xml-text '' ### no ACL ### export CIB_user=unknownguy desc="$CIB_user: Query configuration" cmd="cibadmin -Q" test_assert $CRM_EX_INSUFFICIENT_PRIV 0 desc="$CIB_user: Set enable-acl" cmd="crm_attribute -n enable-acl -v false" test_assert $CRM_EX_INSUFFICIENT_PRIV 0 desc="$CIB_user: Set stonith-enabled" cmd="crm_attribute -n stonith-enabled -v false" test_assert $CRM_EX_INSUFFICIENT_PRIV 0 desc="$CIB_user: Create a resource" cmd="cibadmin -C -o resources --xml-text ''" test_assert $CRM_EX_INSUFFICIENT_PRIV 0 ### deny /cib permission ### export CIB_user=l33t-haxor desc="$CIB_user: Query configuration" cmd="cibadmin -Q" test_assert $CRM_EX_INSUFFICIENT_PRIV 0 desc="$CIB_user: Set enable-acl" cmd="crm_attribute -n enable-acl -v false" test_assert $CRM_EX_INSUFFICIENT_PRIV 0 desc="$CIB_user: Set stonith-enabled" cmd="crm_attribute -n stonith-enabled -v false" test_assert $CRM_EX_INSUFFICIENT_PRIV 0 desc="$CIB_user: Create a resource" cmd="cibadmin -C -o resources --xml-text ''" test_assert $CRM_EX_INSUFFICIENT_PRIV 0 ### observer role ### export CIB_user=niceguy desc="$CIB_user: Query configuration" cmd="cibadmin -Q" test_assert $CRM_EX_OK 0 desc="$CIB_user: Set enable-acl" cmd="crm_attribute -n enable-acl -v false" test_assert $CRM_EX_INSUFFICIENT_PRIV 0 desc="$CIB_user: Set stonith-enabled" cmd="crm_attribute -n stonith-enabled -v false" test_assert $CRM_EX_OK desc="$CIB_user: Create a resource" cmd="cibadmin -C -o resources --xml-text ''" test_assert $CRM_EX_INSUFFICIENT_PRIV 0 export CIB_user=root desc="$CIB_user: Query configuration" cmd="cibadmin -Q" test_assert $CRM_EX_OK 0 desc="$CIB_user: Set stonith-enabled" cmd="crm_attribute -n stonith-enabled -v true" test_assert $CRM_EX_OK desc="$CIB_user: Create a resource" cmd="cibadmin -C -o resources --xml-text ''" test_assert $CRM_EX_OK ### deny /cib permission ### export CIB_user=l33t-haxor desc="$CIB_user: Create a resource meta attribute" cmd="crm_resource -r dummy --meta -p target-role -v Stopped" test_assert $CRM_EX_INSUFFICIENT_PRIV 0 desc="$CIB_user: Query a resource meta attribute" cmd="crm_resource -r dummy --meta -g target-role" test_assert $CRM_EX_INSUFFICIENT_PRIV 0 desc="$CIB_user: Remove a resource meta attribute" cmd="crm_resource -r dummy --meta -d target-role" test_assert $CRM_EX_INSUFFICIENT_PRIV 0 ### observer role ### export CIB_user=niceguy desc="$CIB_user: Create a resource meta attribute" cmd="crm_resource -r dummy --meta -p target-role -v Stopped" test_assert $CRM_EX_OK desc="$CIB_user: Query a resource meta attribute" cmd="crm_resource -r dummy --meta -g target-role" test_assert $CRM_EX_OK desc="$CIB_user: Remove a resource meta attribute" cmd="crm_resource -r dummy --meta -d target-role" test_assert $CRM_EX_OK desc="$CIB_user: Create a resource meta attribute" cmd="crm_resource -r dummy --meta -p target-role -v Started" test_assert $CRM_EX_OK ### read //meta_attributes ### export CIB_user=badidea desc="$CIB_user: Query configuration - implied deny" cmd="cibadmin -Q" test_assert $CRM_EX_OK 0 ### deny /cib, read //meta_attributes ### export CIB_user=betteridea desc="$CIB_user: Query configuration - explicit deny" cmd="cibadmin -Q" test_assert $CRM_EX_OK 0 CIB_user=root cibadmin -Q > "$TMPXML" CIB_user=root CIB_file="$TMPXML" CIB_shadow="" cibadmin --delete --xml-text '' CIB_user=root CIB_file="$TMPXML" CIB_shadow="" cibadmin -Ql ### observer role ### export CIB_user=niceguy desc="$CIB_user: Replace - remove acls" cmd="cibadmin --replace --xml-file $TMPXML" test_assert $CRM_EX_INSUFFICIENT_PRIV 0 CIB_user=root cibadmin -Q > "$TMPXML" CIB_user=root CIB_file="$TMPXML" CIB_shadow="" cibadmin -C -o resources --xml-text '' CIB_user=root CIB_file="$TMPXML" CIB_shadow="" cibadmin -Ql desc="$CIB_user: Replace - create resource" cmd="cibadmin --replace --xml-file $TMPXML" test_assert $CRM_EX_INSUFFICIENT_PRIV 0 CIB_user=root cibadmin -Q > "$TMPXML" CIB_user=root CIB_file="$TMPXML" CIB_shadow="" crm_attribute -n enable-acl -v false CIB_user=root CIB_file="$TMPXML" CIB_shadow="" cibadmin -Ql desc="$CIB_user: Replace - modify attribute (deny)" cmd="cibadmin --replace --xml-file $TMPXML" test_assert $CRM_EX_INSUFFICIENT_PRIV 0 CIB_user=root cibadmin -Q > "$TMPXML" CIB_user=root CIB_file="$TMPXML" CIB_shadow="" cibadmin --replace --xml-text '' CIB_user=root CIB_file="$TMPXML" CIB_shadow="" cibadmin -Ql desc="$CIB_user: Replace - delete attribute (deny)" cmd="cibadmin --replace --xml-file $TMPXML" test_assert $CRM_EX_INSUFFICIENT_PRIV 0 CIB_user=root cibadmin -Q > "$TMPXML" CIB_user=root CIB_file="$TMPXML" CIB_shadow="" cibadmin --modify --xml-text '' CIB_user=root CIB_file="$TMPXML" CIB_shadow="" cibadmin -Ql desc="$CIB_user: Replace - create attribute (deny)" cmd="cibadmin --replace --xml-file $TMPXML" test_assert $CRM_EX_INSUFFICIENT_PRIV 0 ### admin role ### CIB_user=bob CIB_user=root cibadmin -Q > "$TMPXML" CIB_user=root CIB_file="$TMPXML" CIB_shadow="" cibadmin --modify --xml-text '' CIB_user=root CIB_file="$TMPXML" CIB_shadow="" cibadmin -Ql desc="$CIB_user: Replace - create attribute (direct allow)" cmd="cibadmin --replace -o resources --xml-file $TMPXML" test_assert $CRM_EX_OK 0 CIB_user=root cibadmin -Q > "$TMPXML" CIB_user=root CIB_file="$TMPXML" CIB_shadow="" cibadmin --modify --xml-text '' CIB_user=root CIB_file="$TMPXML" CIB_shadow="" cibadmin -Ql desc="$CIB_user: Replace - modify attribute (direct allow)" cmd="cibadmin --replace -o resources --xml-file $TMPXML" test_assert $CRM_EX_OK 0 CIB_user=root cibadmin -Q > "$TMPXML" CIB_user=root CIB_file="$TMPXML" CIB_shadow="" cibadmin --replace -o resources --xml-text '' CIB_user=root CIB_file="$TMPXML" CIB_shadow="" cibadmin -Ql desc="$CIB_user: Replace - delete attribute (direct allow)" cmd="cibadmin --replace -o resources --xml-file $TMPXML" test_assert $CRM_EX_OK 0 ### super_user role ### export CIB_user=joe CIB_user=root cibadmin -Q > "$TMPXML" CIB_user=root CIB_file="$TMPXML" CIB_shadow="" cibadmin --modify --xml-text '' CIB_user=root CIB_file="$TMPXML" CIB_shadow="" cibadmin -Ql desc="$CIB_user: Replace - create attribute (inherited allow)" cmd="cibadmin --replace -o resources --xml-file $TMPXML" test_assert $CRM_EX_OK 0 CIB_user=root cibadmin -Q > "$TMPXML" CIB_user=root CIB_file="$TMPXML" CIB_shadow="" cibadmin --modify --xml-text '' CIB_user=root CIB_file="$TMPXML" CIB_shadow="" cibadmin -Ql desc="$CIB_user: Replace - modify attribute (inherited allow)" cmd="cibadmin --replace -o resources --xml-file $TMPXML" test_assert $CRM_EX_OK 0 CIB_user=root cibadmin -Q > "$TMPXML" CIB_user=root CIB_file="$TMPXML" CIB_shadow="" cibadmin --replace -o resources --xml-text '' CIB_user=root CIB_file="$TMPXML" CIB_shadow="" cibadmin -Ql desc="$CIB_user: Replace - delete attribute (inherited allow)" cmd="cibadmin --replace -o resources --xml-file $TMPXML" test_assert $CRM_EX_OK 0 ### rsc_writer role ### export CIB_user=mike CIB_user=root cibadmin -Q > "$TMPXML" CIB_user=root CIB_file="$TMPXML" CIB_shadow="" cibadmin --modify --xml-text '' CIB_user=root CIB_file="$TMPXML" CIB_shadow="" cibadmin -Ql desc="$CIB_user: Replace - create attribute (allow overrides deny)" cmd="cibadmin --replace -o resources --xml-file $TMPXML" test_assert $CRM_EX_OK 0 CIB_user=root cibadmin -Q > "$TMPXML" CIB_user=root CIB_file="$TMPXML" CIB_shadow="" cibadmin --modify --xml-text '' CIB_user=root CIB_file="$TMPXML" CIB_shadow="" cibadmin -Ql desc="$CIB_user: Replace - modify attribute (allow overrides deny)" cmd="cibadmin --replace -o resources --xml-file $TMPXML" test_assert $CRM_EX_OK 0 CIB_user=root cibadmin -Q > "$TMPXML" CIB_user=root CIB_file="$TMPXML" CIB_shadow="" cibadmin --replace -o resources --xml-text '' CIB_user=root CIB_file="$TMPXML" CIB_shadow="" cibadmin -Ql desc="$CIB_user: Replace - delete attribute (allow overrides deny)" cmd="cibadmin --replace -o resources --xml-file $TMPXML" test_assert $CRM_EX_OK 0 ### rsc_denied role ### export CIB_user=chris CIB_user=root cibadmin -Q > "$TMPXML" CIB_user=root CIB_file="$TMPXML" CIB_shadow="" cibadmin --modify --xml-text '' CIB_user=root CIB_file="$TMPXML" CIB_shadow="" cibadmin -Ql desc="$CIB_user: Replace - create attribute (deny overrides allow)" cmd="cibadmin --replace -o resources --xml-file $TMPXML" test_assert $CRM_EX_INSUFFICIENT_PRIV 0 # Set as root since setting as chris failed CIB_user=root cibadmin --modify --xml-text '' CIB_user=root cibadmin -Q > "$TMPXML" CIB_user=root CIB_file="$TMPXML" CIB_shadow="" cibadmin --modify --xml-text '' CIB_user=root CIB_file="$TMPXML" CIB_shadow="" cibadmin -Ql desc="$CIB_user: Replace - modify attribute (deny overrides allow)" cmd="cibadmin --replace -o resources --xml-file $TMPXML" test_assert $CRM_EX_INSUFFICIENT_PRIV 0 # Set as root since setting as chris failed CIB_user=root cibadmin --modify --xml-text '' CIB_user=root cibadmin -Q > "$TMPXML" CIB_user=root CIB_file="$TMPXML" CIB_shadow="" cibadmin --replace -o resources --xml-text '' CIB_user=root CIB_file="$TMPXML" CIB_shadow="" cibadmin -Ql desc="$CIB_user: Replace - delete attribute (deny overrides allow)" cmd="cibadmin --replace -o resources --xml-file $TMPXML" test_assert $CRM_EX_INSUFFICIENT_PRIV 0 export PCMK_trace_functions="$orig_trace_fns" } function test_acls() { local SHADOWPATH local TMPXML TMPXML=$(mktemp ${TMPDIR:-/tmp}/cts-cli.acls.xml.XXXXXXXXXX) create_shadow_cib --create-empty pacemaker-1.3 cat < "$TMPXML" EOF desc="Configure some ACLs" cmd="cibadmin -M -o acls --xml-file $TMPXML" test_assert $CRM_EX_OK desc="Enable ACLs" cmd="crm_attribute -n enable-acl -v true" test_assert $CRM_EX_OK desc="Set cluster option" cmd="crm_attribute -n no-quorum-policy -v ignore" test_assert $CRM_EX_OK desc="New ACL" cmd="cibadmin --create -o acls --xml-text ''" test_assert $CRM_EX_OK desc="Another ACL" cmd="cibadmin --create -o acls --xml-text ''" test_assert $CRM_EX_OK desc="Updated ACL" cmd="cibadmin --replace -o acls --xml-text ''" test_assert $CRM_EX_OK test_acl_loop "$TMPXML" printf "\n\n !#!#!#!#! Upgrading to latest CIB schema and re-testing !#!#!#!#!\n" printf "\nUpgrading to latest CIB schema and re-testing\n" 1>&2 export CIB_user=root desc="$CIB_user: Upgrade to latest CIB schema" cmd="cibadmin --upgrade --force -V" test_assert $CRM_EX_OK reset_shadow_cib_version test_acl_loop "$TMPXML" unset CIB_shadow_dir rm -f "$TMPXML" } function test_validity() { local TMPGOOD local TMPBAD TMPGOOD=$(mktemp ${TMPDIR:-/tmp}/cts-cli.validity.good.xml.XXXXXXXXXX) TMPBAD=$(mktemp ${TMPDIR:-/tmp}/cts-cli.validity.bad.xml.XXXXXXXXXX) create_shadow_cib --create-empty pacemaker-1.2 orig_trace_fns="$PCMK_trace_functions" export PCMK_trace_functions=apply_upgrade,update_validation cibadmin -C -o resources --xml-text '' cibadmin -C -o resources --xml-text '' cibadmin -C -o constraints --xml-text '' cibadmin -Q > "$TMPGOOD" desc="Try to make resulting CIB invalid (enum violation)" cmd="cibadmin -M -o constraints --xml-text ''" test_assert $CRM_EX_CONFIG sed 's|"start"|"break"|' "$TMPGOOD" > "$TMPBAD" desc="Run crm_simulate with invalid CIB (enum violation)" cmd="crm_simulate -x $TMPBAD -S" test_assert $CRM_EX_CONFIG 0 desc="Try to make resulting CIB invalid (unrecognized validate-with)" cmd="cibadmin -M --xml-text ''" test_assert $CRM_EX_CONFIG sed 's|"pacemaker-1.2"|"pacemaker-9999.0"|' "$TMPGOOD" > "$TMPBAD" desc="Run crm_simulate with invalid CIB (unrecognized validate-with)" cmd="crm_simulate -x $TMPBAD -S" test_assert $CRM_EX_CONFIG 0 desc="Try to make resulting CIB invalid, but possibly recoverable (valid with X.Y+1)" cmd="cibadmin -C -o configuration --xml-text ''" test_assert $CRM_EX_CONFIG sed 's|||' "$TMPGOOD" > "$TMPBAD" desc="Run crm_simulate with invalid, but possibly recoverable CIB (valid with X.Y+1)" cmd="crm_simulate -x $TMPBAD -S" test_assert $CRM_EX_OK 0 sed 's|[ ][ ]*validate-with="[^"]*"||' "$TMPGOOD" > "$TMPBAD" desc="Make resulting CIB valid, although without validate-with attribute" cmd="cibadmin -R --xml-file $TMPBAD" test_assert $CRM_EX_OK desc="Run crm_simulate with valid CIB, but without validate-with attribute" cmd="crm_simulate -x $TMPBAD -S" test_assert $CRM_EX_OK 0 # this will just disable validation and accept the config, outputting # validation errors sed -e 's|[ ][ ]*validate-with="[^"]*"||' \ -e 's|\([ ][ ]*epoch="[^"]*\)"|\10"|' -e 's|"start"|"break"|' \ "$TMPGOOD" > "$TMPBAD" desc="Make resulting CIB invalid, and without validate-with attribute" cmd="cibadmin -R --xml-file $TMPBAD" test_assert $CRM_EX_OK desc="Run crm_simulate with invalid CIB, also without validate-with attribute" cmd="crm_simulate -x $TMPBAD -S" test_assert $CRM_EX_OK 0 unset CIB_shadow_dir rm -f "$TMPGOOD" "$TMPBAD" export PCMK_trace_functions="$orig_trace_fns" } test_upgrade() { local TMPXML TMPXML=$(mktemp ${TMPDIR:-/tmp}/cts-cli.tools.xml.XXXXXXXXXX) create_shadow_cib --create-empty pacemaker-2.10 orig_trace_fns="$PCMK_trace_functions" export PCMK_trace_functions=apply_upgrade,update_validation desc="Set stonith-enabled=false" cmd="crm_attribute -n stonith-enabled -v false" test_assert $CRM_EX_OK cat < "$TMPXML" EOF desc="Configure the initial resource" cmd="cibadmin -M -o resources --xml-file $TMPXML" test_assert $CRM_EX_OK desc="Upgrade to latest CIB schema (trigger 2.10.xsl + the wrapping)" cmd="cibadmin --upgrade --force -V -V" test_assert $CRM_EX_OK desc="Query a resource instance attribute (shall survive)" cmd="crm_resource -r mySmartFuse -g requires" test_assert $CRM_EX_OK unset CIB_shadow_dir rm -f "$TMPXML" export PCMK_trace_functions="$orig_trace_fns" } test_rules() { local TMPXML create_shadow_cib --create-empty cibadmin -C -o crm_config --xml-text '' cibadmin -C -o resources --xml-text '' TMPXML=$(mktemp ${TMPDIR:-/tmp}/cts-cli.tools.xml.XXXXXXXXXX) cat < "$TMPXML" EOF cibadmin -C -o constraints -x "$TMPXML" rm -f "$TMPXML" TMPXML=$(mktemp ${TMPDIR:-/tmp}/cts-cli.tools.xml.XXXXXXXXXX) cat < "$TMPXML" EOF cibadmin -C -o constraints -x "$TMPXML" rm -f "$TMPXML" if [ "$(uname)" == "FreeBSD" ]; then tomorrow=$(date -v+1d +"%F %T %z") else tomorrow=$(date --date=tomorrow +"%F %T %z") fi TMPXML=$(mktemp ${TMPDIR:-/tmp}/cts-cli.tools.xml.XXXXXXXXXX) cat < "$TMPXML" EOF cibadmin -C -o constraints -x "$TMPXML" rm -f "$TMPXML" TMPXML=$(mktemp ${TMPDIR:-/tmp}/cts-cli.tools.xml.XXXXXXXXXX) cat < "$TMPXML" EOF cibadmin -C -o constraints -x "$TMPXML" rm -f "$TMPXML" TMPXML=$(mktemp ${TMPDIR:-/tmp}/cts-cli.tools.xml.XXXXXXXXXX) cat < "$TMPXML" EOF cibadmin -C -o constraints -x "$TMPXML" rm -f "$TMPXML" TMPXML=$(mktemp ${TMPDIR:-/tmp}/cts-cli.tools.xml.XXXXXXXXXX) cat < "$TMPXML" EOF cibadmin -C -o constraints -x "$TMPXML" rm -f "$TMPXML" TMPXML=$(mktemp ${TMPDIR:-/tmp}/cts-cli.tools.xml.XXXXXXXXXX) cat < "$TMPXML" EOF cibadmin -C -o constraints -x "$TMPXML" rm -f "$TMPXML" desc="crm_rule given no arguments" cmd="crm_rule" test_assert $CRM_EX_USAGE 0 desc="crm_rule given no arguments (XML)" cmd="crm_rule --output-as=xml" test_assert_validate $CRM_EX_USAGE 0 desc="crm_rule given no rule to check" cmd="crm_rule -c" test_assert $CRM_EX_USAGE 0 desc="crm_rule given no rule to check (XML)" cmd="crm_rule -c --output-as=xml" test_assert_validate $CRM_EX_USAGE 0 desc="crm_rule given invalid input XML" cmd="crm_rule -c -r blahblah -X 'invalidxml'" test_assert $CRM_EX_DATAERR 0 desc="crm_rule given invalid input XML (XML)" cmd="crm_rule -c -r blahblah -X 'invalidxml' --output-as=xml" test_assert_validate $CRM_EX_DATAERR 0 desc="crm_rule given invalid input XML on stdin" cmd="echo 'invalidxml' | crm_rule -c -r blahblah -X -" test_assert $CRM_EX_DATAERR 0 desc="crm_rule given invalid input XML on stdin (XML)" cmd="echo 'invalidxml' | crm_rule -c -r blahblah -X - --output-as=xml" test_assert_validate $CRM_EX_DATAERR 0 desc="Try to check a rule that doesn't exist" cmd="crm_rule -c -r blahblah" test_assert $CRM_EX_NOSUCH desc="Try to check a rule that doesn't exist, with XML output" cmd="crm_rule -c -r blahblah --output-as=xml" test_assert_validate $CRM_EX_NOSUCH 0 desc="Try to check a rule that has too many date_expressions" cmd="crm_rule -c -r cli-rule-too-many-date-expressions" test_assert $CRM_EX_UNIMPLEMENT_FEATURE 0 desc="Try to check a rule that has too many date_expressions (XML)" cmd="crm_rule -c -r cli-rule-too-many-date-expressions --output-as=xml" test_assert_validate $CRM_EX_UNIMPLEMENT_FEATURE 0 desc="Verify basic rule is expired" cmd="crm_rule -c -r cli-prefer-rule-dummy-expired" test_assert $CRM_EX_EXPIRED 0 desc="Verify basic rule is expired, with XML output" cmd="crm_rule -c -r cli-prefer-rule-dummy-expired --output-as=xml" test_assert_validate $CRM_EX_EXPIRED 0 desc="Verify basic rule worked in the past" cmd="crm_rule -c -r cli-prefer-rule-dummy-expired -d 20180101" test_assert $CRM_EX_OK 0 desc="Verify basic rule worked in the past (XML)" cmd="crm_rule -c -r cli-prefer-rule-dummy-expired -d 20180101 --output-as=xml" test_assert_validate $CRM_EX_OK 0 desc="Verify basic rule is not yet in effect" cmd="crm_rule -c -r cli-prefer-rule-dummy-not-yet" test_assert $CRM_EX_NOT_YET_IN_EFFECT 0 desc="Verify basic rule is not yet in effect (XML)" cmd="crm_rule -c -r cli-prefer-rule-dummy-not-yet --output-as=xml" test_assert_validate $CRM_EX_NOT_YET_IN_EFFECT 0 desc="Verify date_spec rule with years has expired" cmd="crm_rule -c -r cli-prefer-rule-dummy-date_spec-only-years" test_assert $CRM_EX_EXPIRED 0 desc="Verify date_spec rule with years has expired (XML)" cmd="crm_rule -c -r cli-prefer-rule-dummy-date_spec-only-years --output-as=xml" test_assert_validate $CRM_EX_EXPIRED 0 desc="Verify multiple rules at once" cmd="crm_rule -c -r cli-prefer-rule-dummy-not-yet -r cli-prefer-rule-dummy-date_spec-only-years" test_assert $CRM_EX_EXPIRED 0 desc="Verify multiple rules at once, with XML output" cmd="crm_rule -c -r cli-prefer-rule-dummy-not-yet -r cli-prefer-rule-dummy-date_spec-only-years --output-as=xml" test_assert_validate $CRM_EX_EXPIRED 0 desc="Verify date_spec rule with years is in effect" cmd="crm_rule -c -r cli-prefer-rule-dummy-date_spec-only-years -d 20190201" test_assert $CRM_EX_OK 0 desc="Verify date_spec rule with years is in effect (XML)" cmd="crm_rule -c -r cli-prefer-rule-dummy-date_spec-only-years -d 20190201 --output-as=xml" test_assert_validate $CRM_EX_OK 0 desc="Try to check a rule whose date_spec does not contain years=" cmd="crm_rule -c -r cli-prefer-rule-dummy-date_spec-without-years" test_assert $CRM_EX_UNIMPLEMENT_FEATURE 0 desc="Try to check a rule whose date_spec does not contain years= (XML)" cmd="crm_rule -c -r cli-prefer-rule-dummy-date_spec-without-years --output-as=xml" test_assert_validate $CRM_EX_UNIMPLEMENT_FEATURE 0 desc="Try to check a rule whose date_spec contains years= and moon=" cmd="crm_rule -c -r cli-prefer-rule-dummy-date_spec-years-moon" test_assert $CRM_EX_UNIMPLEMENT_FEATURE 0 desc="Try to check a rule whose date_spec contains years= and moon= (XML)" cmd="crm_rule -c -r cli-prefer-rule-dummy-date_spec-years-moon --output-as=xml" test_assert_validate $CRM_EX_UNIMPLEMENT_FEATURE 0 desc="Try to check a rule with no date_expression" cmd="crm_rule -c -r cli-no-date_expression-rule" test_assert $CRM_EX_UNIMPLEMENT_FEATURE 0 desc="Try to check a rule with no date_expression (XML)" cmd="crm_rule -c -r cli-no-date_expression-rule --output-as=xml" test_assert_validate $CRM_EX_UNIMPLEMENT_FEATURE 0 unset CIB_shadow_dir } # Ensure all command output is in portable locale for comparison export LC_ALL="C" test_access_render() { local TMPXML TMPXML=$(mktemp ${TMPDIR:-/tmp}/cts-cli.access_render.xml.XXXXXXXXXX) export CIB_shadow_dir="${shadow_dir}" $VALGRIND_CMD crm_shadow --batch --force --create-empty $shadow 2>&1 export CIB_shadow=$shadow # Create a test CIB that has ACL roles cat < "$TMPXML" EOF desc="Configure some ACLs" cmd="cibadmin -M -o acls --xml-file $TMPXML" test_assert $CRM_EX_OK desc="Enable ACLs" cmd="crm_attribute -n enable-acl -v true" test_assert $CRM_EX_OK unset CIB_user # Run cibadmin --show-access on the test CIB with different users (tony here) desc="An instance of ACLs render (into color)" cmd="cibadmin --force --show-access=color -Q --user tony" test_assert $CRM_EX_OK 0 desc="An instance of ACLs render (into namespacing)" cmd="cibadmin --force --show-access=namespace -Q --user tony" test_assert $CRM_EX_OK 0 desc="An instance of ACLs render (into text)" cmd="cibadmin --force --show-access=text -Q --user tony" test_assert $CRM_EX_OK 0 unset CIB_shadow_dir rm -f "$TMPXML" } function test_feature_set() { create_shadow_cib --create-empty # Import the initial test CIB with non-mixed versions desc="Import the test CIB" cmd="cibadmin --replace --xml-file $test_home/cli/crm_mon-feature_set.xml" test_assert $CRM_EX_OK desc="Complete text output, no mixed status" cmd="crm_mon -1 --show-detail" test_assert $CRM_EX_OK 0 desc="XML output, no mixed status" cmd="crm_mon --output-as=xml" test_assert $CRM_EX_OK 0 # Modify the CIB to fake that the cluster has mixed versions desc="Fake inconsistent feature set" cmd="crm_attribute --node=cluster02 --name=#feature-set --update=3.15.0 --lifetime=reboot" test_assert $CRM_EX_OK desc="Complete text output, mixed status" cmd="crm_mon -1 --show-detail" test_assert $CRM_EX_OK 0 desc="XML output, mixed status" cmd="crm_mon --output-as=xml" test_assert $CRM_EX_OK 0 unset CIB_shadow_dir } # Process command-line arguments while [ $# -gt 0 ]; do case "$1" in -t) tests="$2" shift 2 ;; -V|--verbose) verbose=1 shift ;; -v|--valgrind) export G_SLICE=always-malloc VALGRIND_CMD="valgrind $VALGRIND_OPTS" shift ;; -s) do_save=1 shift ;; -p) export PATH="$2:$PATH" shift ;; --help) echo "$USAGE_TEXT" exit $CRM_EX_OK ;; *) echo "error: unknown option $1" echo echo "$USAGE_TEXT" exit $CRM_EX_USAGE ;; esac done for t in $tests; do case "$t" in agents) ;; daemons) ;; dates) ;; error_codes) ;; tools) ;; acls) ;; validity) ;; upgrade) ;; rules) ;; crm_mon) ;; feature_set) ;; *) echo "error: unknown test $t" echo echo "$USAGE_TEXT" exit $CRM_EX_USAGE ;; esac done XMLLINT_CMD=$(which xmllint 2>/dev/null) if [ $? -ne 0 ]; then XMLLINT_CMD="" echo "xmllint is missing - install it to validate command output" fi # Check whether we're running from source directory SRCDIR=$(dirname $test_home) if [ -x "$SRCDIR/tools/crm_simulate" ]; then path_dirs="$SRCDIR/tools" for daemon in based controld fenced schedulerd; do if [ -x "$SRCDIR/daemons/$daemon/pacemaker-${daemon}" ]; then path_dirs="$path_dirs:$SRCDIR/daemons/$daemon" fi done export PATH="$path_dirs:$PATH" echo "Using local binaries from: ${path_dirs//:/ }" if [ -x "$SRCDIR/xml" ]; then export PCMK_schema_directory="$SRCDIR/xml" echo "Using local schemas from: $PCMK_schema_directory" fi else export PATH="@CRM_DAEMON_DIR@:$PATH" export PCMK_schema_directory=@CRM_SCHEMA_DIRECTORY@ fi for t in $tests; do echo "Testing $t" TMPFILE=$(mktemp ${TMPDIR:-/tmp}/cts-cli.$t.XXXXXXXXXX) eval TMPFILE_$t="$TMPFILE" test_$t > "$TMPFILE" # last-rc-change= is always numeric in the CIB. However, for the crm_mon # test we also need to compare against the XML output of the crm_mon # program. There, these are shown as human readable strings (like the # output of the `date` command). sed -e 's|\(|\1/>|' \ -e 's|\(|\1>|' \ -e 's/Last updated: .*/Last updated:/' \ -e 's/Last change: .*/Last change:/' \ -e 's/(version .*)/(version)/' \ -e 's/last_update time=\".*\"/last_update time=\"\"/' \ -e 's/last_change time=\".*\"/last_change time=\"\"/' \ -e 's/ api-version="[^"]*"/ api-version="X"/' \ -e 's/ default="[^"]*"/ default=""/' \ -e 's/ version="[^"]*"/ version=""/' \ -e 's/request=\".*\(crm_[a-zA-Z0-9]*\)/request=\"\1/' \ -e 's/crm_feature_set="[^"]*" //'\ -e 's/validate-with="[^"]*" //'\ -e 's/Created new pacemaker-.* configuration/Created new pacemaker configuration/'\ -e 's/.*\(crm_time_parse_duration\)@.*\.c:[0-9][0-9]*)/\1/g' \ -e 's/.*\(crm_time_parse_period\)@.*\.c:[0-9][0-9]*)/\1/g' \ -e 's/.*\(crm_time_parse_sec\)@.*\.c:[0-9][0-9]*)/\1/g' \ -e 's/.*\(log_xmllib_err\)@.*\.c:[0-9][0-9]*)/\1/g' \ -e 's/.*\(parse_date\)@.*\.c:[0-9][0-9]*)/\1/g' \ -e 's/.*\(pcmk__.*\)@.*\.c:[0-9][0-9]*)/\1/g' \ -e 's/.*\(unpack_.*\)@.*\.c:[0-9][0-9]*)/\1/g' \ -e 's/.*\(update_validation\)@.*\.c:[0-9][0-9]*)/\1/g' \ -e 's/.*\(apply_upgrade\)@.*\.c:[0-9][0-9]*)/\1/g' \ -e "s/ last-rc-change=['\"][-+A-Za-z0-9: ]*['\"],\{0,1\}//" \ -e 's|^/tmp/cts-cli\.shadow\.[^/]*/|/tmp/cts-cli.shadow/|' \ -e 's|"/tmp/cts-cli\.shadow\.[^/]*/|"/tmp/cts-cli.shadow/|' \ -e 's|^/tmp/cts-cli\.validity\.bad.xml\.[^:]*:|validity.bad.xml:|'\ -e 's/^Entity: line [0-9][0-9]*: //'\ -e 's/\(validation ([0-9][0-9]* of \)[0-9][0-9]*\().*\)/\1X\2/' \ -e 's/^Migration will take effect until: .*/Migration will take effect until:/' \ -e 's/ end=\"[0-9][-+: 0-9]*Z*\"/ end=\"\"/' \ -e 's/ start=\"[0-9][-+: 0-9]*Z*\"/ start=\"\"/' \ -e 's/Device not configured/No such device or address/' \ -e 's/\(Injecting attribute last-failure-ping#monitor_10000=\)[0-9]*/\1/' \ -e 's/^lt-//' \ -e 's/ocf::/ocf:/' \ -e 's/Masters:/Promoted:/' \ -e 's/Slaves:/Unpromoted:/' \ -e 's/Master/Promoted/' \ -e 's/Slave/Unpromoted/' \ -e 's/\x1b/\\x1b/' \ "$TMPFILE" > "${TMPFILE}.$$" mv -- "${TMPFILE}.$$" "$TMPFILE" if [ $do_save -eq 1 ]; then cp "$TMPFILE" $test_home/cli/regression.$t.exp fi done rm -rf "${shadow_dir}" rm -f "${test_assert_outfile}" rm -f "${test_assert_errfile}" rm -f "${xmllint_outfile}" failed=0 if [ $verbose -eq 1 ]; then echo -e "\n\nResults" fi for t in $tests; do eval TMPFILE="\$TMPFILE_$t" if [ $verbose -eq 1 ]; then diff -wu $test_home/cli/regression.$t.exp "$TMPFILE" else diff -w $test_home/cli/regression.$t.exp "$TMPFILE" >/dev/null 2>&1 fi if [ $? -ne 0 ]; then failed=1 fi done echo -e "\n\nSummary" for t in $tests; do eval TMPFILE="\$TMPFILE_$t" grep -e '^\* \(Passed\|Failed\)' "$TMPFILE" done function print_or_remove_file() { eval TMPFILE="\$TMPFILE_$1" if [[ ! $(diff -wq $test_home/cli/regression.$1.exp "$TMPFILE") ]]; then rm -f "$TMPFILE" else echo " $TMPFILE" if [ $verbose -ne 0 ]; then echo "======================================================" cat "$TMPFILE" echo "======================================================" fi fi } if [ $num_errors -ne 0 ] && [ $failed -ne 0 ]; then echo "$num_errors tests failed; see output in:" for t in $tests; do print_or_remove_file "$t" done exit $CRM_EX_ERROR elif [ $num_errors -ne 0 ]; then echo "$num_errors tests failed" for t in $tests; do print_or_remove_file "$t" done exit $CRM_EX_ERROR elif [ $failed -eq 1 ]; then echo "$num_passed tests passed but output was unexpected; see output in:" for t in $tests; do print_or_remove_file "$t" done exit $CRM_EX_DIGEST else echo $num_passed tests passed for t in $tests; do eval TMPFILE="\$TMPFILE_$t" rm -f "$TMPFILE" done crm_shadow --force --delete $shadow >/dev/null 2>&1 exit $CRM_EX_OK fi diff --git a/cts/cts.in b/cts/cts.in index cbb2e097b4..24339aac73 100755 --- a/cts/cts.in +++ b/cts/cts.in @@ -1,262 +1,404 @@ #!@BASH_PATH@ # # Copyright 2012-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. # # e.g. /etc/sysconfig or /etc/default CONFIG_DIR=@CONFIGDIR@ cts_root=`dirname $0` logfile=0 summary=0 verbose=0 watch=0 saved=0 tests="" install=0 clean=0 kill=0 run=0 boot=0 -setup=0 target=rhel-7 cmd="" trace="" custom_log="" patterns="-e CTS:" +function sed_in_place_remotely() { + cluster-helper -g $cluster_name -- cp -p "\"$1\"" "\"$1.sed\"" \&\& sed -e "\"$2\"" "\"$1\"" \> "\"$1.sed\"" \&\& mv "\"$1.sed\"" "\"$1\"" +} + helpmsg=$(cat </dev/null if [ $? != 0 ]; then echo $0 needs the cluster-helper script to be in your path exit 1 fi which cluster-clean &>/dev/null if [ $? != 0 ]; then echo $0 needs the cluster-clean script to be in your path exit 1 fi if [ "x$cluster_name" = x ] || [ "x$cluster_name" = xpick ]; then clusters=`ls -1 ~/.dsh/group/[a-z]+[0-9] | sed s/.*group.// | tr '\n' ' ' ` echo "custom) interactively define a cluster" for i in $clusters; do - echo "$i) `cluster-helper --list short -g $i`" + echo "$i) `cluster-helper --list short -g $i`" done read -p "Choose a cluster [custom]: " cluster_name echo fi if [ -z $cluster_name ]; then cluster_name=custom fi case $cluster_name in - custom) - read -p "Cluster name: " cluster_name - read -p "Cluster hosts: " cluster_hosts - read -p "Cluster log file: " cluster_log - cluster-helper add -g "$cluster_name" -w "$cluster_hosts" - ;; - *) - cluster_hosts=`cluster-helper --list short -g $cluster_name` - cluster_log=~/cluster-$cluster_name.log; - ;; + custom) + read -p "Cluster name: " cluster_name + read -p "Cluster hosts: " cluster_hosts + read -p "Cluster log file: " cluster_log + cluster-helper add -g "$cluster_name" -w "$cluster_hosts" + ;; + *) + cluster_hosts=`cluster-helper --list short -g $cluster_name` + cluster_log=~/cluster-$cluster_name.log + ;; esac +# NOTES ABOUT THESE AWESOME REGULAR EXPRESSIONS: +# +# * We can't assume GNU sed. Unfortunately, + and * are GNU extensions. Thus, +# we have to use {1,} for + and {0,} for *. +# * You don't need to add an extra set of escaped quotes around the sed expression +# arguments here - sed_in_place_remotely will do that for you. +# * Only literal quotes need the triple backslashes. All other special characters +# are fine with just a single one. +# * sed needs a LOT of characters escaped - \, {, }, (, ), and | at least. + if [ x$cmd != x ]; then config="${CONFIG_DIR}/pacemaker" case $cmd in - trace-ls|tls) - cluster-helper -g $cluster_name -- grep PCMK_trace_functions $config - ;; - trace-add|tadd) - echo "Adding $trace to PCMK_trace_functions" - cluster-helper -g $cluster_name -- sed -i "s/.*PCMK_trace_functions=/PCMK_trace_functions=$trace,/" $config - ;; - trace-rm|trm) - echo "Removing $trace from PCMK_trace_functions" - cluster-helper -g $cluster_name -- sed -i "s/.*PCMK_trace_functions=\\\\\\(.*\\\\\\)$trace,\\\\\\(.*\\\\\\)/PCMK_trace_functions=\\\\\\1\\\\\\2/" $config - ;; - trace-set|tset) - echo "Setting PCMK_trace_functions to '$trace'" - cluster-helper -g $cluster_name -- sed -i "s/.*PCMK_trace_functions.*/PCMK_trace_functions=$trace/" $config - ;; + trace-ls|tls) + cluster-helper -g $cluster_name -- grep "^[[:space:]]*PCMK_trace_functions" $config + ;; + trace-add|tadd) + echo "Adding $trace to PCMK_trace_functions" + # Note that this only works if there's already a PCMK_trace_functions line. + # If there isn't one, create it with trace-set first. + # + # Match optional whitespace; then PCMK_trace_functions; then an equals + # surrounded by optional whitespace; then an optional quote; then whatever + # else (presumably, this is the list of previously traced functions with + # an optional trailing quote). Replace the entire line with + # PCMK_trace_functions=, + sed_in_place_remotely "$config" "s/^[ \t]\{0,\}PCMK_trace_functions[ \t]\{0,\}=[ \t]\{0,\}\(\\\"\{0,1\}\)\(.\{1,\}\)/PCMK_trace_functions=\1$trace,\2/" + ;; + trace-rm|trm) + echo "Removing $trace from PCMK_trace_functions" + # A bunch of simple regexes are easier to follow than one giant one. + # Look for $trace in the following places on any line containing + # PCMK_trace_functions near the beginning: + # + # (1) At the start of a list - + # Match one of a leading quote, or an equals followed by optional + # whitespace; then $trace; then a comma. Replace $trace with whatever + # came before it. + # (2) In the middle of a list - + # Match a comma; then $trace; then a comma. Replace $trace with a + # single comma. + # (3) At the end of a list - + # Match a comma; then $trace; then one of a quote, whitespace, or + # the EOL. Replace $trace with whatever came after it. + # (4) All by itself - + # Match one of a leading quote, whitespace, or equals followed by + # optional whitespace; then $trace; then one of a trailing quote, + # whitespace, or the EOL. Replace $trace with whatever came before + # and after it. + sed_in_place_remotely "$config" "/^[ \t]\{0,\}PCMK_trace_functions/ { \ + s/\(\\\"\|=\|[ \t]\{1,\}\)$trace,/\1/ ; \ + s/,$trace,/,/ ; \ + s/,$trace\(\\\"\|[ \t]\{1,\}\|$\)/\1/ ; \ + s/\(\\\"\|[ \t]\{1,\}\|=[ \t]\{0,\}\)$trace\(\\\"\|[ \t]\{1,\}\|$\)/\1\2/ }" + ;; + trace-set|tset) + echo "Setting PCMK_trace_functions to '$trace'" + # Do this in two separate sed commands: + # + # (1) Unconditionally remove any existing PCMK_trace_functions= lines. + # (2) Add a new line with $trace after the example line, which therefore + # must exist. Note that GNU sed would support "a PCMK_trace_functions=$trace", + # but that's an extension. For all other seds, we have to put the + # command and the text on separate lines. + sed_in_place_remotely "$config" "/^[ \t]*PCMK_trace_functions/ d ; /^# Example: PCMK_trace_functions/ a\\\ +PCMK_trace_functions=\\\"$trace\\\"" + ;; esac exit 0 fi if [ $run = 1 ]; then install=1 clean=1 fi if [ $clean = 1 ]; then - rm -f $cluster_log; cluster-clean -g $cluster_name --kill + rm -f $cluster_log + cluster-clean -g $cluster_name --kill elif [ $kill = 1 ]; then cluster-clean -g $cluster_name --kill-only exit 0 fi if [ $install = 1 ]; then cluster-helper -g $cluster_name -- yum install -y pacemaker pacemaker-debuginfo pacemaker-cts libqb libqb-debuginfo fi -if [ $setup = 1 ]; then - cluster-init -g $cluster_name $target -u --test - exit 0 - -elif [ $boot = 1 ]; then +if [ $boot = 1 ]; then $cts_root/cts-lab -r -c -g $cluster_name --boot rc=$? if [ $rc = 0 ]; then - echo "The cluster is ready..." + echo "The cluster is ready..." fi exit $rc elif [ $run = 1 ]; then $cts_root/cts-lab -r -c -g $cluster_name 500 "$@" exit $? elif [ $clean = 1 ]; then exit 0 fi screen -ls | grep cts-$cluster_name &>/dev/null active=$? if [ ! -z $custom_log ]; then cluster_log=$custom_log fi if [ "x$tests" != x ] && [ "x$tests" != "x " ]; then for t in $tests; do - echo "crm_report --cts-log $cluster_log -d -T $t" - crm_report --cts-log $cluster_log -d -T $t + echo "crm_report --cts-log $cluster_log -d -T $t" + crm_report --cts-log $cluster_log -d -T $t done elif [ $logfile = 1 ]; then echo $cluster_log elif [ $summary = 1 ]; then files=$cluster_log if [ $saved = 1 ]; then - files=`ls -1tr ~/CTS-*/cluster-log.txt` + files=`ls -1tr ~/CTS-*/cluster-log.txt` fi for f in $files; do - echo $f - case $verbose in - 0) cat -n $f | grep $patterns | grep -v "CTS: debug:" - ;; - 1) cat -n $f | grep $patterns | grep -v "CTS:.* cmd:" - ;; - *) cat -n $f | grep $patterns - ;; - esac - echo "" + echo $f + case $verbose in + 0) + cat -n $f | grep $patterns | grep -v "CTS: debug:" + ;; + 1) + cat -n $f | grep $patterns | grep -v "CTS:.* cmd:" + ;; + *) + cat -n $f | grep $patterns + ;; + esac + echo "" done elif [ $watch = 1 ]; then case $verbose in - 0) tail -F $cluster_log | grep $patterns | grep -v "CTS: debug:" - ;; - 1) tail -F $cluster_log | grep $patterns | grep -v "CTS:.* cmd:" - ;; - *) tail -F $cluster_log | grep $patterns - ;; + 0) + tail -F $cluster_log | grep $patterns | grep -v "CTS: debug:" + ;; + 1) + tail -F $cluster_log | grep $patterns | grep -v "CTS:.* cmd:" + ;; + *) + tail -F $cluster_log | grep $patterns + ;; esac elif [ $active = 0 ]; then screen -x cts-$cluster_name else touch $cluster_log - -# . ~/.bashrc export cluster_name cluster_hosts cluster_log screen -S cts-$cluster_name bash fi diff --git a/cts/scheduler/Makefile.am b/cts/scheduler/Makefile.am index 9074390a2c..aed7714718 100644 --- a/cts/scheduler/Makefile.am +++ b/cts/scheduler/Makefile.am @@ -1,18 +1,24 @@ # # Copyright 2001-2021 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. # MAINTAINERCLEANFILES = Makefile.in pedir = $(datadir)/$(PACKAGE)/tests/scheduler +.PHONY: list list: @for T in "$(srcdir)"/xml/*.xml; do \ echo $$(basename $$T .xml); \ done -SUBDIRS = dot exp scores stderr summary xml +SUBDIRS = dot \ + exp \ + scores \ + stderr \ + summary \ + xml diff --git a/cts/support/Makefile.am b/cts/support/Makefile.am index 33cfa6f834..d591633468 100644 --- a/cts/support/Makefile.am +++ b/cts/support/Makefile.am @@ -1,24 +1,24 @@ # # Copyright 2021 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. # MAINTAINERCLEANFILES = Makefile.in # Commands intended to be run only via other commands halibdir = $(CRM_DAEMON_DIR) dist_halib_SCRIPTS = cts-support ctsdir = $(datadir)/$(PACKAGE)/tests/cts cts_DATA = pacemaker-cts-dummyd@.service dist_cts_DATA = cts.conf if BUILD_UPSTART dist_cts_DATA += pacemaker-cts-dummyd.conf endif -cts_SCRIPTS = fence_dummy \ - LSBDummy \ - pacemaker-cts-dummyd +cts_SCRIPTS = fence_dummy \ + LSBDummy \ + pacemaker-cts-dummyd diff --git a/daemons/Makefile.am b/daemons/Makefile.am index 743320b669..30dd17ee6e 100644 --- a/daemons/Makefile.am +++ b/daemons/Makefile.am @@ -1,11 +1,17 @@ # -# Copyright 2018 the Pacemaker project contributors +# Copyright 2018-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. # MAINTAINERCLEANFILES = Makefile.in -SUBDIRS = based schedulerd attrd controld execd fenced pacemakerd +SUBDIRS = based \ + schedulerd \ + attrd \ + controld \ + execd \ + fenced \ + pacemakerd diff --git a/daemons/attrd/Makefile.am b/daemons/attrd/Makefile.am index 6bb81c441e..f8d8bc91d6 100644 --- a/daemons/attrd/Makefile.am +++ b/daemons/attrd/Makefile.am @@ -1,48 +1,49 @@ # -# Copyright 2004-2022 the Pacemaker project contributors +# Copyright 2004-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. # include $(top_srcdir)/mk/common.mk halibdir = $(CRM_DAEMON_DIR) halib_PROGRAMS = pacemaker-attrd noinst_HEADERS = pacemaker-attrd.h pacemaker_attrd_CFLAGS = $(CFLAGS_HARDENED_EXE) pacemaker_attrd_LDFLAGS = $(LDFLAGS_HARDENED_EXE) -pacemaker_attrd_LDADD = $(top_builddir)/lib/cluster/libcrmcluster.la \ - $(top_builddir)/lib/pengine/libpe_rules.la \ - $(top_builddir)/lib/common/libcrmcommon.la \ - $(top_builddir)/lib/cib/libcib.la \ - $(top_builddir)/lib/lrmd/liblrmd.la \ - $(CLUSTERLIBS) +pacemaker_attrd_LDADD = $(top_builddir)/lib/cluster/libcrmcluster.la +pacemaker_attrd_LDADD += $(top_builddir)/lib/cib/libcib.la +pacemaker_attrd_LDADD += $(top_builddir)/lib/pengine/libpe_rules.la +pacemaker_attrd_LDADD += $(top_builddir)/lib/lrmd/liblrmd.la +pacemaker_attrd_LDADD += $(top_builddir)/lib/common/libcrmcommon.la +pacemaker_attrd_LDADD += $(CLUSTERLIBS) pacemaker_attrd_SOURCES = attrd_alerts.c \ - attrd_attributes.c \ - attrd_cib.c \ - attrd_corosync.c \ - attrd_elections.c \ - attrd_ipc.c \ - attrd_messages.c \ - attrd_sync.c \ - attrd_utils.c \ - pacemaker-attrd.c - -clean-generic: - rm -f *.log *.debug *.xml *~ - -if BUILD_LEGACY_LINKS + attrd_attributes.c \ + attrd_cib.c \ + attrd_corosync.c \ + attrd_elections.c \ + attrd_ipc.c \ + attrd_messages.c \ + attrd_sync.c \ + attrd_utils.c \ + pacemaker-attrd.c + +.PHONY: install-exec-hook install-exec-hook: +if BUILD_LEGACY_LINKS cd $(DESTDIR)$(CRM_DAEMON_DIR) && rm -f attrd && $(LN_S) pacemaker-attrd attrd +endif +.PHONY: uninstall-hook uninstall-hook: +if BUILD_LEGACY_LINKS cd $(DESTDIR)$(CRM_DAEMON_DIR) && rm -f attrd endif diff --git a/daemons/based/Makefile.am b/daemons/based/Makefile.am index 9fafd732d9..022fc470c5 100644 --- a/daemons/based/Makefile.am +++ b/daemons/based/Makefile.am @@ -1,49 +1,49 @@ # -# Copyright 2004-2021 the Pacemaker project contributors +# Copyright 2004-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. # include $(top_srcdir)/mk/common.mk EXTRA_DIST = cib.pam halibdir = $(CRM_DAEMON_DIR) -COMMONLIBS = $(top_builddir)/lib/common/libcrmcommon.la \ - $(top_builddir)/lib/cib/libcib.la - halib_PROGRAMS = pacemaker-based noinst_HEADERS = based_transaction.h \ pacemaker-based.h pacemaker_based_CFLAGS = $(CFLAGS_HARDENED_EXE) pacemaker_based_LDFLAGS = $(LDFLAGS_HARDENED_EXE) -pacemaker_based_LDADD = $(top_builddir)/lib/cluster/libcrmcluster.la \ - $(COMMONLIBS) $(CLUSTERLIBS) - -pacemaker_based_SOURCES = pacemaker-based.c \ - based_callbacks.c \ - based_io.c \ - based_messages.c \ - based_notify.c \ - based_operation.c \ - based_remote.c \ +pacemaker_based_LDADD = $(top_builddir)/lib/cluster/libcrmcluster.la +pacemaker_based_LDADD += $(top_builddir)/lib/cib/libcib.la +pacemaker_based_LDADD += $(top_builddir)/lib/common/libcrmcommon.la +pacemaker_based_LDADD += $(CLUSTERLIBS) + +pacemaker_based_SOURCES = pacemaker-based.c \ + based_callbacks.c \ + based_io.c \ + based_messages.c \ + based_notify.c \ + based_operation.c \ + based_remote.c \ based_transaction.c -clean-generic: - rm -f *.log *.debug *.xml *~ - -if BUILD_LEGACY_LINKS +.PHONY: install-exec-hook install-exec-hook: +if BUILD_LEGACY_LINKS $(MKDIR_P) -- $(DESTDIR)$(CRM_DAEMON_DIR) cd $(DESTDIR)$(CRM_DAEMON_DIR) && rm -f cib && $(LN_S) pacemaker-based cib +endif +.PHONY: uninstall-hook uninstall-hook: +if BUILD_LEGACY_LINKS cd $(DESTDIR)$(CRM_DAEMON_DIR) && rm -f cib endif diff --git a/daemons/controld/Makefile.am b/daemons/controld/Makefile.am index 08be1ffbaa..131209038a 100644 --- a/daemons/controld/Makefile.am +++ b/daemons/controld/Makefile.am @@ -1,87 +1,75 @@ # # Copyright 2018-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. # include $(top_srcdir)/mk/common.mk include $(top_srcdir)/mk/man.mk halibdir = $(CRM_DAEMON_DIR) halib_PROGRAMS = pacemaker-controld -noinst_HEADERS = controld_alerts.h \ - controld_callbacks.h \ - controld_cib.h \ - controld_fencing.h \ - controld_fsa.h \ - controld_globals.h \ - controld_lrm.h \ - controld_membership.h \ - controld_messages.h \ - controld_metadata.h \ - controld_throttle.h \ - controld_timers.h \ - controld_transition.h \ - controld_utils.h \ - pacemaker-controld.h +noinst_HEADERS = $(wildcard *.h) pacemaker_controld_CFLAGS = $(CFLAGS_HARDENED_EXE) pacemaker_controld_LDFLAGS = $(LDFLAGS_HARDENED_EXE) -pacemaker_controld_LDADD = $(top_builddir)/lib/fencing/libstonithd.la \ - $(top_builddir)/lib/pacemaker/libpacemaker.la \ - $(top_builddir)/lib/pengine/libpe_rules.la \ - $(top_builddir)/lib/cib/libcib.la \ - $(top_builddir)/lib/cluster/libcrmcluster.la \ - $(top_builddir)/lib/common/libcrmcommon.la \ - $(top_builddir)/lib/services/libcrmservice.la \ - $(top_builddir)/lib/lrmd/liblrmd.la \ - $(CLUSTERLIBS) +pacemaker_controld_LDADD = $(top_builddir)/lib/pacemaker/libpacemaker.la +pacemaker_controld_LDADD += $(top_builddir)/lib/cib/libcib.la +pacemaker_controld_LDADD += $(top_builddir)/lib/pengine/libpe_rules.la +pacemaker_controld_LDADD += $(top_builddir)/lib/fencing/libstonithd.la +pacemaker_controld_LDADD += $(top_builddir)/lib/cluster/libcrmcluster.la +pacemaker_controld_LDADD += $(top_builddir)/lib/lrmd/liblrmd.la +pacemaker_controld_LDADD += $(top_builddir)/lib/services/libcrmservice.la +pacemaker_controld_LDADD += $(top_builddir)/lib/common/libcrmcommon.la +pacemaker_controld_LDADD += $(CLUSTERLIBS) pacemaker_controld_SOURCES = pacemaker-controld.c \ controld_alerts.c \ controld_attrd.c \ controld_callbacks.c \ controld_cib.c \ controld_control.c \ controld_corosync.c \ controld_election.c \ controld_execd.c \ controld_execd_state.c \ controld_fencing.c \ controld_fsa.c \ controld_join_client.c \ controld_join_dc.c \ controld_matrix.c \ controld_membership.c \ controld_messages.c \ controld_metadata.c \ controld_remote_ra.c \ controld_schedulerd.c \ controld_te_actions.c \ controld_te_callbacks.c \ controld_te_events.c \ controld_te_utils.c \ controld_throttle.c \ controld_timers.c \ controld_transition.c \ controld_utils.c if BUILD_XML_HELP man7_MANS = pacemaker-controld.7 endif CLEANFILES = $(man7_MANS) if BUILD_LEGACY_LINKS +.PHONY: install-exec-hook install-exec-hook: cd $(DESTDIR)$(CRM_DAEMON_DIR) && rm -f crmd && $(LN_S) pacemaker-controld crmd +.PHONY: uninstall-hook uninstall-hook: cd $(DESTDIR)$(CRM_DAEMON_DIR) && rm -f crmd endif diff --git a/daemons/execd/Makefile.am b/daemons/execd/Makefile.am index 466f0df27d..ab8544f9d7 100644 --- a/daemons/execd/Makefile.am +++ b/daemons/execd/Makefile.am @@ -1,76 +1,85 @@ # -# Copyright 2012-2021 the Pacemaker project contributors +# Copyright 2012-2023 the Pacemaker project contributors # # The version control history for this file may have further details. # # This source code is licensed under the GNU Lesser General Public License # version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY. # include $(top_srcdir)/mk/common.mk include $(top_srcdir)/mk/man.mk halibdir = $(CRM_DAEMON_DIR) -halib_PROGRAMS = pacemaker-execd cts-exec-helper +halib_PROGRAMS = pacemaker-execd \ + cts-exec-helper EXTRA_DIST = pacemaker-remoted.8.inc pacemaker_execd_CFLAGS = $(CFLAGS_HARDENED_EXE) pacemaker_execd_LDFLAGS = $(LDFLAGS_HARDENED_EXE) -pacemaker_execd_LDADD = $(top_builddir)/lib/common/libcrmcommon.la \ - $(top_builddir)/lib/services/libcrmservice.la \ - $(top_builddir)/lib/fencing/libstonithd.la -pacemaker_execd_SOURCES = pacemaker-execd.c execd_commands.c \ - execd_alerts.c +pacemaker_execd_LDADD = $(top_builddir)/lib/fencing/libstonithd.la +pacemaker_execd_LDADD += $(top_builddir)/lib/services/libcrmservice.la +pacemaker_execd_LDADD += $(top_builddir)/lib/common/libcrmcommon.la +pacemaker_execd_SOURCES = pacemaker-execd.c \ + execd_commands.c \ + execd_alerts.c if BUILD_REMOTE sbin_PROGRAMS = pacemaker-remoted if BUILD_SYSTEMD systemdsystemunit_DATA = pacemaker_remote.service else initdir = $(INITDIR) init_SCRIPTS = pacemaker_remote endif -pacemaker_remoted_CPPFLAGS = -DPCMK__COMPILE_REMOTE $(AM_CPPFLAGS) +pacemaker_remoted_CPPFLAGS = -DPCMK__COMPILE_REMOTE \ + $(AM_CPPFLAGS) pacemaker_remoted_CFLAGS = $(CFLAGS_HARDENED_EXE) pacemaker_remoted_LDFLAGS = $(LDFLAGS_HARDENED_EXE) -pacemaker_remoted_LDADD = $(pacemaker_execd_LDADD) \ - $(top_builddir)/lib/lrmd/liblrmd.la -pacemaker_remoted_SOURCES = $(pacemaker_execd_SOURCES) \ - remoted_tls.c remoted_pidone.c remoted_proxy.c +pacemaker_remoted_LDADD = $(top_builddir)/lib/fencing/libstonithd.la +pacemaker_remoted_LDADD += $(top_builddir)/lib/services/libcrmservice.la +pacemaker_remoted_LDADD += $(top_builddir)/lib/lrmd/liblrmd.la +pacemaker_remoted_LDADD += $(top_builddir)/lib/common/libcrmcommon.la +pacemaker_remoted_SOURCES = $(pacemaker_execd_SOURCES) \ + remoted_tls.c \ + remoted_pidone.c \ + remoted_proxy.c endif -cts_exec_helper_LDADD = $(top_builddir)/lib/common/libcrmcommon.la \ - $(top_builddir)/lib/lrmd/liblrmd.la \ - $(top_builddir)/lib/cib/libcib.la \ - $(top_builddir)/lib/services/libcrmservice.la \ - $(top_builddir)/lib/pengine/libpe_status.la +cts_exec_helper_LDADD = $(top_builddir)/lib/pengine/libpe_status.la +cts_exec_helper_LDADD += $(top_builddir)/lib/cib/libcib.la +cts_exec_helper_LDADD += $(top_builddir)/lib/lrmd/liblrmd.la +cts_exec_helper_LDADD += $(top_builddir)/lib/services/libcrmservice.la +cts_exec_helper_LDADD += $(top_builddir)/lib/common/libcrmcommon.la cts_exec_helper_SOURCES = cts-exec-helper.c noinst_HEADERS = pacemaker-execd.h CLEANFILES = $(man8_MANS) # Always create a symlink for the old pacemaker_remoted name, so that bundle # container images using a current Pacemaker will run on cluster nodes running # Pacemaker 1 (>=1.1.17). +.PHONY: install-exec-hook install-exec-hook: if BUILD_LEGACY_LINKS cd $(DESTDIR)$(CRM_DAEMON_DIR) && rm -f lrmd && $(LN_S) pacemaker-execd lrmd endif if BUILD_REMOTE cd $(DESTDIR)$(sbindir) && rm -f pacemaker_remoted && $(LN_S) pacemaker-remoted pacemaker_remoted endif +.PHONY: uninstall-hook uninstall-hook: if BUILD_LEGACY_LINKS cd $(DESTDIR)$(CRM_DAEMON_DIR) && rm -f lrmd endif if BUILD_REMOTE cd $(DESTDIR)$(sbindir) && rm -f pacemaker_remoted endif diff --git a/daemons/fenced/Makefile.am b/daemons/fenced/Makefile.am index 2ca008861e..938e33ed65 100644 --- a/daemons/fenced/Makefile.am +++ b/daemons/fenced/Makefile.am @@ -1,52 +1,57 @@ # # Original Author: Sun Jiang Dong # Copyright 2004 International Business Machines # # with later changes copyright 2004-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. # include $(top_srcdir)/mk/common.mk include $(top_srcdir)/mk/man.mk halibdir = $(CRM_DAEMON_DIR) -halib_PROGRAMS = pacemaker-fenced cts-fence-helper +halib_PROGRAMS = pacemaker-fenced \ + cts-fence-helper noinst_HEADERS = pacemaker-fenced.h if BUILD_XML_HELP man7_MANS = pacemaker-fenced.7 endif cts_fence_helper_SOURCES = cts-fence-helper.c -cts_fence_helper_LDADD = $(top_builddir)/lib/common/libcrmcommon.la \ - $(top_builddir)/lib/fencing/libstonithd.la +cts_fence_helper_LDADD = $(top_builddir)/lib/fencing/libstonithd.la +cts_fence_helper_LDADD += $(top_builddir)/lib/common/libcrmcommon.la pacemaker_fenced_YFLAGS = -d pacemaker_fenced_CFLAGS = $(CFLAGS_HARDENED_EXE) pacemaker_fenced_LDFLAGS = $(LDFLAGS_HARDENED_EXE) -pacemaker_fenced_LDADD = $(top_builddir)/lib/common/libcrmcommon.la \ - $(top_builddir)/lib/cib/libcib.la \ - $(top_builddir)/lib/cluster/libcrmcluster.la \ - $(top_builddir)/lib/fencing/libstonithd.la \ - $(top_builddir)/lib/pengine/libpe_status.la \ - $(top_builddir)/lib/pacemaker/libpacemaker.la \ - $(CLUSTERLIBS) + +pacemaker_fenced_LDADD = $(top_builddir)/lib/pacemaker/libpacemaker.la +pacemaker_fenced_LDADD += $(top_builddir)/lib/pengine/libpe_status.la +pacemaker_fenced_LDADD += $(top_builddir)/lib/cib/libcib.la +pacemaker_fenced_LDADD += $(top_builddir)/lib/cluster/libcrmcluster.la +pacemaker_fenced_LDADD += $(top_builddir)/lib/fencing/libstonithd.la +pacemaker_fenced_LDADD += $(top_builddir)/lib/common/libcrmcommon.la +pacemaker_fenced_LDADD += $(CLUSTERLIBS) + pacemaker_fenced_SOURCES = pacemaker-fenced.c \ fenced_commands.c \ fenced_remote.c \ fenced_history.c CLEANFILES = $(man7_MANS) $(man8_MANS) if BUILD_LEGACY_LINKS +.PHONY: install-exec-hook install-exec-hook: cd $(DESTDIR)$(CRM_DAEMON_DIR) && rm -f stonithd && $(LN_S) pacemaker-fenced stonithd +.PHONY: uninstall-hook uninstall-hook: cd $(DESTDIR)$(CRM_DAEMON_DIR) && rm -f stonithd endif diff --git a/daemons/pacemakerd/Makefile.am b/daemons/pacemakerd/Makefile.am index fc0e01404d..78e7c37fe6 100644 --- a/daemons/pacemakerd/Makefile.am +++ b/daemons/pacemakerd/Makefile.am @@ -1,37 +1,39 @@ # -# Copyright 2004-2021 the Pacemaker project contributors +# Copyright 2004-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. # include $(top_srcdir)/mk/common.mk include $(top_srcdir)/mk/man.mk sbin_PROGRAMS = pacemakerd if BUILD_SYSTEMD systemdsystemunit_DATA = pacemaker.service endif EXTRA_DIST = pacemakerd.8.inc ## SOURCES noinst_HEADERS = pacemakerd.h pacemakerd_CFLAGS = $(CFLAGS_HARDENED_EXE) pacemakerd_LDFLAGS = $(LDFLAGS_HARDENED_EXE) -pacemakerd_LDADD = $(top_builddir)/lib/cluster/libcrmcluster.la $(top_builddir)/lib/common/libcrmcommon.la -pacemakerd_LDADD += $(CLUSTERLIBS) +pacemakerd_LDADD = $(top_builddir)/lib/cluster/libcrmcluster.la +pacemakerd_LDADD += $(top_builddir)/lib/common/libcrmcommon.la +pacemakerd_LDADD += $(CLUSTERLIBS) + pacemakerd_SOURCES = pacemakerd.c if BUILD_CS_SUPPORT pacemakerd_SOURCES += pcmkd_corosync.c endif pacemakerd_SOURCES += pcmkd_messages.c pacemakerd_SOURCES += pcmkd_subdaemons.c CLEANFILES = $(man8_MANS) diff --git a/daemons/schedulerd/Makefile.am b/daemons/schedulerd/Makefile.am index 57e819bd98..fab8e1af05 100644 --- a/daemons/schedulerd/Makefile.am +++ b/daemons/schedulerd/Makefile.am @@ -1,53 +1,61 @@ # -# Copyright 2004-2021 the Pacemaker project contributors +# Copyright 2004-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. # include $(top_srcdir)/mk/common.mk include $(top_srcdir)/mk/man.mk -AM_CPPFLAGS += -I$(top_builddir) -I$(top_srcdir) +AM_CPPFLAGS += -I$(top_builddir) \ + -I$(top_srcdir) halibdir = $(CRM_DAEMON_DIR) ## binary progs halib_PROGRAMS = pacemaker-schedulerd if BUILD_XML_HELP man7_MANS = pacemaker-schedulerd.7 endif ## SOURCES noinst_HEADERS = pacemaker-schedulerd.h -pacemaker_schedulerd_CFLAGS = $(CFLAGS_HARDENED_EXE) +pacemaker_schedulerd_CFLAGS = $(CFLAGS_HARDENED_EXE) pacemaker_schedulerd_LDFLAGS = $(LDFLAGS_HARDENED_EXE) -pacemaker_schedulerd_LDADD = $(top_builddir)/lib/common/libcrmcommon.la \ - $(top_builddir)/lib/pengine/libpe_status.la \ - $(top_builddir)/lib/pacemaker/libpacemaker.la +pacemaker_schedulerd_LDADD = $(top_builddir)/lib/pacemaker/libpacemaker.la +pacemaker_schedulerd_LDADD += $(top_builddir)/lib/pengine/libpe_status.la +pacemaker_schedulerd_LDADD += $(top_builddir)/lib/common/libcrmcommon.la + # libcib for get_object_root() pacemaker_schedulerd_SOURCES = pacemaker-schedulerd.c pacemaker_schedulerd_SOURCES += schedulerd_messages.c +.PHONY: install-exec-local install-exec-local: $(INSTALL) -d -m 750 $(DESTDIR)/$(PE_STATE_DIR) -chown $(CRM_DAEMON_USER):$(CRM_DAEMON_GROUP) $(DESTDIR)/$(PE_STATE_DIR) -if BUILD_LEGACY_LINKS +.PHONY: install-exec-hook install-exec-hook: +if BUILD_LEGACY_LINKS cd $(DESTDIR)$(CRM_DAEMON_DIR) && rm -f pengine && $(LN_S) pacemaker-schedulerd pengine +endif +.PHONY: uninstall-hook uninstall-hook: +if BUILD_LEGACY_LINKS cd $(DESTDIR)$(CRM_DAEMON_DIR) && rm -f pengine endif +.PHONY: uninstall-local uninstall-local: -rmdir $(DESTDIR)/$(PE_STATE_DIR) CLEANFILES = $(man7_MANS) diff --git a/devel/Makefile.am b/devel/Makefile.am index b4b211d6a1..a463875253 100644 --- a/devel/Makefile.am +++ b/devel/Makefile.am @@ -1,300 +1,309 @@ # # Copyright 2020-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. # include $(top_srcdir)/mk/common.mk include $(top_srcdir)/mk/release.mk # Coccinelle is a tool that takes special patch-like files (called semantic patches) and # applies them throughout a source tree. This is useful when refactoring, changing APIs, # catching dangerous or incorrect code, and other similar tasks. It's not especially # easy to write a semantic patch but most users should only be concerned about running # the target and inspecting the results. # # Documentation (including examples, which are the most useful): # https://coccinelle.gitlabpages.inria.fr/website/docs/ # # Run the "make cocci" target to just output what would be done, or "make cocci-inplace" # to apply the changes to the source tree. # # COCCI_FILES may be set on the command line, if you want to test just a single file # while it's under development. Otherwise, it is a list of all the files that are ready # to be run. # # ref-passed-variables-inited.cocci seems to be returning some false positives around # GHashTableIters, so it is disabled for the moment. COCCI_FILES ?= coccinelle/string-any-of.cocci \ coccinelle/string-empty.cocci \ coccinelle/string-null-matches.cocci \ coccinelle/use-func.cocci dist_noinst_SCRIPTS = coccinelle/test/testrunner.sh -EXTRA_DIST = README gdbhelpers $(COCCI_FILES) \ - coccinelle/ref-passed-variables-inited.cocci \ - coccinelle/rename-fn.cocci \ - coccinelle/test/ref-passed-variables-inited.input.c \ +EXTRA_DIST = README \ + gdbhelpers \ + $(COCCI_FILES) \ + coccinelle/ref-passed-variables-inited.cocci \ + coccinelle/rename-fn.cocci \ + coccinelle/test/ref-passed-variables-inited.input.c \ coccinelle/test/ref-passed-variables-inited.output # Any file in this list is allowed to use any of the pcmk__ internal functions. # Coccinelle can use any transformation that depends on "internal" to rewrite # code to use the internal functions. MAY_USE_INTERNAL_FILES = $(shell find .. -path "../lib/*.c" -o -path "../lib/*private.h" -o -path "../tools/*.c" -o -path "../daemons/*.c" -o -path '../include/pcmki/*h' -o -name '*internal.h') # And then any file in this list is public API, which may not use internal # functions. Thus, only those transformations that do not depend on "internal" # may be applied. OTHER_FILES = $(shell find ../include -name '*h' -a \! -name '*internal.h' -a \! -path '../include/pcmki/*') +.PHONY: cocci cocci: -for cf in $(COCCI_FILES); do \ for f in $(MAY_USE_INTERNAL_FILES); do \ spatch $(_SPATCH_FLAGS) -D internal --very-quiet --local-includes --preprocess --sp-file $$cf $$f; \ done ; \ for f in $(OTHER_FILES); do \ spatch $(_SPATCH_FLAGS) --very-quiet --local-includes --preprocess --sp-file $$cf $$f; \ done ; \ done +.PHONY: cocci-inplace cocci-inplace: $(MAKE) $(AM_MAKEFLAGS) _SPATCH_FLAGS=--in-place cocci +.PHONY: cocci-test cocci-test: for f in coccinelle/test/*.c; do \ coccinelle/test/testrunner.sh $$f; \ done # # Static analysis # ## clang # See scan-build(1) for possible checkers (leave empty to use default set) CLANG_checkers ?= +.PHONY: clang clang: OUT=$$(cd $(top_builddir) \ && scan-build $(CLANG_checkers:%=-enable-checker %) \ $(MAKE) $(AM_MAKEFLAGS) CFLAGS="-std=c99 $(CFLAGS)" \ clean all 2>&1); \ REPORT=$$(echo "$$OUT" \ | sed -n -e "s/.*'scan-view \(.*\)'.*/\1/p"); \ [ -z "$$REPORT" ] && echo "$$OUT" || scan-view "$$REPORT" ## coverity # Aggressiveness (low, medium, or high) COVLEVEL ?= low # Generated outputs COVERITY_DIR = $(abs_top_builddir)/coverity-$(TAG) COVTAR = $(abs_top_builddir)/$(PACKAGE)-coverity-$(TAG).tgz COVEMACS = $(abs_top_builddir)/$(TAG).coverity COVHTML = $(COVERITY_DIR)/output/errors # Coverity outputs are phony so they get rebuilt every invocation .PHONY: $(COVERITY_DIR) $(COVERITY_DIR): coverity-clean $(MAKE) $(AM_MAKEFLAGS) -C $(top_builddir) init core-clean $(AM_V_GEN)cd $(top_builddir) \ && cov-build --dir "$@" $(MAKE) $(AM_MAKEFLAGS) core # Public coverity instance .PHONY: $(COVTAR) $(COVTAR): $(COVERITY_DIR) $(AM_V_GEN)tar czf "$@" --transform="s@.*$(TAG)@cov-int@" "$<" .PHONY: coverity coverity: $(COVTAR) @echo "Now go to https://scan.coverity.com/users/sign_in and upload:" @echo " $(COVTAR)" @echo "then make clean at the top level" # Licensed coverity instance # # The prerequisites are a little hacky; rather than actually required, some # of them are designed so that things execute in the proper order (which is # not the same as GNU make's order-only prerequisites). .PHONY: coverity-analyze coverity-analyze: $(COVERITY_DIR) @echo "" @echo "Analyzing (waiting for coverity license if necessary) ..." cd $(top_builddir) && cov-analyze --dir "$<" --wait-for-license \ --security --aggressiveness-level "$(COVLEVEL)" .PHONY: $(COVEMACS) $(COVEMACS): coverity-analyze $(AM_V_GEN)cd $(top_builddir) \ && cov-format-errors --dir "$(COVERITY_DIR)" --emacs-style > "$@" .PHONY: $(COVHTML) $(COVHTML): $(COVEMACS) $(AM_V_GEN)cd $(top_builddir) \ && cov-format-errors --dir "$(COVERITY_DIR)" --html-output "$@" .PHONY: coverity-corp coverity-corp: $(COVHTML) $(MAKE) $(AM_MAKEFLAGS) -C $(top_builddir) core-clean @echo "Done. See:" @echo " file://$(COVHTML)/index.html" @echo "When no longer needed, make coverity-clean" # Remove all outputs regardless of tag .PHONY: coverity-clean coverity-clean: -rm -rf "$(abs_builddir)"/coverity-* \ "$(abs_builddir)"/$(PACKAGE)-coverity-*.tgz \ "$(abs_builddir)"/*.coverity ## cppcheck # Use CPPCHECK_ARGS to pass extra cppcheck options, e.g.: # --enable={warning,style,performance,portability,information,all} # --inconclusive --std=posix # -DBUILD_PUBLIC_LIBPACEMAKER -DDEFAULT_CONCURRENT_FENCING_TRUE CPPCHECK_ARGS ?= CPPCHECK_DIRS = replace lib daemons tools CPPCHECK_OUT = $(abs_top_builddir)/cppcheck.out +.PHONY: cppcheck cppcheck: cppcheck $(CPPCHECK_ARGS) -I $(top_srcdir)/include \ --output-file=$(CPPCHECK_OUT) \ --max-configs=30 --inline-suppr -q \ --library=posix --library=gnu --library=gtk \ $(GLIB_CFLAGS) -D__GNUC__ \ $(foreach dir,$(CPPCHECK_DIRS),$(top_srcdir)/$(dir)) @echo "Done: See $(CPPCHECK_OUT)" @echo "When no longer needed, make cppcheck-clean" .PHONY: cppcheck-clean cppcheck-clean: -rm -f "$(CPPCHECK_OUT)" # # Coverage/profiling # COVERAGE_DIR = $(top_builddir)/coverage # Check coverage of unit tests .PHONY: coverage coverage: coverage-partial-clean cd $(top_builddir) \ && $(MAKE) $(AM_MAKEFLAGS) \ && lcov --no-external --exclude='*_test.c' -c -i -d . \ -o pacemaker_base.info \ && $(MAKE) $(AM_MAKEFLAGS) check \ && lcov --no-external --exclude='*_test.c' -c -d . \ -o pacemaker_test.info \ && lcov -a pacemaker_base.info -a pacemaker_test.info \ -o pacemaker_total.info \ && lcov --remove pacemaker_total.info -o pacemaker_filtered.info\ "$(abs_top_builddir)/tools/*" \ "$(abs_top_builddir)/daemons/*/*" \ "$(abs_top_builddir)/replace/*" \ "$(abs_top_builddir)/lib/gnu/*" genhtml $(top_builddir)/pacemaker_filtered.info -o $(COVERAGE_DIR) -s -t "Pacemaker code coverage" # Check coverage of CLI regression tests .PHONY: coverage-cts coverage-cts: coverage-partial-clean cd $(top_builddir) \ && $(MAKE) $(AM_MAKEFLAGS) \ && lcov --no-external -c -i -d tools -o pacemaker_base.info \ && cts/cts-cli \ && lcov --no-external -c -d tools -o pacemaker_test.info \ && lcov -a pacemaker_base.info -a pacemaker_test.info \ -o pacemaker_total.info genhtml $(top_builddir)/pacemaker_total.info -o $(COVERAGE_DIR) -s # Remove coverage-related files that aren't needed across runs .PHONY: coverage-partial-clean coverage-partial-clean: -rm -f $(top_builddir)/pacemaker_*.info -rm -rf $(COVERAGE_DIR) -find $(top_builddir) -name "*.gcda" -exec rm -f \{\} \; # This target removes all coverage-related files. It is only to be run when # done with coverage analysis and you are ready to go back to normal development, # starting with re-running ./configure. It is not to be run in between # "make coverage" runs. # # In particular, the *.gcno files are generated when the source is built. # Removing those files will break "make coverage" until the whole source tree # has been built and the *.gcno files generated again. .PHONY: coverage-clean coverage-clean: coverage-partial-clean -find $(top_builddir) -name "*.gcno" -exec rm -f \{\} \; # # indent cannot cope with all our exceptions and needs heavy manual editing # # indent target: Limit indent to these directories INDENT_DIRS ?= . # indent target: Extra options to pass to indent INDENT_OPTS ?= INDENT_IGNORE_PATHS = daemons/controld/controld_fsa.h \ lib/gnu/* INDENT_PACEMAKER_STYLE = --blank-lines-after-declarations \ --blank-lines-after-procedures \ --braces-after-func-def-line \ --braces-on-if-line \ --braces-on-struct-decl-line \ --break-before-boolean-operator \ --case-brace-indentation4 \ --case-indentation4 \ --comment-indentation0 \ --continuation-indentation4 \ --continue-at-parentheses \ --cuddle-do-while \ --cuddle-else \ --declaration-comment-column0 \ --declaration-indentation1 \ --else-endif-column0 \ --honour-newlines \ --indent-label0 \ --indent-level4 \ --line-comments-indentation0 \ --line-length80 \ --no-blank-lines-after-commas \ --no-comment-delimiters-on-blank-lines \ --no-space-after-function-call-names \ --no-space-after-parentheses \ --no-tabs \ --preprocessor-indentation2 \ --procnames-start-lines \ --space-after-cast \ --start-left-side-of-comments \ --swallow-optional-blank-lines \ --tab-size8 +.PHONY: indent indent: VERSION_CONTROL=none \ find $(INDENT_DIRS) -type f -name "*.[ch]" \ $(INDENT_IGNORE_PATHS:%= ! -path '%') \ -exec indent $(INDENT_PACEMAKER_STYLE) $(INDENT_OPTS) \{\} \; # # Scratch file for ad-hoc testing # EXTRA_PROGRAMS = scratch nodist_scratch_SOURCES = scratch.c scratch_LDADD = $(top_builddir)/lib/common/libcrmcommon.la +.PHONY: clean-local clean-local: coverage-clean coverity-clean cppcheck-clean -rm -f $(EXTRA_PROGRAMS) diff --git a/doc/Makefile.am b/doc/Makefile.am index 14001457ad..a40ddfe628 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -1,152 +1,171 @@ # -# Copyright 2003-2021 the Pacemaker project contributors +# Copyright 2003-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. # include $(top_srcdir)/mk/common.mk # Define release-related variables include $(top_srcdir)/mk/release.mk # What formats to use for book uploads (i.e. "make www"; # use BOOK_FORMATS in sphinx subdirectory to change local builds) -BOOK_FORMATS ?= html singlehtml pdf epub +BOOK_FORMATS ?= html \ + singlehtml \ + pdf \ + epub # SNMP MIB mibdir = $(datadir)/snmp/mibs dist_mib_DATA = PCMK-MIB.txt # Deprecated plaintext documents (dynamically converted to HTML) DEPRECATED_ORIGINAL = crm_fencing.txt DEPRECATED_GENERATED = if BUILD_ASCIIDOC DEPRECATED_GENERATED += $(DEPRECATED_ORIGINAL:%.txt=%.html) endif -DEPRECATED_ALL = $(DEPRECATED_ORIGINAL) $(DEPRECATED_GENERATED) +DEPRECATED_ALL = $(DEPRECATED_ORIGINAL) \ + $(DEPRECATED_GENERATED) doc_DATA = $(DEPRECATED_ALL) noinst_SCRIPTS = abi-check SUBDIRS = sphinx EXTRA_DIST = $(DEPRECATED_ORIGINAL) # toplevel rsync destination for www targets (without trailing slash) RSYNC_DEST ?= root@www.clusterlabs.org:/var/www/html # recursive, preserve symlinks/permissions/times, verbose, compress, # don't cross filesystems, sparse, show progress RSYNC_OPTS = -rlptvzxS --progress if IS_ASCIIDOC ASCIIDOC_HTML_ARGS = --unsafe --backend=xhtml11 ASCIIDOC_DBOOK_ARGS = -b docbook -d book else ASCIIDOC_HTML_ARGS = --backend=html5 ASCIIDOC_DBOOK_ARGS = -b docbook45 -d book endif %.html: %.txt $(AM_V_GEN)$(ASCIIDOC_CONV) $(ASCIIDOC_HTML_ARGS) --out-file=$@ $< $(PCMK_quiet) # For Makefile debugging .PHONY: vars vars: @echo DEPRECATED_ORIGINAL=\'$(DEPRECATED_ORIGINAL)\' @echo DEPRECATED_GENERATED=\'$(DEPRECATED_GENERATED)\' @echo LAST_RELEASE=\'$(LAST_RELEASE)\' @echo TAG=\'$(TAG)\' .PHONY: deprecated-upload deprecated-upload: $(DEPRECATED_ALL) rsync $(RSYNC_OPTS) $(DEPRECATED_ALL) "$(RSYNC_DEST)/$(PACKAGE)/doc/" .PHONY: deprecated-clean deprecated-clean: -rm -f $(DEPRECATED_GENERATED) # Annotated source code as HTML # Cleaning first ensures we don't index unrelated stuff like RPM sources +.PHONY: global global: $(MAKE) $(AM_MAKEFLAGS) -C .. clean-generic $(MAKE) $(AM_MAKEFLAGS) -C ../rpm rpm-clean cd .. && gtags -q && htags -sanhIT doc +.PHONY: global-upload global-upload: global rsync $(RSYNC_OPTS) HTML/ "$(RSYNC_DEST)/$(PACKAGE)/global/$(TAG)/" +.PHONY: global-clean global-clean: -rm -rf HTML # Man pages as HTML %.8.html: %.8 groff -mandoc `man -w ./$<` -T html > $@ %.7.html: %.7 groff -mandoc `man -w ./$<` -T html > $@ +.PHONY: manhtml manhtml: $(MAKE) $(AM_MAKEFLAGS) -C .. all find .. -name "[a-z]*.[78]" -exec $(MAKE) $(AM_MAKEFLAGS) \{\}.html \; +.PHONY: manhtml-upload manhtml-upload: manhtml find .. -name "[a-z]*.[78].html" -exec \ rsync $(RSYNC_OPTS) \{\} "$(RSYNC_DEST)/$(PACKAGE)/man/" \; +.PHONY: manhtml-clean manhtml-clean: -find .. -name "[a-z]*.[78].html" -exec rm \{\} \; # API documentation as HTML +.PHONY: doxygen doxygen: Doxyfile doxygen Doxyfile +.PHONY: doxygen-upload doxygen-upload: doxygen rsync $(RSYNC_OPTS) api/html/ "$(RSYNC_DEST)/$(PACKAGE)/doxygen/$(TAG)/" +.PHONY: doxygen-clean doxygen-clean: -rm -rf api # ABI compatibility report as HTML +.PHONY: abi abi: abi-check ./abi-check $(PACKAGE) $(LAST_RELEASE) $(TAG) +.PHONY: abi-www abi-www: export RSYNC_DEST=$(RSYNC_DEST); ./abi-check -u $(PACKAGE) $(LAST_RELEASE) $(TAG) +.PHONY: abi-clean abi-clean: -rm -rf abi_dumps compat_reports # The main documentation books (which are actually in the sphinx subdirectory) +.PHONY: books-upload books-upload: $(MAKE) $(AM_MAKEFLAGS) -C sphinx clean $(MAKE) $(AM_MAKEFLAGS) -C sphinx \ RSYNC_DEST="$(RSYNC_DEST)" \ BOOK_FORMATS="$(BOOK_FORMATS)" \ books-upload # All online documentation (except ABI compatibility, which is run separately) .PHONY: www www: clean-local deprecated-upload manhtml-upload global-upload doxygen-upload books-upload +.PHONY: clean-local clean-local: global-clean manhtml-clean doxygen-clean abi-clean deprecated-clean # "make check" will cause "make all" to be run, which means docs will get built # as a part of running tests if they haven't already. That seems unnecessary, so # override the default check-recursive rule with this one that just returns. If # we ever need to add tests to this directory, this rule will have to come out. +.PHONY: check-recursive check-recursive: @true diff --git a/doc/abi-check.in b/doc/abi-check.in index 5a5e253f74..6b6a8d3d78 100755 --- a/doc/abi-check.in +++ b/doc/abi-check.in @@ -1,158 +1,164 @@ #!@BASH_PATH@ # -# Copyright 2011-2022 the Pacemaker project contributors +# 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. # # # abi-check [-u] [...] # # Build ABI dumps for all listed versions. If exactly two are given, # build an ABI compatibility report for them, and if -u is given, # upload it to the website. # # Top-level rsync destination for www targets (without trailing slash) : ${RSYNC_DEST:=root@www.clusterlabs.org:/var/www/html} # If the argument is of form x.y.z, print Pacemaker-x.y.z, # otherwise print the argument (presumably a commit ID) directly tag() { if [[ "$1" =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3} ]]; then echo "Pacemaker-$1" else echo "$1" fi } +sed_in_place() { + cp -p "$1" "$1.$$" + sed -e "$2" "$1" > "$1.$$" + mv "$1.$$" "$1" +} + # Strip anything up to and including a dash from the argument version() { echo "$1" | sed s:.*-:: } # Create configuration file for ABI dumper abi_config() { PACKAGE="$1" VERSION="$2" BUILD_ROOT="$3" DESC="$4" # Create header DESC="$BUILD_ROOT/$VERSION.xml" cat < "$DESC" $VERSION $BUILD_ROOT/root/usr/include/$PACKAGE/crm EOF # Build checkout, installing into subdirectory ( cd "$BUILD_ROOT" && ./autogen.sh && ./configure --disable-fatal-warnings ) make -C "$BUILD_ROOT" V=0 DESTDIR="${BUILD_ROOT}/root" install if [ $? -ne 0 ]; then echo "Build for $TAG failed. Repair, populate and re-run: " echo " abi-compliance-checker -l $PACKAGE -dump_abi $DESC" echo "" echo "To find libraries after building:" echo " find $BUILD_ROOT/root -name "*.so" -print" exit 1 fi # Add library names to configuration file find $BUILD_ROOT/root -name "*.so" -print >> $DESC # Add footer cat <> "$DESC" EOF } # Dump the ABI for a particular version extract_one() { TAG="$1" VERSION="$2" # If dump already exists, remove it if dumping HEAD (which changes), # otherwise use it (a dump for a particular commit stays the same). TARBALL="abi_dumps/$PACKAGE/${PACKAGE}_$VERSION.abi.tar.gz" if [ "$VERSION" = HEAD ]; then rm -rf "$TARBALL" elif [ -f "$TARBALL" ]; then return fi echo "Building ABI dump for $*" # Get a clean checkout at the desired commit BUILD_ROOT=".ABI-build" rm -rf "$BUILD_ROOT" ( cd .. ; git archive --prefix "doc/$BUILD_ROOT/" "$TAG" | tar xv ) if [ $? -ne 0 ]; then exit fi # Remove "doc" from SUBDIRS in Makefile (but why?) BUILD_ROOT="$(pwd)/$BUILD_ROOT" - sed -i.sed 's: doc::' "$BUILD_ROOT/Makefile.am" + sed_in_place "$BUILD_ROOT/Makefile.am" 's: doc::' # Run ABI dump abi_config "$PACKAGE" "$VERSION" "$BUILD_ROOT" "$DESC" abi-compliance-checker -l "$PACKAGE" -dump_abi "$DESC" \ -dump-path "abi_dumps/${PACKAGE}/${PACKAGE}_${VERSION}.abi.tar.gz" # Clean up rm -rf "$BUILD_ROOT" } extract_all() { for arg in $*; do T=$(tag "$arg") V=$(version "$T") extract_one "$T" "$V" done } die() { echo "$@" 1>&2 exit 1 } which git 2>/dev/null || die "abi-check: git must be installed" git rev-parse --git-dir >/dev/null 2>/dev/null \ || die "abi-check: must be run from git checkout" UPLOAD=0 if [ "$1" = "-u" ]; then UPLOAD=1; shift fi PACKAGE="$1"; shift extract_all "$@" if [ $# -eq 2 ]; then V1=$(version "$1") V2=$(version "$2") abi-compliance-checker -l ${PACKAGE} \ -d1 abi_dumps/${PACKAGE}/${PACKAGE}_${V1}.abi.tar.gz \ -d2 abi_dumps/${PACKAGE}/${PACKAGE}_${V2}.abi.tar.gz if [ $? -ne 0 ]; then echo "WARNING: compliance checker exited $?" fi COMPAT_REPORT="compat_reports/${PACKAGE}/${V1}_to_${V2}" if [ $UPLOAD -eq 1 ] && [ -d "$COMPAT_REPORT" ]; then rsync -azxlSD --progress "$COMPAT_REPORT" "${RSYNC_DEST}/${PACKAGE}/abi/" fi fi diff --git a/doc/sphinx/Makefile.am b/doc/sphinx/Makefile.am index e144172a09..dc7ded2058 100644 --- a/doc/sphinx/Makefile.am +++ b/doc/sphinx/Makefile.am @@ -1,200 +1,214 @@ # # Copyright 2003-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. # include $(top_srcdir)/mk/common.mk # Define release-related variables include $(top_srcdir)/mk/release.mk # Things you might want to override on the command line # Books to generate BOOKS ?= Clusters_from_Scratch \ Pacemaker_Administration \ Pacemaker_Development \ Pacemaker_Explained \ Pacemaker_Python_API \ Pacemaker_Remote # Output formats to generate. Possible values: # html (multiple HTML files) # dirhtml (HTML files named index.html in multiple directories) # singlehtml (a single large HTML file) # text # pdf # epub # latex # linkcheck (not actually a format; check validity of external links) # # The results will end up in /_build/ BOOK_FORMATS ?= singlehtml # Set to "a4paper" or "letterpaper" if building latex format PAPER ?= letterpaper # Additional options for sphinx-build SPHINXFLAGS ?= # toplevel rsync destination for www targets (without trailing slash) RSYNC_DEST ?= root@www.clusterlabs.org:/var/www/html # End of useful overrides # Example scheduler transition graphs # @TODO The original CIB XML for these is long lost. Ideally, we would recreate # something similar and keep those here instead of the DOTs (or use a couple of # scheduler regression test inputs instead), then regenerate the SVG # equivalents using crm_simulate and dot when making a release. DOTS = $(wildcard shared/images/*.dot) # Vector sources for generated PNGs (including SVG equivalents of DOTS, created # manually using dot) -SVGS = $(wildcard shared/images/pcmk-*.svg) $(DOTS:%.dot=%.svg) +SVGS = $(wildcard shared/images/pcmk-*.svg) \ + $(DOTS:%.dot=%.svg) # PNG images generated from SVGS # # These will not be accessible in a VPATH build, which will generate warnings # when building the documentation, but the make will still succeed. It is # nontrivial to get them working for VPATH builds and not worth the effort. PNGS_GENERATED = $(SVGS:%.svg=%.png) # Original PNG image sources PNGS_Clusters_from_Scratch = $(wildcard Clusters_from_Scratch/images/*.png) PNGS_Pacemaker_Explained = $(wildcard Pacemaker_Explained/images/*.png) PNGS_Pacemaker_Remote = $(wildcard Pacemaker_Remote/images/*.png) STATIC_FILES = $(wildcard _static/*.css) -EXTRA_DIST = $(wildcard */*.rst) $(DOTS) $(SVGS) \ - $(PNGS_Clusters_from_Scratch) \ - $(PNGS_Pacemaker_Explained) \ - $(PNGS_Pacemaker_Remote) \ - $(wildcard Pacemaker_Python_API/_templates/*rst) \ - $(STATIC_FILES) \ +EXTRA_DIST = $(wildcard */*.rst) $(DOTS) $(SVGS) \ + $(PNGS_Clusters_from_Scratch) \ + $(PNGS_Pacemaker_Explained) \ + $(PNGS_Pacemaker_Remote) \ + $(wildcard Pacemaker_Python_API/_templates/*rst) \ + $(STATIC_FILES) \ conf.py.in # recursive, preserve symlinks/permissions/times, verbose, compress, # don't cross filesystems, sparse, show progress RSYNC_OPTS = -rlptvzxS --progress PACKAGE_SERIES=$(shell echo "$VERSION" | awk -F. '{ print $1"."$2 }'`) BOOK_RSYNC_DEST = $(RSYNC_DEST)/$(PACKAGE)/doc/$(PACKAGE_SERIES) BOOK = none -DEPS_intro = shared/pacemaker-intro.rst $(PNGS_GENERATED) +DEPS_intro = shared/pacemaker-intro.rst \ + $(PNGS_GENERATED) -DEPS_Clusters_from_Scratch = $(DEPS_intro) $(PNGS_Clusters_from_Scratch) +DEPS_Clusters_from_Scratch = $(DEPS_intro) \ + $(PNGS_Clusters_from_Scratch) DEPS_Pacemaker_Administration = $(DEPS_intro) DEPS_Pacemaker_Development = -DEPS_Pacemaker_Explained = $(DEPS_intro) $(PNGS_Pacemaker_Explained) +DEPS_Pacemaker_Explained = $(DEPS_intro) \ + $(PNGS_Pacemaker_Explained) DEPS_Pacemaker_Python_API = ../../python DEPS_Pacemaker_Remote = $(PNGS_Pacemaker_Remote) if BUILD_SPHINX_DOCS INKSCAPE_CMD = $(INKSCAPE) --export-dpi=90 -C # Pattern rule to generate PNGs from SVGs # (--export-png works with Inkscape <1.0, --export-filename with >=1.0; # create the destination directory in case this is a VPATH build) %.png: %.svg $(AM_V_at)-$(MKDIR_P) "$(shell dirname "$@")" $(AM_V_GEN) { \ $(INKSCAPE_CMD) --export-png="$@" "$<" 2>/dev/null \ || $(INKSCAPE_CMD) --export-filename="$@" "$<"; \ } $(PCMK_quiet) # Create a book's Sphinx configuration. # Create the book directory in case this is a VPATH build. $(BOOKS:%=%/conf.py): conf.py.in $(AM_V_at)-$(MKDIR_P) "$(@:%/conf.py=%)" $(AM_V_GEN)sed \ -e 's/%VERSION%/$(VERSION)/g' \ -e 's/%BOOK_ID%/$(@:%/conf.py=%)/g' \ -e 's/%BOOK_TITLE%/$(subst _, ,$(@:%/conf.py=%))/g' \ -e 's#%SRC_DIR%#$(abs_srcdir)#g' \ -e 's#%ABS_TOP_SRCDIR%#$(abs_top_srcdir)#g' \ $(<) > "$@" $(BOOK)/_build: $(STATIC_FILES) $(BOOK)/conf.py $(DEPS_$(BOOK)) $(wildcard $(srcdir)/$(BOOK)/*.rst) @echo 'Building "$(subst _, ,$(BOOK))" because of $?' $(PCMK_quiet) $(AM_V_at)rm -rf "$@" $(AM_V_BOOK)for format in $(BOOK_FORMATS); do \ echo -e "\n * Building $$format" $(PCMK_quiet); \ doctrees="doctrees"; \ real_format="$$format"; \ case "$$format" in \ pdf) real_format="latex" ;; \ gettext) doctrees="gettext-doctrees" ;; \ esac; \ $(SPHINX) -b "$$real_format" -d "$@/$$doctrees" \ -c "$(builddir)/$(BOOK)" \ -D latex_elements.papersize=$(PAPER) \ $(SPHINXFLAGS) \ "$(srcdir)/$(BOOK)" "$@/$$format" \ $(PCMK_quiet); \ if [ "$$format" = "pdf" ]; then \ $(MAKE) $(AM_MAKEFLAGS) -C "$@/$$format" \ all-pdf; \ fi; \ done endif build-$(PACKAGE_SERIES).txt: all $(AM_V_GEN)echo "Generated on `date --utc` from version $(TAG)" > "$@" .PHONY: books-upload books-upload: all build-$(PACKAGE_SERIES).txt if BUILD_SPHINX_DOCS @echo "Uploading $(PACKAGE_SERIES) documentation set" @for book in $(BOOKS); do \ echo " * $$book"; \ rsync $(RSYNC_OPTS) $(BOOK_FORMATS:%=$$book/_build/%) \ "$(BOOK_RSYNC_DEST)/$$book/"; \ done @rsync $(RSYNC_OPTS) "$(builddir)/build-$(PACKAGE_SERIES).txt" \ "$(RSYNC_DEST)/$(PACKAGE)/doc" +endif +.PHONY: all-local all-local: +if BUILD_SPHINX_DOCS @for book in $(BOOKS); do \ $(MAKE) $(AM_MAKEFLAGS) BOOK=$$book \ PAPER="$(PAPER)" SPHINXFLAGS="$(SPHINXFLAGS)" \ BOOK_FORMATS="$(BOOK_FORMATS)" $$book/_build; \ done +endif +.PHONY: install-data-local install-data-local: all-local +if BUILD_SPHINX_DOCS $(AM_V_at)for book in $(BOOKS); do \ for format in $(BOOK_FORMATS); do \ formatdir="$$book/_build/$$format"; \ for f in `find "$$formatdir" -print`; do \ dname="`echo $$f | sed s:_build/::`"; \ dloc="$(DESTDIR)/$(docdir)/$$dname"; \ if [ -d "$$f" ]; then \ $(INSTALL) -d -m 755 "$$dloc"; \ else \ $(INSTALL_DATA) "$$f" "$$dloc"; \ fi \ done; \ done; \ done +endif +.PHONY: uninstall-local uninstall-local: +if BUILD_SPHINX_DOCS $(AM_V_at)for book in $(BOOKS); do \ rm -rf "$(DESTDIR)/$(docdir)/$$book"; \ done endif +.PHONY: clean-local clean-local: $(AM_V_at)-rm -rf \ $(BOOKS:%="$(builddir)/%/_build") \ $(BOOKS:%="$(builddir)/%/conf.py") \ $(BOOKS:%="$(builddir)/%/generated") \ $(PNGS_GENERATED) diff --git a/etc/Makefile.am b/etc/Makefile.am index b810f82db9..b90bb50db6 100644 --- a/etc/Makefile.am +++ b/etc/Makefile.am @@ -1,38 +1,41 @@ # -# Copyright 2021-2022 the Pacemaker project contributors +# Copyright 2021-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. # MAINTAINERCLEANFILES = Makefile.in configdir = @CONFIGDIR@ -CONFIGS = crm_mon pacemaker +CONFIGS = crm_mon \ + pacemaker if !BUILD_SYSTEMD initdir = $(INITDIR) init_SCRIPTS = init.d/pacemaker endif logrotatedir = $(sysconfdir)/logrotate.d logrotate_DATA = logrotate.d/pacemaker EXTRA_DIST = $(foreach f,$(CONFIGS),sysconfig/$(f)) # Don't overwrite user's existing config files +.PHONY: install-data-local install-data-local: $(AM_V_at)$(MKDIR_P) $(DESTDIR)$(configdir) $(AM_V_at)for f in $(CONFIGS); do \ dest="$(DESTDIR)$(configdir)/$$f"; \ [ -e "$$dest" ] && dest="$$dest.new"; \ $(INSTALL_DATA) "$(srcdir)/sysconfig/$$f" "$$dest"; \ done +.PHONY: uninstall-local uninstall-local: $(AM_V_at)for f in $(CONFIGS); do \ dest="$(DESTDIR)$(configdir)/$$f"; \ rm -f "$$dest" "$$dest.new"; \ done diff --git a/include/Makefile.am b/include/Makefile.am index ffc25068ae..6618c7a5a4 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -1,40 +1,42 @@ # # Copyright 2003-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. # -MAINTAINERCLEANFILES = Makefile.in config.h.in +MAINTAINERCLEANFILES = Makefile.in \ + config.h.in -noinst_HEADERS = config.h \ - crm_internal.h \ - doxygen.h \ - pacemaker.h \ - pacemaker-internal.h \ - portability.h \ +noinst_HEADERS = config.h \ + crm_internal.h \ + doxygen.h \ + pacemaker.h \ + pacemaker-internal.h \ + portability.h \ gettext.h pkginclude_HEADERS = crm_config.h SUBDIRS = crm pcmki # gettext.h is supplied by the gettext project GETTEXT_H ?= $(datadir)/gettext/gettext.h +.PHONY: update-gettext update-gettext: @if [ ! -e "$(GETTEXT_H)" ]; then \ echo "$(GETTEXT_H) not found"; \ else \ cp "$(GETTEXT_H)" gettext.h; \ "$(GIT)" diff --quiet gettext.h 2>/dev/null; \ if [ $$? -eq 0 ]; then \ echo "No update needed"; \ else \ "$(GIT)" add gettext.h; \ echo 'Review changes then run:'; \ echo 'git commit -m "Low: NLS: update gettext.h from upstream"'; \ fi \ fi diff --git a/include/crm/Makefile.am b/include/crm/Makefile.am index fcba5a7c3b..95564b8786 100644 --- a/include/crm/Makefile.am +++ b/include/crm/Makefile.am @@ -1,29 +1,33 @@ # # Copyright 2004-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. # MAINTAINERCLEANFILES = Makefile.in headerdir=$(pkgincludedir)/crm header_HEADERS = cib.h \ cluster.h \ compatibility.h \ crm.h \ crm_compat.h \ lrmd.h \ lrmd_events.h \ msg_xml.h \ msg_xml_compat.h \ services.h \ services_compat.h \ stonith-ng.h -noinst_HEADERS = lrmd_internal.h services_internal.h +noinst_HEADERS = $(wildcard *_internal.h) -SUBDIRS = common pengine cib fencing cluster +SUBDIRS = common \ + pengine \ + cib \ + fencing \ + cluster diff --git a/include/crm/cluster/Makefile.am b/include/crm/cluster/Makefile.am index 96f2bd0eb5..2500a87581 100644 --- a/include/crm/cluster/Makefile.am +++ b/include/crm/cluster/Makefile.am @@ -1,14 +1,15 @@ # -# Copyright 2012-2021 the Pacemaker project contributors +# Copyright 2012-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. # MAINTAINERCLEANFILES = Makefile.in headerdir=$(pkgincludedir)/crm/cluster -noinst_HEADERS = internal.h election_internal.h +noinst_HEADERS = internal.h \ + $(wildcard *_internal.h) header_HEADERS = compat.h diff --git a/include/crm/common/Makefile.am b/include/crm/common/Makefile.am index d5fd578830..f54b30903c 100644 --- a/include/crm/common/Makefile.am +++ b/include/crm/common/Makefile.am @@ -1,63 +1,41 @@ # # Copyright 2004-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. # MAINTAINERCLEANFILES = Makefile.in headerdir=$(pkgincludedir)/crm/common -header_HEADERS = acl.h \ +header_HEADERS = acl.h \ actions.h \ - agents.h \ - agents_compat.h \ - cib.h \ - ipc.h \ - ipc_attrd_internal.h \ - ipc_controld.h \ - ipc_pacemakerd.h \ - ipc_schedulerd.h \ - iso8601.h \ - logging.h \ - logging_compat.h \ - mainloop.h \ - mainloop_compat.h \ - nodes.h \ - nvpair.h \ - output.h \ - resources.h \ - results.h \ - results_compat.h \ - roles.h \ - scheduler.h \ - util.h \ - util_compat.h \ - xml.h \ - xml_compat.h + agents.h \ + agents_compat.h \ + cib.h \ + ipc.h \ + ipc_controld.h \ + ipc_pacemakerd.h \ + ipc_schedulerd.h \ + iso8601.h \ + logging.h \ + logging_compat.h \ + mainloop.h \ + mainloop_compat.h \ + nodes.h \ + nvpair.h \ + output.h \ + resources.h \ + results.h \ + results_compat.h \ + roles.h \ + scheduler.h \ + util.h \ + util_compat.h \ + xml.h \ + xml_compat.h -noinst_HEADERS = acl_internal.h \ - actions_internal.h \ - alerts_internal.h \ - attrd_internal.h \ - cmdline_internal.h \ - health_internal.h \ - internal.h \ - io_internal.h \ - ipc_internal.h \ - iso8601_internal.h \ - lists_internal.h \ - logging_internal.h \ - messages_internal.h \ - options_internal.h \ - output_internal.h \ - remote_internal.h \ - results_internal.h \ - roles_internal.h \ - scheduler_internal.h \ - strings_internal.h \ - unittest_internal.h \ - xml_internal.h +noinst_HEADERS = $(wildcard *internal.h) diff --git a/include/crm/pengine/Makefile.am b/include/crm/pengine/Makefile.am index fac60317a3..3560d24613 100644 --- a/include/crm/pengine/Makefile.am +++ b/include/crm/pengine/Makefile.am @@ -1,17 +1,22 @@ # -# Copyright 2006-2021 the Pacemaker project contributors +# Copyright 2006-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. # MAINTAINERCLEANFILES = Makefile.in headerdir=$(pkgincludedir)/crm/pengine -noinst_HEADERS = internal.h remote_internal.h rules_internal.h -header_HEADERS = common.h complex.h pe_types.h rules.h status.h \ +noinst_HEADERS = internal.h \ + $(wildcard *_internal.h) +header_HEADERS = common.h \ + complex.h \ + pe_types.h \ + rules.h \ + status.h \ common_compat.h \ pe_types_compat.h \ rules_compat.h diff --git a/include/pcmki/Makefile.am b/include/pcmki/Makefile.am index 824ef6c838..b9475af13f 100644 --- a/include/pcmki/Makefile.am +++ b/include/pcmki/Makefile.am @@ -1,24 +1,14 @@ # # Copyright 2019-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. # MAINTAINERCLEANFILES = Makefile.in -noinst_HEADERS = pcmki_acl.h \ - pcmki_cluster_queries.h \ - pcmki_fence.h \ - pcmki_output.h \ - pcmki_resource.h \ - pcmki_result_code.h \ - pcmki_rule.h \ - pcmki_scheduler.h \ - pcmki_simulate.h \ - pcmki_status.h \ - pcmki_transition.h +noinst_HEADERS = $(wildcard *.h) .PHONY: $(ARCHIVE_VERSION) diff --git a/lib/Makefile.am b/lib/Makefile.am index ed5bfa3964..52cf9742c1 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -1,21 +1,33 @@ # -# Copyright 2003-2021 the Pacemaker project contributors +# Copyright 2003-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. # MAINTAINERCLEANFILES = Makefile.in -LIBS = cib lrmd service fencing cluster +LIBS = cib \ + lrmd \ + service \ + fencing \ + cluster pkgconfig_DATA = $(LIBS:%=pacemaker-%.pc) \ libpacemaker.pc \ pacemaker.pc \ pacemaker-pe_rules.pc \ pacemaker-pe_status.pc EXTRA_DIST = $(pkgconfig_DATA:%=%.in) -SUBDIRS = gnu common pengine cib services fencing lrmd cluster pacemaker +SUBDIRS = gnu \ + common \ + pengine \ + cib \ + services \ + fencing \ + lrmd \ + cluster \ + pacemaker diff --git a/lib/cib/Makefile.am b/lib/cib/Makefile.am index 721fca1ffa..2fe5f6b17b 100644 --- a/lib/cib/Makefile.am +++ b/lib/cib/Makefile.am @@ -1,28 +1,30 @@ # -# Copyright 2004-2018 the Pacemaker project contributors +# Copyright 2004-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. # include $(top_srcdir)/mk/common.mk ## libraries lib_LTLIBRARIES = libcib.la ## SOURCES -libcib_la_SOURCES = cib_ops.c cib_utils.c cib_client.c cib_native.c cib_attrs.c -libcib_la_SOURCES += cib_file.c cib_remote.c +libcib_la_SOURCES = cib_ops.c \ + cib_utils.c \ + cib_client.c \ + cib_native.c \ + cib_attrs.c \ + cib_file.c \ + cib_remote.c libcib_la_LDFLAGS = -version-info 31:0:4 libcib_la_CPPFLAGS = -I$(top_srcdir) $(AM_CPPFLAGS) libcib_la_CFLAGS = $(CFLAGS_HARDENED_LIB) libcib_la_LDFLAGS += $(LDFLAGS_HARDENED_LIB) -libcib_la_LIBADD = $(top_builddir)/lib/pengine/libpe_rules.la \ - $(top_builddir)/lib/common/libcrmcommon.la - -clean-generic: - rm -f *.log *.debug *.xml *~ +libcib_la_LIBADD = $(top_builddir)/lib/pengine/libpe_rules.la \ + $(top_builddir)/lib/common/libcrmcommon.la diff --git a/lib/cluster/Makefile.am b/lib/cluster/Makefile.am index 9225f29152..d145330f23 100644 --- a/lib/cluster/Makefile.am +++ b/lib/cluster/Makefile.am @@ -1,29 +1,31 @@ # -# Copyright 2004-2018 the Pacemaker project contributors +# Copyright 2004-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. # include $(top_srcdir)/mk/common.mk noinst_HEADERS = crmcluster_private.h ## libraries lib_LTLIBRARIES = libcrmcluster.la libcrmcluster_la_LDFLAGS = -version-info 30:0:1 libcrmcluster_la_CFLAGS = $(CFLAGS_HARDENED_LIB) libcrmcluster_la_LDFLAGS += $(LDFLAGS_HARDENED_LIB) -libcrmcluster_la_LIBADD = $(top_builddir)/lib/common/libcrmcommon.la $(top_builddir)/lib/fencing/libstonithd.la $(CLUSTERLIBS) +libcrmcluster_la_LIBADD = $(top_builddir)/lib/fencing/libstonithd.la +libcrmcluster_la_LIBADD += $(top_builddir)/lib/common/libcrmcommon.la +libcrmcluster_la_LIBADD += $(CLUSTERLIBS) -libcrmcluster_la_SOURCES = election.c cluster.c membership.c +libcrmcluster_la_SOURCES = election.c \ + cluster.c \ + membership.c if BUILD_CS_SUPPORT -libcrmcluster_la_SOURCES += cpg.c corosync.c +libcrmcluster_la_SOURCES += cpg.c \ + corosync.c endif - -clean-generic: - rm -f *.log *.debug *.xml *~ diff --git a/lib/common/Makefile.am b/lib/common/Makefile.am index 03a2f66a5c..5442fa08e1 100644 --- a/lib/common/Makefile.am +++ b/lib/common/Makefile.am @@ -1,125 +1,132 @@ # # Copyright 2004-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. # include $(top_srcdir)/mk/common.mk -AM_CPPFLAGS += -I$(top_builddir)/lib/gnu -I$(top_srcdir)/lib/gnu +AM_CPPFLAGS += -I$(top_builddir)/lib/gnu \ + -I$(top_srcdir)/lib/gnu ## libraries lib_LTLIBRARIES = libcrmcommon.la check_LTLIBRARIES = libcrmcommon_test.la # Disable -Wcast-qual if used, because we do some hacky casting, # and because libxml2 has some signatures that should be const but aren't # for backward compatibility reasons. # s390 needs -fPIC # s390-suse-linux/bin/ld: .libs/ipc.o: relocation R_390_PC32DBL against `__stack_chk_fail@@GLIBC_2.4' can not be used when making a shared object; recompile with -fPIC CFLAGS = $(CFLAGS_COPY:-Wcast-qual=) -fPIC # Without "." here, check-recursive will run through the subdirectories first # and then run "make check" here. This will fail, because there's things in # the subdirectories that need check_LTLIBRARIES built first. Adding "." here # changes the order so the subdirectories are processed afterwards. SUBDIRS = . tests -noinst_HEADERS = crmcommon_private.h mock_private.h +noinst_HEADERS = crmcommon_private.h \ + mock_private.h libcrmcommon_la_LDFLAGS = -version-info 45:0:11 libcrmcommon_la_CFLAGS = $(CFLAGS_HARDENED_LIB) libcrmcommon_la_LDFLAGS += $(LDFLAGS_HARDENED_LIB) -libcrmcommon_la_LIBADD = @LIBADD_DL@ $(top_builddir)/lib/gnu/libgnu.la +libcrmcommon_la_LIBADD = @LIBADD_DL@ \ + $(top_builddir)/lib/gnu/libgnu.la # If configured with --with-profiling or --with-coverage, BUILD_PROFILING will # be set and -fno-builtin will be added to the CFLAGS. However, libcrmcommon # uses the fabs() function which is normally supplied by gcc as one of its # builtins. Therefore we need to explicitly link against libm here or the # tests won't link. if BUILD_PROFILING libcrmcommon_la_LIBADD += -lm endif # Use += rather than backlashed continuation lines for parsing by bumplibs libcrmcommon_la_SOURCES = libcrmcommon_la_SOURCES += acl.c libcrmcommon_la_SOURCES += actions.c libcrmcommon_la_SOURCES += agents.c libcrmcommon_la_SOURCES += alerts.c libcrmcommon_la_SOURCES += attrs.c libcrmcommon_la_SOURCES += cib.c if BUILD_CIBSECRETS libcrmcommon_la_SOURCES += cib_secrets.c endif libcrmcommon_la_SOURCES += cmdline.c libcrmcommon_la_SOURCES += digest.c libcrmcommon_la_SOURCES += health.c libcrmcommon_la_SOURCES += io.c libcrmcommon_la_SOURCES += ipc_attrd.c libcrmcommon_la_SOURCES += ipc_client.c libcrmcommon_la_SOURCES += ipc_common.c libcrmcommon_la_SOURCES += ipc_controld.c libcrmcommon_la_SOURCES += ipc_pacemakerd.c libcrmcommon_la_SOURCES += ipc_schedulerd.c libcrmcommon_la_SOURCES += ipc_server.c libcrmcommon_la_SOURCES += iso8601.c libcrmcommon_la_SOURCES += lists.c libcrmcommon_la_SOURCES += logging.c libcrmcommon_la_SOURCES += mainloop.c libcrmcommon_la_SOURCES += messages.c libcrmcommon_la_SOURCES += nodes.c libcrmcommon_la_SOURCES += nvpair.c libcrmcommon_la_SOURCES += options.c libcrmcommon_la_SOURCES += output.c libcrmcommon_la_SOURCES += output_html.c libcrmcommon_la_SOURCES += output_log.c libcrmcommon_la_SOURCES += output_none.c libcrmcommon_la_SOURCES += output_text.c libcrmcommon_la_SOURCES += output_xml.c libcrmcommon_la_SOURCES += patchset.c libcrmcommon_la_SOURCES += patchset_display.c libcrmcommon_la_SOURCES += pid.c libcrmcommon_la_SOURCES += procfs.c libcrmcommon_la_SOURCES += remote.c libcrmcommon_la_SOURCES += results.c libcrmcommon_la_SOURCES += schemas.c libcrmcommon_la_SOURCES += scores.c libcrmcommon_la_SOURCES += strings.c libcrmcommon_la_SOURCES += utils.c libcrmcommon_la_SOURCES += watchdog.c libcrmcommon_la_SOURCES += xml.c libcrmcommon_la_SOURCES += xml_attr.c libcrmcommon_la_SOURCES += xml_display.c libcrmcommon_la_SOURCES += xpath.c # # libcrmcommon_test is used only with unit tests, so we can mock system calls. # See mock.c for details. # include $(top_srcdir)/mk/tap.mk libcrmcommon_test_la_SOURCES = $(libcrmcommon_la_SOURCES) libcrmcommon_test_la_SOURCES += mock.c -libcrmcommon_test_la_LDFLAGS = $(libcrmcommon_la_LDFLAGS) -rpath $(libdir) $(LDFLAGS_WRAP) +libcrmcommon_test_la_LDFLAGS = $(libcrmcommon_la_LDFLAGS) \ + -rpath $(libdir) \ + $(LDFLAGS_WRAP) # If GCC emits a builtin function in place of something we've mocked up, that will # get used instead of the mocked version which leads to unexpected test results. So # disable all builtins. Older versions of GCC (at least, on RHEL7) will still emit # replacement code for strdup (and possibly other functions) unless -fno-inline is # also added. -libcrmcommon_test_la_CFLAGS = $(libcrmcommon_la_CFLAGS) -DPCMK__UNIT_TESTING -fno-builtin -fno-inline +libcrmcommon_test_la_CFLAGS = $(libcrmcommon_la_CFLAGS) \ + -DPCMK__UNIT_TESTING \ + -fno-builtin \ + -fno-inline # If -fno-builtin is used, -lm also needs to be added. See the comment at # BUILD_PROFILING above. -libcrmcommon_test_la_LIBADD = $(libcrmcommon_la_LIBADD) -lcmocka -lm +libcrmcommon_test_la_LIBADD = $(libcrmcommon_la_LIBADD) \ + -lcmocka \ + -lm nodist_libcrmcommon_test_la_SOURCES = $(nodist_libcrmcommon_la_SOURCES) - -clean-generic: - rm -f *.log *.debug *.xml *~ diff --git a/lib/common/tests/acl/Makefile.am b/lib/common/tests/acl/Makefile.am index 50408f9671..19903dbc76 100644 --- a/lib/common/tests/acl/Makefile.am +++ b/lib/common/tests/acl/Makefile.am @@ -1,21 +1,20 @@ # -# Copyright 2021-2022 the Pacemaker project contributors +# Copyright 2021-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. # include $(top_srcdir)/mk/tap.mk include $(top_srcdir)/mk/unittest.mk # Add "_test" to the end of all test program names to simplify .gitignore. -check_PROGRAMS = \ - pcmk__is_user_in_group_test \ - pcmk_acl_required_test \ - xml_acl_denied_test \ - xml_acl_enabled_test +check_PROGRAMS = pcmk__is_user_in_group_test \ + pcmk_acl_required_test \ + xml_acl_denied_test \ + xml_acl_enabled_test TESTS = $(check_PROGRAMS) diff --git a/lib/common/tests/actions/Makefile.am b/lib/common/tests/actions/Makefile.am index 4687e1ba93..6890b84ddb 100644 --- a/lib/common/tests/actions/Makefile.am +++ b/lib/common/tests/actions/Makefile.am @@ -1,22 +1,22 @@ # -# Copyright 2020-2022 the Pacemaker project contributors +# Copyright 2020-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. # include $(top_srcdir)/mk/tap.mk include $(top_srcdir)/mk/unittest.mk # Add "_test" to the end of all test program names to simplify .gitignore. -check_PROGRAMS = copy_in_properties_test \ - expand_plus_plus_test \ - fix_plus_plus_recursive_test \ - parse_op_key_test \ - pcmk_is_probe_test \ - pcmk_xe_is_probe_test \ - pcmk_xe_mask_probe_failure_test +check_PROGRAMS = copy_in_properties_test \ + expand_plus_plus_test \ + fix_plus_plus_recursive_test \ + parse_op_key_test \ + pcmk_is_probe_test \ + pcmk_xe_is_probe_test \ + pcmk_xe_mask_probe_failure_test TESTS = $(check_PROGRAMS) diff --git a/lib/common/tests/agents/Makefile.am b/lib/common/tests/agents/Makefile.am index 7a54b7deff..b3837d734f 100644 --- a/lib/common/tests/agents/Makefile.am +++ b/lib/common/tests/agents/Makefile.am @@ -1,20 +1,20 @@ # -# Copyright 2020-2022 the Pacemaker project contributors +# Copyright 2020-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. # include $(top_srcdir)/mk/tap.mk include $(top_srcdir)/mk/unittest.mk # Add "_test" to the end of all test program names to simplify .gitignore. -check_PROGRAMS = crm_generate_ra_key_test \ - crm_parse_agent_spec_test \ - pcmk__effective_rc_test \ - pcmk_get_ra_caps_test \ - pcmk_stonith_param_test +check_PROGRAMS = crm_generate_ra_key_test \ + crm_parse_agent_spec_test \ + pcmk__effective_rc_test \ + pcmk_get_ra_caps_test \ + pcmk_stonith_param_test TESTS = $(check_PROGRAMS) diff --git a/lib/common/tests/cmdline/Makefile.am b/lib/common/tests/cmdline/Makefile.am index c778f7d370..792425b9f8 100644 --- a/lib/common/tests/cmdline/Makefile.am +++ b/lib/common/tests/cmdline/Makefile.am @@ -1,18 +1,18 @@ # # Copyright 2020-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. # include $(top_srcdir)/mk/tap.mk include $(top_srcdir)/mk/unittest.mk # Add "_test" to the end of all test program names to simplify .gitignore. check_PROGRAMS = pcmk__cmdline_preproc_test \ - pcmk__new_common_args_test \ - pcmk__quote_cmdline_test + pcmk__new_common_args_test \ + pcmk__quote_cmdline_test TESTS = $(check_PROGRAMS) diff --git a/lib/common/tests/flags/Makefile.am b/lib/common/tests/flags/Makefile.am index 16d8ffb336..22a101ab1b 100644 --- a/lib/common/tests/flags/Makefile.am +++ b/lib/common/tests/flags/Makefile.am @@ -1,20 +1,19 @@ # -# Copyright 2020-2022 the Pacemaker project contributors +# Copyright 2020-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. # include $(top_srcdir)/mk/tap.mk include $(top_srcdir)/mk/unittest.mk # Add "_test" to the end of all test program names to simplify .gitignore. -check_PROGRAMS = \ - pcmk__clear_flags_as_test \ - pcmk__set_flags_as_test \ - pcmk_all_flags_set_test \ - pcmk_any_flags_set_test +check_PROGRAMS = pcmk__clear_flags_as_test \ + pcmk__set_flags_as_test \ + pcmk_all_flags_set_test \ + pcmk_any_flags_set_test TESTS = $(check_PROGRAMS) diff --git a/lib/common/tests/io/Makefile.am b/lib/common/tests/io/Makefile.am index c26482c488..f7519d8f3f 100644 --- a/lib/common/tests/io/Makefile.am +++ b/lib/common/tests/io/Makefile.am @@ -1,18 +1,17 @@ # -# Copyright 2020-2022 the Pacemaker project contributors +# Copyright 2020-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. # include $(top_srcdir)/mk/tap.mk include $(top_srcdir)/mk/unittest.mk # Add "_test" to the end of all test program names to simplify .gitignore. -check_PROGRAMS = \ - pcmk__full_path_test \ - pcmk__get_tmpdir_test +check_PROGRAMS = pcmk__full_path_test \ + pcmk__get_tmpdir_test TESTS = $(check_PROGRAMS) diff --git a/lib/common/tests/lists/Makefile.am b/lib/common/tests/lists/Makefile.am index ae0c0b69f5..0fa1e153bd 100644 --- a/lib/common/tests/lists/Makefile.am +++ b/lib/common/tests/lists/Makefile.am @@ -1,20 +1,19 @@ # -# Copyright 2022 the Pacemaker project contributors +# Copyright 2022-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. # include $(top_srcdir)/mk/tap.mk include $(top_srcdir)/mk/unittest.mk # Add "_test" to the end of all test program names to simplify .gitignore. -check_PROGRAMS = \ - pcmk__list_of_1_test \ - pcmk__list_of_multiple_test \ - pcmk__subtract_lists_test +check_PROGRAMS = pcmk__list_of_1_test \ + pcmk__list_of_multiple_test \ + pcmk__subtract_lists_test TESTS = $(check_PROGRAMS) diff --git a/lib/common/tests/nvpair/Makefile.am b/lib/common/tests/nvpair/Makefile.am index 7acaba3f27..7f406bd502 100644 --- a/lib/common/tests/nvpair/Makefile.am +++ b/lib/common/tests/nvpair/Makefile.am @@ -1,18 +1,18 @@ # -# Copyright 2021-2022 the Pacemaker project contributors +# Copyright 2021-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. # include $(top_srcdir)/mk/tap.mk include $(top_srcdir)/mk/unittest.mk # Add "_test" to the end of all test program names to simplify .gitignore. -check_PROGRAMS = pcmk__xe_attr_is_true_test \ - pcmk__xe_get_bool_attr_test \ - pcmk__xe_set_bool_attr_test +check_PROGRAMS = pcmk__xe_attr_is_true_test \ + pcmk__xe_get_bool_attr_test \ + pcmk__xe_set_bool_attr_test TESTS = $(check_PROGRAMS) diff --git a/lib/common/tests/options/Makefile.am b/lib/common/tests/options/Makefile.am index 9a5fa985de..cc1008e587 100644 --- a/lib/common/tests/options/Makefile.am +++ b/lib/common/tests/options/Makefile.am @@ -1,19 +1,18 @@ # -# Copyright 2022 the Pacemaker project contributors +# Copyright 2022-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. # include $(top_srcdir)/mk/tap.mk include $(top_srcdir)/mk/unittest.mk # Add "_test" to the end of all test program names to simplify .gitignore. -check_PROGRAMS = \ - pcmk__env_option_test \ - pcmk__set_env_option_test \ - pcmk__env_option_enabled_test +check_PROGRAMS = pcmk__env_option_test \ + pcmk__set_env_option_test \ + pcmk__env_option_enabled_test TESTS = $(check_PROGRAMS) diff --git a/lib/common/tests/output/Makefile.am b/lib/common/tests/output/Makefile.am index 6ac7b5fd06..30f149463f 100644 --- a/lib/common/tests/output/Makefile.am +++ b/lib/common/tests/output/Makefile.am @@ -1,24 +1,24 @@ # -# Copyright 2021-2022 the Pacemaker project contributors +# Copyright 2021-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. # include $(top_srcdir)/mk/tap.mk include $(top_srcdir)/mk/unittest.mk # Add "_test" to the end of all test program names to simplify .gitignore. -check_PROGRAMS = pcmk__call_message_test \ - pcmk__output_and_clear_error_test \ - pcmk__output_free_test \ - pcmk__output_new_test \ - pcmk__register_format_test \ - pcmk__register_formats_test \ - pcmk__register_message_test \ - pcmk__register_messages_test \ - pcmk__unregister_formats_test +check_PROGRAMS = pcmk__call_message_test \ + pcmk__output_and_clear_error_test \ + pcmk__output_free_test \ + pcmk__output_new_test \ + pcmk__register_format_test \ + pcmk__register_formats_test \ + pcmk__register_message_test \ + pcmk__register_messages_test \ + pcmk__unregister_formats_test TESTS = $(check_PROGRAMS) diff --git a/lib/common/tests/results/Makefile.am b/lib/common/tests/results/Makefile.am index 8d51d12915..a7d566362e 100644 --- a/lib/common/tests/results/Makefile.am +++ b/lib/common/tests/results/Makefile.am @@ -1,16 +1,16 @@ # -# Copyright 2021-2022 the Pacemaker project contributors +# Copyright 2021-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. # include $(top_srcdir)/mk/tap.mk include $(top_srcdir)/mk/unittest.mk # Add "_test" to the end of all test program names to simplify .gitignore. -check_PROGRAMS = pcmk__results_test +check_PROGRAMS = pcmk__results_test TESTS = $(check_PROGRAMS) diff --git a/lib/common/tests/scores/Makefile.am b/lib/common/tests/scores/Makefile.am index 66ca0731a3..cb961553f6 100644 --- a/lib/common/tests/scores/Makefile.am +++ b/lib/common/tests/scores/Makefile.am @@ -1,19 +1,18 @@ # -# Copyright 2020-2022 the Pacemaker project contributors +# Copyright 2020-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. # include $(top_srcdir)/mk/tap.mk include $(top_srcdir)/mk/unittest.mk # Add "_test" to the end of all test program names to simplify .gitignore. -check_PROGRAMS = \ - char2score_test \ - pcmk__add_scores_test \ - pcmk_readable_score_test +check_PROGRAMS = char2score_test \ + pcmk__add_scores_test \ + pcmk_readable_score_test TESTS = $(check_PROGRAMS) diff --git a/lib/common/tests/strings/Makefile.am b/lib/common/tests/strings/Makefile.am index 01b69fa57c..e66af0d35f 100644 --- a/lib/common/tests/strings/Makefile.am +++ b/lib/common/tests/strings/Makefile.am @@ -1,42 +1,41 @@ # # Copyright 2020-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. # include $(top_srcdir)/mk/tap.mk include $(top_srcdir)/mk/unittest.mk # Add "_test" to the end of all test program names to simplify .gitignore. -check_PROGRAMS = \ - crm_get_msec_test \ - crm_is_true_test \ - crm_str_to_boolean_test \ - pcmk__add_word_test \ - pcmk__btoa_test \ - pcmk__char_in_any_str_test \ - pcmk__compress_test \ - pcmk__ends_with_test \ - pcmk__g_strcat_test \ - pcmk__guint_from_hash_test \ - pcmk__numeric_strcasecmp_test \ - pcmk__parse_ll_range_test \ - pcmk__s_test \ - pcmk__scan_double_test \ - pcmk__scan_ll_test \ - pcmk__scan_min_int_test \ - pcmk__scan_port_test \ - pcmk__starts_with_test \ - pcmk__str_any_of_test \ - pcmk__str_in_list_test \ - pcmk__str_table_dup_test \ - pcmk__str_update_test \ - pcmk__strcmp_test \ - pcmk__strkey_table_test \ - pcmk__strikey_table_test \ - pcmk__trim_test +check_PROGRAMS = crm_get_msec_test \ + crm_is_true_test \ + crm_str_to_boolean_test \ + pcmk__add_word_test \ + pcmk__btoa_test \ + pcmk__char_in_any_str_test \ + pcmk__compress_test \ + pcmk__ends_with_test \ + pcmk__g_strcat_test \ + pcmk__guint_from_hash_test \ + pcmk__numeric_strcasecmp_test \ + pcmk__parse_ll_range_test \ + pcmk__s_test \ + pcmk__scan_double_test \ + pcmk__scan_ll_test \ + pcmk__scan_min_int_test \ + pcmk__scan_port_test \ + pcmk__starts_with_test \ + pcmk__str_any_of_test \ + pcmk__str_in_list_test \ + pcmk__str_table_dup_test \ + pcmk__str_update_test \ + pcmk__strcmp_test \ + pcmk__strkey_table_test \ + pcmk__strikey_table_test \ + pcmk__trim_test TESTS = $(check_PROGRAMS) diff --git a/lib/common/tests/utils/Makefile.am b/lib/common/tests/utils/Makefile.am index 9bb66f2e55..f028ce492e 100644 --- a/lib/common/tests/utils/Makefile.am +++ b/lib/common/tests/utils/Makefile.am @@ -1,31 +1,30 @@ # # Copyright 2020-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. # include $(top_srcdir)/mk/tap.mk include $(top_srcdir)/mk/unittest.mk # Add "_test" to the end of all test program names to simplify .gitignore. -check_PROGRAMS = \ - compare_version_test \ - crm_meta_name_test \ - crm_meta_value_test \ - crm_user_lookup_test \ - pcmk_daemon_user_test \ - pcmk_str_is_infinity_test \ - pcmk_str_is_minus_infinity_test \ - pcmk__fail_attr_name_test \ - pcmk__failcount_name_test \ - pcmk__getpid_s_test \ - pcmk__lastfailure_name_test +check_PROGRAMS = compare_version_test \ + crm_meta_name_test \ + crm_meta_value_test \ + crm_user_lookup_test \ + pcmk_daemon_user_test \ + pcmk_str_is_infinity_test \ + pcmk_str_is_minus_infinity_test \ + pcmk__fail_attr_name_test \ + pcmk__failcount_name_test \ + pcmk__getpid_s_test \ + pcmk__lastfailure_name_test if WRAPPABLE_UNAME check_PROGRAMS += pcmk_hostname_test endif TESTS = $(check_PROGRAMS) diff --git a/lib/common/tests/xml/Makefile.am b/lib/common/tests/xml/Makefile.am index 0ccdcc37b6..465c950702 100644 --- a/lib/common/tests/xml/Makefile.am +++ b/lib/common/tests/xml/Makefile.am @@ -1,17 +1,17 @@ # -# Copyright 2022 the Pacemaker project contributors +# Copyright 2022-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. # include $(top_srcdir)/mk/tap.mk include $(top_srcdir)/mk/unittest.mk # Add "_test" to the end of all test program names to simplify .gitignore. -check_PROGRAMS = pcmk__xe_foreach_child_test \ - pcmk__xe_match_test +check_PROGRAMS = pcmk__xe_foreach_child_test \ + pcmk__xe_match_test TESTS = $(check_PROGRAMS) diff --git a/lib/common/tests/xpath/Makefile.am b/lib/common/tests/xpath/Makefile.am index 94abeee2dc..d4c504b63b 100644 --- a/lib/common/tests/xpath/Makefile.am +++ b/lib/common/tests/xpath/Makefile.am @@ -1,16 +1,16 @@ # -# Copyright 2021-2022 the Pacemaker project contributors +# Copyright 2021-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. # include $(top_srcdir)/mk/tap.mk include $(top_srcdir)/mk/unittest.mk # Add "_test" to the end of all test program names to simplify .gitignore. -check_PROGRAMS = pcmk__xpath_node_id_test +check_PROGRAMS = pcmk__xpath_node_id_test TESTS = $(check_PROGRAMS) diff --git a/lib/fencing/Makefile.am b/lib/fencing/Makefile.am index a72b7d6943..7458bc18c7 100644 --- a/lib/fencing/Makefile.am +++ b/lib/fencing/Makefile.am @@ -1,28 +1,31 @@ # # Original Author: Sun Jiang Dong # Copyright 2004 International Business Machines # # with later changes copyright 2004-2022 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 noinst_HEADERS = fencing_private.h lib_LTLIBRARIES = libstonithd.la libstonithd_la_LDFLAGS = -version-info 34:3:8 libstonithd_la_CFLAGS = $(CFLAGS_HARDENED_LIB) libstonithd_la_LDFLAGS += $(LDFLAGS_HARDENED_LIB) -libstonithd_la_LIBADD = $(top_builddir)/lib/common/libcrmcommon.la -libstonithd_la_LIBADD += $(top_builddir)/lib/services/libcrmservice.la +libstonithd_la_LIBADD = $(top_builddir)/lib/services/libcrmservice.la +libstonithd_la_LIBADD += $(top_builddir)/lib/common/libcrmcommon.la -libstonithd_la_SOURCES = st_actions.c st_client.c st_output.c st_rhcs.c +libstonithd_la_SOURCES = st_actions.c \ + st_client.c \ + st_output.c \ + st_rhcs.c if BUILD_LHA_SUPPORT libstonithd_la_SOURCES += st_lha.c endif diff --git a/lib/lrmd/Makefile.am b/lib/lrmd/Makefile.am index e9ac906f95..f333237df5 100644 --- a/lib/lrmd/Makefile.am +++ b/lib/lrmd/Makefile.am @@ -1,21 +1,24 @@ # -# Copyright 2012-2020 the Pacemaker project contributors +# Copyright 2012-2023 the Pacemaker project contributors # # The version control history for this file may have further details. # # This source code is licensed under the GNU Lesser General Public License # version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY. # include $(top_srcdir)/mk/common.mk lib_LTLIBRARIES = liblrmd.la liblrmd_la_LDFLAGS = -version-info 29:6:1 liblrmd_la_CFLAGS = $(CFLAGS_HARDENED_LIB) liblrmd_la_LDFLAGS += $(LDFLAGS_HARDENED_LIB) -liblrmd_la_LIBADD = $(top_builddir)/lib/common/libcrmcommon.la \ - $(top_builddir)/lib/services/libcrmservice.la \ - $(top_builddir)/lib/fencing/libstonithd.la -liblrmd_la_SOURCES = lrmd_client.c proxy_common.c lrmd_alerts.c lrmd_output.c +liblrmd_la_LIBADD = $(top_builddir)/lib/fencing/libstonithd.la +liblrmd_la_LIBADD += $(top_builddir)/lib/services/libcrmservice.la +liblrmd_la_LIBADD += $(top_builddir)/lib/common/libcrmcommon.la +liblrmd_la_SOURCES = lrmd_client.c \ + proxy_common.c \ + lrmd_alerts.c \ + lrmd_output.c diff --git a/lib/pacemaker/Makefile.am b/lib/pacemaker/Makefile.am index ebf3b6da32..2b7ea4d1e0 100644 --- a/lib/pacemaker/Makefile.am +++ b/lib/pacemaker/Makefile.am @@ -1,69 +1,69 @@ # # Copyright 2004-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. # include $(top_srcdir)/mk/common.mk AM_CPPFLAGS += -I$(top_builddir) -I$(top_srcdir) noinst_HEADERS = libpacemaker_private.h ## libraries lib_LTLIBRARIES = libpacemaker.la ## SOURCES libpacemaker_la_LDFLAGS = -version-info 7:0:6 libpacemaker_la_CFLAGS = $(CFLAGS_HARDENED_LIB) libpacemaker_la_LDFLAGS += $(LDFLAGS_HARDENED_LIB) -libpacemaker_la_LIBADD = $(top_builddir)/lib/pengine/libpe_status.la \ - $(top_builddir)/lib/cib/libcib.la \ - $(top_builddir)/lib/lrmd/liblrmd.la \ - $(top_builddir)/lib/fencing/libstonithd.la \ - $(top_builddir)/lib/services/libcrmservice.la \ - $(top_builddir)/lib/common/libcrmcommon.la +libpacemaker_la_LIBADD = $(top_builddir)/lib/pengine/libpe_status.la +libpacemaker_la_LIBADD += $(top_builddir)/lib/cib/libcib.la +libpacemaker_la_LIBADD += $(top_builddir)/lib/lrmd/liblrmd.la +libpacemaker_la_LIBADD += $(top_builddir)/lib/fencing/libstonithd.la +libpacemaker_la_LIBADD += $(top_builddir)/lib/services/libcrmservice.la +libpacemaker_la_LIBADD += $(top_builddir)/lib/common/libcrmcommon.la # -L$(top_builddir)/lib/pils -lpils -export-dynamic -module -avoid-version # Use += rather than backlashed continuation lines for parsing by bumplibs libpacemaker_la_SOURCES = libpacemaker_la_SOURCES += pcmk_acl.c libpacemaker_la_SOURCES += pcmk_cluster_queries.c libpacemaker_la_SOURCES += pcmk_fence.c libpacemaker_la_SOURCES += pcmk_graph_consumer.c libpacemaker_la_SOURCES += pcmk_graph_logging.c libpacemaker_la_SOURCES += pcmk_graph_producer.c libpacemaker_la_SOURCES += pcmk_injections.c libpacemaker_la_SOURCES += pcmk_output.c libpacemaker_la_SOURCES += pcmk_resource.c libpacemaker_la_SOURCES += pcmk_result_code.c libpacemaker_la_SOURCES += pcmk_rule.c libpacemaker_la_SOURCES += pcmk_sched_actions.c libpacemaker_la_SOURCES += pcmk_sched_bundle.c libpacemaker_la_SOURCES += pcmk_sched_clone.c libpacemaker_la_SOURCES += pcmk_sched_colocation.c libpacemaker_la_SOURCES += pcmk_sched_constraints.c libpacemaker_la_SOURCES += pcmk_sched_fencing.c libpacemaker_la_SOURCES += pcmk_sched_group.c libpacemaker_la_SOURCES += pcmk_sched_instances.c libpacemaker_la_SOURCES += pcmk_sched_location.c libpacemaker_la_SOURCES += pcmk_sched_migration.c libpacemaker_la_SOURCES += pcmk_sched_nodes.c libpacemaker_la_SOURCES += pcmk_sched_ordering.c libpacemaker_la_SOURCES += pcmk_sched_primitive.c libpacemaker_la_SOURCES += pcmk_sched_probes.c libpacemaker_la_SOURCES += pcmk_sched_promotable.c libpacemaker_la_SOURCES += pcmk_sched_recurring.c libpacemaker_la_SOURCES += pcmk_sched_remote.c libpacemaker_la_SOURCES += pcmk_sched_resource.c libpacemaker_la_SOURCES += pcmk_sched_tickets.c libpacemaker_la_SOURCES += pcmk_sched_utilization.c libpacemaker_la_SOURCES += pcmk_scheduler.c libpacemaker_la_SOURCES += pcmk_simulate.c libpacemaker_la_SOURCES += pcmk_status.c diff --git a/lib/pengine/Makefile.am b/lib/pengine/Makefile.am index 805772b87a..e2de35409d 100644 --- a/lib/pengine/Makefile.am +++ b/lib/pengine/Makefile.am @@ -1,81 +1,93 @@ # # Copyright 2004-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. # include $(top_srcdir)/mk/common.mk # Without "." here, check-recursive will run through the subdirectories first # and then run "make check" here. This will fail, because there's things in # the subdirectories that need check_LTLIBRARIES built first. Adding "." here # changes the order so the subdirectories are processed afterwards. SUBDIRS = . tests ## libraries -lib_LTLIBRARIES = libpe_rules.la libpe_status.la -check_LTLIBRARIES = libpe_rules_test.la libpe_status_test.la +lib_LTLIBRARIES = libpe_rules.la \ + libpe_status.la +check_LTLIBRARIES = libpe_rules_test.la \ + libpe_status_test.la ## SOURCES noinst_HEADERS = pe_status_private.h libpe_rules_la_LDFLAGS = -version-info 30:0:4 libpe_rules_la_CFLAGS = $(CFLAGS_HARDENED_LIB) libpe_rules_la_LDFLAGS += $(LDFLAGS_HARDENED_LIB) libpe_rules_la_LIBADD = $(top_builddir)/lib/common/libcrmcommon.la -libpe_rules_la_SOURCES = rules.c rules_alerts.c common.c +libpe_rules_la_SOURCES = rules.c \ + rules_alerts.c \ + common.c libpe_status_la_LDFLAGS = -version-info 34:0:6 libpe_status_la_CFLAGS = $(CFLAGS_HARDENED_LIB) libpe_status_la_LDFLAGS += $(LDFLAGS_HARDENED_LIB) libpe_status_la_LIBADD = $(top_builddir)/lib/common/libcrmcommon.la # Use += rather than backlashed continuation lines for parsing by bumplibs libpe_status_la_SOURCES = libpe_status_la_SOURCES += bundle.c libpe_status_la_SOURCES += clone.c libpe_status_la_SOURCES += common.c libpe_status_la_SOURCES += complex.c libpe_status_la_SOURCES += failcounts.c libpe_status_la_SOURCES += group.c libpe_status_la_SOURCES += native.c libpe_status_la_SOURCES += pe_actions.c libpe_status_la_SOURCES += pe_health.c libpe_status_la_SOURCES += pe_digest.c libpe_status_la_SOURCES += pe_notif.c libpe_status_la_SOURCES += pe_output.c libpe_status_la_SOURCES += remote.c libpe_status_la_SOURCES += rules.c libpe_status_la_SOURCES += status.c libpe_status_la_SOURCES += tags.c libpe_status_la_SOURCES += unpack.c libpe_status_la_SOURCES += utils.c # # libpe_rules_test and libpe_status_test are only used with unit tests, so we can # mock system calls. See lib/common/mock.c for details. # include $(top_srcdir)/mk/tap.mk libpe_rules_test_la_SOURCES = $(libpe_rules_la_SOURCES) -libpe_rules_test_la_LDFLAGS = $(libpe_rules_la_LDFLAGS) -rpath $(libdir) $(LDFLAGS_WRAP) +libpe_rules_test_la_LDFLAGS = $(libpe_rules_la_LDFLAGS) \ + -rpath $(libdir) \ + $(LDFLAGS_WRAP) # See comments on libcrmcommon_test_la in lib/common/Makefile.am regarding these flags. -libpe_rules_test_la_CFLAGS = $(libpe_rules_la_CFLAGS) -DPCMK__UNIT_TESTING \ +libpe_rules_test_la_CFLAGS = $(libpe_rules_la_CFLAGS) \ + -DPCMK__UNIT_TESTING \ -fno-builtin -fno-inline -libpe_rules_test_la_LIBADD = $(top_builddir)/lib/common/libcrmcommon_test.la -lcmocka -lm +libpe_rules_test_la_LIBADD = $(top_builddir)/lib/common/libcrmcommon_test.la \ + -lcmocka \ + -lm libpe_status_test_la_SOURCES = $(libpe_status_la_SOURCES) -libpe_status_test_la_LDFLAGS = $(libpe_status_la_LDFLAGS) -rpath $(libdir) $(LDFLAGS_WRAP) +libpe_status_test_la_LDFLAGS = $(libpe_status_la_LDFLAGS) \ + -rpath $(libdir) \ + $(LDFLAGS_WRAP) # See comments on libcrmcommon_test_la in lib/common/Makefile.am regarding these flags. -libpe_status_test_la_CFLAGS = $(libpe_status_la_CFLAGS) -DPCMK__UNIT_TESTING \ - -fno-builtin -fno-inline -libpe_status_test_la_LIBADD = $(top_builddir)/lib/common/libcrmcommon_test.la -lcmocka -lm - -clean-generic: - rm -f *.log *.debug *~ +libpe_status_test_la_CFLAGS = $(libpe_status_la_CFLAGS) \ + -DPCMK__UNIT_TESTING \ + -fno-builtin \ + -fno-inline +libpe_status_test_la_LIBADD = $(top_builddir)/lib/common/libcrmcommon_test.la \ + -lcmocka \ + -lm diff --git a/lib/pengine/tests/Makefile.am b/lib/pengine/tests/Makefile.am index 4986ef2d6e..48ec5b4cb4 100644 --- a/lib/pengine/tests/Makefile.am +++ b/lib/pengine/tests/Makefile.am @@ -1 +1,14 @@ -SUBDIRS = rules native status unpack utils +# +# Copyright 2020-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. +# + +SUBDIRS = rules \ + native \ + status \ + unpack \ + utils diff --git a/lib/pengine/tests/native/Makefile.am b/lib/pengine/tests/native/Makefile.am index 5046ff1a94..07cc1a1cf3 100644 --- a/lib/pengine/tests/native/Makefile.am +++ b/lib/pengine/tests/native/Makefile.am @@ -1,22 +1,22 @@ # -# Copyright 2022 the Pacemaker project contributors +# Copyright 2022-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. # include $(top_srcdir)/mk/tap.mk include $(top_srcdir)/mk/unittest.mk AM_CPPFLAGS += -I$(top_srcdir) LDADD += $(top_builddir)/lib/pengine/libpe_status_test.la AM_TESTS_ENVIRONMENT += PCMK_CTS_CLI_DIR=$(top_srcdir)/cts/cli # Add "_test" to the end of all test program names to simplify .gitignore. check_PROGRAMS = native_find_rsc_test \ - pe_base_name_eq_test + pe_base_name_eq_test TESTS = $(check_PROGRAMS) diff --git a/lib/pengine/tests/status/Makefile.am b/lib/pengine/tests/status/Makefile.am index 3f95496181..c7ddb70eae 100644 --- a/lib/pengine/tests/status/Makefile.am +++ b/lib/pengine/tests/status/Makefile.am @@ -1,22 +1,22 @@ # -# Copyright 2022 the Pacemaker project contributors +# Copyright 2022-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. # include $(top_srcdir)/mk/tap.mk include $(top_srcdir)/mk/unittest.mk LDADD += $(top_builddir)/lib/pengine/libpe_status_test.la # Add "_test" to the end of all test program names to simplify .gitignore. -check_PROGRAMS = pe_find_node_any_test \ - pe_find_node_id_test \ - pe_find_node_test \ - pe_new_working_set_test \ - set_working_set_defaults_test +check_PROGRAMS = pe_find_node_any_test \ + pe_find_node_id_test \ + pe_find_node_test \ + pe_new_working_set_test \ + set_working_set_defaults_test TESTS = $(check_PROGRAMS) diff --git a/lib/pengine/tests/utils/Makefile.am b/lib/pengine/tests/utils/Makefile.am index 4a3e8a256e..64421e261f 100644 --- a/lib/pengine/tests/utils/Makefile.am +++ b/lib/pengine/tests/utils/Makefile.am @@ -1,21 +1,20 @@ # -# Copyright 2022 the Pacemaker project contributors +# Copyright 2022-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. # include $(top_srcdir)/mk/tap.mk include $(top_srcdir)/mk/unittest.mk AM_CPPFLAGS += -I$(top_srcdir)/lib/pengine LDADD += $(top_builddir)/lib/pengine/libpe_status_test.la # Add "_test" to the end of all test program names to simplify .gitignore. -check_PROGRAMS = \ - pe__cmp_node_name_test \ +check_PROGRAMS = pe__cmp_node_name_test \ pe__cmp_rsc_priority_test TESTS = $(check_PROGRAMS) diff --git a/lib/services/Makefile.am b/lib/services/Makefile.am index a7e10c969b..97a93e0e74 100644 --- a/lib/services/Makefile.am +++ b/lib/services/Makefile.am @@ -1,43 +1,41 @@ # -# Copyright 2012-2021 the Pacemaker project contributors +# Copyright 2012-2023 the Pacemaker project contributors # # The version control history for this file may have further details. # # This source code is licensed under the GNU Lesser General Public License # version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY. # MAINTAINERCLEANFILES = Makefile.in AM_CPPFLAGS = -I$(top_srcdir)/include lib_LTLIBRARIES = libcrmservice.la -noinst_HEADERS = pcmk-dbus.h upstart.h systemd.h \ - services_lsb.h services_nagios.h \ - services_ocf.h \ - services_private.h +noinst_HEADERS = $(wildcard *.h) libcrmservice_la_LDFLAGS = -version-info 31:2:3 libcrmservice_la_CFLAGS = libcrmservice_la_CFLAGS += $(CFLAGS_HARDENED_LIB) libcrmservice_la_LDFLAGS += $(LDFLAGS_HARDENED_LIB) -libcrmservice_la_LIBADD = $(top_builddir)/lib/common/libcrmcommon.la $(DBUS_LIBS) +libcrmservice_la_LIBADD = $(top_builddir)/lib/common/libcrmcommon.la \ + $(DBUS_LIBS) libcrmservice_la_SOURCES = services.c libcrmservice_la_SOURCES += services_linux.c libcrmservice_la_SOURCES += services_lsb.c libcrmservice_la_SOURCES += services_ocf.c if BUILD_DBUS libcrmservice_la_SOURCES += dbus.c endif if BUILD_UPSTART libcrmservice_la_SOURCES += upstart.c endif if BUILD_SYSTEMD libcrmservice_la_SOURCES += systemd.c endif if BUILD_NAGIOS libcrmservice_la_SOURCES += services_nagios.c endif diff --git a/maint/Makefile.am b/maint/Makefile.am index 66804d5a6a..bfdbfaf234 100644 --- a/maint/Makefile.am +++ b/maint/Makefile.am @@ -1,109 +1,117 @@ # # Copyright 2019-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. # # Define release-related variables include $(abs_srcdir)/../mk/release.mk noinst_SCRIPTS = bumplibs EXTRA_DIST = README # # Change log generation # # Count changes in these directories -CHANGELOG_DIRS = ../include ../lib ../daemons ../tools ../xml +CHANGELOG_DIRS = ../include \ + ../lib \ + ../daemons \ + ../tools \ + ../xml .PHONY: require_last_release require_last_release: @if [ -z "$(CHECKOUT)" ]; then \ echo "This target must be run from a git checkout"; \ exit 1; \ elif ! "$(GIT)" rev-parse $(LAST_RELEASE) >/dev/null 2>&1; then \ echo "LAST_RELEASE must be set to a valid git tag"; \ exit 1; \ fi .PHONY: summary summary: require_last_release @printf "* %s %s <%s> %s\n" "$$(date +'%a %b %d %Y')" \ "$$("$(GIT)" config user.name)" \ "$$("$(GIT)" config user.email)" \ "$(NEXT_RELEASE)" @printf "\055 %d commits with%s\n" \ "$$("$(GIT)" log --pretty=oneline --no-merges \ $(LAST_RELEASE)..HEAD | wc -l)" \ "$$("$(GIT)" diff $(LAST_RELEASE)..HEAD --shortstat \ $(CHANGELOG_DIRS))" .PHONY: changes changes: summary @printf "\n- Features added since $(LAST_RELEASE)\n" @"$(GIT)" log --pretty=format:'%s' --no-merges \ --abbrev-commit $(LAST_RELEASE)..HEAD \ | sed -n -e 's/^ *Feature: */ + /p' | sort -uf @printf "\n- Fixes since $(LAST_RELEASE)\n" @"$(GIT)" log --pretty=format:'%s' --no-merges \ --abbrev-commit $(LAST_RELEASE)..HEAD \ | sed -n -e 's/^ *\(Fix\|High\|Bug\): */ + /p' | sed \ -e 's/\(cib\|pacemaker-based\|based\):/CIB:/' \ -e 's/\(lrmd\|pacemaker-execd\|execd\):/executor:/' \ -e 's/\(crmd\|pacemaker-controld\|controld\):/controller:/' \ -e 's/\(Fencing\|stonithd?\|pacemaker-fenced\|fenced\):/fencing:/' \ -e 's/\(PE\|pengine\|pacemaker-schedulerd\|schedulerd\):/scheduler:/' \ | sort -uf @printf "\n- Public API changes since $(LAST_RELEASE)\n" @"$(GIT)" log --pretty=format:'%s' --no-merges \ --abbrev-commit $(LAST_RELEASE)..HEAD \ | sed -n -e 's/^ *API: */ + /p' | sort -uf .PHONY: changelog changelog: require_last_release @printf "%s\n\n%s\n" \ "$$($(MAKE) $(AM_MAKEFLAGS) changes \ | grep -v 'make\(\[[0-9]*\]\)\?:')" \ "$$(cat ../ChangeLog)" > ../ChangeLog .PHONY: authors authors: require_last_release "$(GIT)" log $(LAST_RELEASE)..$(COMMIT) --format='%an' | sort -u # # gnulib updates # # See https://www.gnu.org/software/gnulib/manual/html_node/ # # V3 = scandir unsetenv alphasort xalloc # V2 = setenv strerror strchrnul strndup GNU_MODS = crypto/md5-buffer # stdint appears to be surrogate only for C99-lacking environments GNU_MODS_AVOID = stdint .PHONY: gnulib-update gnulib-update: @echo 'Newer versions of gnulib require automake 1.14' @echo 'Pacemaker cannot update until minimum supported automake is 1.14' @exit 1 if test -e gnulib; then \ cd gnulib && "$(GIT)" pull; \ else \ "$(GIT)" clone https://git.savannah.gnu.org/git/gnulib.git \ gnulib \ && cd gnulib && "$(GIT)" config pull.rebase false; \ fi cd $(top_srcdir) && maint/gnulib/gnulib-tool --source-base=lib/gnu \ --lgpl=2 --no-vc-files --no-conditional-dependencies --libtool \ $(GNU_MODS_AVOID:%=--avoid %) --import $(GNU_MODS) - sed -i -e "s/bundled(gnulib).*/bundled(gnulib) = `date +'%Y%m%d'`/" \ - ../rpm/pacemaker.spec.in - sed -i -e "s/_GL_EXTERN_INLINE/_GL_INLINE/" \ + cp -p ../rpm/pacemaker.spec.in ../rpm/pacemaker.spec.in.$$ + sed -e "s/bundled(gnulib).*/bundled(gnulib) = `date +'%Y%m%d'`/" \ + ../rpm/pacemaker.spec.in > ../rpm/pacemaker.spec.in.$$ + mv ../rpm/pacemaker.spec.in.$$ ../rpm/pacemaker.spec.in + cp -p ../lib/gnu/md5.c ../lib/gnu/md5.c.$$ + sed -e "s/_GL_EXTERN_INLINE/_GL_INLINE/" \ -e "s#left_over -= 64;#left_over \&= 63; /* helps static analysis */#" \ -e "s#&ctx->buffer\[16\]#\&(((char *) ctx->buffer)[64]) /* helps static analysis */#" \ - ../lib/gnu/md5.c + ../lib/gnu/md5.c > ../lib/gnu/md5.c.$$ + mv ../lib/gnu/md5.c.$$ ../lib/gnu/md5.c diff --git a/maint/bumplibs.in b/maint/bumplibs.in index 99698315b7..ddaa1a9b59 100644 --- a/maint/bumplibs.in +++ b/maint/bumplibs.in @@ -1,290 +1,296 @@ #!@BASH_PATH@ # # Copyright 2012-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. # # List regular expressions (not globs) that match all of a library's public API # headers. Any files ending in "internal.h" will be excluded from matches. declare -A HEADERS HEADERS[cib]="include/crm/cib.h include/crm/cib/.*.h" HEADERS[crmcommon]="include/crm/crm.h include/crm/msg_xml.h include/crm/common/.*.h" HEADERS[crmcluster]="include/crm/cluster.h include/crm/cluster/.*.h" HEADERS[crmservice]="include/crm/services.*.h" HEADERS[lrmd]="include/crm/lrmd.*.h" HEADERS[pacemaker]="include/pacemaker.*.h" HEADERS[pe_rules]="include/crm/pengine/ru.*.h" HEADERS[pe_status]="include/crm/pengine/[^r].*.h include/crm/pengine/r[^u].*.h" HEADERS[stonithd]="include/crm/stonith-ng.h include/crm/fencing/.*.h" yesno() { local RESPONSE read -p "$1 " RESPONSE case $(echo "$RESPONSE" | tr '[:upper:]' '[:lower:]') in y|yes|ano|ja|si|oui) return 0 ;; *) return 1 ;; esac } prompt_to_continue() { yesno "Continue?" || exit 0 } +sed_in_place() { + cp -p "$1" "$1.$$" + sed -e "$2" "$1" > "$1.$$" + mv "$1.$$" "$1" +} + find_last_release() { if [ -n "$1" ]; then echo "$1" else git tag -l | grep Pacemaker | grep -v rc | sort -Vr | head -n 1 fi } find_libs() { find lib -name "*.am" -exec grep "lib.*_la_LDFLAGS.*version-info" \{\} \; \ | sed -e 's/lib\(.*\)_la_LDFLAGS.*/\1/' } find_makefile() { find lib -name Makefile.am -exec grep -l "lib${1}_la.*version-info" \{\} \; } find_sources() { local LIB="$1" local AMFILE="$2" local SOURCES # Library makefiles should use "+=" to break up long sources lines rather # than backslashed continuation lines, to allow this script to detect # source files correctly. Warn if that's not the case. if grep "lib${LIB}_la_SOURCES.*\\\\" "$AMFILE" then echo -e "\033[1;35m -- Sources list for lib$LIB is probably truncated! --\033[0m" echo "Edit to use '+=' rather than backslashed continuation lines" prompt_to_continue fi SOURCES=$(grep "^lib${LIB}_la_SOURCES" "$AMFILE" \ | sed -e 's/.*=//' -e 's/\\//' -e 's:\.\./gnu/:lib/gnu/:') for SOURCE in $SOURCES; do if echo "$SOURCE" | grep -q "/" then echo "$SOURCE" else echo "$(dirname "$AMFILE")/$SOURCE" fi done } find_headers_as_of() { local TAG local LIB local FILE local PATTERN TAG="$1" LIB="$2" for FILE in $(git ls-tree -r --name-only "$TAG"); do for PATTERN in ${HEADERS[$LIB]}; do if [[ $FILE =~ $PATTERN ]] && [[ ! $FILE =~ internal.h$ ]]; then echo "$FILE" break fi done done } extract_version() { grep "lib${1}_la.*version-info" | sed -e 's/.*version-info\s*\(\S*\)/\1/' } shared_lib_name() { local LIB="$1" local VERSION="$2" echo "lib${LIB}.so.$(echo "$VERSION" | cut -d: -f 1)" } process_lib() { local LIB="$1" local LAST_RELEASE="$2" local AMFILE local SOURCES local HEADERS_LAST local HEADERS_HEAD local HEADERS_DIFF local HEADERS_GONE local HEADERS_ADDED local CHANGE local DEFAULT_CHANGE if [ -z "${HEADERS[$LIB]}" ]; then echo "Can't check lib$LIB until this script is updated with its headers" prompt_to_continue fi AMFILE="$(find_makefile "$LIB")" # Get current shared library version VER_NOW=$(extract_version "$LIB" < "$AMFILE") # Check whether library existed at last release if ! git cat-file -e "$LAST_RELEASE:$AMFILE" 2>/dev/null; then echo "lib$LIB is new, not changing version ($VER_NOW)" prompt_to_continue echo "" return fi HEADERS_LAST="$(find_headers_as_of "$LAST_RELEASE" "$LIB")" HEADERS_HEAD="$(find_headers_as_of "HEAD" "$LIB")" HEADERS_DIFF="$(diff <(echo "$HEADERS_LAST") <(echo "$HEADERS_HEAD"))" HEADERS_GONE="$(echo "$HEADERS_DIFF" | sed -n -e 's/^< //p')" HEADERS_ADDED="$(echo "$HEADERS_DIFF" | sed -n -e 's/^> //p')" # Check whether there were any changes to headers or sources SOURCES="$(find_sources "$LIB" "$AMFILE")" if [ -n "$HEADERS_GONE" ]; then DEFAULT_CHANGE="i" # Removed public header is incompatible change elif [ -n "$HEADERS_ADDED" ]; then DEFAULT_CHANGE="c" # Additions are likely compatible elif git diff --quiet -w "$LAST_RELEASE..HEAD" $HEADERS_HEAD $SOURCES ; then echo "No changes to $LIB interface" prompt_to_continue echo "" return else DEFAULT_CHANGE="f" # Sources changed, so it's at least a fix fi # Show all header changes since last release echo "- Changes in lib$LIB public headers since $LAST_RELEASE:" if [ -n "$HEADERS_GONE" ]; then for HEADER in $HEADERS_GONE; do echo "-- $HEADER was removed" done fi if [ -n "$HEADERS_ADDED" ]; then for HEADER in $HEADERS_ADDED; do echo "++ $HEADER is new" done fi git --no-pager diff --color -w "$LAST_RELEASE..HEAD" $HEADERS_HEAD echo "" if yesno "Show commits (minus refactor/build/merge) touching lib$LIB since $LAST_RELEASE [y/N]?" then git log --color "$LAST_RELEASE..HEAD" -z $HEADERS_HEAD $SOURCES "$AMFILE" \ | grep -vzE "Refactor:|Build:|Merge pull request" echo prompt_to_continue fi # @TODO this seems broken ... #echo "" #if yesno "Show merged PRs touching lib$LIB since $LAST_RELEASE [y/N]?" #then # git log --merges $LAST_RELEASE..HEAD $HEADERS_HEAD $SOURCES $AMFILE # echo # prompt_to_continue #fi # Show summary of source changes since last release echo "" echo "- Headers: $HEADERS_HEAD" echo "- Changed sources since $LAST_RELEASE:" git --no-pager diff --color -w "$LAST_RELEASE..HEAD" --stat $SOURCES echo "" # Ask for human guidance echo "Are the changes to lib$LIB:" read -p "[c]ompatible additions, [i]ncompatible additions/removals or [f]ixes? [$DEFAULT_CHANGE]: " CHANGE [ -z "$CHANGE" ] && CHANGE="$DEFAULT_CHANGE" # Get (and show) shared library version at last release VER=$(git show "$LAST_RELEASE:$AMFILE" | extract_version "$LIB") VER_1=$(echo "$VER" | awk -F: '{print $1}') VER_2=$(echo "$VER" | awk -F: '{print $2}') VER_3=$(echo "$VER" | awk -F: '{print $3}') echo "lib$LIB version at $LAST_RELEASE: $VER" # Show current shared library version if changed if [ "$VER_NOW" != "$VER" ]; then echo "lib$LIB version currently: $VER_NOW" fi # Calculate new library version case $CHANGE in i|I) echo "New backwards-incompatible version: x+1:0:0" (( VER_1++ )) VER_2=0 VER_3=0 # Some headers define constants for shared library names, # update them if the name changed for H in $HEADERS_HEAD; do - sed -i -e "s/$(shared_lib_name "$LIB" "$VER_NOW")/$(shared_lib_name "$LIB" "$VER_1:0:0")/" "$H" + sed_in_place "$H" "s/$(shared_lib_name "$LIB" "$VER_NOW")/$(shared_lib_name "$LIB" "$VER_1:0:0")/" done ;; c|C) echo "New version with backwards-compatible extensions: x+1:0:z+1" (( VER_1++ )) VER_2=0 (( VER_3++ )) ;; F|f) echo "Code changed though interfaces didn't: x:y+1:z" (( VER_2++ )) ;; *) echo "Not updating lib$LIB version" prompt_to_continue CHANGE="" ;; esac VER_NEW=$VER_1:$VER_2:$VER_3 if [ -n "$CHANGE" ]; then if [ "$VER_NEW" != "$VER_NOW" ]; then echo "Updating lib$LIB version from $VER_NOW to $VER_NEW" prompt_to_continue - sed -i "s/version-info\s*$VER_NOW/version-info $VER_NEW/" "$AMFILE" + sed_in_place "$AMFILE" "s/version-info\s*$VER_NOW/version-info $VER_NEW/" else echo "No version change needed for lib$LIB" prompt_to_continue fi fi echo "" } echo "Definitions:" echo "- Compatible additions: new public API functions, structs, etc." echo "- Incompatible additions/removals: new arguments to public API functions," echo " new members added to the middle of public API structs," echo " removal of any public API, etc." echo "- Fixes: any other code changes at all" echo "" echo "When possible, improve backward compatibility first:" echo "- move new members to the end of structs" echo "- use bitfields instead of booleans" echo "- when adding arguments, create a new function that the old one can wrap" echo "" prompt_to_continue LAST_RELEASE=$(find_last_release "$1") for LIB in $(find_libs); do process_lib "$LIB" "$LAST_RELEASE" done # Show all proposed changes git --no-pager diff --color -w diff --git a/mk/common.mk b/mk/common.mk index ac360cc5ea..4c92a0f0dc 100644 --- a/mk/common.mk +++ b/mk/common.mk @@ -1,40 +1,42 @@ # -# Copyright 2014-2021 the Pacemaker project contributors +# Copyright 2014-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. # # # Some variables to help with silent rules # https://www.gnu.org/software/automake/manual/html_node/Automake-silent_002drules-Option.html V ?= $(AM_DEFAULT_VERBOSITY) # When a make command is prefixed with one of the AM_V_* macros, it may also be # desirable to suffix the command with this, to silence stdout. PCMK_quiet = $(pcmk_quiet_$(V)) pcmk_quiet_0 = >/dev/null pcmk_quiet_1 = # AM_V_GEN is intended to be used in custom pattern rules, and replaces echoing # the command used with a more concise line with "GEN" and the name of the file # being generated. Our AM_V_* macros are similar but more descriptive. AM_V_MAN = $(am__v_MAN_$(V)) am__v_MAN_0 = @echo " MAN $@"; am__v_MAN_1 = AM_V_SCHEMA = $(am__v_SCHEMA_$(V)) am__v_SCHEMA_0 = @echo " SCHEMA $@"; am__v_SCHEMA_1 = AM_V_BOOK = $(am__v_BOOK_$(V)) am__v_BOOK_0 = @echo " BOOK $(@:%/_build=%): $(BOOK_FORMATS)"; am__v_BOOK_1 = MAINTAINERCLEANFILES = Makefile.in -AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include \ - -I$(top_builddir)/libltdl -I$(top_srcdir)/libltdl +AM_CPPFLAGS = -I$(top_builddir)/include \ + -I$(top_srcdir)/include \ + -I$(top_builddir)/libltdl \ + -I$(top_srcdir)/libltdl diff --git a/mk/tap.mk b/mk/tap.mk index df57e7f63b..fd6d4e2dfd 100644 --- a/mk/tap.mk +++ b/mk/tap.mk @@ -1,36 +1,36 @@ # # Copyright 2021-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. # -AM_TESTS_ENVIRONMENT= \ - G_DEBUG=gc-friendly \ - MALLOC_CHECK_=2 \ +AM_TESTS_ENVIRONMENT= \ + G_DEBUG=gc-friendly \ + MALLOC_CHECK_=2 \ MALLOC_PERTURB_=$$(($${RANDOM:-256} % 256)) LOG_DRIVER = env AM_TAP_AWK='$(AWK)' $(SHELL) $(top_srcdir)/tests/tap-driver.sh LOG_COMPILER = $(top_srcdir)/tests/tap-test CLEANFILES = *.log *.trs WRAPPED = calloc \ endgrent \ fopen \ getenv \ getpid \ getgrent \ getpwnam_r \ readlink \ setenv \ setgrent \ strdup \ uname \ unsetenv if WRAPPABLE_FOPEN64 WRAPPED += fopen64 endif LDFLAGS_WRAP = $(foreach fn,$(WRAPPED),-Wl,--wrap=$(fn)) diff --git a/python/Makefile.am b/python/Makefile.am index ab15edc8a2..e7086547cf 100644 --- a/python/Makefile.am +++ b/python/Makefile.am @@ -1,20 +1,23 @@ # # Copyright 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. # MAINTAINERCLEANFILES = Makefile.in EXTRA_DIST = pylintrc -SUBDIRS = pacemaker tests +SUBDIRS = pacemaker \ + tests +.PHONY: check-local check-local: PYTHONPATH=$(top_srcdir)/python:$(top_builddir)/python $(PYTHON) -m unittest discover -v -s $(top_srcdir)/python/tests $(top_builddir)/python/tests +.PHONY: pylint pylint: pylint $(SUBDIRS) diff --git a/python/pacemaker/Makefile.am b/python/pacemaker/Makefile.am index f209bba159..df9cc46eef 100644 --- a/python/pacemaker/Makefile.am +++ b/python/pacemaker/Makefile.am @@ -1,17 +1,17 @@ # # Copyright 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. # MAINTAINERCLEANFILES = Makefile.in -pkgpython_PYTHON = __init__.py \ - exitstatus.py +pkgpython_PYTHON = __init__.py \ + exitstatus.py nodist_pkgpython_PYTHON = buildoptions.py SUBDIRS = _cts diff --git a/python/pacemaker/_cts/Makefile.am b/python/pacemaker/_cts/Makefile.am index d1d12cebef..efb00193ca 100644 --- a/python/pacemaker/_cts/Makefile.am +++ b/python/pacemaker/_cts/Makefile.am @@ -1,35 +1,16 @@ # # Copyright 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. # MAINTAINERCLEANFILES = Makefile.in pkgpythondir = $(pythondir)/$(PACKAGE)/_cts -pkgpython_PYTHON = CTS.py \ - __init__.py \ - audits.py \ - cib.py \ - cibxml.py \ - clustermanager.py \ - cmcorosync.py \ - corosync.py \ - environment.py \ - errors.py \ - input.py \ - logging.py \ - network.py \ - patterns.py \ - process.py \ - remote.py \ - scenarios.py \ - test.py \ - timer.py \ - watcher.py +pkgpython_PYTHON = $(wildcard *.py) SUBDIRS = tests diff --git a/python/pacemaker/_cts/tests/Makefile.am b/python/pacemaker/_cts/tests/Makefile.am index e4b746e869..0dba74ba40 100644 --- a/python/pacemaker/_cts/tests/Makefile.am +++ b/python/pacemaker/_cts/tests/Makefile.am @@ -1,40 +1,14 @@ # # Copyright 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. # MAINTAINERCLEANFILES = Makefile.in pkgpythondir = $(pythondir)/$(PACKAGE)/_cts/tests -pkgpython_PYTHON = __init__.py \ - componentfail.py \ - ctstest.py \ - fliptest.py \ - maintenancemode.py \ - nearquorumpointtest.py \ - partialstart.py \ - reattach.py \ - remotebasic.py \ - remotedriver.py \ - remotemigrate.py \ - remotestonithd.py \ - resourcerecover.py \ - remoterscfailure.py \ - restarttest.py \ - restartonebyone.py \ - resynccib.py \ - simulstart.py \ - simulstop.py \ - simulstartlite.py \ - simulstoplite.py \ - splitbraintest.py \ - standbytest.py \ - startonebyone.py \ - starttest.py \ - stonithdtest.py \ - stoptest.py +pkgpython_PYTHON = $(wildcard *.py) diff --git a/python/tests/Makefile.am b/python/tests/Makefile.am index 40098b1021..219812cc5d 100644 --- a/python/tests/Makefile.am +++ b/python/tests/Makefile.am @@ -1,12 +1,13 @@ # # Copyright 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. # MAINTAINERCLEANFILES = Makefile.in -EXTRA_DIST = $(wildcard test_*) __init__.py +EXTRA_DIST = $(wildcard test_*) \ + __init__.py diff --git a/rpm/Makefile.am b/rpm/Makefile.am index 91e381aaf0..2388ad60ee 100644 --- a/rpm/Makefile.am +++ b/rpm/Makefile.am @@ -1,291 +1,294 @@ # # Copyright 2003-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. # # We want to support the use case where this file is fed straight to make # without running automake first, so define defaults for any automake variables # used in this file. top_srcdir ?= .. abs_srcdir ?= $(shell pwd) -abs_builddir ?= $(abs_srcdir) +abs_builddir ?= $(abs_srcdir) MAKE ?= make PACKAGE ?= pacemaker AM_V_at ?= @ MKDIR_P ?= mkdir -p include $(top_srcdir)/mk/common.mk include $(top_srcdir)/mk/release.mk -EXTRA_DIST = pacemaker.spec.in \ +EXTRA_DIST = pacemaker.spec.in \ rpmlintrc # Extra options to pass to rpmbuild (this can be used to override the location # options this file normally passes, or to override macros used by the spec) RPM_EXTRA ?= # Where to put RPM artifacts; possible values: # # - subtree (default): RPM sources (i.e. TARFILE) in top-level build directory, # everything else in dedicated "rpm" subdirectory of build tree # # - toplevel (deprecated): RPM sources, spec, and source rpm in top-level build # directory, everything else uses the usual rpmbuild defaults # # - anything else: The value will be treated as a directory path to be used for # all RPM artifacts. WARNING: The entire directory will get removed with # "make clean" or "make rpm-clean". # RPMDEST ?= subtree RPM_SPEC_DIR_subtree = $(abs_builddir)/SPECS RPM_SRCRPM_DIR_subtree = $(abs_builddir)/SRPMS RPM_OPTS_subtree = --define "_sourcedir $(abs_builddir)/.." \ --define "_topdir $(abs_builddir)" RPM_CLEAN_subtree = "$(abs_builddir)/BUILD" \ "$(abs_builddir)/BUILDROOT" \ "$(abs_builddir)/RPMS" \ "$(abs_builddir)/SPECS" \ "$(abs_builddir)/SRPMS" RPM_SPEC_DIR_toplevel = $(abs_builddir)/.. RPM_SRCRPM_DIR_toplevel = $(abs_builddir)/.. RPM_OPTS_toplevel = --define "_sourcedir $(abs_builddir)/.." \ --define "_specdir $(RPM_SPEC_DIR_toplevel)" \ --define "_srcrpmdir $(RPM_SRCRPM_DIR_toplevel)" RPM_CLEAN_toplevel = RPM_SPEC_DIR_other = $(RPMDEST)/SPECS RPM_SRCRPM_DIR_other = $(RPMDEST)/SRPMS RPM_OPTS_other = --define "_sourcedir $(abs_builddir)/.." \ --define "_topdir $(RPMDEST)" RPM_CLEAN_other = "$(RPMDEST)" RPMTYPE = $(shell case "$(RPMDEST)" in \ toplevel$(rparen) echo toplevel ;; \ subtree$(rparen) echo subtree ;; \ *$(rparen) echo other ;; \ esac) RPM_SPEC_DIR = $(RPM_SPEC_DIR_$(RPMTYPE)) RPM_SRCRPM_DIR = $(RPM_SRCRPM_DIR_$(RPMTYPE)) RPM_OPTS = $(RPM_OPTS_$(RPMTYPE)) $(RPM_EXTRA) RPM_CLEAN = $(RPM_CLEAN_$(RPMTYPE)) WITH ?= --without doc # If $(BUILD_COUNTER) is an existing file, its contents will be used as the # spec version in built RPMs, unless $(SPECVERSION) is set to override it, # and the next increment will be written back to the file after building. BUILD_COUNTER ?= $(shell test -e build.counter && echo build.counter || echo ../build.counter) LAST_COUNT = $(shell test -e "$(BUILD_COUNTER)" && cat "$(BUILD_COUNTER)" || echo 0) COUNT = $(shell expr 1 + $(LAST_COUNT)) SPECVERSION ?= $(COUNT) # SPEC_COMMIT is identical to TAG for DIST and tagged releases, otherwise it is # the short commit ID (which must be used in order for "make export" to use the # same archive name as "make dist") SPEC_COMMIT ?= $(shell \ case $(TAG) in \ Pacemaker-*|DIST$(rparen) \ echo '$(TAG)' ;; \ *$(rparen) \ "$(GIT)" log --pretty=format:%h -n 1 '$(TAG)';; \ esac)$(DIRTY_EXT) SPEC_ABBREV = $(shell printf %s '$(SPEC_COMMIT)' | wc -c) SPEC_RELEASE = $(shell case "$(WITH)" in \ *pre_release*$(rparen) \ [ "$(LAST_RELEASE)" = "$(TAG)" ] \ && echo "$(LAST_RELEASE)" \ || echo "$(NEXT_RELEASE)" ;; \ *$(rparen) \ echo "$(LAST_RELEASE)" ;; \ esac) SPEC_RELEASE_NO = $(shell echo $(SPEC_RELEASE) | sed -e s:Pacemaker-:: -e s:-.*::) MOCK_DIR = $(abs_builddir)/mock MOCK_OPTIONS ?= --resultdir="$(MOCK_DIR)" --no-cleanup-after F ?= $(shell test ! -e /etc/fedora-release && echo 0; test -e /etc/fedora-release && rpm --eval %{fedora}) ARCH ?= $(shell test ! -e /etc/fedora-release && uname -m; test -e /etc/fedora-release && rpm --eval %{_arch}) MOCK_CFG ?= $(shell test -e /etc/fedora-release && echo fedora-$(F)-$(ARCH)) distdir = $(top_distdir)/rpm TARFILE = $(abs_builddir)/../$(top_distdir).tar.gz # Create a source distribution based on a git archive. (If we aren't in a git # checkout, do a make dist instead.) +.PHONY: export export: cd $(abs_srcdir)/..; \ if [ -z "$(CHECKOUT)" ] && [ -f "$(TARFILE)" ]; then \ echo "`date`: Using existing tarball: $(TARFILE)"; \ elif [ -z "$(CHECKOUT)" ]; then \ $(MAKE) $(AM_MAKEFLAGS) dist; \ echo "`date`: Rebuilt tarball: $(TARFILE)"; \ elif [ -n "$(DIRTY_EXT)" ]; then \ "$(GIT)" commit -m "DO-NOT-PUSH" -a; \ "$(GIT)" archive --prefix=$(top_distdir)/ -o "$(TARFILE)" \ HEAD^{tree}; \ "$(GIT)" reset --mixed HEAD^; \ echo "`date`: Rebuilt $(TARFILE)"; \ elif [ -f "$(TARFILE)" ]; then \ echo "`date`: Using existing tarball: $(TARFILE)"; \ else \ "$(GIT)" archive --prefix=$(top_distdir)/ -o "$(TARFILE)" \ $(TAG)^{tree}; \ echo "`date`: Rebuilt $(TARFILE)"; \ fi # Depend on spec-clean so the spec gets rebuilt every time $(RPM_SPEC_DIR)/$(PACKAGE).spec: spec-clean pacemaker.spec.in $(AM_V_at)$(MKDIR_P) "$(RPM_SPEC_DIR)" $(AM_V_GEN)if [ x"`"$(GIT)" ls-files \ -m pacemaker.spec.in 2>/dev/null`" != x ]; then \ cat "$(abs_srcdir)/pacemaker.spec.in"; \ elif "$(GIT)" cat-file -e $(TAG):rpm/pacemaker.spec.in \ 2>/dev/null; then \ "$(GIT)" show $(TAG):rpm/pacemaker.spec.in; \ elif "$(GIT)" cat-file -e $(TAG):pacemaker.spec.in 2>/dev/null; \ then \ "$(GIT)" show $(TAG):pacemaker.spec.in; \ else \ cat "$(abs_srcdir)/pacemaker.spec.in"; \ fi | sed \ -e 's/^\(%global pcmkversion \).*/\1$(SPEC_RELEASE_NO)/' \ -e 's/^\(%global specversion \).*/\1$(SPECVERSION)/' \ -e 's/^\(%global commit \).*/\1$(SPEC_COMMIT)/' \ -e 's/^\(%global commit_abbrev \).*/\1$(SPEC_ABBREV)/' \ -e "s/PACKAGE_DATE/$$(date +'%a %b %d %Y')/" \ -e 's/PACKAGE_VERSION/$(SPEC_RELEASE_NO)-$(SPECVERSION)/' \ > "$@" .PHONY: spec $(PACKAGE).spec spec $(PACKAGE).spec: $(RPM_SPEC_DIR)/$(PACKAGE).spec spec-clean: -rm -f "$(RPM_SPEC_DIR)/$(PACKAGE).spec" .PHONY: srpm srpm: export srpm-clean $(RPM_SPEC_DIR)/$(PACKAGE).spec if [ -e "$(BUILD_COUNTER)" ]; then \ echo $(COUNT) > "$(BUILD_COUNTER)"; \ fi rpmbuild -bs $(RPM_OPTS) $(WITH) "$(RPM_SPEC_DIR)/$(PACKAGE).spec" .PHONY: srpm-clean srpm-clean: -rm -f "$(RPM_SRCRPM_DIR)"/*.src.rpm # e.g. make WITH="--with pre_release" rpm .PHONY: rpm rpm: srpm @echo To create custom builds, edit the flags and options in $(PACKAGE).spec first rpmbuild $(RPM_OPTS) $(WITH) --rebuild "$(RPM_SRCRPM_DIR)"/*.src.rpm .PHONY: rpm-clean rpm-clean: spec-clean srpm-clean -if [ -n "$(RPM_CLEAN)" ]; then rm -rf $(RPM_CLEAN); fi .PHONY: rpmlint rpmlint: $(RPM_SPEC_DIR)/$(PACKAGE).spec rpmlint -f rpmlintrc "$<" .PHONY: rpm-dep rpm-dep: $(RPM_SPEC_DIR)/$(PACKAGE).spec sudo yum-builddep "$(RPM_SPEC_DIR)/$(PACKAGE).spec" .PHONY: release release: $(MAKE) $(AM_MAKEFLAGS) TAG=$(LAST_RELEASE) rpm # Build the highest-versioned rc tag .PHONY: rc rc: @if [ -z "$(CHECKOUT)" ]; then \ echo 'This target must be run from a git checkout'; \ exit 1; \ fi $(MAKE) $(AM_MAKEFLAGS) TAG="$$("$(GIT)" tag -l 2>/dev/null \ | sed -n -e 's/^\(Pacemaker-[0-9.]*-rc[0-9]*\)$$/\1/p' \ | sort -Vr | head -n 1)" rpm .PHONY: chroot chroot: mock-$(MOCK_CFG) mock-install-$(MOCK_CFG) mock-sh-$(MOCK_CFG) @echo Done .PHONY: mock-next mock-next: $(MAKE) $(AM_MAKEFLAGS) F=$(shell expr 1 + $(F)) mock .PHONY: mock-rawhide mock-rawhide: $(MAKE) $(AM_MAKEFLAGS) F=rawhide mock mock-install-%: @echo "Installing packages" mock --root=$* $(MOCK_OPTIONS) --install "$(MOCK_DIR)"/*.rpm \ vi sudo valgrind lcov gdb fence-agents psmisc .PHONY: mock-install mock-install: mock-install-$(MOCK_CFG) @echo Done .PHONY: mock-sh mock-sh: mock-sh-$(MOCK_CFG) @echo Done mock-sh-%: @echo Connecting mock --root=$* $(MOCK_OPTIONS) --shell @echo Done mock-%: srpm mock-clean mock $(MOCK_OPTIONS) --root=$* --no-cleanup-after --rebuild \ $(WITH) "$(RPM_SRCRPM_DIR)"/*.src.rpm .PHONY: mock mock: mock-$(MOCK_CFG) @echo Done .PHONY: dirty dirty: $(MAKE) $(AM_MAKEFLAGS) DIRTY=yes mock .PHONY: mock-clean mock-clean: -rm -rf "$(MOCK_DIR)" # Make debugging makefile issues easier +.PHONY: vars vars: @echo "CHECKOUT=$(CHECKOUT)" @echo "VERSION=$(VERSION)" @echo "COMMIT=$(COMMIT)" @echo "TAG=$(TAG)" @echo "DIRTY=$(DIRTY)" @echo "DIRTY_EXT=$(DIRTY_EXT)" @echo "LAST_RELEASE=$(LAST_RELEASE)" @echo "NEXT_RELEASE=$(NEXT_RELEASE)" @echo "top_distdir=$(top_distdir)" @echo "RPMDEST=$(RPMDEST)" @echo "RPMTYPE=$(RPMTYPE)" @echo "RPM_SPEC_DIR=$(RPM_SPEC_DIR)" @echo "RPM_SRCRPM_DIR=$(RPM_SRCRPM_DIR)" @echo "RPM_OPTS=$(RPM_OPTS)" @echo "RPM_CLEAN=$(RPM_CLEAN)" @echo "WITH=$(WITH)" @echo "BUILD_COUNTER=$(BUILD_COUNTER)" @echo "LAST_COUNT=$(LAST_COUNT)" @echo "COUNT=$(COUNT)" @echo "SPECVERSION=$(SPECVERSION)" @echo "SPEC_COMMIT=$(SPEC_COMMIT)" @echo "SPEC_ABBREV=$(SPEC_ABBREV)" @echo "SPEC_RELEASE=$(SPEC_RELEASE)" @echo "SPEC_RELEASE_NO=$(SPEC_RELEASE_NO)" @echo "TARFILE=$(TARFILE)" +.PHONY: clean-local clean-local: mock-clean rpm-clean -rm -f "$(TARFILE)" diff --git a/tests/Makefile.am b/tests/Makefile.am index 96019defcb..8601e1ba09 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,21 +1,22 @@ # -# Copyright 2020-2022 the Pacemaker project contributors +# Copyright 2020-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. # # tap-test is copied from /usr/share/automake-*/tap-driver.sh. -EXTRA_DIST = tap-driver.sh \ - tap-test \ +EXTRA_DIST = tap-driver.sh \ + tap-test \ test-headers.sh +.PHONY: check check: check-headers .PHONY: check-headers check-headers: CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" CC="$(CC)" \ - CXX="$(CXX)" CPPFLAGS="$(CPPFLAGS)" LIBS="$(LIBS)" \ + CXX="$(CXX)" CPPFLAGS="$(CPPFLAGS) -I$(top_builddir)/include" LIBS="$(LIBS)" \ SRCDIR="$(top_srcdir)" sh "$(srcdir)/test-headers.sh" diff --git a/tools/Makefile.am b/tools/Makefile.am index 2bd97613a9..3efa938f8e 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -1,166 +1,154 @@ # # Copyright 2004-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. # include $(top_srcdir)/mk/common.mk include $(top_srcdir)/mk/man.mk if BUILD_SYSTEMD systemdsystemunit_DATA = crm_mon.service endif -noinst_HEADERS = crm_mon.h crm_resource.h +noinst_HEADERS = crm_mon.h \ + crm_resource.h pcmkdir = $(datadir)/$(PACKAGE) -pcmk_DATA = report.common report.collector +pcmk_DATA = report.common \ + report.collector -sbin_SCRIPTS = crm_report crm_standby crm_master crm_failcount +sbin_SCRIPTS = crm_report \ + crm_standby \ + crm_master \ + crm_failcount if BUILD_CIBSECRETS sbin_SCRIPTS += cibsecret endif noinst_SCRIPTS = cluster-clean \ - cluster-init \ cluster-helper \ pcmk_simtimes -EXTRA_DIST = attrd_updater.8.inc \ - cibadmin.8.inc \ - crm_attribute.8.inc \ - crm_diff.8.inc \ - crm_error.8.inc \ - crm_mon.8.inc \ - crm_node.8.inc \ - crm_resource.8.inc \ - crm_rule.8.inc \ - crm_shadow.8.inc \ - crm_simulate.8.inc \ - crm_ticket.8.inc \ - crm_verify.8.inc \ - crmadmin.8.inc \ - fix-manpages \ - iso8601.8.inc \ - stonith_admin.8.inc +EXTRA_DIST = $(wildcard *.inc) \ + fix-manpages sbin_PROGRAMS = attrd_updater \ - cibadmin \ - crmadmin \ - crm_simulate \ + cibadmin \ + crmadmin \ + crm_simulate \ crm_attribute \ - crm_diff \ - crm_error \ - crm_mon \ - crm_node \ - crm_resource \ - crm_rule \ - crm_shadow \ - crm_verify \ - crm_ticket \ - iso8601 \ + crm_diff \ + crm_error \ + crm_mon \ + crm_node \ + crm_resource \ + crm_rule \ + crm_shadow \ + crm_verify \ + crm_ticket \ + iso8601 \ stonith_admin ## SOURCES # A few tools are just thin wrappers around crm_attribute. # This makes their help get updated when crm_attribute changes # (see mk/common.mk). MAN8DEPS = crm_attribute crmadmin_SOURCES = crmadmin.c -crmadmin_LDADD = $(top_builddir)/lib/pengine/libpe_status.la \ - $(top_builddir)/lib/cib/libcib.la \ - $(top_builddir)/lib/common/libcrmcommon.la \ - $(top_builddir)/lib/pacemaker/libpacemaker.la +crmadmin_LDADD = $(top_builddir)/lib/pacemaker/libpacemaker.la +crmadmin_LDADD += $(top_builddir)/lib/pengine/libpe_status.la +crmadmin_LDADD += $(top_builddir)/lib/cib/libcib.la +crmadmin_LDADD += $(top_builddir)/lib/common/libcrmcommon.la crm_error_SOURCES = crm_error.c -crm_error_LDADD = $(top_builddir)/lib/pacemaker/libpacemaker.la \ - $(top_builddir)/lib/common/libcrmcommon.la +crm_error_LDADD = $(top_builddir)/lib/pacemaker/libpacemaker.la +crm_error_LDADD += $(top_builddir)/lib/common/libcrmcommon.la cibadmin_SOURCES = cibadmin.c -cibadmin_LDADD = $(top_builddir)/lib/pacemaker/libpacemaker.la \ - $(top_builddir)/lib/cib/libcib.la \ - $(top_builddir)/lib/common/libcrmcommon.la +cibadmin_LDADD = $(top_builddir)/lib/pacemaker/libpacemaker.la +cibadmin_LDADD += $(top_builddir)/lib/cib/libcib.la +cibadmin_LDADD += $(top_builddir)/lib/common/libcrmcommon.la crm_shadow_SOURCES = crm_shadow.c -crm_shadow_LDADD = $(top_builddir)/lib/cib/libcib.la \ - $(top_builddir)/lib/common/libcrmcommon.la +crm_shadow_LDADD = $(top_builddir)/lib/cib/libcib.la +crm_shadow_LDADD += $(top_builddir)/lib/common/libcrmcommon.la crm_node_SOURCES = crm_node.c -crm_node_LDADD = $(top_builddir)/lib/pacemaker/libpacemaker.la \ - $(top_builddir)/lib/cib/libcib.la \ - $(top_builddir)/lib/common/libcrmcommon.la +crm_node_LDADD = $(top_builddir)/lib/pacemaker/libpacemaker.la +crm_node_LDADD += $(top_builddir)/lib/cib/libcib.la +crm_node_LDADD += $(top_builddir)/lib/common/libcrmcommon.la crm_simulate_SOURCES = crm_simulate.c - -crm_simulate_LDADD = $(top_builddir)/lib/pengine/libpe_status.la \ - $(top_builddir)/lib/pacemaker/libpacemaker.la \ - $(top_builddir)/lib/cib/libcib.la \ - $(top_builddir)/lib/common/libcrmcommon.la +crm_simulate_LDADD = $(top_builddir)/lib/pacemaker/libpacemaker.la +crm_simulate_LDADD += $(top_builddir)/lib/pengine/libpe_status.la +crm_simulate_LDADD += $(top_builddir)/lib/cib/libcib.la +crm_simulate_LDADD += $(top_builddir)/lib/common/libcrmcommon.la crm_diff_SOURCES = crm_diff.c -crm_diff_LDADD = $(top_builddir)/lib/common/libcrmcommon.la +crm_diff_LDADD = $(top_builddir)/lib/common/libcrmcommon.la crm_mon_SOURCES = crm_mon.c crm_mon_curses.c -crm_mon_LDADD = $(top_builddir)/lib/pengine/libpe_status.la \ - $(top_builddir)/lib/fencing/libstonithd.la \ - $(top_builddir)/lib/pacemaker/libpacemaker.la \ - $(top_builddir)/lib/cib/libcib.la \ - $(top_builddir)/lib/common/libcrmcommon.la \ - $(CURSESLIBS) +crm_mon_LDADD = $(top_builddir)/lib/pacemaker/libpacemaker.la +crm_mon_LDADD += $(top_builddir)/lib/pengine/libpe_status.la +crm_mon_LDADD += $(top_builddir)/lib/fencing/libstonithd.la +crm_mon_LDADD += $(top_builddir)/lib/cib/libcib.la +crm_mon_LDADD += $(top_builddir)/lib/common/libcrmcommon.la +crm_mon_LDADD += $(CURSESLIBS) crm_verify_SOURCES = crm_verify.c -crm_verify_LDADD = $(top_builddir)/lib/pengine/libpe_status.la \ - $(top_builddir)/lib/pacemaker/libpacemaker.la \ - $(top_builddir)/lib/cib/libcib.la \ - $(top_builddir)/lib/common/libcrmcommon.la +crm_verify_LDADD = $(top_builddir)/lib/pacemaker/libpacemaker.la +crm_verify_LDADD += $(top_builddir)/lib/pengine/libpe_status.la +crm_verify_LDADD += $(top_builddir)/lib/cib/libcib.la +crm_verify_LDADD += $(top_builddir)/lib/common/libcrmcommon.la crm_attribute_SOURCES = crm_attribute.c -crm_attribute_LDADD = $(top_builddir)/lib/pacemaker/libpacemaker.la \ - $(top_builddir)/lib/cib/libcib.la \ - $(top_builddir)/lib/common/libcrmcommon.la +crm_attribute_LDADD = $(top_builddir)/lib/pacemaker/libpacemaker.la +crm_attribute_LDADD += $(top_builddir)/lib/cib/libcib.la +crm_attribute_LDADD += $(top_builddir)/lib/common/libcrmcommon.la crm_resource_SOURCES = crm_resource.c \ crm_resource_ban.c \ crm_resource_print.c \ crm_resource_runtime.c -crm_resource_LDADD = $(top_builddir)/lib/pengine/libpe_rules.la \ - $(top_builddir)/lib/fencing/libstonithd.la \ - $(top_builddir)/lib/lrmd/liblrmd.la \ - $(top_builddir)/lib/services/libcrmservice.la \ - $(top_builddir)/lib/pengine/libpe_status.la \ - $(top_builddir)/lib/pacemaker/libpacemaker.la \ - $(top_builddir)/lib/cib/libcib.la \ - $(top_builddir)/lib/common/libcrmcommon.la +crm_resource_LDADD = $(top_builddir)/lib/pacemaker/libpacemaker.la +crm_resource_LDADD += $(top_builddir)/lib/pengine/libpe_status.la +crm_resource_LDADD += $(top_builddir)/lib/cib/libcib.la +crm_resource_LDADD += $(top_builddir)/lib/pengine/libpe_rules.la +crm_resource_LDADD += $(top_builddir)/lib/lrmd/liblrmd.la +crm_resource_LDADD += $(top_builddir)/lib/fencing/libstonithd.la +crm_resource_LDADD += $(top_builddir)/lib/services/libcrmservice.la +crm_resource_LDADD += $(top_builddir)/lib/common/libcrmcommon.la crm_rule_SOURCES = crm_rule.c -crm_rule_LDADD = $(top_builddir)/lib/pacemaker/libpacemaker.la \ - $(top_builddir)/lib/cib/libcib.la \ - $(top_builddir)/lib/pengine/libpe_rules.la \ - $(top_builddir)/lib/pengine/libpe_status.la \ - $(top_builddir)/lib/common/libcrmcommon.la +crm_rule_LDADD = $(top_builddir)/lib/pacemaker/libpacemaker.la +crm_rule_LDADD += $(top_builddir)/lib/pengine/libpe_status.la +crm_rule_LDADD += $(top_builddir)/lib/cib/libcib.la +crm_rule_LDADD += $(top_builddir)/lib/pengine/libpe_rules.la +crm_rule_LDADD += $(top_builddir)/lib/common/libcrmcommon.la iso8601_SOURCES = iso8601.c iso8601_LDADD = $(top_builddir)/lib/common/libcrmcommon.la attrd_updater_SOURCES = attrd_updater.c -attrd_updater_LDADD = $(top_builddir)/lib/pacemaker/libpacemaker.la \ - $(top_builddir)/lib/common/libcrmcommon.la +attrd_updater_LDADD = $(top_builddir)/lib/pacemaker/libpacemaker.la +attrd_updater_LDADD += $(top_builddir)/lib/common/libcrmcommon.la crm_ticket_SOURCES = crm_ticket.c -crm_ticket_LDADD = $(top_builddir)/lib/pengine/libpe_rules.la \ - $(top_builddir)/lib/pengine/libpe_status.la \ - $(top_builddir)/lib/pacemaker/libpacemaker.la \ - $(top_builddir)/lib/cib/libcib.la \ - $(top_builddir)/lib/common/libcrmcommon.la +crm_ticket_LDADD = $(top_builddir)/lib/pacemaker/libpacemaker.la +crm_ticket_LDADD += $(top_builddir)/lib/pengine/libpe_status.la +crm_ticket_LDADD += $(top_builddir)/lib/pengine/libpe_rules.la +crm_ticket_LDADD += $(top_builddir)/lib/cib/libcib.la +crm_ticket_LDADD += $(top_builddir)/lib/common/libcrmcommon.la stonith_admin_SOURCES = stonith_admin.c -stonith_admin_LDADD = $(top_builddir)/lib/pacemaker/libpacemaker.la \ - $(top_builddir)/lib/cib/libcib.la \ - $(top_builddir)/lib/pengine/libpe_status.la \ - $(top_builddir)/lib/fencing/libstonithd.la \ - $(top_builddir)/lib/common/libcrmcommon.la +stonith_admin_LDADD = $(top_builddir)/lib/pacemaker/libpacemaker.la +stonith_admin_LDADD += $(top_builddir)/lib/pengine/libpe_status.la +stonith_admin_LDADD += $(top_builddir)/lib/cib/libcib.la +stonith_admin_LDADD += $(top_builddir)/lib/fencing/libstonithd.la +stonith_admin_LDADD += $(top_builddir)/lib/common/libcrmcommon.la CLEANFILES = $(man8_MANS) diff --git a/tools/cluster-helper.in b/tools/cluster-helper.in index d8dac6ec9a..5bfe89046b 100755 --- a/tools/cluster-helper.in +++ b/tools/cluster-helper.in @@ -1,201 +1,201 @@ #!@BASH_PATH@ # # 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. # hosts= group=$cluster_name user=root pdsh=`which pdsh 2>/dev/null` ssh=`which qarsh 2>/dev/null` scp=`which qacp 2>/dev/null` command=list format=oneline replace="{}" if [ x$ssh = "x" ]; then ssh=ssh scp=scp fi function helptext() { echo "cluster-helper - A tool for running commands on multiple hosts" echo "" echo "Attempt to use pdsh, qarsh, or ssh (in that order) to execute commands" echo "on multiple hosts" echo "" echo "DSH groups can be configured and specified with -g instead of listing" echo "the individual hosts every time" echo "" echo "Usage: cluster-helper [options] [command]" echo "" echo "Options:" echo "--ssh Force the use of ssh instead of qarsh even if it available" echo "-g, --group Specify the group to operate on/with" echo "-w, --host Specify a host to operate on/with. May be specified multiple times" echo "-f, --format Specifiy the output format When listing hosts or group contents" echo " Allowed values: [oneline], long, short, pdsh, bullet" echo "" echo "" echo "Commands:" echo "--list format List the contents of a group in the specified format" echo "--add name Add supplied (-w) hosts to the named group" echo "--create name Create the named group with the supplied (-w) hosts" echo "--run, -- Treat all subsequent arguments as a command to perform on" echo " the specified command on the hosts or group" echo "--xargs Run the supplied command having replaced any occurrences" echo " of {} with the node name" echo "" echo "--copy file(s) host:file Pass subsequent arguments to scp or qacp" echo " Any occurrences of {} are replaced with the node name" echo "--key Install an ssh key" echo "" exit $1 } while true ; do case "$1" in --help|-h|-\?) helptext 0;; -x) set -x; shift;; --ssh) ssh="ssh"; scp="scp"; pdsh=""; shift;; -g|--group) group="$2"; shift; shift;; -w|--host) for h in $2; do hosts="$hosts $h"; done shift; shift;; -f|--format) format=$2; shift; shift;; -I) replace=$2; shift; shift;; --list|list) format=$2; command=list; shift; shift;; --add|add) command=group-add; shift;; - --create|create) group="$2", command=group-create; shift; shift;; + --create|create) group="$2"; command=group-create; shift; shift;; --run|run) command=run; shift;; --copy|copy) command=copy; shift; break ;; --key|key) command=key; shift; break ;; --xargs) command=xargs; shift; break ;; --) command=run; shift; break ;; "") break;; *) helptext 1;; esac done if [ x"$group" = x -a x"$hosts" = x ]; then group=$CTS_GROUP fi function expand() { fmt=$1 if [ x$group != x -a -f ~/.dsh/group/$group ]; then hosts=`cat ~/.dsh/group/$group` elif [ x$group != x ]; then echo "Unknown group: $group" >&2 exit 1 fi if [ "x$hosts" != x -a $fmt = oneline ]; then echo $hosts elif [ "x$hosts" != x -a $fmt = short ]; then ( for h in $hosts; do echo $h | sed 's:\..*::' done ) | tr '\n' ' ' echo "" elif [ "x$hosts" != x -a $fmt = pdsh ]; then ( for h in $hosts; do echo "-w $h" done ) | tr '\n' ' ' echo "" elif [ "x$hosts" != x -a $fmt = long ]; then for h in $hosts; do echo $h done elif [ "x$hosts" != x -a $fmt = bullet ]; then for h in $hosts; do echo " * $h" done elif [ "x$hosts" != x ]; then echo "Unknown format: $fmt" >&2 fi } if [ $command = list ]; then expand $format elif [ $command = key ]; then hosts=`expand oneline` for h in $hosts; do ssh-copy-id root@$h done elif [ $command = group-create ]; then f=`mktemp` mkdir -p ~/.dsh/group if [ -f ~/.dsh/group/$group ]; then echo "Overwriting existing group $group" fi for h in $hosts; do echo $h >> $f done echo "Creating group $group in ~/.dsh/group" sort -u $f > ~/.dsh/group/$group rm -f $f elif [ $command = group-add ]; then if [ x$group = x ]; then echo "Please specify a group to append to" exit 1 fi f=`mktemp` mkdir -p ~/.dsh/group if [ -f ~/.dsh/group/$group ]; then cat ~/.dsh/group/$group > $f fi for h in $hosts; do echo $h >> $f done echo "Appending hosts to group $group in ~/.dsh/group" sort -u $f > ~/.dsh/group/$group rm -f $f elif [ $command = run ]; then if [ x$pdsh != x ]; then hosts=`expand pdsh` $pdsh -l $user $hosts -- $* else hosts=`expand oneline` for n in $hosts; do $ssh -l $user $n -- $* < /dev/null done if [ x"$hosts" = x ]; then echo "No hosts specified" fi fi elif [ $command = copy ]; then hosts=`expand oneline` for n in $hosts; do $scp `echo $* | sed 's@'$replace'@'$n'@'` done elif [ $command = xargs ]; then hosts=`expand oneline` for n in $hosts; do eval `echo $* | sed 's@'$replace'@'$n'@'` done fi diff --git a/tools/cluster-init.in b/tools/cluster-init.in deleted file mode 100755 index 1485c81f8e..0000000000 --- a/tools/cluster-init.in +++ /dev/null @@ -1,537 +0,0 @@ -#!@BASH_PATH@ -# -# 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. -# - -accept_defaults=0 -do_raw=0 -ETCHOSTS=0 -nodelist=0 -limit=0 - -pkgs="corosync xinetd nmap abrt-cli fence-agents perl-TimeDate gdb" - -transport="multicast" -inaddr_any="no" - -INSTALL= -cs_conf= -fence_conf= - -dsh_group=0 -if [ ! -z $cluster_name ]; then - cluster=$cluster_name -else - cluster=dummy0 -fi - -# Corosync Settings -cs_port=666 - -# Settings that work great on nXX -join=60 -#token=3000 -consensus=1500 - -# Official settings -join=2000 -token=5000 -consensus=2500 - -# Testing -join=1000 -consensus=7500 -do_debug=off - -function ip_for_node() { - ping -c 1 $1 | grep "bytes from" | head -n 1 | sed -e 's/.*bytes from//' -e 's/: icmp.*//' | awk '{print $NF}' | sed 's:(::' | sed 's:)::' -# if [ $do_raw = 1 ]; then -# echo $1 -# else -# #host $1 | grep "has address" | head -n 1 | awk '{print $NF}' | sed 's:(::' | sed 's:)::' -# fi -} -function id_for_node() { - ip_for_node $* | tr '.' ' ' | awk '{print $4}' -} -function name_for_node() { - echo $1 | awk -F. '{print $1}' -} - -function helptext() { - echo "cluster-init - Configure cluster communication for the infrastructures supported by Pacemaker" - echo "" - echo "-g, --group Specify the group to operate on/with" - echo "-w, --host Specify a host to operate on/with. May be specified multiple times" - echo "-r, --raw-ip Supplied nodes were listed as their IP addresses" - echo "" - echo "-c, --corosync configure for corosync" - echo "-C, --nodelist configure for corosync with a node list" - echo "-u, --unicast configure point-to-point communication instead of multicast" - echo "" - echo "-I, --install Install packages" - echo "" - echo "-d, --debug Enable debug logging for the cluster" - echo "--hosts Copy the local /etc/hosts file to all nodes" - echo "-e, --extra list Whitespace separated list of extra packages to install" - echo "-l, --limit N Use the first N hosts from the named group" - echo " Extra packages to install" - exit $1 -} - -host_input="" -while true; do - case "$1" in - -g) cluster=$2; - shift; shift;; - -w|--host) - for h in $2; do - host_input="$host_input -w $h"; - done - shift; shift;; - -w) host_input="$host_input -w $2" - shift; shift;; - -r|--raw-ip) do_raw=1; shift;; - - -d|--debug) do_debug=on; shift;; - - -I|--install) INSTALL=Yes; shift;; - --hosts) ETCHOSTS=1; shift;; - - -c|--corosync) CTYPE=corosync; shift;; - -C|--nodelist) CTYPE=corosync; nodelist=1; shift;; - -u|--unicast) nodelist=1; transport=udpu; inaddr_any="yes"; shift;; - -e|--extra) pkgs="$pkgs $2"; shift; shift;; - -t|--test) pkgs="$pkgs valgrind"; shift;; - -l|--limit) limit=$2; shift; shift;; - - r*[0-9]) - rhel=`echo $1 | sed -e s/rhel// -e s/-// -e s/r//` - pkgs="$pkgs qarsh-server"; - case $rhel in - 7) CTYPE=corosync;; - esac - shift - ;; - - f*[0-9][0-9]) - CTYPE=corosync; - shift - ;; - - -y|--yes|--defaults) accept_defaults=1; shift;; - -x) set -x; shift;; - -\?|--help) helptext 0; shift;; - "") break;; - *) echo "unknown option: $1"; exit 1;; - esac -done - -if [ ! -z $cluster ]; then - host_input="-g $cluster" - # use the last digit present in the variable (if any) - dsh_group=`echo $cluster | sed 's/[^0-9][^0-9]*//g;s/.*\([0-9]\)$/\1/'` -fi - -if [ -z $dsh_group ]; then - dsh_group=1 -fi - -if [ x = "x$host_input" -a x = "x$cluster" ]; then - if [ -d $HOME/.dsh/group ]; then - read -p "Please specify a dsh group you'd like to configure as a cluster? [] " -t 60 cluster - else - read -p "Please specify a whitespace delimetered list of nodes you'd like to configure as a cluster? [] " -t 60 host_list - - for h in $2; do - host_input="$host_input -w $h"; - done - fi -fi - -if [ -z "$host_input" ]; then - echo "You didn't specify any nodes or groups to configure" - exit 1 -fi - -if [ $limit -gt 0 ]; then - echo "Using only the first $limit hosts in $cluster group" - host_list=`cluster-helper --list bullet $host_input | head -n $limit | tr '\n*' ' '` -else - host_list=`cluster-helper --list short $host_input` -fi -num_hosts=`echo $host_list | wc -w` - -if [ $num_hosts -gt 9 ]; then - cs_port=66 -fi - -for h in $host_list; do - ping -c 1 -q $h - if [ $? != 0 ]; then - echo "Using long names..." - host_list=`cluster-helper --list long $host_input` - break - fi -done - -if [ -z $CTYPE ]; then - echo "" - read -p "Where should Pacemaker obtain membership and quorum from? [corosync] (corosync) " -t 60 CTYPE -fi - -case $CTYPE in - corosync) cs_conf="@PCMK__COROSYNC_CONF@" ;; -esac - -function get_defaults() -{ - if [ -z $SSH ]; then - SSH="No" - fi - - if [ -z $SELINUX ]; then - SELINUX="No" - fi - - if [ -z $IPTABLES ]; then - IPTABLES="Yes" - fi - - if [ -z $DOMAIN ]; then - DOMAIN="No" - fi - if [ -z $INSTALL ]; then - INSTALL="Yes" - fi - if [ -z $DATE ]; then - DATE="No" - fi -} - -get_defaults -if [ $accept_defaults = 0 ]; then - echo "" - read -p "Shall I install an ssh key to cluster nodes? [$SSH] " -t 60 SSH - echo "" - echo "SELinux prevent many things, including password-less ssh logins" - read -p "Shall I disable selinux? [$SELINUX] " -t 60 SELINUX - echo "" - echo "Incorrectly configured firewalls will prevent corosync from starting up" - read -p "Shall I disable iptables? [$IPTABLES] " -t 60 IPTABLES - - echo "" - read -p "Shall I install/update the relevant packages? [$INSTALL] " -t 60 INSTALL - - echo "" - read -p "Shall I sync the date/time? [$DATE] " -t 60 DATE -fi -get_defaults - -echo "" -echo "Detecting possible fencing options" -if [ -e /etc/cluster/fence_xvm.key ]; then - echo "* Found fence_xvm" - fence_conf=/etc/cluster/fence_xvm.key - pkgs="$pkgs fence-virt" -fi - -if [ ! -z ${OS_AUTH_URL} ]; then - echo "* Found openstack credentials" - fence_conf=/sbin/fence_openstack - pkgs="$pkgs python-novaclient" -fi -echo "" -echo "Beginning cluster configuration" -echo "" - -case $SSH in - [Yy][Ee][Ss]|[Yy]) - for host in $host_list; do - echo "Installing our ssh key on ${host}" - ssh-copy-id root@${host} >/dev/null 2>&1 - # Fix selinux labeling - ssh -l root ${host} -- restorecon -R -v . - done - ;; -esac - -case $DATE in - [Yy][Ee][Ss]|[Yy]) - for host in $host_list; do - echo "Setting time on ${host}" - scp /etc/localtime root@${host}:/etc - now=`date +%s` - ssh -l root ${host} -- date -s @$now - echo "" - done - ;; -esac - -init=`mktemp` -cat<<-END>$init -verbose=0 -pkgs="$pkgs" - -lhost=\`uname -n\` -lshort=\`echo \$lhost | awk -F. '{print \$1}'\` - -log() { - printf "%-10s \$*\n" "\$lshort:" 1>&2 -} - -debug() { - if [ \$verbose -gt 0 ]; then - log "Debug: \$*" - fi -} - -info() { - log "\$*" -} - -warning() { - log "WARN: \$*" -} - -fatal() { - log "ERROR: \$*" - exit 1 -} - -case $SELINUX in - [Yy][Ee][Ss]|[Yy]) - sed -i.sed "s/enforcing/disabled/g" /etc/selinux/config - ;; -esac - -case $IPTABLES in - [Yy][Ee][Ss]|[Yy]|"") - service iptables stop - chkconfig iptables off - service firewalld stop - chkconfig firewalld off - ;; -esac - -case $DOMAIN in - [Nn][Oo]|"") - ;; - *.*) - if - ! grep domain /etc/resolv.conf - then - sed -i.sed "s/nameserver/domain\ $DOMAIN\\\nnameserver/g" /etc/resolv.conf - fi - ;; - *) echo "Unknown domain: $DOMAIN";; -esac - -case $INSTALL in - [Yy][Ee][Ss]|[Yy]|"") - info Installing cluster software - yum install -y $pkgs pacemaker - ;; -esac - -info "Configuring services" -chkconfig xinetd on -service xinetd start &>/dev/null - -chkconfig corosync off &> /dev/null -mkdir -p /etc/cluster - -info "Turning on core files" -grep -q "unlimited" /etc/bashrc -if [ $? = 1 ]; then - sed -i.sed "s/bashrc/bashrc\\\nulimit\ -c\ unlimited/g" /etc/bashrc -fi - -function patch_cs_config() { - test $num_hosts != 2 - two_node=$? - - priority="info" - if [ $do_debug = 1 ]; then - priority="debug" - fi - - ssh -l root ${host} -- sed -i.sed "s/.*mcastaddr:.*/mcastaddr:\ 226.94.1.1/g" $cs_conf - ssh -l root ${host} -- sed -i.sed "s/.*mcastport:.*/mcastport:\ $cs_port$dsh_group/g" $cs_conf - ssh -l root ${host} -- sed -i.sed "s/.*bindnetaddr:.*/bindnetaddr:\ $ip/g" $cs_conf - ssh -l root ${host} -- sed -i.sed "s/.*syslog_facility:.*/syslog_facility:\ daemon/g" $cs_conf - ssh -l root ${host} -- sed -i.sed "s/.*logfile_priority:.*/logfile_priority:\ $priority/g" $cs_conf - - if [ ! -z $token ]; then - ssh -l root ${host} -- sed -i.sed "s/.*token:.*/token:\ $token/g" $cs_conf - fi - if [ ! -z $consensus ]; then - ssh -l root ${host} -- sed -i.sed "s/.*consensus:.*/consensus:\ $consensus/g" $cs_conf - fi - if [ ! -z $join ]; then - ssh -l root ${host} -- sed -i.sed "s/^join:.*/join:\ $join/g" $cs_conf - ssh -l root ${host} -- sed -i.sed "s/\\\Wjoin:.*/join:\ $join/g" $cs_conf - fi - - ssh -l root ${host} -- grep -q "corosync_votequorum" $cs_conf 2>&1 > /dev/null - if [ $? -eq 0 ]; then - ssh -l root ${host} -- sed -i.sed "s/\\\Wexpected_votes:.*/expected_votes:\ $num_hosts/g" $cs_conf - ssh -l root ${host} -- sed -i.sed "s/\\\Wtwo_node:.*/two_node:\ $two_node/g" $cs_conf - else - printf "%-10s Wrong quorum provider: installing $cs_conf for corosync instead\n" ${host} - create_cs_config - fi -} - -function create_cs_config() { - cs_tmp=/tmp/cs_conf.$$ - test $num_hosts != 2 - two_node=$? - - # Base config - priority="info" - if [ $do_debug = 1 ]; then - priority="debug" - fi - - cat <<-END >$cs_tmp -# Please read the corosync.conf.5 manual page -totem { - version: 2 - - # cypto_cipher and crypto_hash: Used for mutual node authentication. - # If you choose to enable this, then do remember to create a shared - # secret with "corosync-keygen". - crypto_cipher: none - crypto_hash: none - - # Assign a fixed node id - nodeid: $id - - # Disable encryption - secauth: off - - transport: $transport - inaddr_any: $inaddr_any - - # interface: define at least one interface to communicate - # over. If you define more than one interface stanza, you must - # also set rrp_mode. - interface { - # Rings must be consecutively numbered, starting at 0. - ringnumber: 0 - - # This is normally the *network* address of the - # interface to bind to. This ensures that you can use - # identical instances of this configuration file - # across all your cluster nodes, without having to - # modify this option. - bindnetaddr: $ip - - # However, if you have multiple physical network - # interfaces configured for the same subnet, then the - # network address alone is not sufficient to identify - # the interface Corosync should bind to. In that case, - # configure the *host* address of the interface - # instead: - # bindnetaddr: 192.168.1.1 - # When selecting a multicast address, consider RFC - # 2365 (which, among other things, specifies that - # 239.255.x.x addresses are left to the discretion of - # the network administrator). Do not reuse multicast - # addresses across multiple Corosync clusters sharing - # the same network. - - # Corosync uses the port you specify here for UDP - # messaging, and also the immediately preceding - # port. Thus if you set this to 5405, Corosync sends - # messages over UDP ports 5405 and 5404. - mcastport: $cs_port$dsh_group - - # Time-to-live for cluster communication packets. The - # number of hops (routers) that this ring will allow - # itself to pass. Note that multicast routing must be - # specifically enabled on most network routers. - ttl: 1 - mcastaddr: 226.94.1.1 - } -} - -logging { - debug: off - fileline: off - to_syslog: yes - to_stderr: no - syslog_facility: daemon - timestamp: on - to_logfile: yes - logfile: /var/log/corosync.log - logfile_priority: $priority -} - -amf { - mode: disabled -} - -quorum { - provider: corosync_votequorum - expected_votes: $num_hosts - votes: 1 - two_node: $two_node - wait_for_all: 0 - last_man_standing: 0 - auto_tie_breaker: 0 -} -END - scp -q $cs_tmp root@${host}:$cs_conf - rm -f $cs_tmp -} - -for host in $host_list; do - echo "" - echo "" - echo "* Configuring $host" - - cs_short_host=`name_for_node $host` - ip=`ip_for_node $host` - id=`id_for_node $host` - - echo $ip | grep -qis NXDOMAIN - if [ $? = 0 ]; then - echo "Couldn't find resolve $host to an IP address" - exit 1 - fi - - if [ `uname -n` = $host ]; then - bash $init - else - cat $init | ssh -l root -T $host -- "cat > $init; bash $init" - fi - - if [ "x$fence_conf" != x ]; then - if [ -e $fence_conf ]; then - scp $fence_conf root@${host}:$fence_conf - fi - fi - - if [ $ETCHOSTS = 1 ]; then - scp /etc/hosts root@${host}:/etc/hosts - fi - - ssh -l root ${host} -- grep -q "token:" $cs_conf 2>&1 > /dev/null - new_config=$? - new_config=1 - - if [ $new_config = 0 ]; then - printf "%-10s Updating $cs_conf\n" ${host}: - patch_cs_config - else - printf "%-10s Installing $cs_conf\n" ${host}: - create_cs_config - fi -done diff --git a/xml/Makefile.am b/xml/Makefile.am index d3f2229c17..6acb338e13 100644 --- a/xml/Makefile.am +++ b/xml/Makefile.am @@ -1,321 +1,307 @@ # # Copyright 2004-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. # 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_error \ + crm_mon \ crm_node \ crm_resource \ - crm_rule \ + crm_rule \ crm_shadow \ crm_simulate \ crmadmin \ digests \ 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 +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 \ patchset \ resources \ status \ subprocess-output -CIB_base = cib $(CIB_cfg_base) status score rule nvset + +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.xsl \ $(abs_srcdir)/upgrade-2.10.xsl \ $(wildcard $(abs_srcdir)/upgrade-*enter.xsl) \ $(wildcard $(abs_srcdir)/upgrade-*leave.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.xsl \ - $(srcdir)/upgrade-2.10.xsl \ + $(srcdir)/upgrade-2.10.xsl \ $(wildcard $(srcdir)/upgrade-*enter.xsl) \ $(wildcard $(srcdir)/upgrade-*leave.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 +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) +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 \ best-match.sh \ cibtr-2.rng \ context-of.xsl \ ocf-meta2man.xsl \ regression.sh \ upgrade-2.10-roundtrip.xsl \ upgrade-detail.xsl \ xslt_cibtr-2.rng \ assets \ test-2 \ test-2-enter \ test-2-leave \ test-2-roundtrip +.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) best-match.sh 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 ' ' >> $@ $(AM_V_at)for rng in $(API_request_base); do $(srcdir)/best-match.sh api/$$rng $(*) $(@) " " || :; done $(AM_V_at)echo ' ' >> $@ $(AM_V_at)echo ' ' >> $@ $(AM_V_at)$(srcdir)/best-match.sh api/status $(*) $(@) " " || : $(AM_V_at)echo ' ' >> $@ $(AM_V_at)echo ' ' >> $@ $(AM_V_SCHEMA)echo '' >> $@ 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) best-match.sh Makefile.am $(AM_V_at)echo '' > $@ $(AM_V_at)echo '' >> $@ $(AM_V_at)echo ' ' >> $@ $(AM_V_at)echo ' ' >> $@ $(AM_V_at)$(srcdir)/best-match.sh cib $(*) $(@) " " $(AM_V_at)echo ' ' >> $@ $(AM_V_at)echo ' ' >> $@ $(AM_V_at)for rng in $(CIB_cfg_base); do $(srcdir)/best-match.sh $$rng $(*) $(@) " " || :; done $(AM_V_at)echo ' ' >> $@ $(AM_V_at)echo ' ' >> $@ $(AM_V_at)echo ' ' >> $@ $(AM_V_at)echo ' ' >> $@ $(AM_V_at)$(srcdir)/best-match.sh status $(*) $(@) " " $(AM_V_at)echo ' ' >> $@ $(AM_V_at)echo ' ' >> $@ $(AM_V_at)echo ' ' >> $@ $(AM_V_at)echo ' ' >> $@ $(AM_V_SCHEMA)echo '' >> $@ # Dynamically generated CIB schema listing all pacemaker versions 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 '' >> $@ -# diff fails with ec=2 if no predecessor is found; -# this uses '=' GNU extension to sed, if that's not available, -# one can use: hline=`echo "$${p}" | grep -Fn "$${hunk}" | cut -d: -f1`; -# XXX: use line information from hunk to avoid "not detected" for ambiguity -version_diff = \ - @for p in $(1); do \ - set `echo "$${p}" | tr '-' ' '`; \ - echo "\#\#\# *-$$2.rng vs. predecessor"; \ - for v in *-$$2.rng; do \ - echo "\#\#\#\# $${v} vs. predecessor"; b=`echo "$${v}" | cut -d- -f1`; \ - old=`./best-match.sh $${b} $$1`; \ - p=`diff -u "$${old}" "$${v}" 2>/dev/null`; \ - case $$? in \ - 1) echo "$${p}" | sed -n -e '/^@@ /!d;=;p' \ - -e ':l;n;/^\([- ]\|+.*<[^ />]\+\([^/>]\+="ID\|>$$\)\)/bl;s/^[+ ]\(.*\)/\1/p' \ - | while read hline; do \ - read h && read i || break; \ - iline=`grep -Fn "$${i}" "$${v}" | cut -d: -f1`; \ - ctxt="(not detected)"; \ - if test `echo "$${iline}" | wc -l` -eq 1; then \ - ctxt=`{ sed -n -e "1,$$(($${iline}-1))p" "$${v}"; \ - echo "$${i}"; \ - sed -n -e "$$(($${iline}+1)),$$ p" "$${v}"; \ - } | $(XSLTPROC) --param skip 1 context-of.xsl -`; \ - fi; \ - echo "$${p}" | sed -n -e "$$(($${hline}-2)),$${hline}!d" \ - -e '/^\(+++\|---\)/p'; \ - echo "$${h} context: $${ctxt}"; \ - echo "$${p}" | sed -n -e "1,$${hline}d" \ - -e '/^\(---\|@@ \)/be;p;d;:e;n;be'; \ - done; \ - ;; \ - 2) echo "\#\#\#\#\# $${v} has no predecessor";; \ - esac; \ - done; \ - done - +.PHONY: diff diff: best-match.sh @echo "# Comparing changes in + since $(CIB_max)" - $(call version_diff,${CIB_version_pairs_last}) + @./version-diff.sh ${CIB_version_pairs_last} +.PHONY: fulldiff fulldiff: best-match.sh @echo "# Comparing all changes across all the subsequent increments" - $(call version_diff,${CIB_version_pairs}) + @./version-diff.sh ${CIB_version_pairs} -CLEANFILES = $(API_generated) $(CIB_generated) $(MON_generated) +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 diff --git a/xml/version-diff.sh.in b/xml/version-diff.sh.in new file mode 100644 index 0000000000..1ece3b3460 --- /dev/null +++ b/xml/version-diff.sh.in @@ -0,0 +1,60 @@ +#!@BASH_PATH@ +# +# Copyright 2016-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. +# + +# diff fails with ec=2 if no predecessor is found; +# this uses '=' GNU extension to sed, if that's not available, +# one can use: hline=`echo "$${p}" | grep -Fn "$${hunk}" | cut -d: -f1`; +# XXX: use line information from hunk to avoid "not detected" for ambiguity +for p in $*; do + set $(echo "$p" | tr '-' ' ') + echo "### *-$2.rng vs. predecessor" + + for v in *-"$2".rng; do + echo "#### $v vs. predecessor" + + b=$(echo "$v" | cut -d- -f1) + old=$(./best-match.sh "$b" "$1") + p=$(diff -u "$old" "$v" 2>/dev/null) + + case $? in + 1) + echo "$p" | sed -n -e '/^@@ /!d;=;p' -e ':l;n;/^\([- ]\|+.*<[^ />]\+\([^/>]\+="ID\|>$$\)\)/bl;s/^[+ ]\(.*\)/\1/p' | + while read -r hline; do + if read -r h; then + read -r i + else + break + fi + + iline=$(grep -Fn "$i" "$v" | cut -d: -f1) + + if [ "$(echo "$iline" | wc -l)" = "1" ]; then + ctxt=$({ sed -n -e "1,$((iline - 1))p" "$v" + echo "$i" + sed -n -e "$((iline + 1)),$ p" "$v" + } | xsltproc --param skip 1 context-of.xsl -) + else + ctxt="(not detected)" + fi + + echo "$p" | sed -n -e "$((hline - 2)),$hline!d" -e '/^\(+++\|---\)/p' + echo "$h context: $ctxt" + echo "$p" | sed -n -e "1,${hline}d" -e '/^\(---\|@@ \)/be;p;d;:e;n;be' + done + + ;; + + 2) + echo "##### $v has no predecessor" + ;; + + esac + done +done