diff --git a/.booth.metadata b/.booth.metadata new file mode 100644 index 0000000..5e82a0e --- /dev/null +++ b/.booth.metadata @@ -0,0 +1 @@ +bc909d915b3884e7fe16f296abd1b9736a04b345 SOURCES/booth-ef769ef.tar.gz diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d012af7 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/booth-ef769ef.tar.gz diff --git a/SOURCES/0001-test-README-testing-indent-configuration-literal-par.patch b/SOURCES/0001-test-README-testing-indent-configuration-literal-par.patch new file mode 100644 index 0000000..5262cc3 --- /dev/null +++ b/SOURCES/0001-test-README-testing-indent-configuration-literal-par.patch @@ -0,0 +1,40 @@ +From f3e4db6a6751e38084e305093a3452512ba40336 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jan=20Pokorn=C3=BD?= +Date: Fri, 27 May 2016 22:51:14 +0200 +Subject: [PATCH 1/4] test: README-testing: indent configuration (~literal + paragraph) + +--- + README-testing | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/README-testing b/README-testing +index ac768e5..81c4158 100644 +--- a/README-testing ++++ b/README-testing +@@ -47,16 +47,16 @@ is used to manipulate iptables rules. + This is a sample pacemaker configuration for a single-node + cluster: + +-primitive booth ocf:pacemaker:booth-site +-primitive d-src1 ocf:heartbeat:Dummy +-rsc_ticket global-d-src1 ticket-A: d-src1 ++ primitive booth ocf:pacemaker:booth-site ++ primitive d-src1 ocf:heartbeat:Dummy ++ rsc_ticket global-d-src1 ticket-A: d-src1 + + Additionally, you may also add an ocf:booth:sharedrsc resource to + also check that the ticket is granted always to only one site: + +-primitive shared ocf:booth:sharedrsc \ +- params dir="10.2.13.82:/var/tmp/boothtestdir" +-rsc_ticket global-shared ticket-A: shared ++ primitive shared ocf:booth:sharedrsc \ ++ params dir="10.2.13.82:/var/tmp/boothtestdir" ++ rsc_ticket global-shared ticket-A: shared + + Please adjust to your environment. + +-- +2.4.11 + diff --git a/SOURCES/0002-test-README-testing-provide-pcs-configuration-altern.patch b/SOURCES/0002-test-README-testing-provide-pcs-configuration-altern.patch new file mode 100644 index 0000000..2024bb0 --- /dev/null +++ b/SOURCES/0002-test-README-testing-provide-pcs-configuration-altern.patch @@ -0,0 +1,39 @@ +From 917429b09dcca7c7049b703a005119817a7e749a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jan=20Pokorn=C3=BD?= +Date: Fri, 27 May 2016 22:54:40 +0200 +Subject: [PATCH 2/4] test: README-testing: provide pcs configuration + alternatives + +--- + README-testing | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/README-testing b/README-testing +index 81c4158..ffde9bf 100644 +--- a/README-testing ++++ b/README-testing +@@ -48,15 +48,21 @@ This is a sample pacemaker configuration for a single-node + cluster: + + primitive booth ocf:pacemaker:booth-site ++ (pcs resource create booth ocf:pacemaker:booth-site) + primitive d-src1 ocf:heartbeat:Dummy ++ (pcs resource create d-src1 ocf:heartbeat:Dummy) + rsc_ticket global-d-src1 ticket-A: d-src1 ++ (pcs constraint ticket add ticket-A d-src1 id=global-d-src1) + + Additionally, you may also add an ocf:booth:sharedrsc resource to + also check that the ticket is granted always to only one site: + + primitive shared ocf:booth:sharedrsc \ + params dir="10.2.13.82:/var/tmp/boothtestdir" ++ (pcs resource create shared ocf:booth:sharedrsc \ ++ dir="10.2.13.82:/var/tmp/boothtestdir") + rsc_ticket global-shared ticket-A: shared ++ (pcs constraint ticket add ticket-A shared id=global-shared) + + Please adjust to your environment. + +-- +2.4.11 + diff --git a/SOURCES/0003-test-live_test-use-a-defined-literal-uniformly.patch b/SOURCES/0003-test-live_test-use-a-defined-literal-uniformly.patch new file mode 100644 index 0000000..3c4a9a7 --- /dev/null +++ b/SOURCES/0003-test-live_test-use-a-defined-literal-uniformly.patch @@ -0,0 +1,25 @@ +From 6bc22016a368faac697274b0ff764b309489d8ea Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jan=20Pokorn=C3=BD?= +Date: Fri, 27 May 2016 22:44:34 +0200 +Subject: [PATCH 3/4] test: live_test: use a defined literal uniformly + +--- + test/live_test.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/test/live_test.sh b/test/live_test.sh +index 4425bfb..5ee918e 100755 +--- a/test/live_test.sh ++++ b/test/live_test.sh +@@ -418,7 +418,7 @@ show_pref() { + run_site $1 crm configure show $PREFNAME > /dev/null + } + repair_external_prog() { +- run_site $1 crm configure delete __pref_booth_live_test ++ run_site $1 crm configure delete $PREFNAME + } + get_tkt() { + grep "^ticket=" | head -1 | sed 's/ticket=//;s/"//g' +-- +2.4.11 + diff --git a/SOURCES/0004-test-live_test-offer-alternatives-to-crm-pcs-native.patch b/SOURCES/0004-test-live_test-offer-alternatives-to-crm-pcs-native.patch new file mode 100644 index 0000000..d6bf79e --- /dev/null +++ b/SOURCES/0004-test-live_test-offer-alternatives-to-crm-pcs-native.patch @@ -0,0 +1,112 @@ +From b565fb6402af40789762ee281baf2b074c1532e1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jan=20Pokorn=C3=BD?= +Date: Fri, 27 May 2016 23:17:32 +0200 +Subject: [PATCH 4/4] test: live_test: offer alternatives to crm (pcs + native) + +Note that existing use of crm_ticket can be eventually also extended +with higher-level CLI tool usage, following the same pattern. +--- + test/live_test.sh | 61 +++++++++++++++++++++++++++++++++++++++++++++++++------ + 1 file changed, 55 insertions(+), 6 deletions(-) + +diff --git a/test/live_test.sh b/test/live_test.sh +index 5ee918e..b7f27eb 100755 +--- a/test/live_test.sh ++++ b/test/live_test.sh +@@ -50,6 +50,9 @@ logf=test_booth.log + SSH_OPTS="-o StrictHostKeyChecking=no -l root" + iprules=/usr/share/booth/tests/test/booth_path + : ${HA_LOGFACILITY:="syslog"} ++cli_driver=native ++which crm >/dev/null 2>&1 && cli_driver=crm || : ++which pcs >/dev/null 2>&1 && cli_driver=pcs || : + + get_site() { + local n=$1 +@@ -159,7 +162,26 @@ runcmd() { + return $rc + } + manage_site() { +- runcmd $1 crm -w resource $2 booth ++ local action=$2 resource=booth cmd ++ case "$action" in ++ start) ++ case "$cli_driver" in ++ native) action=Started;; ++ pcs) action=enable;; ++ esac;; ++ stop) ++ case "$cli_driver" in ++ native) action=Stopped;; ++ pcs) action=disable;; ++ esac;; ++ esac ++ ++ case "$cli_driver" in ++ native) cmd="crm_resource --wait --resource \"$resource\" --set-parameter target-role --meta --parameter-value \"$action\"";; ++ crm) cmd="crm -w resource \"$action\" \"$resource\"";; ++ pcs) cmd="pcs resource \"$action\" \"$resource\" --wait";; ++ esac ++ runcmd $1 $cmd + } + manage_arbitrator() { + if ps 1 | grep -qws systemd; then +@@ -211,9 +233,15 @@ cleanup_booth() { + cleanup_dep_rsc() { + local dep_rsc=`get_rsc` + test -z "$dep_rsc" && return +- local h procs ++ local cmd h procs ++ case "$cli_driver" in ++ native) cmd="crm_resource --cleanup --resource \"$dep_rsc\"; crm_resource --wait";; ++ crm) cmd="crm -w resource cleanup \"$dep_rsc\"";; ++ # XXX pcs does not support --wait here? ++ pcs) cmd="pcs resource cleanup \"$dep_rsc\"; crm_resource --wait";; ++ esac + for h in $sites; do +- runcmd $h crm -w resource cleanup $dep_rsc & procs="$! $procs" ++ runcmd $h $cmd & procs="$! $procs" + done >/dev/null 2>&1 + wait $procs + } +@@ -412,13 +440,34 @@ del_site_attr() { + run_site $site geostore delete $1 + } + break_external_prog() { +- run_site $1 crm configure "location $PREFNAME `get_rsc` rule -inf: defined \#uname" ++ local cmd ++ case "$cli_driver" in ++ native) cmd="cibadmin --create --scope constraints --xml-text=\"" ++ cmd="$cmd" ++ cmd="$cmd" ++ cmd="$cmd\"";; ++ crm) cmd="crm configure \"location $PREFNAME `get_rsc` rule -inf: defined \#uname\"";; ++ pcs) cmd="pcs constraint location `get_rsc` rule id=$PREFNAME score=-INFINITY defined \#uname";; ++ esac ++ runcmd $1 $cmd + } + show_pref() { +- run_site $1 crm configure show $PREFNAME > /dev/null ++ local cmd ++ case "$cli_driver" in ++ native) cmd="cibadmin --query --xpath \"//rsc_location[@id = '$PREFNAME']\"";; ++ crm) cmd="crm configure show $PREFNAME > /dev/null";; ++ pcs) cmd="pcs constraint show --full | grep -q $PREFNAME";; ++ esac ++ runcmd $1 $cmd + } + repair_external_prog() { +- run_site $1 crm configure delete $PREFNAME ++ local cmd ++ case "$cli_driver" in ++ native) cmd="cibadmin --delete --xpath \"//rsc_location[@id = '$PREFNAME']\"";; ++ crm) cmd="crm configure delete $PREFNAME";; ++ pcs) cmd="pcs constraint remove $PREFNAME";; ++ esac ++ runcmd $1 $cmd + } + get_tkt() { + grep "^ticket=" | head -1 | sed 's/ticket=//;s/"//g' +-- +2.4.11 + diff --git a/SOURCES/bz1341720-zealous-local-address-matching.patch b/SOURCES/bz1341720-zealous-local-address-matching.patch new file mode 100644 index 0000000..54c612c --- /dev/null +++ b/SOURCES/bz1341720-zealous-local-address-matching.patch @@ -0,0 +1,64 @@ +From b9560cc74c99e96f97490608b292f23735252aaf Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jan=20Pokorn=C3=BD?= +Date: Wed, 14 Sep 2016 22:31:56 +0200 +Subject: [PATCH] High: zealous local address matching with the same subnet + entries + +Previously, having booth components on the same subnet could seriously +confuse self-determination of those tolerating fuzziness when doing so +(i.e., not site nor arbitrator). + +It would be the case when there are two (or more) addresses sharing the +same network part of the address as one of the actual hosts's addresses +(assigned to one of its interfaces), and the exactly matching one is +listed _after_ at least a single network-part-match-only one ("fuzzy" +match). Due to the original requirement that any subsequent candidate +would have to beat a running winner in the length of the network prefix, +such exact match could never have been tested and hence missed. +(IOW, algorithm used to search for local, not global maximum in some +circumstances). + +Now we allow further examination of the candidate with the same length +of the network prefix as a running winner, which -- moreover -- cannot +be the exact match because now, it terminates the search immediately. +--- + src/transport.c | 22 ++++++++++++++-------- + 1 file changed, 14 insertions(+), 8 deletions(-) + +diff --git a/src/transport.c b/src/transport.c +index b3e4432..1d620a0 100644 +--- a/src/transport.c ++++ b/src/transport.c +@@ -237,15 +237,21 @@ int _find_myself(int family, struct booth_site **mep, int fuzzy_allowed) + BOOTH_IPADDR_LEN); + } + +- /* First try with exact addresses, then optionally with subnet matching. */ +- if (ifa->ifa_prefixlen > address_bits_matched) { +- find_address(ipaddr, +- ifa->ifa_family, ifa->ifa_prefixlen, +- fuzzy_allowed, &me, &address_bits_matched); +- if (me) { +- log_debug("found myself at %s (%d bits matched)", +- site_string(me), address_bits_matched); ++ if (ifa->ifa_prefixlen >= address_bits_matched) { ++ /* First attempt exact match with addresses in the config, ++ then optionally with subnet matching. */ ++ if (find_address(ipaddr, ++ ifa->ifa_family, ifa->ifa_prefixlen, ++ fuzzy_allowed, &me, &address_bits_matched) ++ == EXACT_MATCH) { ++ log_debug("found exactly myself at %s (%d bits matched)", ++ site_string(me), address_bits_matched); ++ break; + } ++ if (me) ++ log_debug("running winner to determine myself at %s" ++ " (%d bits matched)", ++ site_string(me), address_bits_matched); + } + } + h = NLMSG_NEXT(h, status); +-- +2.4.11 + diff --git a/SOURCES/bz1366616-local_site_resolved_prevents_segfault.patch b/SOURCES/bz1366616-local_site_resolved_prevents_segfault.patch new file mode 100644 index 0000000..7d8836f --- /dev/null +++ b/SOURCES/bz1366616-local_site_resolved_prevents_segfault.patch @@ -0,0 +1,404 @@ +From 5b8a336bb3d7a25ba43f444bc586b27fb9f42746 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jan=20Pokorn=C3=BD?= +Date: Tue, 13 Sep 2016 17:47:03 +0200 +Subject: [PATCH 1/4] Low: make find_site_by_name failure set error code + +At one instance (query_get_string_answer) it just flips the sign as it +is customary to return negative value upon error (for uniform +treatment). +--- + src/attr.c | 2 ++ + src/main.c | 3 ++- + 2 files changed, 4 insertions(+), 1 deletion(-) + +diff --git a/src/attr.c b/src/attr.c +index d9e5c91..0e407b6 100644 +--- a/src/attr.c ++++ b/src/attr.c +@@ -16,6 +16,7 @@ + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + ++#include + #include + #include + #include "attr.h" +@@ -162,6 +163,7 @@ int do_attr_command(cmd_request_t cmd) + else { + if (!find_site_by_name(cl.site, &site, 1)) { + log_error("Site \"%s\" not configured.", cl.site); ++ rv = -ENOENT; + goto out_close; + } + } +diff --git a/src/main.c b/src/main.c +index 206c881..b1ff1e7 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -665,7 +665,7 @@ static int query_get_string_answer(cmd_request_t cmd) + site = local; + else if (!find_site_by_name(cl.site, &site, 1)) { + log_error("cannot find site \"%s\"", cl.site); +- rv = ENOENT; ++ rv = -ENOENT; + goto out; + } + +@@ -741,6 +741,7 @@ static int do_command(cmd_request_t cmd) + else { + if (!find_site_by_name(cl.site, &site, 1)) { + log_error("Site \"%s\" not configured.", cl.site); ++ rv = -ENOENT; + goto out_close; + } + } +-- +2.4.11 + + +From bcf1117d7e1f37165c6d0da022cadc63e391a2fa Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jan=20Pokorn=C3=BD?= +Date: Tue, 13 Sep 2016 18:20:17 +0200 +Subject: [PATCH 2/4] High: ensure local site resolved for all effective + actions + +Previously, running: + + touch /etc/booth/booth.conf + booth grant a_ticket + +would result in a segfault due to not guarding resolution of local +site properly in some circumstances, so do it at the central place. +Also error messaging is now centralized. +--- + src/main.c | 19 ++++--------------- + 1 file changed, 4 insertions(+), 15 deletions(-) + +diff --git a/src/main.c b/src/main.c +index b1ff1e7..c05446f 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -377,9 +377,10 @@ static int setup_config(int type) + return -EINVAL; + } + local->local = 1; +- } else +- find_myself(NULL, type == CLIENT || type == GEOSTORE); +- ++ } else if (!find_myself(NULL, type == CLIENT || type == GEOSTORE)) { ++ log_error("Cannot find myself in the configuration."); ++ return -EINVAL; ++ } + + rv = check_config(type); + if (rv < 0) +@@ -1302,13 +1303,6 @@ static int do_status(int type) + goto quit; + } + +- +- if (!local) { +- reason = "No Service IP active here."; +- goto quit; +- } +- +- + rv = _lockfile(O_RDWR, &status_lock_fd, &pid); + if (status_lock_fd == -1) { + reason = "No PID file."; +@@ -1422,11 +1416,6 @@ static int do_server(int type) + if (rv < 0) + return rv; + +- if (!local) { +- log_error("Cannot find myself in the configuration."); +- exit(EXIT_FAILURE); +- } +- + if (daemonize) { + if (daemon(0, 0) < 0) { + perror("daemon error"); +-- +2.4.11 + + +From 1185487afbd2a063664863f7bd98d1480ca0a2dd Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jan=20Pokorn=C3=BD?= +Date: Tue, 13 Sep 2016 20:18:33 +0200 +Subject: [PATCH 3/4] Low: make daemon with "-s site" (debug mode) claim + "myself" + +--- + src/main.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/main.c b/src/main.c +index c05446f..76e62c7 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -372,8 +372,8 @@ static int setup_config(int type) + /* Set "local" pointer, ignoring errors. */ + if (cl.type == DAEMON && cl.site[0]) { + if (!find_site_by_name(cl.site, &local, 1)) { +- log_error("Cannot find \"%s\" in the configuration.", +- cl.site); ++ log_error("Cannot find \"%s\" (myself) in the configuration.", ++ cl.site); + return -EINVAL; + } + local->local = 1; +-- +2.4.11 + + +From 736f58db41acd32b2ea2af1b4c0ba02683d58cf5 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jan=20Pokorn=C3=BD?= +Date: Tue, 13 Sep 2016 20:10:13 +0200 +Subject: [PATCH 4/4] Refactor: call find_site_by_name just once, up the stream + +Respective logic was duplicated for all "booth list/peers/grant/revoke" +and "geostore list/get/set/del" separately, so utilize a natural control +flow to carry this once-resolved target site from here, sharing it with +the special case of "daemon" role invoked with "-s site" (debug mode). +Side effect: simpler, terser code. +--- + src/attr.c | 13 +---------- + src/attr.h | 2 +- + src/main.c | 75 ++++++++++++++++++++++++++++---------------------------------- + 3 files changed, 36 insertions(+), 54 deletions(-) + +diff --git a/src/attr.c b/src/attr.c +index 0e407b6..805ccb3 100644 +--- a/src/attr.c ++++ b/src/attr.c +@@ -150,24 +150,13 @@ static int read_server_reply( + return rv; + } + +-int do_attr_command(cmd_request_t cmd) ++int do_attr_command(cmd_request_t cmd, struct booth_site *site) + { +- struct booth_site *site = NULL; + struct boothc_header *header; + struct booth_transport const *tpt; + int len, rv = -1; + char *msg = NULL; + +- if (!*cl.site) +- site = local; +- else { +- if (!find_site_by_name(cl.site, &site, 1)) { +- log_error("Site \"%s\" not configured.", cl.site); +- rv = -ENOENT; +- goto out_close; +- } +- } +- + if (site->type == ARBITRATOR) { + if (site == local) { + log_error("We're just an arbitrator, no attributes here."); +diff --git a/src/attr.h b/src/attr.h +index 1c680bd..a94ac16 100644 +--- a/src/attr.h ++++ b/src/attr.h +@@ -31,7 +31,7 @@ + + void print_geostore_usage(void); + int test_attr_reply(cmd_result_t reply_code, cmd_request_t cmd); +-int do_attr_command(cmd_request_t cmd); ++int do_attr_command(cmd_request_t cmd, struct booth_site *site); + int process_attr_request(struct client *req_client, void *buf); + int attr_recv(void *buf, struct booth_site *source); + int store_geo_attr(struct ticket_config *tk, const char *name, const char *val, int notime); +diff --git a/src/main.c b/src/main.c +index 76e62c7..e09536a 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -346,7 +346,7 @@ int update_authkey() + return 0; + } + +-static int setup_config(int type) ++static int setup_config(int type, struct booth_site **site) + { + int rv; + +@@ -369,18 +369,31 @@ static int setup_config(int type) + #endif + } + +- /* Set "local" pointer, ignoring errors. */ +- if (cl.type == DAEMON && cl.site[0]) { +- if (!find_site_by_name(cl.site, &local, 1)) { +- log_error("Cannot find \"%s\" (myself) in the configuration.", +- cl.site); +- return -EINVAL; ++ /* Determine the target based on the provided address, ignore ++ errors with DAEMON (special debug/testing arrangement). */ ++ if (*cl.site && (cl.type == DAEMON || (site && strcmp(cl.site, OTHER_SITE)))) { ++ if (!find_site_by_name(cl.site, cl.type == DAEMON ? &local : site, 1)) { ++ log_error("Cannot find \"%s\"%s in the configuration.", ++ cl.site, cl.type == DAEMON ? " (myself)" : ""); ++ if (cl.type != DAEMON) ++ return -EINVAL; + } +- local->local = 1; +- } else if (!find_myself(NULL, type == CLIENT || type == GEOSTORE)) { ++ if (cl.type == DAEMON) ++ local->local = 1; ++ else ++ site = NULL; /* prevent from overwriting */ ++ } ++ /* Self-determine us. */ ++ if (!find_myself(site, type == CLIENT || type == GEOSTORE)) { + log_error("Cannot find myself in the configuration."); + return -EINVAL; + } ++ /* We can resolve "other" only after we've determined us. */ ++ if (*cl.site && site && !strcmp(cl.site, OTHER_SITE) ++ && !find_site_by_name(cl.site, site, 1)) { ++ log_error("Cannot find %s node in the configuration.", cl.site); ++ return -EINVAL; ++ } + + rv = check_config(type); + if (rv < 0) +@@ -635,9 +648,8 @@ static int test_reply(cmd_result_t reply_code, cmd_request_t cmd) + return rv; + } + +-static int query_get_string_answer(cmd_request_t cmd) ++static int query_get_string_answer(cmd_request_t cmd, struct booth_site *site) + { +- struct booth_site *site; + struct boothc_hdr_msg reply; + struct boothc_header *header; + char *data; +@@ -662,14 +674,6 @@ static int query_get_string_answer(cmd_request_t cmd) + + init_header(header, cmd, 0, cl.options, 0, 0, msg_size); + +- if (!*cl.site) +- site = local; +- else if (!find_site_by_name(cl.site, &site, 1)) { +- log_error("cannot find site \"%s\"", cl.site); +- rv = -ENOENT; +- goto out; +- } +- + tpt = booth_transport + TCP; + rv = tpt->open(site); + if (rv < 0) +@@ -709,16 +713,14 @@ out_test_reply: + rv = test_reply_f(ntohl(reply.header.result), cmd); + out_close: + tpt->close(site); +-out: + if (data) + free(data); + return rv; + } + + +-static int do_command(cmd_request_t cmd) ++static int do_command(cmd_request_t cmd, struct booth_site *site) + { +- struct booth_site *site; + struct boothc_ticket_msg reply; + struct booth_transport const *tpt; + uint32_t leader_id; +@@ -732,21 +734,10 @@ static int do_command(cmd_request_t cmd) + op_str = "revoke"; + + rv = 0; +- site = NULL; + + /* Always use TCP for client - at least for now. */ + tpt = booth_transport + TCP; + +- if (!*cl.site) +- site = local; +- else { +- if (!find_site_by_name(cl.site, &site, 1)) { +- log_error("Site \"%s\" not configured.", cl.site); +- rv = -ENOENT; +- goto out_close; +- } +- } +- + if (site->type == ARBITRATOR) { + if (site == local) { + log_error("We're just an arbitrator, cannot grant/revoke tickets here."); +@@ -1296,7 +1287,7 @@ static int do_status(int type) + + ret = PCMK_OCF_NOT_RUNNING; + +- rv = setup_config(type); ++ rv = setup_config(type, NULL); + if (rv) { + reason = "Error reading configuration."; + ret = PCMK_OCF_UNKNOWN_ERROR; +@@ -1412,7 +1403,7 @@ static int do_server(int type) + int rv = -1; + static char log_ent[128] = DAEMON_NAME "-"; + +- rv = setup_config(type); ++ rv = setup_config(type, NULL); + if (rv < 0) + return rv; + +@@ -1478,8 +1469,9 @@ static int do_server(int type) + static int do_client(void) + { + int rv; ++ struct booth_site *site; + +- rv = setup_config(CLIENT); ++ rv = setup_config(CLIENT, &site); + if (rv < 0) { + log_error("cannot read config"); + goto out; +@@ -1488,12 +1480,12 @@ static int do_client(void) + switch (cl.op) { + case CMD_LIST: + case CMD_PEERS: +- rv = query_get_string_answer(cl.op); ++ rv = query_get_string_answer(cl.op, site); + break; + + case CMD_GRANT: + case CMD_REVOKE: +- rv = do_command(cl.op); ++ rv = do_command(cl.op, site); + break; + } + +@@ -1504,8 +1496,9 @@ out: + static int do_attr(void) + { + int rv = -1; ++ struct booth_site *site; + +- rv = setup_config(GEOSTORE); ++ rv = setup_config(GEOSTORE, &site); + if (rv < 0) { + log_error("cannot read config"); + goto out; +@@ -1529,12 +1522,12 @@ static int do_attr(void) + switch (cl.op) { + case ATTR_LIST: + case ATTR_GET: +- rv = query_get_string_answer(cl.op); ++ rv = query_get_string_answer(cl.op, site); + break; + + case ATTR_SET: + case ATTR_DEL: +- rv = do_attr_command(cl.op); ++ rv = do_attr_command(cl.op, site); + break; + } + +-- +2.4.11 + diff --git a/SOURCES/ef62b8cc3f0808e7e75fb608d096369e24135aa1.patch b/SOURCES/ef62b8cc3f0808e7e75fb608d096369e24135aa1.patch new file mode 100644 index 0000000..fb3df59 --- /dev/null +++ b/SOURCES/ef62b8cc3f0808e7e75fb608d096369e24135aa1.patch @@ -0,0 +1,20 @@ +From ef62b8cc3f0808e7e75fb608d096369e24135aa1 Mon Sep 17 00:00:00 2001 +From: Kazunori INOUE +Date: Mon, 2 Apr 2018 13:12:33 +0900 +Subject: [PATCH] Low: conf: Add Restart option to booth-arbitrator.service + +--- + conf/booth-arbitrator.service.in | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/conf/booth-arbitrator.service.in b/conf/booth-arbitrator.service.in +index a7a59a9..7050ae2 100644 +--- a/conf/booth-arbitrator.service.in ++++ b/conf/booth-arbitrator.service.in +@@ -14,3 +14,6 @@ WantedBy=multi-user.target + Type=simple + @NOTIFY_ACCESS_SWITCH@NotifyAccess=main + ExecStart=/usr/sbin/boothd daemon -S -c /etc/booth/booth.conf ++ ++# Restart options include: no, on-success, on-failure, on-abnormal, on-watchdog, on-abort, or always ++Restart=on-failure diff --git a/SPECS/booth.spec b/SPECS/booth.spec new file mode 100644 index 0000000..4553c74 --- /dev/null +++ b/SPECS/booth.spec @@ -0,0 +1,334 @@ +# 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 8 +%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 ef769ef9614e8446f597ee4d26d5d339a491ab2f +%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-test-README-testing-indent-configuration-literal-par.patch +Patch1: 0002-test-README-testing-provide-pcs-configuration-altern.patch +Patch2: 0003-test-live_test-use-a-defined-literal-uniformly.patch +Patch3: 0004-test-live_test-offer-alternatives-to-crm-pcs-native.patch +Patch4: bz1341720-zealous-local-address-matching.patch +Patch5: bz1366616-local_site_resolved_prevents_segfault.patch +Patch6: https://github.com/ClusterLabs/booth/commit/ef62b8cc3f0808e7e75fb608d096369e24135aa1.patch + +# imposed by the same statement in pacemaker.spec +%if 0%{?rhel} > 0 +ExclusiveArch: i686 x86_64 aarch64 ppc64le s390x + +%endif + +# 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} = %{version}-%{release} +Requires: %{name}-site = %{version}-%{release} +%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 +# fix issue with acutely broken .gitignore preventing later patch application +# (see first commit of https://github.com/ClusterLabs/booth/pull/70) +%global __scm_setup_git(q)\ +rm -f .gitignore; %{expand:%__scm_setup_git %{-q}} +%autosetup -n %{name}-%{commit} -S git_am -p1 + +%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}/conf +cp -a -t %{buildroot}/%{test_path} \ + -- test unit-tests script/unit-test.py +cp -a -t %{buildroot}/%{test_path}/conf \ + -- conf/booth.conf.example +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 +* Tue Jun 26 2018 Jan Pokorný - 1.0-8.ef769ef.git +- build for aarch64 + Resolves: rhbz#1422615 +- fix unconditional "dist" RPM macro reference in Release field + Resolves: rhbz#1465933 +- ensure booth-arbitrator service will get restarted when it fails + +* Mon Mar 27 2017 Jan Pokorný - 1.0-7.ef769ef.git +- build for ppc64le + Resolves: rhbz#1402563 + +* Thu Sep 15 2016 Jan Pokorný - 1.0-6.ef769ef.git +- fix an issue with identity self-determination based on match + between the addresses assigned at host and the configured addresses + when a network-part-of-the-address-only match preceded a possible + exact address match which would not be even tested if the length + of the network prefix was the same (no longer for this exact one) + Resolves: rhbz#1341720 +- fix a crash when running booth without determined identity + (e.g., existing, yet empty configuration) under some circumstances + Resolves: rhbz#1366616 +- make patches be applied using "git am" rather than "git apply" + +* Wed Jun 22 2016 Jan Pokorný - 1.0-5.77d65dd.git +- update per the the current upstream, most notably the support for + cluster-glue alternatives has been accepted (separate patches no + longer needed) +- make the main (envelope) package properly require the subpackages + of the same version +- add patches allowing for live_test.sh using pcs +- allow building also against s390x architecture + (per Pacemaker dependency constraint) + Resolves: rhbz#1302087 + +* Wed May 25 2016 Jan Pokorný - 1.0-3.570876d.git +- update per the changesets recently accepted by the upstream + (memory/resource leaks fixes, patches previously attached separately + that make unit test pass, internal cleanups, etc.) + Resolves: rhbz#1302087 + +* Mon May 09 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#1302087 + Related (Fedora): rhbz#1314865 + Related (Fedora): rhbz#1333509 + +* Thu Apr 28 2016 Jan Pokorný - 1.0-1.eb4256a.git +- initial build