From b4585aa546e508ae6e9e0748d40a51f6ab33e64c Mon Sep 17 00:00:00 2001 From: Jan Pokorný Date: May 06 2016 17:53:16 +0000 Subject: 1.0-2.eb4256a.git - update a subset of out-of-tree patches ...per https://github.com/ClusterLabs/booth/pull/22#issuecomment-216936987 - pre-inclusion cleanups in the spec (apply systemd scriptlet operations with booth-arbitrator, avoid overloading file implicitly considered %%doc as %%license) Resolves: rhbz#1314865 Related: rhbz#1333509 Signed-off-by: Jan Pokorný --- diff --git a/.gitignore b/.gitignore index e69de29..26f1320 100644 --- a/.gitignore +++ b/.gitignore @@ -0,0 +1,6 @@ +/booth-*.tar.gz +/booth-*.rpm +/booth-*/ + +*~ +*.sw? diff --git a/0001-Feature-offer-alternatives-to-libraries-from-cluster.patch b/0001-Feature-offer-alternatives-to-libraries-from-cluster.patch new file mode 100644 index 0000000..e5f2ecd --- /dev/null +++ b/0001-Feature-offer-alternatives-to-libraries-from-cluster.patch @@ -0,0 +1,112 @@ +From bd7a1383a8d514b24197c902991c39ec5fe032f8 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jan=20Pokorn=C3=BD?= +Date: Tue, 26 Apr 2016 16:43:50 +0200 +Subject: [PATCH 1/6] Feature: offer alternatives to libraries from + (cluster-)glue + +This revision is a preparation work establishing --without-glue switch +to configure that will eventually allow non-glue alternatives. + +The analogous conditional is added to the spec file, based on premise +that cluster-glue will not be re-introduced into Fedora, RHEL, atc. +--- + booth.spec | 20 +++++++++++++++++--- + configure.ac | 5 +++++ + src/Makefile.am | 6 +++--- + 3 files changed, 25 insertions(+), 6 deletions(-) + +diff --git a/booth.spec b/booth.spec +index cd54ab1..f73d2d8 100644 +--- a/booth.spec ++++ b/booth.spec +@@ -1,5 +1,11 @@ + %bcond_with html_man + ++%if 0%{?fedora} > 18 || 0%{?centos} > 6 || 0%{?rhel} > 6 ++%bcond_with glue ++%else ++%bcond_without glue ++%endif ++ + %if 0%{?suse_version} + %global booth_docdir %{_defaultdocdir}/%{name} + %else +@@ -50,17 +56,24 @@ BuildRequires: pkgconfig(glib-2.0) + %endif + BuildRequires: libgcrypt-devel + %if 0%{?fedora} || 0%{?centos} || 0%{?rhel} +-BuildRequires: cluster-glue-libs-devel + BuildRequires: pacemaker-libs-devel + %else +-BuildRequires: libglue-devel + BuildRequires: libpacemaker-devel + %endif ++%if 0%{?with_glue} ++%if 0%{?fedora} || 0%{?centos} || 0%{?rhel} ++BuildRequires: cluster-glue-libs-devel ++%else ++BuildRequires: libglue-devel ++%endif ++%endif + BuildRequires: libxml2-devel + BuildRequires: zlib-devel + %if 0%{?fedora} || 0%{?centos} || 0%{?rhel} + Requires: pacemaker >= 1.1.8 ++%if 0%{?with_glue} + Requires: cluster-glue-libs >= 1.0.6 ++%endif + %else + Requires: pacemaker-ticket-support >= 2.0 + %endif +@@ -79,7 +92,8 @@ Pacemaker. + %configure \ + --with-initddir=%{_initrddir} \ + --docdir=%{booth_docdir} \ +- %{!?with_html_man:--without-html_man} ++ %{!?with_html_man:--without-html_man} \ ++ %{!?with_glue:--without-glue} + + make + +diff --git a/configure.ac b/configure.ac +index 872ec50..f8fb3cc 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -213,6 +213,11 @@ AC_ARG_WITH([build-version], + AC_ARG_WITH([html_man], + [ --without-html_man : Avoid generating man pages in HTML.]) + ++AC_ARG_WITH([glue], ++ [ --without-glue : Avoid libraries from (cluster-)glue project.], ++ [], ++ [with_glue=yes]) ++ + # OS detection + # THIS SECTION MUST DIE! + CP=cp +diff --git a/src/Makefile.am b/src/Makefile.am +index 7d05d76..e7f5aa2 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -10,6 +10,9 @@ sbin_PROGRAMS = boothd + boothd_SOURCES = config.c main.c raft.c ticket.c transport.c \ + pacemaker.c handler.c request.c attr.c + ++noinst_HEADERS = booth.h pacemaker.h \ ++ config.h log.h raft.h ticket.h transport.h handler.h request.h attr.h ++ + if BUILD_TIMER_C + boothd_SOURCES += timer.c + endif +@@ -22,8 +25,5 @@ boothd_LDFLAGS = $(OS_DYFLAGS) -L./ + boothd_LDADD = -lplumb -lplumbgpl -lm $(GLIB_LIBS) $(ZLIB_LIBS) + boothd_CFLAGS = $(GLIB_CFLAGS) + +-noinst_HEADERS = booth.h pacemaker.h \ +- config.h log.h raft.h ticket.h transport.h handler.h request.h attr.h +- + lint: + -splint $(INCLUDES) $(LINT_FLAGS) $(CFLAGS) *.c +-- +2.4.11 + diff --git a/0002-Feature-alternative-logging-provider-libqb.patch b/0002-Feature-alternative-logging-provider-libqb.patch new file mode 100644 index 0000000..37d5f74 --- /dev/null +++ b/0002-Feature-alternative-logging-provider-libqb.patch @@ -0,0 +1,373 @@ +From 78d087328bc73c53380ae9de1412f1f5f949ad1b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jan=20Pokorn=C3=BD?= +Date: Tue, 26 Apr 2016 16:44:48 +0200 +Subject: [PATCH 2/6] Feature: alternative logging provider: libqb + +--- + booth.spec | 3 ++ + configure.ac | 28 ++++++++++++++++- + src/Makefile.am | 8 +++++ + src/alt/logging_libqb.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++ + src/alt/logging_libqb.h | 70 +++++++++++++++++++++++++++++++++++++++++ + src/log.h | 22 +++++++++---- + src/main.c | 26 ++++++++++++--- + 7 files changed, 229 insertions(+), 12 deletions(-) + create mode 100644 src/alt/logging_libqb.c + create mode 100644 src/alt/logging_libqb.h + +diff --git a/booth.spec b/booth.spec +index f73d2d8..cc73af2 100644 +--- a/booth.spec ++++ b/booth.spec +@@ -66,6 +66,9 @@ BuildRequires: cluster-glue-libs-devel + %else + BuildRequires: libglue-devel + %endif ++%else ++# logging provider ++BuildRequires: pkgconfig(libqb) + %endif + BuildRequires: libxml2-devel + BuildRequires: zlib-devel +diff --git a/configure.ac b/configure.ac +index f8fb3cc..2495e0b 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -6,7 +6,7 @@ AC_PREREQ([2.61]) + + AC_INIT([booth], [1.0], [users@clusterlabs.org]) + +-AM_INIT_AUTOMAKE([-Wno-portability]) ++AM_INIT_AUTOMAKE([-Wno-portability subdir-objects]) + + AC_CONFIG_SRCDIR([src/main.c]) + AC_CONFIG_HEADER([src/b_config.h src/booth_config.h]) +@@ -218,6 +218,31 @@ AC_ARG_WITH([glue], + [], + [with_glue=yes]) + ++# figure out logging provider ++logging_provider="" ++if test "x$logging_provider" = "x" && test "x$with_glue" = "xyes"; then ++ AC_CHECK_LIB([plumb], [cl_log], [logging_provider="libplumb"]) ++fi ++if test "x$logging_provider" = "x" && test "x$with_glue" = "xno"; then ++ AC_CHECK_LIB([qb], [qb_log_real_], [logging_provider="libqb"]) ++fi ++case "$logging_provider" in ++libplumb) ++ ;; ++libqb) ++ PKG_CHECK_MODULES([LIBQB], [libqb]) ++ AC_DEFINE([LOGGING_LIBQB], [], [use libqb as a logging provider]) ++ PKG_CHECK_MODULES([LIBQB1], [libqb >= 1.0], ++ [AC_DEFINE([LOGGING_LIBQB_MAJOR], [1], ++ [libqb major version lower bound])], ++ [AC_MSG_WARN([[syslog identifier will not get changed]])]) ++ ;; ++*) ++ AC_MSG_ERROR([logging provider required (libplumb, or libqb when --without-glue)]) ++ ;; ++esac ++AM_CONDITIONAL([LOGGING_LIBQB], [test "x$logging_provider" = "xlibqb"]) ++ + # OS detection + # THIS SECTION MUST DIE! + CP=cp +@@ -446,6 +471,7 @@ AC_MSG_RESULT([ System init.d directory = ${INITDDIR}]) + AC_MSG_RESULT([ booth config dir = ${BOOTHSYSCONFDIR}]) + AC_MSG_RESULT([ SOCKETDIR = ${SOCKETDIR}]) + AC_MSG_RESULT([ Features = ${PACKAGE_FEATURES}]) ++AC_MSG_RESULT([ Logging provider = ${logging_provider}]) + AC_MSG_RESULT([]) + AC_MSG_RESULT([$PACKAGE build info:]) + AC_MSG_RESULT([ Library SONAME = ${SONAME}]) +diff --git a/src/Makefile.am b/src/Makefile.am +index e7f5aa2..49c3ac4 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -25,5 +25,13 @@ boothd_LDFLAGS = $(OS_DYFLAGS) -L./ + boothd_LDADD = -lplumb -lplumbgpl -lm $(GLIB_LIBS) $(ZLIB_LIBS) + boothd_CFLAGS = $(GLIB_CFLAGS) + ++if !LOGGING_LIBQB ++boothd_LDADD += -lplumb ++else ++boothd_LDADD += $(LIBQB_LIBS) ++boothd_SOURCES += alt/logging_libqb.c ++noinst_HEADERS += alt/logging_libqb.h ++endif ++ + lint: + -splint $(INCLUDES) $(LINT_FLAGS) $(CFLAGS) *.c +diff --git a/src/alt/logging_libqb.c b/src/alt/logging_libqb.c +new file mode 100644 +index 0000000..34cf97c +--- /dev/null ++++ b/src/alt/logging_libqb.c +@@ -0,0 +1,84 @@ ++/* ++ * Copyright (C) 2016 Jan Pokorny ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This software is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++ */ ++ ++#include ++#include ++ ++#include ++ ++#include "logging_libqb.h" ++ ++int debug_level = 0; ++ ++/* ENV_X definitions based on glue/lib/clplumbing/cl_log.c of glue project: ++ http://hg.linux-ha.org/glue */ ++#define ENV_HADEBUGVAL "HA_debug" ++#define ENV_LOGFENV "HA_logfile" /* well-formed log file :-) */ ++#define ENV_DEBUGFENV "HA_debugfile" /* Debug log file */ ++#define ENV_LOGFACILITY "HA_logfacility"/* Facility to use for logger */ ++#define ENV_SYSLOGFMT "HA_syslogmsgfmt"/* TRUE if we should use syslog message formatting */ ++ ++void ++alt_qb_inherit_logging_environment(void) ++{ ++ char *inherit_env; ++ ++ /* Don't need to free the return pointer from getenv */ ++ inherit_env = getenv(ENV_HADEBUGVAL); ++ if (inherit_env != NULL && atoi(inherit_env) != 0 ) ++ debug_level = atoi(inherit_env); ++ ++ inherit_env = getenv(ENV_LOGFENV); ++ if (inherit_env != NULL && *inherit_env != '\0') { ++ int32_t log_fd = qb_log_file_open(inherit_env); ++ qb_log_ctl(log_fd, QB_LOG_CONF_ENABLED, QB_TRUE); ++ /* do not log debug info even if debug_level non-zero */ ++ qb_log_filter_ctl(log_fd, QB_LOG_FILTER_ADD, ++ QB_LOG_FILTER_FILE, "*", LOG_INFO); ++ } ++ ++ inherit_env = getenv(ENV_DEBUGFENV); ++ if (inherit_env != NULL && *inherit_env != '\0') { ++ int32_t log_fd = qb_log_file_open(inherit_env); ++ qb_log_ctl(log_fd, QB_LOG_CONF_ENABLED, QB_TRUE); ++ } ++ ++ inherit_env = getenv(ENV_LOGFACILITY); ++ if (inherit_env != NULL && *inherit_env != '\0') { ++ int fac = qb_log_facility2int(inherit_env); ++ if (fac > 0) ++ qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_FACILITY, fac); ++ else ++ qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_ENABLED, QB_FALSE); ++ } ++ ++ inherit_env = getenv(ENV_SYSLOGFMT); ++ if (inherit_env != NULL && *inherit_env != '\0' ++ && ( !strcasecmp(inherit_env, "false") ++ || !strcasecmp(inherit_env, "off") ++ || !strcasecmp(inherit_env, "no") ++ || !strcasecmp(inherit_env, "n") ++ || !strcasecmp(inherit_env, "0"))){ ++ enum qb_log_target_slot i; ++ for (i = QB_LOG_TARGET_START; i < QB_LOG_TARGET_MAX; i++) { ++ if (i == QB_LOG_SYSLOG || i == QB_LOG_BLACKBOX) ++ continue; ++ qb_log_format_set(i, NULL); ++ } ++ } ++} +diff --git a/src/alt/logging_libqb.h b/src/alt/logging_libqb.h +new file mode 100644 +index 0000000..76592d4 +--- /dev/null ++++ b/src/alt/logging_libqb.h +@@ -0,0 +1,70 @@ ++/* ++ * Copyright (C) 2016 Jan Pokorny ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This software is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++ */ ++ ++#include ++ ++#include "b_config.h" ++ ++/* qb logging compat definitions */ ++#if (!defined LOGGING_LIBQB_MAJOR || (LOGGING_LIBQB_MAJOR < 1)) ++enum tmp_log_target_slot { ++ TMP_LOG_SYSLOG = QB_LOG_SYSLOG, ++ TMP_LOG_STDERR = QB_LOG_STDERR, ++ TMP_LOG_BLACKBOX = QB_LOG_BLACKBOX, ++ TMP_LOG_TARGET_MAX = QB_LOG_TARGET_MAX, ++}; ++ ++#undef QB_LOG_SYSLOG ++#undef QB_LOG_STDERR ++#undef QB_LOG_BLACKBOX ++#undef QB_LOG_TARGET_MAX ++ ++enum qb_log_target_slot { ++ QB_LOG_TARGET_START, ++ QB_LOG_SYSLOG = TMP_LOG_SYSLOG, ++ QB_LOG_STDERR = TMP_LOG_STDERR, ++ QB_LOG_BLACKBOX = TMP_LOG_BLACKBOX, ++ QB_LOG_TARGET_MAX = TMP_LOG_TARGET_MAX, ++}; ++ ++#define QB_LOG_CTL2_S(a) (a) ++#define qb_log_ctl2(t, s, a) ((void) 0) ++#endif ++ ++ ++#ifndef HA_LOG_FACILITY ++/* based on glue/configure.ac of glue project: http://hg.linux-ha.org/glue */ ++#define HA_LOG_FACILITY LOG_DAEMON ++#endif ++ ++extern int debug_level; ++#define ANYDEBUG (debug_level) ++ ++void alt_qb_inherit_logging_environment(void); ++ ++#define cl_log_set_entity(ent) \ ++ (void) qb_log_ctl2(QB_LOG_SYSLOG, QB_LOG_CONF_IDENT, QB_LOG_CTL2_S(ent)) ++ ++#define cl_log_enable_stderr(b) \ ++ (void) qb_log_ctl(QB_LOG_STDERR, QB_LOG_CONF_ENABLED, b ? QB_TRUE : QB_FALSE) ++ ++#define cl_log_set_facility(f) \ ++ (void) qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_FACILITY, f) ++ ++#define cl_inherit_logging_environment(logqueuemax) \ ++ alt_qb_inherit_logging_environment() +diff --git a/src/log.h b/src/log.h +index 0be4066..e570a8d 100644 +--- a/src/log.h ++++ b/src/log.h +@@ -21,26 +21,36 @@ + #ifndef _LOG_H + #define _LOG_H + ++#include "b_config.h" ++ ++#ifndef LOGGING_LIBQB + #include + #include ++#define priv_log(prio, ...) cl_log(prio, __VA_ARGS__) ++#else ++#include "alt/logging_libqb.h" ++#define priv_log(prio, ...) qb_log(prio, __VA_ARGS__) ++#endif ++ + #include "inline-fn.h" + ++ + #define log_debug(fmt, args...) do { \ +- if (ANYDEBUG) cl_log(LOG_DEBUG, fmt, ##args); } \ ++ if (ANYDEBUG) priv_log(LOG_DEBUG, fmt, ##args); } \ + while (0) +-#define log_info(fmt, args...) cl_log(LOG_INFO, fmt, ##args) +-#define log_warn(fmt, args...) cl_log(LOG_WARNING, fmt, ##args) +-#define log_error(fmt, args...) cl_log(LOG_ERR, fmt, ##args) ++#define log_info(fmt, args...) priv_log(LOG_INFO, fmt, ##args) ++#define log_warn(fmt, args...) priv_log(LOG_WARNING, fmt, ##args) ++#define log_error(fmt, args...) priv_log(LOG_ERR, fmt, ##args) + + /* all tk_* macros prepend "%(tk->name): " (the caller needs to + * have the ticket named tk!) + */ + #define tk_cl_log(sev, fmt, args...) \ +- cl_log(sev, "%s (%s/%d/%d): " fmt, \ ++ priv_log(sev, "%s (%s/%d/%d): " fmt, \ + tk->name, state_to_string(tk->state), tk->current_term, term_time_left(tk), \ + ##args) + #define tk_cl_log_src(sev, fmt, args...) \ +- cl_log(sev, "%s:%d: %s (%s/%d/%d): " fmt, \ ++ priv_log(sev, "%s:%d: %s (%s/%d/%d): " fmt, \ + __FUNCTION__, __LINE__, \ + tk->name, state_to_string(tk->state), tk->current_term, term_time_left(tk), \ + ##args) +diff --git a/src/main.c b/src/main.c +index c23c121..6f53475 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -1540,6 +1540,9 @@ int main(int argc, char *argv[], char *envp[]) + { + int rv; + const char *cp; ++#ifdef LOGGING_LIBQB ++ enum qb_log_target_slot i; ++#endif + + init_set_proc_title(argc, argv, envp); + get_time(&start_time); +@@ -1550,15 +1553,25 @@ int main(int argc, char *argv[], char *envp[]) + cl.lockfile[0] = 0; + debug_level = 0; + +- cl_log_set_entity( +- (cp = strstr(argv[0], ATTR_PROG)) && !strcmp(cp, ATTR_PROG) ++ ++ cp = ((cp = strstr(argv[0], ATTR_PROG)) && !strcmp(cp, ATTR_PROG) + ? ATTR_PROG +- : "booth" +- ); ++ : "booth"); ++#ifndef LOGGING_LIBQB ++ cl_log_set_entity(cp); ++#else ++ qb_log_init(cp, LOG_USER, LOG_DEBUG); /* prio driven by debug_level */ ++ for (i = QB_LOG_TARGET_START; i < QB_LOG_TARGET_MAX; i++) { ++ if (i == QB_LOG_SYSLOG || i == QB_LOG_BLACKBOX) ++ continue; ++ qb_log_format_set(i, "%t %H %N: [%P]: %p: %b"); ++ } ++ (void) qb_log_filter_ctl(QB_LOG_STDERR, QB_LOG_FILTER_ADD, ++ QB_LOG_FILTER_FILE, "*", LOG_DEBUG); ++#endif + cl_log_enable_stderr(TRUE); + cl_log_set_facility(0); + +- + rv = read_arguments(argc, argv); + if (rv < 0) + goto out; +@@ -1585,6 +1598,9 @@ int main(int argc, char *argv[], char *envp[]) + } + + out: ++#ifdef LOGGING_LIBQB ++ qb_log_fini(); ++#endif + /* Normalize values. 0x100 would be seen as "OK" by waitpid(). */ + return (rv >= 0 && rv < 0x70) ? rv : 1; + } +-- +2.4.11 + diff --git a/0003-Feature-alternative-range2random-provider-glib.patch b/0003-Feature-alternative-range2random-provider-glib.patch new file mode 100644 index 0000000..e0fd893 --- /dev/null +++ b/0003-Feature-alternative-range2random-provider-glib.patch @@ -0,0 +1,179 @@ +From 4fb8dfa9a8c32eb92004cb9deb6248908a25d81a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jan=20Pokorn=C3=BD?= +Date: Wed, 24 Feb 2016 02:12:34 +0100 +Subject: [PATCH 3/6] Feature: alternative range2random provider: glib + +Also check if cl_rand_from_interval is actually defined in + (not the case with older glue/plumb lib). +--- + booth.spec | 2 ++ + configure.ac | 24 ++++++++++++++++++++++++ + src/Makefile.am | 8 ++++++++ + src/alt/range2random_glib.c | 33 +++++++++++++++++++++++++++++++++ + src/alt/range2random_glib.h | 22 ++++++++++++++++++++++ + src/ticket.c | 6 +++++- + 6 files changed, 94 insertions(+), 1 deletion(-) + create mode 100644 src/alt/range2random_glib.c + create mode 100644 src/alt/range2random_glib.h + +diff --git a/booth.spec b/booth.spec +index cc73af2..b88ff4c 100644 +--- a/booth.spec ++++ b/booth.spec +@@ -69,6 +69,8 @@ BuildRequires: libglue-devel + %else + # logging provider + BuildRequires: pkgconfig(libqb) ++# random2range provider ++BuildRequires: pkgconfig(glib-2.0) + %endif + BuildRequires: libxml2-devel + BuildRequires: zlib-devel +diff --git a/configure.ac b/configure.ac +index 2495e0b..b3df2d9 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -243,6 +243,29 @@ libqb) + esac + AM_CONDITIONAL([LOGGING_LIBQB], [test "x$logging_provider" = "xlibqb"]) + ++# figure out range2random provider ++range2random_provider="" ++if test "x$range2random_provider" = "x" && test "x$with_glue" = "xyes"; then ++ AC_CHECK_LIB([plumb], [get_next_random], [range2random_provider="libplumb"]) ++ AC_CHECK_DECL([cl_rand_from_interval], [], [range2random_provider=""], ++ [#include ]) ++fi ++if test "x$range2random_provider" = "x" && test "x$with_glue" = "xno"; then ++ AC_CHECK_LIB([glib-2.0], [g_random_int_range], [range2random_provider="glib"]) ++fi ++case "$range2random_provider" in ++libplumb) ++ ;; ++glib) ++ PKG_CHECK_MODULES([GLIB], [glib-2.0]) ++ AC_DEFINE([RANGE2RANDOM_GLIB], [], [use glib as a range2random provider]) ++ ;; ++*) ++ AC_MSG_ERROR([range2random provider required (libplumb, or glib when --without-glue)]) ++ ;; ++esac ++AM_CONDITIONAL([RANGE2RANDOM_GLIB], [test "x$range2random_provider" = "xglib"]) ++ + # OS detection + # THIS SECTION MUST DIE! + CP=cp +@@ -472,6 +495,7 @@ AC_MSG_RESULT([ booth config dir = ${BOOTHSYSCONFDIR}]) + AC_MSG_RESULT([ SOCKETDIR = ${SOCKETDIR}]) + AC_MSG_RESULT([ Features = ${PACKAGE_FEATURES}]) + AC_MSG_RESULT([ Logging provider = ${logging_provider}]) ++AC_MSG_RESULT([ Range2random provider = ${range2random_provider}]) + AC_MSG_RESULT([]) + AC_MSG_RESULT([$PACKAGE build info:]) + AC_MSG_RESULT([ Library SONAME = ${SONAME}]) +diff --git a/src/Makefile.am b/src/Makefile.am +index 49c3ac4..317710e 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -33,5 +33,13 @@ boothd_SOURCES += alt/logging_libqb.c + noinst_HEADERS += alt/logging_libqb.h + endif + ++if !RANGE2RANDOM_GLIB ++boothd_LDADD += -lplumb ++else ++boothd_LDADD += $(GLIB_LIBS) ++boothd_SOURCES += alt/range2random_glib.c ++noinst_HEADERS += alt/range2random_glib.h ++endif ++ + lint: + -splint $(INCLUDES) $(LINT_FLAGS) $(CFLAGS) *.c +diff --git a/src/alt/range2random_glib.c b/src/alt/range2random_glib.c +new file mode 100644 +index 0000000..8363559 +--- /dev/null ++++ b/src/alt/range2random_glib.c +@@ -0,0 +1,33 @@ ++/* ++ * Copyright (C) 2016 Jan Pokorny ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This software is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++ */ ++ ++#include ++#include ++ ++#include ++ ++#include "range2random_glib.h" ++#include "ticket.h" ++ ++int ++alt_glib_rand_from_interval(int from, int to) ++{ ++ assert(from >= 0 && from < to); ++ assert(sizeof(to) <= sizeof(gint32) || (to < 0x7fffffff)); ++ return (int) g_random_int_range(from, to); ++} +diff --git a/src/alt/range2random_glib.h b/src/alt/range2random_glib.h +new file mode 100644 +index 0000000..4b87c46 +--- /dev/null ++++ b/src/alt/range2random_glib.h +@@ -0,0 +1,22 @@ ++/* ++ * Copyright (C) 2016 Jan Pokorny ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This software is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++ */ ++ ++int alt_glib_rand_from_interval(int from, int to); ++ ++#define cl_rand_from_interval(from, to) \ ++ alt_glib_rand_from_interval(from, to) +diff --git a/src/ticket.c b/src/ticket.c +index f0ba74b..d76b4d4 100644 +--- a/src/ticket.c ++++ b/src/ticket.c +@@ -25,8 +25,12 @@ + #include + #include + #include +-#include + #include "b_config.h" ++#ifndef RANGE2RANDOM_GLIB ++#include ++#else ++#include "alt/range2random_glib.h" ++#endif + #include "ticket.h" + #include "config.h" + #include "pacemaker.h" +-- +2.4.11 + diff --git a/0004-Feature-alternative-nametag-provider-libsystemd.patch b/0004-Feature-alternative-nametag-provider-libsystemd.patch new file mode 100644 index 0000000..f04388b --- /dev/null +++ b/0004-Feature-alternative-nametag-provider-libsystemd.patch @@ -0,0 +1,239 @@ +From 11626be181e6d27484e908f00b0cb896568aad03 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jan=20Pokorn=C3=BD?= +Date: Wed, 24 Feb 2016 02:15:47 +0100 +Subject: [PATCH 4/6] Feature: alternative "nametag" provider: libsystemd + +--- + booth.spec | 2 ++ + configure.ac | 22 ++++++++++++ + src/Makefile.am | 10 +++++- + src/alt/nametag_libsystemd.c | 81 ++++++++++++++++++++++++++++++++++++++++++++ + src/alt/nametag_libsystemd.h | 23 +++++++++++++ + src/main.c | 6 +++- + 6 files changed, 142 insertions(+), 2 deletions(-) + create mode 100644 src/alt/nametag_libsystemd.c + create mode 100644 src/alt/nametag_libsystemd.h + +diff --git a/booth.spec b/booth.spec +index b88ff4c..18387f7 100644 +--- a/booth.spec ++++ b/booth.spec +@@ -71,6 +71,8 @@ BuildRequires: libglue-devel + BuildRequires: pkgconfig(libqb) + # random2range provider + BuildRequires: pkgconfig(glib-2.0) ++# nametag provider ++BuildRequires: pkgconfig(libsystemd) + %endif + BuildRequires: libxml2-devel + BuildRequires: zlib-devel +diff --git a/configure.ac b/configure.ac +index b3df2d9..c8502c6 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -266,6 +266,27 @@ glib) + esac + AM_CONDITIONAL([RANGE2RANDOM_GLIB], [test "x$range2random_provider" = "xglib"]) + ++# figure out nametag/distinguished-role provider ++nametag_provider="" ++if test "x$nametag_provider" = "x" && test "x$with_glue" != "xno"; then ++ AC_CHECK_LIB([plumbgpl], [set_proc_title], [nametag_provider="libplumbgpl"]) ++fi ++if test "x$nametag_provider" = "x" && test "x$with_glue" = "xno"; then ++ AC_CHECK_LIB([systemd], [sd_notify], [nametag_provider="libsystemd"]) ++fi ++case "$nametag_provider" in ++libplumbgpl) ++ ;; ++libsystemd) ++ PKG_CHECK_MODULES([LIBSYSTEMD], [libsystemd]) ++ AC_DEFINE([NAMETAG_LIBSYSTEMD], [], [use libsystemd as a nametag provider]) ++ ;; ++*) ++ AC_MSG_ERROR([nametag provider required (libplumbgpl, or libsystemd when --without-glue)]) ++ ;; ++esac ++AM_CONDITIONAL([NAMETAG_LIBSYSTEMD], [test "x$nametag_provider" = "xlibsystemd"]) ++ + # OS detection + # THIS SECTION MUST DIE! + CP=cp +@@ -496,6 +517,7 @@ AC_MSG_RESULT([ SOCKETDIR = ${SOCKETDIR}]) + AC_MSG_RESULT([ Features = ${PACKAGE_FEATURES}]) + AC_MSG_RESULT([ Logging provider = ${logging_provider}]) + AC_MSG_RESULT([ Range2random provider = ${range2random_provider}]) ++AC_MSG_RESULT([ Nametag provider = ${nametag_provider}]) + AC_MSG_RESULT([]) + AC_MSG_RESULT([$PACKAGE build info:]) + AC_MSG_RESULT([ Library SONAME = ${SONAME}]) +diff --git a/src/Makefile.am b/src/Makefile.am +index 317710e..69b7b48 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -22,7 +22,7 @@ boothd_SOURCES += auth.c + endif + + boothd_LDFLAGS = $(OS_DYFLAGS) -L./ +-boothd_LDADD = -lplumb -lplumbgpl -lm $(GLIB_LIBS) $(ZLIB_LIBS) ++boothd_LDADD = -lplumb -lm $(GLIB_LIBS) $(ZLIB_LIBS) + boothd_CFLAGS = $(GLIB_CFLAGS) + + if !LOGGING_LIBQB +@@ -41,5 +41,13 @@ boothd_SOURCES += alt/range2random_glib.c + noinst_HEADERS += alt/range2random_glib.h + endif + ++if !NAMETAG_LIBSYSTEMD ++boothd_LDADD += -lplumbgpl ++else ++boothd_LDADD += $(LIBSYSTEMD_LIBS) ++boothd_SOURCES += alt/nametag_libsystemd.c ++noinst_HEADERS += alt/nametag_libsystemd.h ++endif ++ + lint: + -splint $(INCLUDES) $(LINT_FLAGS) $(CFLAGS) *.c +diff --git a/src/alt/nametag_libsystemd.c b/src/alt/nametag_libsystemd.c +new file mode 100644 +index 0000000..1fb9ffa +--- /dev/null ++++ b/src/alt/nametag_libsystemd.c +@@ -0,0 +1,81 @@ ++/* ++ * Copyright (C) 2016 Jan Pokorny ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This software is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#include ++ ++#include "nametag_libsystemd.h" ++#include "booth.h" ++#include "log.h" ++#include "transport.h" ++ ++/* assume first argument after "fmt" is for DAEMON_NAME, that is ++ really not of interest in our "nametag" function based on ++ sd_notify (that very data point is provided implicitly) */ ++void sd_notify_wrapper(const char *fmt, ...) ++{ ++ /* assume that first %s in fmt is intended for DAEMON_NAME, ++ i.e., for first argument following fmt in original ++ set_proc_title invocation, which has already been dropped ++ before it boils down here (using the wrapping macro trick); ++ we now simply append the reset after that first %s ++ (with whitespace stripped) to the "Running: " prefix */ ++ int rv; ++ char buffer[255]; ++ char *fmt_iter; ++ char *suffix = NULL; ++ va_list ap; ++ ++ switch (local->type) { ++ case ARBITRATOR: ++ case GEOSTORE: ++ break; ++ default: ++ return; /* not expected to be run as system service */ ++ } ++ ++ fmt_iter = strchr(fmt, '%'); ++ while (fmt_iter) { ++ switch (*++fmt_iter) { ++ case 's': suffix = fmt_iter; ++ /* fall through */ ++ default: fmt_iter = NULL; ++ } ++ } ++ if (!suffix) { ++ log_warn("%s:%d: invalid format: %s", __FILE__, __LINE__, fmt); ++ return; ++ } ++ while (isspace(*++suffix)) /* noop */ ; ++ ++ va_start(ap, fmt); ++ fmt_iter = va_arg(ap, char *); /* just shift by one */ ++ assert(!strcmp(fmt_iter, DAEMON_NAME)); ++ rv = vsnprintf(buffer, sizeof(buffer), suffix, ap); ++ va_end(ap); ++ ++ rv = sd_notifyf(0, "READY=1\n" ++ "STATUS=Running: %s", ++ buffer); ++ if (rv < 0) ++ log_warn("%s:%d: sd_notifyf fail", __FILE__, __LINE__); ++} +diff --git a/src/alt/nametag_libsystemd.h b/src/alt/nametag_libsystemd.h +new file mode 100644 +index 0000000..2c1dc1e +--- /dev/null ++++ b/src/alt/nametag_libsystemd.h +@@ -0,0 +1,23 @@ ++/* ++ * Copyright (C) 2016 Jan Pokorny ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This software is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++ */ ++ ++void ++sd_notify_wrapper(const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); ++ ++#define init_set_proc_title(c, a, e) /* omitted */ ++#define set_proc_title sd_notify_wrapper +diff --git a/src/main.c b/src/main.c +index 6f53475..c5f5b66 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -34,7 +34,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -49,6 +48,11 @@ + #include + #include + #include "b_config.h" ++#ifndef NAMETAG_LIBSYSTEMD ++#include ++#else ++#include "alt/nametag_libsystemd.h" ++#endif + #include "log.h" + #include "booth.h" + #include "config.h" +-- +2.4.11 + diff --git a/0005-Feature-allow-skipping-coredump-nursing-phase.patch b/0005-Feature-allow-skipping-coredump-nursing-phase.patch new file mode 100644 index 0000000..d2227ce --- /dev/null +++ b/0005-Feature-allow-skipping-coredump-nursing-phase.patch @@ -0,0 +1,115 @@ +From 3426f311a24f9f09645cedf6c30675c95dbb137d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jan=20Pokorn=C3=BD?= +Date: Tue, 26 Apr 2016 16:50:50 +0200 +Subject: [PATCH 5/6] Feature: allow skipping "coredump nursing" phase + +This effectively eliminates the last dependency on glue libraries. +--- + configure.ac | 11 +++++++++++ + src/Makefile.am | 6 +++++- + src/main.c | 12 +++++++++--- + 3 files changed, 25 insertions(+), 4 deletions(-) + +diff --git a/configure.ac b/configure.ac +index c8502c6..937f563 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -287,6 +287,16 @@ libsystemd) + esac + AM_CONDITIONAL([NAMETAG_LIBSYSTEMD], [test "x$nametag_provider" = "xlibsystemd"]) + ++# figure out if "coredump nursing" supported and desired ++coredump_nursing="no" ++if test "x$with_glue" != "xno"; then ++ AC_CHECK_LIB([plumb], [cl_enable_coredumps], [coredump_nursing="libplumb"]) ++fi ++if test "x$coredump_nursing" != "xno"; then ++ AC_DEFINE(COREDUMP_NURSING, [], [eligible for coredump nursing]) ++fi ++AM_CONDITIONAL([COREDUMP_NURSING], [test "x$coredump_nursing" != "xno"]) ++ + # OS detection + # THIS SECTION MUST DIE! + CP=cp +@@ -518,6 +528,7 @@ AC_MSG_RESULT([ Features = ${PACKAGE_FEATURES}]) + AC_MSG_RESULT([ Logging provider = ${logging_provider}]) + AC_MSG_RESULT([ Range2random provider = ${range2random_provider}]) + AC_MSG_RESULT([ Nametag provider = ${nametag_provider}]) ++AC_MSG_RESULT([ Coredump nursing = ${coredump_nursing}]) + AC_MSG_RESULT([]) + AC_MSG_RESULT([$PACKAGE build info:]) + AC_MSG_RESULT([ Library SONAME = ${SONAME}]) +diff --git a/src/Makefile.am b/src/Makefile.am +index 69b7b48..2a985ae 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -22,7 +22,7 @@ boothd_SOURCES += auth.c + endif + + boothd_LDFLAGS = $(OS_DYFLAGS) -L./ +-boothd_LDADD = -lplumb -lm $(GLIB_LIBS) $(ZLIB_LIBS) ++boothd_LDADD = -lm $(GLIB_LIBS) $(ZLIB_LIBS) + boothd_CFLAGS = $(GLIB_CFLAGS) + + if !LOGGING_LIBQB +@@ -49,5 +49,9 @@ boothd_SOURCES += alt/nametag_libsystemd.c + noinst_HEADERS += alt/nametag_libsystemd.h + endif + ++if COREDUMP_NURSING ++boothd_LDADD += -lplumb ++endif ++ + lint: + -splint $(INCLUDES) $(LINT_FLAGS) $(CFLAGS) *.c +diff --git a/src/main.c b/src/main.c +index c5f5b66..7f173c9 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -33,9 +33,6 @@ + #include + #include + #include +-#include +-#include +-#include + #include + #include + #include +@@ -47,12 +44,19 @@ + #include + #include + #include ++ ++#include ++ + #include "b_config.h" + #ifndef NAMETAG_LIBSYSTEMD + #include + #else + #include "alt/nametag_libsystemd.h" + #endif ++#ifdef COREDUMP_NURSING ++#include ++#include ++#endif + #include "log.h" + #include "booth.h" + #include "config.h" +@@ -1461,11 +1465,13 @@ static int do_server(int type) + if (rv) + return rv; + ++#ifdef COREDUMP_NURSING + if (cl_enable_coredumps(TRUE) < 0){ + log_error("enabling core dump failed"); + } + cl_cdtocoredir(); + prctl(PR_SET_DUMPABLE, (unsigned long)TRUE, 0UL, 0UL, 0UL); ++#endif + + signal(SIGCHLD, (__sighandler_t)wait_child); + rv = loop(lock_fd); +-- +2.4.11 + diff --git a/0006-Feature-alternative-logger-in-service-runnable-scrip.patch b/0006-Feature-alternative-logger-in-service-runnable-scrip.patch new file mode 100644 index 0000000..eecc105 --- /dev/null +++ b/0006-Feature-alternative-logger-in-service-runnable-scrip.patch @@ -0,0 +1,179 @@ +From da326b0fc4d97eb8ef5dad0469933c1b63e0a0c9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jan=20Pokorn=C3=BD?= +Date: Wed, 2 Mar 2016 19:38:46 +0100 +Subject: [PATCH 6/6] Feature: alternative logger (in service-runnable script) + +This effectively eliminates the last dependency on glue project as such. +--- + Makefile.am | 2 +- + configure.ac | 2 ++ + script/service-runnable | 62 ---------------------------------------------- + script/service-runnable.in | 61 +++++++++++++++++++++++++++++++++++++++++++++ + 4 files changed, 64 insertions(+), 63 deletions(-) + delete mode 100755 script/service-runnable + create mode 100755 script/service-runnable.in + +diff --git a/Makefile.am b/Makefile.am +index 5f360c4..3ab326b 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -66,7 +66,7 @@ bootharbitrator_SCRIPTS = script/lsb/booth-arbitrator + + boothnoarchdir = $(datadir)/$(PACKAGE_NAME) + +-boothnoarch_SCRIPTS = script/service-runnable ++nodist_boothnoarch_SCRIPTS = script/service-runnable + + sbin_SCRIPTS = script/booth-keygen + +diff --git a/configure.ac b/configure.ac +index 937f563..c50c553 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -147,6 +147,8 @@ AC_CONFIG_FILES([Makefile + src/Makefile + docs/Makefile]) + ++AC_CONFIG_FILES([script/service-runnable], [chmod +x script/service-runnable]) ++ + # =============================================== + # Helpers + # =============================================== +diff --git a/script/service-runnable b/script/service-runnable +deleted file mode 100755 +index ed90c5e..0000000 +--- a/script/service-runnable ++++ /dev/null +@@ -1,62 +0,0 @@ +-#!/bin/bash +-# This script is part of Booth. +-# It checks whether the given resource (service) still has a chance +-# to run on the local cluster, so that booth knows whether to +-# acquire the ticket here. +- +-service="${1:?Need a resource name as first argument.}" +-if [ -z "$service" ]; then +- ha_logger "$0: bad usage: no resource name" +- exit 1 +-fi +-tmpshadow=`mktemp booth-check.XXXXXX` +-if [ $? -ne 0 -o ! -f "$tmpshadow" ]; then +- ha_logger "$0: mktemp failed" +- exit 1 +-fi +- +-trap "rm -f $tmpshadow" EXIT +- +- +-# We expect an output like +-# p_dummy (ocf::pacemaker:Dummy): Started geo-rz2-a +- +-status=`crm_simulate -O $tmpshadow --ticket-grant "$BOOTH_TICKET" --simulate --live-check 2>&1` +-if [ $? -ne 0 ]; then +- ha_logger "$0: crm_simulate failed" +- ha_logger "$0: crm_simulate: $status" +- exit 1 +-fi +- +-if echo "$status" | +- sed -n '/^Revised cluster status:/,$p' | +- egrep "^[[:space:]]+$service[[:space:]]+\(.*\):[[:space:]]+Started ([^[:space:]]+) *$" >/dev/null +-then +- # can be started - we're done. +- exit 0 +-fi +- +-# If target-role is Stopped, it judges with being stopped explicitly. +-output=$(crm_resource --meta --get-parameter="target-role" --resource=$service 2>/dev/null) +-rc=$? +-if [ $rc -eq 0 -a "$output" = "Stopped" ]; then +- exit 0 +-fi +- +-# is ticket in standby? +-output=$(crm_ticket --ticket "$BOOTH_TICKET" --get-attr standby) +-rc=$? +-if [ $rc -eq 0 -a "$output" = true ]; then +- exit 0 +-fi +- +-# Some error occured. +-# Try to help the admin with a bit of diagnostic. +-# +-# disallow ms-resources, ie. only primitives wanted here +-if ! crm_resource -l | grep -v ":" | grep "$service" ; then +- ha_logger "Defined resource '$service' in $BOOTH_CONF_PATH is not a primitive??" +-fi +- +-exit 1 +- +diff --git a/script/service-runnable.in b/script/service-runnable.in +new file mode 100755 +index 0000000..9ea33d4 +--- /dev/null ++++ b/script/service-runnable.in +@@ -0,0 +1,61 @@ ++#!/bin/bash ++# This script is part of Booth. ++# It checks whether the given resource (service) still has a chance ++# to run on the local cluster, so that booth knows whether to ++# acquire the ticket here. ++ ++service="${1:?Need a resource name as first argument.}" ++if [ -z "$service" ]; then ++ @LOGGER@ "$0: bad usage: no resource name" ++ exit 1 ++fi ++tmpshadow=`mktemp booth-check.XXXXXX` ++if [ $? -ne 0 -o ! -f "$tmpshadow" ]; then ++ @LOGGER@ "$0: mktemp failed" ++ exit 1 ++fi ++ ++trap "rm -f $tmpshadow" EXIT ++ ++ ++# We expect an output like ++# p_dummy (ocf::pacemaker:Dummy): Started geo-rz2-a ++ ++status=`crm_simulate -O $tmpshadow --ticket-grant "$BOOTH_TICKET" --simulate --live-check 2>&1` ++if [ $? -ne 0 ]; then ++ @LOGGER@ "$0: crm_simulate failed" ++ @LOGGER@ "$0: crm_simulate: $status" ++ exit 1 ++fi ++ ++if echo "$status" | ++ sed -n '/^Revised cluster status:/,$p' | ++ egrep "^[[:space:]]+$service[[:space:]]+\(.*\):[[:space:]]+Started ([^[:space:]]+) *$" >/dev/null ++then ++ # can be started - we're done. ++ exit 0 ++fi ++ ++# If target-role is Stopped, it judges with being stopped explicitly. ++output=$(crm_resource --meta --get-parameter="target-role" --resource=$service 2>/dev/null) ++rc=$? ++if [ $rc -eq 0 -a "$output" = "Stopped" ]; then ++ exit 0 ++fi ++ ++# is ticket in standby? ++output=$(crm_ticket --ticket "$BOOTH_TICKET" --get-attr standby) ++rc=$? ++if [ $rc -eq 0 -a "$output" = true ]; then ++ exit 0 ++fi ++ ++# Some error occured. ++# Try to help the admin with a bit of diagnostic. ++# ++# disallow ms-resources, ie. only primitives wanted here ++if ! crm_resource -l | grep -v ":" | grep "$service" ; then ++ @LOGGER@ "Defined resource '$service' in $BOOTH_CONF_PATH is not a primitive??" ++fi ++ ++exit 1 +-- +2.4.11 + diff --git a/0007-test-fix-failing-test_a_few_trailing_whitespaces.patch b/0007-test-fix-failing-test_a_few_trailing_whitespaces.patch new file mode 100644 index 0000000..9a97357 --- /dev/null +++ b/0007-test-fix-failing-test_a_few_trailing_whitespaces.patch @@ -0,0 +1,27 @@ +From e6846aa10a64fdfb7f6c2b3a3dc63ccebb91a45d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jan=20Pokorn=C3=BD?= +Date: Wed, 27 Apr 2016 12:12:08 +0200 +Subject: [PATCH] test: fix failing test_a_few_trailing_whitespaces + +Original assertion tested the exact opposite to what is expected +(when daemon gets killed, lock/pid file should no longer exist). +--- + test/serverenv.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/test/serverenv.py b/test/serverenv.py +index bbe7ff3..2e662cb 100755 +--- a/test/serverenv.py ++++ b/test/serverenv.py +@@ -143,7 +143,7 @@ def check_daemon_handling(self, runner, expected_daemon): + self.kill_pid(int(daemon_pid)) + time.sleep(1) + daemon_pid = self.get_daemon_pid_from_lock_file(runner.lock_file) +- self.assertTrue(daemon_pid is not None, ++ self.assertTrue(daemon_pid is None, + 'bnc#749763: lock file should vanish after daemon is killed') + + def get_daemon_pid_from_lock_file(self, lock_file): +-- +2.4.11 + diff --git a/0008-test-adapt-to-libqb-based-logging-with-lowercased-pr.patch b/0008-test-adapt-to-libqb-based-logging-with-lowercased-pr.patch new file mode 100644 index 0000000..bcabae8 --- /dev/null +++ b/0008-test-adapt-to-libqb-based-logging-with-lowercased-pr.patch @@ -0,0 +1,39 @@ +From 14c17a4c675a616b089400c935f74c27d15f5ee3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jan=20Pokorn=C3=BD?= +Date: Wed, 27 Apr 2016 19:39:21 +0200 +Subject: [PATCH] test: adapt to libqb-based logging with lowercased priorities + +--- + test/assertions.py | 2 +- + test/servertests.py | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/test/assertions.py b/test/assertions.py +index ea242b7..4396ab7 100755 +--- a/test/assertions.py ++++ b/test/assertions.py +@@ -8,7 +8,7 @@ def configFileMissingMyIP(self, config_file=None, lock_file=None): + self.run_booth(config_file=config_file, lock_file=lock_file, + expected_exitcode=1, expected_daemon=False) + +- expected_error = "ERROR: Cannot find myself in the configuration" ++ expected_error = "(ERROR|error): Cannot find myself in the configuration" + self.assertRegexpMatches(stderr, expected_error) + + def assertLockFileError(self, config_file=None, config_text=None, +diff --git a/test/servertests.py b/test/servertests.py +index 3742ed6..290bce2 100755 +--- a/test/servertests.py ++++ b/test/servertests.py +@@ -79,7 +79,7 @@ def test_missing_quotes(self): + if line_contains_IP: + self.assertRegexpMatches( + self.read_log(), +- "ERROR: invalid config file format: unquoted '.'", ++ "(ERROR|error): invalid config file format: unquoted '.'", + 'IP addresses need to be quoted' + ) + +-- +2.4.11 + diff --git a/0009-test-booth-cannot-cope-with-address-device-IPv6-addr.patch b/0009-test-booth-cannot-cope-with-address-device-IPv6-addr.patch new file mode 100644 index 0000000..7b3c3e0 --- /dev/null +++ b/0009-test-booth-cannot-cope-with-address-device-IPv6-addr.patch @@ -0,0 +1,29 @@ +From 4754bd5a62283359caa0867c4e6a463d2c62193c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jan=20Pokorn=C3=BD?= +Date: Wed, 27 Apr 2016 20:58:33 +0200 +Subject: [PATCH] test: booth cannot cope with
% IPv6 + addresses + +...at least for the time being. So craft ::1 address in that case +as a substitute. +--- + test/utils.py | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/test/utils.py b/test/utils.py +index cbbd8d4..ceeef98 100755 +--- a/test/utils.py ++++ b/test/utils.py +@@ -12,5 +12,7 @@ def get_IP(): + (stdout, stderr, returncode) = run_cmd(['hostname', '-i']) + if returncode != 0: + raise RuntimeError, "Failed to run hostname -i:\n" + stderr +- # in case multiple IP addresses are returned, use only the first. +- return re.sub(r'\s.*', '', stdout) ++ # in case multiple IP addresses are returned, use only the first ++ # and also strip '%' part possibly present with IPv6 address ++ ret = re.sub(r'\s.*', '', stdout) ++ return "::1" if '%' in ret else ret +-- +2.4.11 + diff --git a/booth.spec b/booth.spec new file mode 100644 index 0000000..9414c75 --- /dev/null +++ b/booth.spec @@ -0,0 +1,283 @@ +# RPMs are split as follows: +# * booth: +# - envelope package serving as a syntactic shortcut to install +# booth-site (with architecture reliably preserved) +# * booth-core: +# - package serving as a base for booth-{arbitrator,site}, +# carrying also basic documentation, license, etc. +# * booth-arbitrator: +# - package to be installed at a machine accessible within HA cluster(s), +# but not (necessarily) a member of any, hence no dependency +# on anything from cluster stack is required +# * booth-site: +# - package to be installed at a cluster member node +# (requires working cluster environment to be useful) +# * booth-test: +# - files for testing booth +# +# TODO: +# wireshark-dissector.lua currently of no use (rhbz#1259623), but if/when +# this no longer persists, add -wireshark package (akin to libvirt-wireshark) + +%bcond_with html_man +%bcond_with glue + +%global specver 2 +%global boothver 1.0 +# set following to the actual commit or, for final release, concatenate +# "boothver" macro to "v" (will yield a tag per the convention) +%global commit eb4256a64b559a7c5a03a7ce76c103f6069c7eb7 +%global lparen ( +%global rparen ) +%global shortcommit %(c=%{commit}; case ${c} in + v*%{rparen} echo ${c:1};; + *%{rparen} echo ${c:0:7};; esac) +%global pre_release %(s=%{shortcommit}; [ ${s: -3:2} != rc ]; echo $?) +%global post_release %([ %{commit} = v%{shortcommit} ]; echo $?) +%global github_owner ClusterLabs + +%if 0%{pre_release} +%global boothrel 0.%{specver}.%(s=%{shortcommit}; echo ${s: -3}) +%else +%if 0%{post_release} +%global boothrel %{specver}.%{shortcommit}.git +%else +%global boothrel %{specver} +%endif +%endif + +%{!?_pkgdocdir: %global _pkgdocdir %{_docdir}/%{name}} +# https://fedoraproject.org/wiki/EPEL:Packaging?rd=Packaging:EPEL#The_.25license_tag +%{!?_licensedir:%global license %doc} + +%global test_path %{_datadir}/booth/tests + +Name: booth +Version: %{boothver} +Release: %{boothrel}%{dist} +Summary: Ticket Manager for Multi-site Clusters +Group: System Environment/Daemons +License: GPLv2+ +Url: https://github.com/%{github_owner}/%{name} +Source0: https://github.com/%{github_owner}/%{name}/archive/%{commit}/%{name}-%{shortcommit}.tar.gz +Patch0: 0001-Feature-offer-alternatives-to-libraries-from-cluster.patch +Patch1: 0002-Feature-alternative-logging-provider-libqb.patch +Patch2: 0003-Feature-alternative-range2random-provider-glib.patch +Patch3: 0004-Feature-alternative-nametag-provider-libsystemd.patch +Patch4: 0005-Feature-allow-skipping-coredump-nursing-phase.patch +Patch5: 0006-Feature-alternative-logger-in-service-runnable-scrip.patch +Patch6: 0007-test-fix-failing-test_a_few_trailing_whitespaces.patch +Patch7: 0008-test-adapt-to-libqb-based-logging-with-lowercased-pr.patch +Patch8: 0009-test-booth-cannot-cope-with-address-device-IPv6-addr.patch + +# direct build process dependencies +BuildRequires: autoconf +BuildRequires: automake +BuildRequires: coreutils +BuildRequires: make +## ./autogen.sh +BuildRequires: /bin/sh +# general build dependencies +BuildRequires: asciidoc +BuildRequires: gcc +BuildRequires: pkgconfig +# linking dependencies +BuildRequires: libgcrypt-devel +BuildRequires: libxml2-devel +## just for include +BuildRequires: pacemaker-libs-devel +BuildRequires: pkgconfig(glib-2.0) +BuildRequires: zlib-devel +## logging provider +BuildRequires: pkgconfig(libqb) +## random2range provider +BuildRequires: pkgconfig(glib-2.0) +## nametag provider +BuildRequires: pkgconfig(libsystemd) +# check scriptlet (for hostname and killall respectively) +BuildRequires: hostname psmisc +BuildRequires: python2-devel +# spec file specifics +## for _unitdir, systemd_requires and specific scriptlet macros +BuildRequires: systemd +## for autosetup +BuildRequires: git + +# this is for a composite-requiring-its-components arranged +# as an empty package (empty files section) requiring subpackages +# (_isa so as to preserve the architecture) +Requires: %{name}-core%{?_isa} +Requires: %{name}-site +%files +# intentionally empty + +%description +Booth manages tickets which authorize cluster sites located +in geographically dispersed locations to run resources. +It facilitates support of geographically distributed +clustering in Pacemaker. + +# SUBPACKAGES # + +%package core +Summary: Booth core files (executables, etc.) +Group: System Environment/Daemons +# for booth-keygen (chown, dd) +Requires: coreutils +# deal with pre-split arrangement +Conflicts: %{name} < 1.0-1 + +%description core +Core files (executables, etc.) for Booth, ticket manager for +multi-site clusters. + +%package arbitrator +Summary: Booth support for running as an arbitrator +Group: System Environment/Daemons +BuildArch: noarch +Requires: %{name}-core = %{version}-%{release} +%{?systemd_requires} +# deal with pre-split arrangement +Conflicts: %{name} < 1.0-1 + +%description arbitrator +Support for running Booth, ticket manager for multi-site clusters, +as an arbitrator. + +%post arbitrator +%systemd_post booth@.service booth-arbitrator.service + +%preun arbitrator +%systemd_preun booth@.service booth-arbitrator.service + +%postun arbitrator +%systemd_postun_with_restart booth@.service booth-arbitrator.service + +%package site +Summary: Booth support for running as a full-fledged site +Group: System Environment/Daemons +BuildArch: noarch +Requires: %{name}-core = %{version}-%{release} +# for crm_{resource,simulate,ticket} utilities +Requires: pacemaker >= 1.1.8 +# for ocf-shellfuncs and other parts of OCF shell-based environment +Requires: resource-agents +# deal with pre-split arrangement +Conflicts: %{name} < 1.0-1 + +%description site +Support for running Booth, ticket manager for multi-site clusters, +as a full-fledged site. + +%package test +Summary: Test scripts for Booth +Group: System Environment/Daemons +BuildArch: noarch +# runtests.py suite (for hostname and killall respectively) +Requires: hostname psmisc +Requires: python(abi) < 3 +# any of the following internal dependencies will pull -core package +## for booth@booth.service +Requires: %{name}-arbitrator = %{version}-%{release} +## for booth-site and service-runnable scripts +## (and /usr/lib/ocf/resource.d/booth) +Requires: %{name}-site = %{version}-%{release} + +%description test +Automated tests for running Booth, ticket manager for multi-site clusters. + +# BUILD # + +%prep +%autosetup -n %{name}-%{commit} -S git + +%build +./autogen.sh +%{configure} \ + --with-initddir=%{_initrddir} \ + --docdir=%{_pkgdocdir} \ + --enable-user-flags \ + %{!?with_html_man:--without-html_man} \ + %{!?with_glue:--without-glue} +%{make_build} + +%install +%{make_install} +mkdir -p %{buildroot}/%{_unitdir} +cp -a -t %{buildroot}/%{_unitdir} \ + -- conf/booth@.service conf/booth-arbitrator.service +install -D -m 644 -t %{buildroot}/%{_mandir}/man8 \ + -- docs/boothd.8 +ln -s boothd.8 %{buildroot}/%{_mandir}/man8/booth.8 +cp -a -t %{buildroot}/%{_pkgdocdir} \ + -- ChangeLog README-testing conf/booth.conf.example +# drop what we don't package anyway (COPYING added via tarball-relative path) +rm -rf %{buildroot}/%{_initrddir}/booth-arbitrator +rm -rf %{buildroot}/%{_pkgdocdir}/README.upgrade-from-v0.1 +rm -rf %{buildroot}/%{_pkgdocdir}/COPYING +# tests +mkdir -p %{buildroot}/%{test_path} +cp -a -t %{buildroot}/%{test_path} \ + -- conf test unit-tests script/unit-test.py +chmod +x %{buildroot}/%{test_path}/test/booth_path +chmod +x %{buildroot}/%{test_path}/test/live_test.sh +mkdir -p %{buildroot}/%{test_path}/src +ln -s -t %{buildroot}/%{test_path}/src \ + -- %{_sbindir}/boothd + +%check +# alternatively: test/runtests.py +VERBOSE=1 make check + +%files core +%license COPYING +%doc %{_pkgdocdir}/AUTHORS +%doc %{_pkgdocdir}/ChangeLog +%doc %{_pkgdocdir}/README +%doc %{_pkgdocdir}/booth.conf.example +# core command(s) + man pages +%{_sbindir}/booth* +%{_mandir}/man8/booth*.8* +# configuration +%dir %{_sysconfdir}/booth +%exclude %{_sysconfdir}/booth/booth.conf.example + +%files arbitrator +%{_unitdir}/booth@.service +%{_unitdir}/booth-arbitrator.service + +%files site +# OCF (agent + a helper) +## /usr/lib/ocf/resource.d/pacemaker provided by pacemaker +/usr/lib/ocf/resource.d/pacemaker/booth-site +%dir /usr/lib/ocf/lib/booth + /usr/lib/ocf/lib/booth/geo_attr.sh +# geostore (command + OCF agent) +%{_sbindir}/geostore +%{_mandir}/man8/geostore.8* +## /usr/lib/ocf/resource.d provided by resource-agents +%dir /usr/lib/ocf/resource.d/booth + /usr/lib/ocf/resource.d/booth/geostore +# helper (possibly used in the configuration hook) +%dir %{_datadir}/booth + %{_datadir}/booth/service-runnable + +%files test +%doc %{_pkgdocdir}/README-testing +# /usr/share/booth provided by -site +%{test_path} +# /usr/lib/ocf/resource.d/booth provided by -site +/usr/lib/ocf/resource.d/booth/sharedrsc + +%changelog +* Thu May 05 2016 Jan Pokorný - 1.0-2.eb4256a.git +- update a subset of out-of-tree patches per + https://github.com/ClusterLabs/booth/pull/22#issuecomment-216936987 +- pre-inclusion cleanups in the spec (apply systemd scriptlet operations + with booth-arbitrator, avoid overloading file implicitly considered %%doc + as %%license) + Resolves: rhbz#1314865 + Related: rhbz#1333509 + +* Thu Apr 28 2016 Jan Pokorný - 1.0-1.eb4256a.git +- initial build diff --git a/sources b/sources index e69de29..c7868bb 100644 --- a/sources +++ b/sources @@ -0,0 +1 @@ +e6ac10c38a8e181306316150861c8923 booth-eb4256a.tar.gz