Compare commits

..

No commits in common. "imports/c8-beta/booth-1.0-5.f2d38ce.git.el8" and "c8" have entirely different histories.

18 changed files with 334 additions and 1795 deletions

View File

@ -1 +0,0 @@
1c6b69921dc435310094b53f4555d60c95889a19 SOURCES/booth-f2d38ce.tar.gz

2
.gitignore vendored
View File

@ -1 +1 @@
SOURCES/booth-f2d38ce.tar.gz
SOURCES/booth-1.1.tar.gz

View File

@ -1,158 +0,0 @@
From 9469ffc2d58a5673fffae8778b9c48f5605dda6a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Pokorn=C3=BD?= <jpokorny@redhat.com>
Date: Tue, 10 Jul 2018 18:41:18 +0200
Subject: [PATCH] test: remove superfluous shebangs for import-only modules
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Consequently, there's no reason to have the affected files marked as
executable.
Signed-off-by: Jan Pokorný <jpokorny@redhat.com>
---
test/arbtests.py | 2 --
test/assertions.py | 2 --
test/boothrunner.py | 2 --
test/boothtestenv.py | 2 --
test/clientenv.py | 2 --
test/clienttests.py | 2 --
test/serverenv.py | 2 --
test/servertests.py | 2 --
test/sitetests.py | 2 --
test/utils.py | 2 --
10 files changed, 20 deletions(-)
mode change 100755 => 100644 test/arbtests.py
mode change 100755 => 100644 test/assertions.py
mode change 100755 => 100644 test/boothrunner.py
mode change 100755 => 100644 test/boothtestenv.py
mode change 100755 => 100644 test/clientenv.py
mode change 100755 => 100644 test/clienttests.py
mode change 100755 => 100644 test/serverenv.py
mode change 100755 => 100644 test/servertests.py
mode change 100755 => 100644 test/sitetests.py
mode change 100755 => 100644 test/utils.py
diff --git a/test/arbtests.py b/test/arbtests.py
old mode 100755
new mode 100644
index caba010..ef7b7f9
--- a/test/arbtests.py
+++ b/test/arbtests.py
@@ -1,5 +1,3 @@
-#!/usr/bin/python
-
from servertests import ServerTests
class ArbitratorConfigTests(ServerTests):
diff --git a/test/assertions.py b/test/assertions.py
old mode 100755
new mode 100644
index 4396ab7..0b7f995
--- a/test/assertions.py
+++ b/test/assertions.py
@@ -1,5 +1,3 @@
-#!/usr/bin/python
-
import re
class BoothAssertions:
diff --git a/test/boothrunner.py b/test/boothrunner.py
old mode 100755
new mode 100644
index f9154e7..d981183
--- a/test/boothrunner.py
+++ b/test/boothrunner.py
@@ -1,5 +1,3 @@
-#!/usr/bin/python
-
import os
import subprocess
import time
diff --git a/test/boothtestenv.py b/test/boothtestenv.py
old mode 100755
new mode 100644
index 89a484a..fcd0c4d
--- a/test/boothtestenv.py
+++ b/test/boothtestenv.py
@@ -1,5 +1,3 @@
-#!/usr/bin/python
-
import os
import subprocess
import time
diff --git a/test/clientenv.py b/test/clientenv.py
old mode 100755
new mode 100644
index fcd40fa..73b2791
--- a/test/clientenv.py
+++ b/test/clientenv.py
@@ -1,5 +1,3 @@
-#!/usr/bin/python
-
from boothtestenv import BoothTestEnvironment
from boothrunner import BoothRunner
diff --git a/test/clienttests.py b/test/clienttests.py
old mode 100755
new mode 100644
index 61b691b..c4b9d8a
--- a/test/clienttests.py
+++ b/test/clienttests.py
@@ -1,5 +1,3 @@
-#!/usr/bin/python
-
import string
from clientenv import ClientTestEnvironment
diff --git a/test/serverenv.py b/test/serverenv.py
old mode 100755
new mode 100644
index d0467b9..c6d4e30
--- a/test/serverenv.py
+++ b/test/serverenv.py
@@ -1,5 +1,3 @@
-#!/usr/bin/python
-
import os
import re
import time
diff --git a/test/servertests.py b/test/servertests.py
old mode 100755
new mode 100644
index f574f26..39a6ffc
--- a/test/servertests.py
+++ b/test/servertests.py
@@ -1,5 +1,3 @@
-#!/usr/bin/python
-
import copy
from pprint import pprint, pformat
import re
diff --git a/test/sitetests.py b/test/sitetests.py
old mode 100755
new mode 100644
index dfdf6b9..6944ffe
--- a/test/sitetests.py
+++ b/test/sitetests.py
@@ -1,5 +1,3 @@
-#!/usr/bin/python
-
from servertests import ServerTests
class SiteConfigTests(ServerTests):
diff --git a/test/utils.py b/test/utils.py
old mode 100755
new mode 100644
index ceeef98..5b70cfc
--- a/test/utils.py
+++ b/test/utils.py
@@ -1,5 +1,3 @@
-#!/usr/bin/python
-
import subprocess
import re
--
2.18.0.rc2

View File

@ -1,60 +0,0 @@
From a642a833e31a6bd1e71dc2045a16e494775b35e6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Pokorn=C3=BD?= <jpokorny@redhat.com>
Date: Thu, 12 Jul 2018 18:58:32 +0200
Subject: [PATCH] test: do not mix tabs with spaces in Python code
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Beside being matter of a good style, it's also forbidden inside
a single, non-delimited block in Python 3.
Signed-off-by: Jan Pokorný <jpokorny@redhat.com>
---
test/servertests.py | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/test/servertests.py b/test/servertests.py
index 39a6ffc..71e808e 100644
--- a/test/servertests.py
+++ b/test/servertests.py
@@ -51,8 +51,8 @@ class ServerTests(ServerTestEnvironment):
config_text=self.working_config)
def test_missing_quotes(self):
- # quotes no longer required
- return True
+ # quotes no longer required
+ return True
orig_lines = self.working_config.split("\n")
for i in xrange(len(orig_lines)):
new_lines = copy.copy(orig_lines)
@@ -97,8 +97,8 @@ class ServerTests(ServerTestEnvironment):
expected_exitcode=None, expected_daemon=True)
def test_missing_transport(self):
- # UDP is default -- TODO?
- return True
+ # UDP is default -- TODO?
+ return True
config = re.sub('transport=.+\n', '', self.typical_config)
(pid, ret, stdout, stderr, runner) = \
self.run_booth(config_text=config, expected_exitcode=1, expected_daemon=False)
@@ -141,10 +141,10 @@ class ServerTests(ServerTestEnvironment):
self.assertRegexpMatches(stderr, 'ticket name "' + ticket + '" invalid')
def test_unreachable_peer(self):
- # what should this test do? daemon not expected, but no exitcode either?
- # booth would now just run, and try to reach that peer...
- # TCP reachability is not required during startup anymore.
- return True
+ # what should this test do? daemon not expected, but no exitcode either?
+ # booth would now just run, and try to reach that peer...
+ # TCP reachability is not required during startup anymore.
+ return True
config = re.sub('#(.+147.+)', lambda m: m.group(1), self.working_config)
self.run_booth(config_text=config,
expected_exitcode=None, expected_daemon=False)
--
2.18.0.rc2

View File

@ -1,510 +0,0 @@
From ab2229451827f530959d554920619d87daa34586 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Pokorn=C3=BD?= <jpokorny@redhat.com>
Date: Wed, 11 Jul 2018 16:18:25 +0200
Subject: [PATCH] test: make Python files supported _also_ with Python 3.3+
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- use "print" like a function rather than a statement
. where implicit newline is to be suppressed, don't do that
and rather strip it from the string to be printed instead
- use 2+3 compatible convention for parametrizing exceptions
- Python 3 doesn't recognize "basestring" class, and at the place
of use (pre Python 2.7 only), unicode string is really not expected
(also re.UNICODE flag is not used...)
- Python 3 doesn't recognize "xrange" function, but the surrounding
code can be reasonably simplified using "enumerate" function
- arrange dict treatment in a compatible way:
. d.has_key(k) -> k in d
. d.iteritems() -> custom "iter_items", always efficient wrapper
. d.iterkeys(), here incl. lazy mapping and filtering
-> rewrite while retaining laziness
. optimize UT.merge_dicts in script/unit-test.py along
- also in three instances, deal with string/uninterpreted bytes proper
dichotomy introduced in Python 3, and related to that, "string"
module only supports "ascii_lowercase" attribute in Python 3
(as opposed to system-specific plain "lowercase" one)
Note that script/unit-test.py has a pre-existing issue (regardless
of which Python version interpreter is used), so at least document
that in the header for now.
Signed-off-by: Jan Pokorný <jpokorny@redhat.com>
---
script/unit-test.py | 65 ++++++++++++++++++++++++++------------------
test/assertions.py | 4 +--
test/boothrunner.py | 32 ++++++++++++----------
test/boothtestenv.py | 6 ++--
test/clienttests.py | 4 +--
test/runtests.py | 2 +-
test/serverenv.py | 18 ++++++------
test/servertests.py | 10 +++----
test/utils.py | 10 +++++--
9 files changed, 84 insertions(+), 67 deletions(-)
diff --git a/script/unit-test.py b/script/unit-test.py
index 6871930..399528e 100755
--- a/script/unit-test.py
+++ b/script/unit-test.py
@@ -1,6 +1,8 @@
#!/usr/bin/python
# vim: fileencoding=utf-8
# see http://stackoverflow.com/questions/728891/correct-way-to-define-python-source-code-encoding
+# NOTE: setting the encoding is needed as non-ASCII characters are contained
+# FIXME: apparently, pexpect.EOF is not being excepted properly
import os, sys, time, signal, tempfile, socket, posix, time
import re, shutil, pexpect, logging, pprint
@@ -16,6 +18,16 @@ default_log_format = '%(asctime)s: : %(message)s'
default_log_datefmt = '%b %d %H:%M:%S'
+# Compatibility with dictionary methods not present in Python 3;
+# https://www.python.org/dev/peps/pep-0469/#migrating-to-the-common-subset-of-python-2-and-3
+try:
+ dict.iteritems
+except AttributeError: # Python 3
+ iter_items = lambda d: iter(d.items())
+else: # Python 2
+ iter_items = lambda d: d.iteritems()
+
+
# {{{ pexpect-logging glue
# needed for use as pexpect.logfile, to relay into existing logfiles
class expect_logging():
@@ -28,9 +40,12 @@ class expect_logging():
def flush(self, *arg):
pass
+
def write(self, stg):
if self.test.dont_log_expect == 0:
# TODO: split by input/output, give program
+ if sys.version_info[0] >= 3:
+ stg = str(stg, 'UTF-8')
for line in re.split(r"[\r\n]+", stg):
if line == self.test.prompt:
continue
@@ -110,7 +125,7 @@ class UT():
res = re.match(r"^\s*(\w+)\s*:(?:\s*(#.*?\S))?\s*$", line)
if res:
state = res.group(1)
- if not m.has_key(state):
+ if state not in m:
m[state] = dict_plus()
if res.group(2):
m[state].aux["comment"] = res.group(2)
@@ -188,17 +203,15 @@ class UT():
name = re.sub(r".*/", "", bin)
# How to get stderr, too?
expct = pexpect.spawn(bin,
- env = dict( os.environ.items() +
- [('PATH',
- self.test_base + "/bin/:" +
- os.getenv('PATH')),
- ('UNIT_TEST_PATH', self.test_base),
- ('LC_ALL', 'C'),
- ('LANG', 'C')] +
- env_add ),
- timeout = 30,
- maxread = 32768,
- **args)
+ env=dict(os.environ, **dict({
+ 'PATH': ':'.join((self.test_base + "/bin/",
+ os.getenv('PATH'))),
+ 'UNIT_TEST_PATH': self.test_base,
+ 'LC_ALL': 'C',
+ 'LANG': 'C'}, **dict(env_add))),
+ timeout=30,
+ maxread=32768,
+ **args)
expct.setecho(False)
expct.logfile_read = expect_logging("<- %s" % name, self)
expct.logfile_send = expect_logging(" -> %s" % name, self)
@@ -361,7 +374,7 @@ class UT():
self.current_nr = kv.aux.get("line")
#os.system("strace -f -tt -s 2000 -e write -p" + str(self.gdb.pid) + " &")
- for n, v in kv.iteritems():
+ for n, v in iter_items(kv):
self.set_val( self.translate_shorthand(n, "ticket"), v)
logging.info("set state")
@@ -372,7 +385,7 @@ class UT():
if not sys.stdin.isatty():
logging.error("Not a terminal, stopping.")
else:
- print "\n\nEntering interactive mode.\n\n"
+ print("\n\nEntering interactive mode.\n\n")
self.gdb.sendline("set prompt GDB> \n")
self.gdb.setecho(True)
# can't use send_cmd, doesn't reply with expected prompt anymore.
@@ -415,7 +428,7 @@ class UT():
self.send_cmd("next")
# push message.
- for (n, v) in msg.iteritems():
+ for (n, v) in iter_items(msg):
self.set_val( self.translate_shorthand(n, "message"), v, "htonl")
# set "received" length
@@ -426,7 +439,7 @@ class UT():
def wait_outgoing(self, msg):
self.wait_for_function("booth_udp_send")
ok = True
- for (n, v) in msg.iteritems():
+ for (n, v) in iter_items(msg):
if re.search(r"\.", n):
ok = self.check_value( self.translate_shorthand(n, "inject"), v) and ok
else:
@@ -438,14 +451,12 @@ class UT():
#stopped_at = self.sync()
def merge_dicts(self, base, overlay):
- return dict(base.items() + overlay.items())
+ return dict(base, **overlay)
def loop(self, fn, data):
- matches = map(lambda k: re.match(r"^(outgoing|message)(\d+)$", k), data.iterkeys())
- valid_matches = filter(None, matches)
- nums = map(lambda m: int(m.group(2)), valid_matches)
- loop_max = max(nums)
+ matches = (re.match(r"^(outgoing|message)(\d+)$", k) for k in data)
+ loop_max = max(int(m.group(2)) for m in matches if m)
for counter in range(0, loop_max+1): # incl. last message
kmsg = 'message%d' % counter
@@ -471,14 +482,14 @@ class UT():
logging.info("ticket change %s (%s:%d) %s" % (ktkt, fn, self.current_nr, comment))
self.set_state(tkt)
if gdb:
- for (k, v) in gdb.iteritems():
+ for (k, v) in iter_items(gdb):
self.send_cmd(k + " " + v.replace("§", "\n"))
if msg:
self.current_nr = msg.aux.get("line")
comment = msg.aux.get("comment", "")
logging.info("sending %s (%s:%d) %s" % (kmsg, fn, self.current_nr, comment))
self.send_message(self.merge_dicts(data["message"], msg))
- if data.has_key(kgdb) and len(gdb) == 0:
+ if kgdb in data and len(gdb) == 0:
self.user_debug("manual override")
if out:
self.current_nr = out.aux.get("line")
@@ -520,7 +531,7 @@ class UT():
self.let_booth_go_a_bit()
ok = True
- for (n, v) in data.iteritems():
+ for (n, v) in iter_items(data):
ok = self.check_value( self.translate_shorthand(n, "ticket"), v) and ok
if not ok:
sys.exit(1)
@@ -529,8 +540,8 @@ class UT():
def run(self, start_from="000", end_with="999"):
os.chdir(self.test_base)
# TODO: sorted, random order
- tests = filter( (lambda f: re.match(r"^\d\d\d_.*\.txt$", f)), glob.glob("*"))
- tests.sort()
+ tests = sorted(f for f in glob.glob("*")
+ if re.match(r"^\d\d\d_.*\.txt$", f))
failed = 0
for f in tests:
if f[0:3] < start_from:
@@ -561,7 +572,7 @@ class UT():
except:
failed += 1
logging.error(self.colored_string("Broke in %s:%s %s" % (f, self.current_nr, sys.exc_info()), self.RED))
- for frame in traceback.format_tb(sys.exc_traceback):
+ for frame in traceback.format_tb(sys.exc_info()[2]):
logging.info(" - %s " % frame.rstrip())
finally:
self.stop_processes()
diff --git a/test/assertions.py b/test/assertions.py
index 0b7f995..34333ca 100644
--- a/test/assertions.py
+++ b/test/assertions.py
@@ -21,7 +21,7 @@ class BoothAssertions:
# backported from 2.7 just in case we're running on an older Python
def assertRegexpMatches(self, text, expected_regexp, msg=None):
"""Fail the test unless the text matches the regular expression."""
- if isinstance(expected_regexp, basestring):
+ if isinstance(expected_regexp, str):
expected_regexp = re.compile(expected_regexp)
if not expected_regexp.search(text, MULTILINE):
msg = msg or "Regexp didn't match"
@@ -30,7 +30,7 @@ class BoothAssertions:
def assertNotRegexpMatches(self, text, unexpected_regexp, msg=None):
"""Fail the test if the text matches the regular expression."""
- if isinstance(unexpected_regexp, basestring):
+ if isinstance(unexpected_regexp, str):
unexpected_regexp = re.compile(unexpected_regexp)
match = unexpected_regexp.search(text)
if match:
diff --git a/test/boothrunner.py b/test/boothrunner.py
index d981183..347912b 100644
--- a/test/boothrunner.py
+++ b/test/boothrunner.py
@@ -1,4 +1,5 @@
import os
+import sys
import subprocess
import time
import unittest
@@ -37,14 +38,14 @@ class BoothRunner:
def show_output(self, stdout, stderr):
if stdout:
- print "STDOUT:"
- print "------"
- print stdout,
+ print("STDOUT:")
+ print("------")
+ print(stdout.rstrip('\n'))
if stderr:
- print "STDERR: (N.B. crm_ticket failures indicate daemon started correctly)"
- print "------"
- print stderr,
- print "-" * 70
+ print("STDERR: (N.B. crm_ticket failures indicate daemon started correctly)")
+ print("------")
+ print(stderr.rstrip('\n'))
+ print("-" * 70)
def subproc_completed_within(self, p, timeout):
start = time.time()
@@ -55,7 +56,7 @@ class BoothRunner:
elapsed = time.time() - start
if elapsed + wait > timeout:
wait = timeout - elapsed
- print "Waiting on %d for %.1fs ..." % (p.pid, wait)
+ print("Waiting on %d for %.1fs ..." % (p.pid, wait))
time.sleep(wait)
elapsed = time.time() - start
if elapsed >= timeout:
@@ -83,26 +84,29 @@ class BoothRunner:
return text
def show_args(self):
- print "\n"
- print "-" * 70
- print "Running", ' '.join(self.all_args())
+ print("\n")
+ print("-" * 70)
+ print("Running", ' '.join(self.all_args()))
msg = "with config from %s" % self.config_file_used()
config_text = self.config_text_used()
if config_text is not None:
msg += ": [%s]" % config_text
- print msg
+ print(msg)
def run(self):
p = subprocess.Popen(self.all_args(), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
if not p:
- raise RuntimeError, "failed to start subprocess"
+ raise RuntimeError("failed to start subprocess")
- print "Started subprocess pid %d" % p.pid
+ print("Started subprocess pid %d" % p.pid)
completed = self.subproc_completed_within(p, 2)
if completed:
(stdout, stderr) = p.communicate()
+ if sys.version_info[0] >= 3:
+ # only expect ASCII/UTF-8 encodings for the obtained input bytes
+ stdout, stderr = str(stdout, 'UTF-8'), str(stderr, 'UTF-8')
self.show_output(stdout, stderr)
return (p.pid, p.returncode, stdout, stderr)
diff --git a/test/boothtestenv.py b/test/boothtestenv.py
index fcd0c4d..59e25c3 100644
--- a/test/boothtestenv.py
+++ b/test/boothtestenv.py
@@ -17,7 +17,7 @@ class BoothTestEnvironment(unittest.TestCase, BoothAssertions):
def setUp(self):
if not self._testMethodName.startswith('test_'):
- raise RuntimeError, "unexpected test method name: " + self._testMethodName
+ raise RuntimeError("unexpected test method name: " + self._testMethodName)
self.test_name = self._testMethodName[5:]
self.test_path = os.path.join(self.test_run_path, self.test_name)
os.makedirs(self.test_path)
@@ -54,11 +54,11 @@ class BoothTestEnvironment(unittest.TestCase, BoothAssertions):
def check_return_code(self, pid, return_code, expected_exitcode):
if return_code is None:
- print "pid %d still running" % pid
+ print("pid %d still running" % pid)
if expected_exitcode is not None:
self.fail("expected exit code %d, not long-running process" % expected_exitcode)
else:
- print "pid %d exited with code %d" % (pid, return_code)
+ print("pid %d exited with code %d" % (pid, return_code))
if expected_exitcode is None:
msg = "should not exit"
else:
diff --git a/test/clienttests.py b/test/clienttests.py
index c4b9d8a..512620e 100644
--- a/test/clienttests.py
+++ b/test/clienttests.py
@@ -7,14 +7,14 @@ class ClientConfigTests(ClientTestEnvironment):
def test_site_buffer_overflow(self):
# https://bugzilla.novell.com/show_bug.cgi?id=750256
- longfile = (string.lowercase * 3)[:63]
+ longfile = (string.ascii_lowercase * 3)[:63]
expected_error = "'%s' exceeds maximum site name length" % longfile
args = [ 'grant', '-s', longfile, '-t', 'ticket' ]
self._test_buffer_overflow(expected_error, args=args)
def test_ticket_buffer_overflow(self):
# https://bugzilla.novell.com/show_bug.cgi?id=750256
- longfile = (string.lowercase * 3)[:63]
+ longfile = (string.ascii_lowercase * 3)[:63]
expected_error = "'%s' exceeds maximum ticket name length" % longfile
args = [ 'grant', '-s', 'site', '-t', longfile ]
self._test_buffer_overflow(expected_error, args=args)
diff --git a/test/runtests.py b/test/runtests.py
index 0532c01..833b1a7 100755
--- a/test/runtests.py
+++ b/test/runtests.py
@@ -53,5 +53,5 @@ if __name__ == '__main__':
shutil.rmtree(test_run_path)
sys.exit(0)
else:
- print "Left %s for debugging" % test_run_path
+ print("Left %s for debugging" % test_run_path)
sys.exit(1)
diff --git a/test/serverenv.py b/test/serverenv.py
index c6d4e30..5d6c6c4 100644
--- a/test/serverenv.py
+++ b/test/serverenv.py
@@ -73,12 +73,10 @@ ticket="ticketB"
where return_code/stdout/stderr are None iff pid is still running.
'''
if expected_daemon and expected_exitcode is not None and expected_exitcode != 0:
- raise RuntimeError, \
- "Shouldn't ever expect daemon to start and then failure"
+ raise RuntimeError("Shouldn't ever expect daemon to start and then failure")
if not expected_daemon and expected_exitcode == 0:
- raise RuntimeError, \
- "Shouldn't ever expect success without starting daemon"
+ raise RuntimeError("Shouldn't ever expect success without starting daemon")
self.init_log()
@@ -122,9 +120,9 @@ ticket="ticketB"
return config_file
def kill_pid(self, pid):
- print "killing %d ..." % pid
+ print("killing %d ..." % pid)
os.kill(pid, 15)
- print "killed"
+ print("killed")
def check_daemon_handling(self, runner, expected_daemon):
'''
@@ -154,7 +152,7 @@ ticket="ticketB"
Returns the pid contained in lock_file, or None if it doesn't exist.
'''
if not os.path.exists(lock_file):
- print "%s does not exist" % lock_file
+ print("%s does not exist" % lock_file)
return None
l = open(lock_file)
@@ -162,7 +160,7 @@ ticket="ticketB"
l.close()
self.assertEqual(len(lines), 1, "Lock file should contain one line")
pid = re.search('\\bbooth_pid="?(\\d+)"?', lines[0]).group(1)
- print "lockfile contains: <%s>" % pid
+ print("lockfile contains: <%s>" % pid)
return pid
def is_pid_running_daemon(self, pid):
@@ -185,11 +183,11 @@ ticket="ticketB"
c = open("/proc/%s/cmdline" % pid)
cmdline = "".join(c.readlines())
- print cmdline
+ print(cmdline)
c.close()
if cmdline.find('boothd') == -1:
- print 'no boothd in cmdline:', cmdline
+ print('no boothd in cmdline:', cmdline)
return False
# self.assertRegexpMatches(
diff --git a/test/servertests.py b/test/servertests.py
index 71e808e..288d19f 100644
--- a/test/servertests.py
+++ b/test/servertests.py
@@ -35,13 +35,13 @@ class ServerTests(ServerTestEnvironment):
def test_config_file_buffer_overflow(self):
# https://bugzilla.novell.com/show_bug.cgi?id=750256
- longfile = (string.lowercase * 5)[:127]
+ longfile = (string.ascii_lowercase * 5)[:127]
expected_error = "'%s' exceeds maximum config name length" % longfile
self._test_buffer_overflow(expected_error, config_file=longfile)
def test_lock_file_buffer_overflow(self):
# https://bugzilla.novell.com/show_bug.cgi?id=750256
- longfile = (string.lowercase * 5)[:127]
+ longfile = (string.ascii_lowercase * 5)[:127]
expected_error = "'%s' exceeds maximum lock file length" % longfile
self._test_buffer_overflow(expected_error, lock_file=longfile)
@@ -54,12 +54,12 @@ class ServerTests(ServerTestEnvironment):
# quotes no longer required
return True
orig_lines = self.working_config.split("\n")
- for i in xrange(len(orig_lines)):
+ for (i, line) in enumerate(orig_lines):
new_lines = copy.copy(orig_lines)
- new_lines[i] = new_lines[i].replace('"', '')
+ new_lines[i] = line.replace('"', '')
new_config = "\n".join(new_lines)
- line_contains_IP = re.search('^\s*(site|arbitrator)=.*[0-9]\.', orig_lines[i])
+ line_contains_IP = re.search('^\s*(site|arbitrator)=.*[0-9]\.', line)
if line_contains_IP:
# IP addresses need to be surrounded by quotes,
# so stripping them should cause it to fail
diff --git a/test/utils.py b/test/utils.py
index 5b70cfc..aca3592 100644
--- a/test/utils.py
+++ b/test/utils.py
@@ -1,5 +1,6 @@
import subprocess
import re
+import sys
def run_cmd(cmd):
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
@@ -9,8 +10,11 @@ def run_cmd(cmd):
def get_IP():
(stdout, stderr, returncode) = run_cmd(['hostname', '-i'])
if returncode != 0:
- raise RuntimeError, "Failed to run hostname -i:\n" + stderr
+ raise RuntimeError("Failed to run hostname -i:\n" + stderr)
# in case multiple IP addresses are returned, use only the first
- # and also strip '%<device>' part possibly present with IPv6 address
- ret = re.sub(r'\s.*', '', stdout)
+ # and also strip '%<device>' part possibly present with IPv6 address;
+ # in Python 3 context, only expect ASCII/UTF-8 encodings for the
+ # obtained input bytes
+ ret = re.sub(r'\s.*', '',
+ stdout if sys.version_info[0] < 3 else str(stdout, 'UTF-8'))
return "::1" if '%' in ret else ret
--
2.18.0.rc2

View File

@ -1,89 +0,0 @@
From 31133e8ac07c08b607ee7799c0074c1dce37a952 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Pokorn=C3=BD?= <jpokorny@redhat.com>
Date: Wed, 11 Jul 2018 14:18:50 +0200
Subject: [PATCH] build: parametrize Python invocations in the shebangs
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Consequently, there's no reason to have the affected files marked as
executable (processing the files by the means of AC_CONFIG_FILES will
get rid of any such permission bits, anyway), but at the very least,
test/runtests.py needs to be set executable afterwards so as no to
cause failures with the current "make check" arrangement that invokes
TESTS subtargets directly (i.e. no extension-based LOG_COMPILER set).
Signed-off-by: Jan Pokorný <jpokorny@redhat.com>
---
configure.ac | 12 +++++++++++-
script/{unit-test.py => unit-test.py.in} | 2 +-
test/{runtests.py => runtests.py.in} | 2 +-
3 files changed, 13 insertions(+), 3 deletions(-)
rename script/{unit-test.py => unit-test.py.in} (99%)
mode change 100755 => 100644
rename test/{runtests.py => runtests.py.in} (98%)
mode change 100755 => 100644
diff --git a/configure.ac b/configure.ac
index 3bf41b3..a6ad86e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -97,6 +97,14 @@ CPPFLAGS="$CPPFLAGS $XML2HEAD"
PKG_CHECK_MODULES(GLIB, [glib-2.0])
+# Python casing, prefer 3.3+ to 2.{6...}
+AM_PATH_PYTHON([3.3], , [PYTHON=:])
+if test "x$PYTHON" = x:; then
+ AM_PATH_PYTHON([2.6])
+fi
+PYTHON_SHEBANG="$PYTHON ${PYTHON_OPTS--Es}"
+AC_ARG_VAR([PYTHON_SHEBANG], [Python invocation used in shebangs])
+
# Checks for header files.
AC_FUNC_ALLOCA
AC_HEADER_DIRENT
@@ -157,7 +165,9 @@ AC_CONFIG_FILES([Makefile
docs/Makefile
conf/Makefile])
AC_CONFIG_FILES([conf/booth-arbitrator.service conf/booth@.service])
-
+AC_CONFIG_FILES([script/unit-test.py test/runtests.py],
+ dnl Following required at least for "make check"
+ [chmod +x test/runtests.py])
AC_CONFIG_FILES([script/service-runnable], [chmod +x script/service-runnable])
# ===============================================
diff --git a/script/unit-test.py b/script/unit-test.py.in
old mode 100755
new mode 100644
similarity index 99%
rename from script/unit-test.py
rename to script/unit-test.py.in
index 399528e..4f3cf62
--- a/script/unit-test.py
+++ b/script/unit-test.py.in
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!@PYTHON_SHEBANG@
# vim: fileencoding=utf-8
# see http://stackoverflow.com/questions/728891/correct-way-to-define-python-source-code-encoding
# NOTE: setting the encoding is needed as non-ASCII characters are contained
diff --git a/test/runtests.py b/test/runtests.py.in
old mode 100755
new mode 100644
similarity index 98%
rename from test/runtests.py
rename to test/runtests.py.in
index 833b1a7..ec59159
--- a/test/runtests.py
+++ b/test/runtests.py.in
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!@PYTHON_SHEBANG@
import os
import re
--
2.18.0.rc2

View File

@ -1,36 +0,0 @@
From 541e6184fca60a01ff7e8c1bba794c083ac4245f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Pokorn=C3=BD?= <jpokorny@redhat.com>
Date: Tue, 10 Jul 2018 19:25:34 +0200
Subject: [PATCH] test: drop underqualified identifier in unittest's 2.6 compat
"polyfill"
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Specifically, in supplemented unittest.TestCase.assertRegexpMatches
method. In Python 2.7's implementation, there's no re.MULTILINE
modifier at that very place, either.
Not sure what the original purpose of introducing that with c1c47f5 was.
Signed-off-by: Jan Pokorný <jpokorny@redhat.com>
---
test/assertions.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/test/assertions.py b/test/assertions.py
index 34333ca..fafb291 100644
--- a/test/assertions.py
+++ b/test/assertions.py
@@ -23,7 +23,7 @@ class BoothAssertions:
"""Fail the test unless the text matches the regular expression."""
if isinstance(expected_regexp, str):
expected_regexp = re.compile(expected_regexp)
- if not expected_regexp.search(text, MULTILINE):
+ if not expected_regexp.search(text):
msg = msg or "Regexp didn't match"
msg = '%s: %r not found in %r' % (msg, expected_regexp.pattern, text)
raise self.failureException(msg)
--
2.18.0.rc2

View File

@ -1,90 +0,0 @@
From 6a6834a8110d9e6aff50cd6d6935976af4cbdb8f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Pokorn=C3=BD?= <jpokorny@redhat.com>
Date: Thu, 12 Jul 2018 20:18:07 +0200
Subject: [PATCH] test: drop/comment out superfluous imports
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Jan Pokorný <jpokorny@redhat.com>
---
test/boothrunner.py | 2 --
test/boothtestenv.py | 1 -
test/runtests.py.in | 3 +--
test/serverenv.py | 2 --
test/servertests.py | 1 -
5 files changed, 1 insertion(+), 8 deletions(-)
diff --git a/test/boothrunner.py b/test/boothrunner.py
index 347912b..31c2213 100644
--- a/test/boothrunner.py
+++ b/test/boothrunner.py
@@ -1,8 +1,6 @@
-import os
import sys
import subprocess
import time
-import unittest
class BoothRunner:
default_config_file = '/etc/booth/booth.conf'
diff --git a/test/boothtestenv.py b/test/boothtestenv.py
index 59e25c3..ba54360 100644
--- a/test/boothtestenv.py
+++ b/test/boothtestenv.py
@@ -5,7 +5,6 @@ import tempfile
import unittest
from assertions import BoothAssertions
-from boothrunner import BoothRunner
class BoothTestEnvironment(unittest.TestCase, BoothAssertions):
test_src_path = os.path.abspath(os.path.dirname(__file__))
diff --git a/test/runtests.py.in b/test/runtests.py.in
index ec59159..73d70a3 100644
--- a/test/runtests.py.in
+++ b/test/runtests.py.in
@@ -1,7 +1,6 @@
#!@PYTHON_SHEBANG@
import os
-import re
import shutil
import sys
import tempfile
@@ -10,7 +9,7 @@ import unittest
from clienttests import ClientConfigTests
from sitetests import SiteConfigTests
-from arbtests import ArbitratorConfigTests
+#from arbtests import ArbitratorConfigTests
if __name__ == '__main__':
if os.geteuid() == 0:
diff --git a/test/serverenv.py b/test/serverenv.py
index 5d6c6c4..7b8915d 100644
--- a/test/serverenv.py
+++ b/test/serverenv.py
@@ -1,9 +1,7 @@
import os
import re
import time
-import unittest
-from assertions import BoothAssertions
from boothrunner import BoothRunner
from boothtestenv import BoothTestEnvironment
from utils import get_IP
diff --git a/test/servertests.py b/test/servertests.py
index 288d19f..f72dbed 100644
--- a/test/servertests.py
+++ b/test/servertests.py
@@ -1,5 +1,4 @@
import copy
-from pprint import pprint, pformat
import re
import string
--
2.18.0.rc2

View File

@ -1,178 +0,0 @@
From 34cc2fcda6804d42ee66fa5a417fc42b64fe3806 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Pokorn=C3=BD?= <jpokorny@redhat.com>
Date: Tue, 10 Jul 2018 19:45:56 +0200
Subject: [PATCH] test: avoid dangerous mutable/sticky default value
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Incl. slight refactoring towards more frequent use of tuples where
advantage of lists are dubious.
Signed-off-by: Jan Pokorný <jpokorny@redhat.com>
---
script/unit-test.py.in | 34 ++++++++++++++++------------------
test/assertions.py | 2 +-
test/boothrunner.py | 14 +++++++-------
test/clientenv.py | 4 ++--
test/serverenv.py | 4 ++--
5 files changed, 28 insertions(+), 30 deletions(-)
diff --git a/script/unit-test.py.in b/script/unit-test.py.in
index 4f3cf62..fc98bc1 100644
--- a/script/unit-test.py.in
+++ b/script/unit-test.py.in
@@ -199,7 +199,7 @@ class UT():
self.booth.close( force=self.booth.isalive() )
- def start_a_process(self, bin, env_add=[], **args):
+ def start_a_process(self, bin, env_add=(), **args):
name = re.sub(r".*/", "", bin)
# How to get stderr, too?
expct = pexpect.spawn(bin,
@@ -220,16 +220,15 @@ class UT():
def start_processes(self, test):
self.booth = self.start_a_process(self.binary,
- args = [ "daemon", "-D",
- "-c", self.test_base + "/booth.conf",
- "-s", "127.0.0.1",
- "-l", self.lockfile,
- ],
- env_add=[ ('UNIT_TEST', test),
+ args = ["daemon", "-D",
+ "-c", self.test_base + "/booth.conf",
+ "-s", "127.0.0.1",
+ "-l", self.lockfile],
+ env_add=( ('UNIT_TEST', test),
('UNIT_TEST_FILE', os.path.realpath(test)),
# provide some space, so that strcpy(getenv()) works
('UNIT_TEST_AUX', "".zfill(1024)),
- ]);
+ ));
logging.info("started booth with PID %d, lockfile %s" % (self.booth.pid, self.lockfile))
self.booth.expect("BOOTH site \S+ \(build \S+\) daemon is starting", timeout=2)
@@ -237,16 +236,15 @@ class UT():
self.gdb = self.start_a_process("gdb",
args=["-quiet",
- "-p", str(self.booth.pid),
- # Don't use .gdbinit
- "-nx", "-nh",
- # Run until the defined point.
- # This is necessary so that ticket state setting doesn't
- # happen _before_ the call to pcmk_load_ticket()
- # (which would overwrite our data)
- "-ex", "break ticket_cron",
- "-ex", "continue",
- ])
+ "-p", str(self.booth.pid),
+ # Don't use .gdbinit
+ "-nx", "-nh",
+ # Run until the defined point.
+ # This is necessary so that ticket state setting doesn't
+ # happen _before_ the call to pcmk_load_ticket()
+ # (which would overwrite our data)
+ "-ex", "break ticket_cron",
+ "-ex", "continue"])
logging.info("started GDB with PID %d" % self.gdb.pid)
self.gdb.expect("(gdb)")
self.gdb.sendline("set pagination off\n")
diff --git a/test/assertions.py b/test/assertions.py
index fafb291..db6fcd8 100644
--- a/test/assertions.py
+++ b/test/assertions.py
@@ -10,7 +10,7 @@ class BoothAssertions:
self.assertRegexpMatches(stderr, expected_error)
def assertLockFileError(self, config_file=None, config_text=None,
- lock_file=True, args=[]):
+ lock_file=True, args=()):
(pid, ret, stdout, stderr, runner) = \
self.run_booth(config_text=config_text, config_file=config_file,
lock_file=lock_file, args=args, expected_exitcode=1)
diff --git a/test/boothrunner.py b/test/boothrunner.py
index 31c2213..0285fe6 100644
--- a/test/boothrunner.py
+++ b/test/boothrunner.py
@@ -8,14 +8,14 @@ class BoothRunner:
def __init__(self, boothd_path, mode, args):
self.boothd_path = boothd_path
- self.args = [ mode ]
- self.final_args = args # will be appended to self.args
+ self.args = (mode, )
+ self.final_args = tuple(args) # will be appended to self.args
self.mode = mode
self.config_file = None
self.lock_file = None
def set_config_file_arg(self):
- self.args += [ '-c', self.config_file ]
+ self.args += ('-c', self.config_file)
def set_config_file(self, config_file):
self.config_file = config_file
@@ -23,16 +23,16 @@ class BoothRunner:
def set_lock_file(self, lock_file):
self.lock_file = lock_file
- self.args += [ '-l', self.lock_file ]
+ self.args += ('-l', self.lock_file)
def set_debug(self):
- self.args += [ '-D' ]
+ self.args += ('-D', )
def set_foreground(self):
- self.args += [ '-S' ]
+ self.args += ('-S', )
def all_args(self):
- return [ self.boothd_path ] + self.args + self.final_args
+ return (self.boothd_path, ) + self.args + self.final_args
def show_output(self, stdout, stderr):
if stdout:
diff --git a/test/clientenv.py b/test/clientenv.py
index 73b2791..141e33c 100644
--- a/test/clientenv.py
+++ b/test/clientenv.py
@@ -4,8 +4,8 @@ from boothrunner import BoothRunner
class ClientTestEnvironment(BoothTestEnvironment):
mode = 'client'
- def run_booth(self, config_text=None, config_file=None, lock_file=True, args=[],
- expected_exitcode=0, debug=False):
+ def run_booth(self, config_text=None, config_file=None, lock_file=True,
+ args=(), expected_exitcode=0, debug=False):
'''
Runs boothd.
diff --git a/test/serverenv.py b/test/serverenv.py
index 7b8915d..62c37d0 100644
--- a/test/serverenv.py
+++ b/test/serverenv.py
@@ -29,7 +29,7 @@ ticket="ticketB"
def run_booth(self, expected_exitcode, expected_daemon,
config_text=None, config_file=None, lock_file=True,
- args=[], debug=False, foreground=False):
+ args=(), debug=False, foreground=False):
'''
Runs boothd. Defaults to using a temporary lock file and the
standard config file path. There are four possible types of
@@ -52,7 +52,7 @@ ticket="ticketB"
True: pass a temporary lockfile parameter to booth via -l
string: pass the given lockfile path to booth via -l
args
- array of extra args to pass to booth
+ iterable of extra args to pass to booth
expected_exitcode
an integer, or False if booth is not expected to terminate
within the timeout
--
2.18.0.rc2

View File

@ -1,41 +0,0 @@
From 0a7b51d1eb6f948724c08e94148e8ff1f448d100 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Pokorn=C3=BD?= <jpokorny@redhat.com>
Date: Fri, 13 Jul 2018 14:10:28 +0200
Subject: [PATCH] test: unit-test.py: daemon will not stay in foreground with
-D anymore
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Commit a66ac33 missed this impact (it may have missed impact on
test/boothrunner.py but it appears to be fine either way).
Signed-off-by: Jan Pokorný <jpokorny@redhat.com>
---
script/unit-test.py.in | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/script/unit-test.py.in b/script/unit-test.py.in
index fc98bc1..74a014b 100644
--- a/script/unit-test.py.in
+++ b/script/unit-test.py.in
@@ -2,7 +2,6 @@
# vim: fileencoding=utf-8
# see http://stackoverflow.com/questions/728891/correct-way-to-define-python-source-code-encoding
# NOTE: setting the encoding is needed as non-ASCII characters are contained
-# FIXME: apparently, pexpect.EOF is not being excepted properly
import os, sys, time, signal, tempfile, socket, posix, time
import re, shutil, pexpect, logging, pprint
@@ -220,7 +219,7 @@ class UT():
def start_processes(self, test):
self.booth = self.start_a_process(self.binary,
- args = ["daemon", "-D",
+ args = ["daemon", "-DS",
"-c", self.test_base + "/booth.conf",
"-s", "127.0.0.1",
"-l", self.lockfile],
--
2.18.0.rc2

View File

@ -1,50 +0,0 @@
From d3bf9f5ced41ad0f4e8ae87e80c7e44df4157b61 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Pokorn=C3=BD?= <jpokorny@redhat.com>
Date: Fri, 13 Jul 2018 14:40:07 +0200
Subject: [PATCH] Refactor: fix "strncpy may miss trailing null byte" warnings
of GCC 8.1
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Verbatim warning:
> strncpy specified bound 64 equals destination size [-Wstringop-truncation]
Signed-off-by: Jan Pokorný <jpokorny@redhat.com>
---
src/config.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/src/config.c b/src/config.c
index 9df5767..e4d36ab 100644
--- a/src/config.c
+++ b/src/config.c
@@ -75,7 +75,10 @@ static void hostname_to_ip(char * hostname)
/* Return the first found address */
if (addr_list[0] != NULL) {
- strncpy(hostname, inet_ntoa(*addr_list[0]), BOOTH_NAME_LEN);
+ strncpy(hostname, inet_ntoa(*addr_list[0]), BOOTH_NAME_LEN - 1);
+ /* buffer overflow will not happen (IPv6 notation < 63 chars),
+ but suppress the warnings */
+ hostname[BOOTH_NAME_LEN - 1] = '\0';
}
else {
log_error("no IP addresses found for the host \"%s\"", hostname);
@@ -106,7 +109,12 @@ static int add_site(char *addr_string, int type)
site->family = AF_INET;
site->type = type;
- strncpy(site->addr_string, addr_string, sizeof(site->addr_string));
+ /* buffer overflow will not hapen (we've already checked that
+ addr_string will fit incl. terminating '\0' above), but
+ suppress the warnings with copying everything but the boundary
+ byte, which is valid as-is, since this last byte will be safely
+ pre-zeroed from the struct booth_config initialization */
+ strncpy(site->addr_string, addr_string, sizeof(site->addr_string) - 1);
if (!(inet_pton(AF_INET, site->addr_string, &site->sa4.sin_addr) > 0) &&
!(inet_pton(AF_INET6, site->addr_string, &site->sa6.sin6_addr) > 0)) {
--
2.18.0.rc2

View File

@ -1,145 +0,0 @@
From 5703061ba7142509647eb6ee8a0155464677b45a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Pokorn=C3=BD?= <jpokorny@redhat.com>
Date: Thu, 19 Jul 2018 18:45:59 +0200
Subject: [PATCH 1/3] maint: lsb: polish arbitrator's initscript, fix
condrestart
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- previously, condrestart/try-restart (regardless whether "multi-tenant"
or not) would not work as expected
- make it apparent the script is in fact not fully LSB-compliant
- suppress some ShellCheck issues, mostly related to the fact that
some variables are injected based on "boothd status" invocation,
also drop an unused variable (see commits 8732542 + 054dafa
[until which it might have been useful] + 9e6359f)
- fix whitespace issues + normalize indentation of "case - esac"
Signed-off-by: Jan Pokorný <jpokorny@redhat.com>
---
script/lsb/booth-arbitrator | 64 ++++++++++++++++++++++---------------
1 file changed, 38 insertions(+), 26 deletions(-)
diff --git a/script/lsb/booth-arbitrator b/script/lsb/booth-arbitrator
index d90fe4b..3cdafc0 100755
--- a/script/lsb/booth-arbitrator
+++ b/script/lsb/booth-arbitrator
@@ -1,6 +1,7 @@
#!/bin/bash
#
-# BOOTH daemon init script for LSB-compliant Linux distributions.
+# BOOTH daemon init script for SUSE Linux based distributions
+# (almost LSB-compliant, except for s/startproc/start_daemon/ etc.)
#
# booth-arbitrator BOOTH arbitrator daemon
#
@@ -40,12 +41,13 @@ check_status() {
rc=$BOOTH_ERROR_GENERIC
eval `"$exec" status "${cnf:+-c$cnf}" ; echo rc=$?`
- case $rc in
+ case $rc in
0)
- case "$booth_state" in
+ # shellcheck disable=SC2154
+ case "$booth_state" in
started) return $BOOTH_DAEMON_STARTED;;
starting) return $BOOTH_DAEMON_STARTING;;
- *) return $BOOTH_ERROR_GENERIC;;
+ *) return $BOOTH_ERROR_GENERIC;;
esac
;;
$OCF_NOT_RUNNING) return $BOOTH_DAEMON_NOT_RUNNING;;
@@ -57,6 +59,7 @@ check_status() {
status() {
echo -n "BOOTH daemon is "
if check_status; then
+ # shellcheck disable=SC2154
echo "running - PID $booth_lockpid for $booth_cfg_name, $booth_addr_string:$booth_port"
return 0
else
@@ -90,16 +93,15 @@ stop() {
wait_time=5
check_status; rc=$?
case $rc in
- $BOOTH_DAEMON_STARTED);;
- $BOOTH_DAEMON_STARTING);;
- $BOOTH_DAEMON_EXIST);;
+ $BOOTH_DAEMON_STARTED|$BOOTH_DAEMON_STARTING|$BOOTH_DAEMON_EXIST)
+ ;;
$BOOTH_DAEMON_NOT_RUNNING)
echo "BOOTH arbitrator daemon is not running."
return 0
- ;;
+ ;;
*) return 1;;
esac
-
+
echo -n $"Stopping BOOTH arbitrator daemon: "
# $exec stop "${cnf:+-c$cnf}"
# sleep 1
@@ -122,11 +124,10 @@ stop() {
}
foreach() {
- local cnf cnf_base
+ local cnf
local rc=0
for cnf in ${BOOTH_CONF_FILE:-$CONF_DIR/*.conf} ; do
- cnf_base=`basename $cnf`
"$@"
rc=$((rc|$?))
done
@@ -138,20 +139,31 @@ restart() {
start
}
+condrestart() {
+ local rc
+
+ check_status; rc=$?
+
+ case "$rc" in
+ $BOOTH_DAEMON_STARTED|$BOOTH_DAEMON_STARTING|$BOOTH_DAEMON_EXIST)
+ # shellcheck disable=SC2154
+ [ ! -f "$booth_lockfile" ] || restart
+ ;;
+ esac
+}
+
case "$1" in
- start|stop|restart)
- foreach $1
- ;;
- reload|force-reload)
- foreach restart
- ;;
- condrestart|try-restart)
- [ ! -f "$booth_lockfile" ] || restart
- ;;
- status)
- foreach status
- ;;
- *)
- echo $"Usage: $0 {start|stop|restart|try-restart|condrestart|reload|force-reload|status}"
- exit 2
+start|stop|restart|condrestart|status)
+ foreach $1
+ ;;
+reload|force-reload)
+ foreach restart
+ ;;
+try-restart)
+ foreach condrestart
+ ;;
+*)
+ echo $"Usage: $0 {start|stop|restart|try-restart|condrestart|reload|force-reload|status}"
+ exit 2
+ ;;
esac
--
2.18.0.rc2

View File

@ -1,260 +0,0 @@
From 4d7278dbd9cf5f9a7d6060eb96e1ba5af6b3d505 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Pokorn=C3=BD?= <jpokorny@redhat.com>
Date: Thu, 19 Jul 2018 19:44:34 +0200
Subject: [PATCH 2/3] maint: test: polish live_test.sh
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- from issues found with ShellCheck, fix those marked as important
- suppress some ShellCheck issues, mostly related to the fact that
some ticket-related variables are established dynamically,
also drop a never-used local variable (see commits 74a3f5c + 4136682)
and another global one that was used but consequently ditched
(see commits 08f56bd + d952b27)
- fix s/boots not uptodate/booths not up-to-date/ spelling
- fix whitespace issues
Signed-off-by: Jan Pokorný <jpokorny@redhat.com>
---
test/live_test.sh | 60 ++++++++++++++++++++++++-----------------------
1 file changed, 31 insertions(+), 29 deletions(-)
diff --git a/test/live_test.sh b/test/live_test.sh
index f8644a2..c131f8c 100755
--- a/test/live_test.sh
+++ b/test/live_test.sh
@@ -41,7 +41,6 @@ EOF
[ $# -eq 0 ] && usage 0
cnf=$1
-BOOTH_DIR="/etc/booth"
run_cnf="/etc/booth/booth.conf"
shift 1
@@ -62,9 +61,9 @@ get_internal_site() {
logmsg() {
if [ "$WE_SERVER" -o "$_JUST_NETEM" ]; then
- logger -t "BOOTHTEST" -p $HA_LOGFACILITY.info -- $@
+ logger -t "BOOTHTEST" -p $HA_LOGFACILITY.info -- "$@"
else
- ssh $SSH_OPTS `get_site 1` logger -t "BOOTHTEST" -p $HA_LOGFACILITY.info -- $@
+ ssh $SSH_OPTS `get_site 1` logger -t "BOOTHTEST" -p $HA_LOGFACILITY.info -- "$@"
fi
}
@@ -141,20 +140,20 @@ local_netem_env() {
}
is_function() {
- test z"`command -v $1`" = z"$1"
+ test z"`command -v $1`" = z"$1"
}
runcmd() {
local h=$1 rc
shift 1
- echo "$h: running '$@'" | logmsg
+ echo "$h: running '$*'" | logmsg
if ip a l | fgrep -wq $h; then
- eval $@
+ eval "$@"
else
- ssh $SSH_OPTS $h $@
+ ssh $SSH_OPTS $h "$@"
fi
rc=$?
if [ $rc -ne 0 ]; then
- echo "$h: '$@' failed (exit code $rc)" | logmsg
+ echo "$h: '$*' failed (exit code $rc)" | logmsg
fi
return $rc
}
@@ -306,7 +305,7 @@ dump_conf() {
forall() {
local h rc=0
for h in $sites $arbitrators; do
- runcmd $h $@
+ runcmd $h "$@"
rc=$((rc|$?))
done
return $rc
@@ -314,7 +313,7 @@ forall() {
forall_withname() {
local h rc=0 output
for h in $sites $arbitrators; do
- output=`runcmd $h $@`
+ output=`runcmd $h "$@"`
rc=$((rc|$?))
echo $h: $output
done
@@ -323,7 +322,7 @@ forall_withname() {
forall_sites() {
local h rc=0
for h in $sites; do
- runcmd $h $@
+ runcmd $h "$@"
rc=$((rc|$?))
done
return $rc
@@ -343,7 +342,7 @@ forall_fun2() {
f=$1
shift 1
for h in $sites $arbitrators; do
- $f $@ | ssh $SSH_OPTS $h
+ $f "$@" | ssh $SSH_OPTS $h
rc=$((rc|$?))
[ $rc -ne 0 ] && break
done
@@ -353,13 +352,13 @@ run_site() {
local n=$1 h
shift 1
h=`echo $sites | awk '{print $'$n'}'`
- runcmd $h $@
+ runcmd $h "$@"
}
run_arbitrator() {
local n=$1 h
shift 1
h=`echo $arbitrators | awk '{print $'$n'}'`
- runcmd $h $@
+ runcmd $h "$@"
}
# need to get logs from _all_ clusters' nodes
@@ -450,6 +449,8 @@ n && (/^$/ || /^ticket.*/) {exit}
' $1
}
wait_exp() {
+ # shellcheck disable=SC2154
+ # (T_expire: defined with get_tkt_settings)
sleep $T_expire
}
wait_renewal() {
@@ -593,7 +594,7 @@ booth_leader_consistency_2() {
# b) some booths not uptodate (have no leader for the ticket)
# c) ticket expiry times differ
check_booth_consistency() {
- local tlist tlist_validate rc rc_lead maxdiff
+ local tlist rc rc_lead maxdiff
tlist=`forall_withname booth list 2>/dev/null | grep $tkt`
# Check time consistency
@@ -620,7 +621,7 @@ check_booth_consistency() {
`if [ $rc -ge 4 ]; then
echo "booth list consistency failed (more than one leader!):"
elif [ $rc -ge 2 ]; then
- echo "booth list consistency failed (some boots not uptodate):"
+ echo "booth list consistency failed (some booths not up-to-date):"
else
echo "booth list consistency failed (max valid time diff: $maxdiff):"
fi`
@@ -677,11 +678,10 @@ run_report() {
runtest() {
local start_ts end_ts
local rc booth_status dep_rsc_status
- local start_time end_time
local usrmsg
rc=0
TEST=$1
- start_time=`date`
+ start_ts=`date` # to have the expanded form in the logfile
start_ts=`date +%s`
echo -n "Testing: $1 (ticket: $tkt)... "
can_run_test $1 || return 0
@@ -719,7 +719,7 @@ runtest() {
usrmsg="test FAIL: $rc"
;;
esac
- end_time=`date`
+ end_ts=`date` # to have the expanded form in the logfile
end_ts=`date +%s`
echo "finished booth test $1 ($tkt): $usrmsg" | logmsg
echo "==================================================" | logmsg
@@ -791,6 +791,8 @@ setup_longgrant2() {
}
test_longgrant2() {
local i
+ # shellcheck disable=SC2034
+ # (variable exists merely out of necessity)
for i in `seq 10`; do
wait_exp
done
@@ -1033,14 +1035,14 @@ setup_split_leader() {
return 0
}
test_split_leader() {
- run_site 1 $iprules stop $port >/dev/null
+ run_site 1 $iprules stop $port >/dev/null
wait_exp
wait_timeout
wait_timeout
wait_timeout
wait_timeout
check_cib any || return 1
- run_site 1 $iprules start $port >/dev/null
+ run_site 1 $iprules start $port >/dev/null
wait_timeout
wait_timeout
wait_timeout
@@ -1049,7 +1051,7 @@ check_split_leader() {
check_consistency any
}
recover_split_leader() {
- run_site 1 $iprules start $port >/dev/null
+ run_site 1 $iprules start $port >/dev/null
}
## TEST: split_follower ##
@@ -1059,10 +1061,10 @@ setup_split_follower() {
grant_ticket_cib 1
}
test_split_follower() {
- run_site 2 $iprules stop $port >/dev/null
+ run_site 2 $iprules stop $port >/dev/null
wait_exp
wait_timeout
- run_site 2 $iprules start $port >/dev/null
+ run_site 2 $iprules start $port >/dev/null
wait_timeout
}
check_split_follower() {
@@ -1076,9 +1078,9 @@ setup_split_edge() {
grant_ticket_cib 1
}
test_split_edge() {
- run_site 1 $iprules stop $port >/dev/null
+ run_site 1 $iprules stop $port >/dev/null
wait_exp
- run_site 1 $iprules start $port >/dev/null
+ run_site 1 $iprules start $port >/dev/null
wait_timeout
wait_timeout
}
@@ -1215,13 +1217,11 @@ internal_arbitrators=`get_value arbitrator < $cnf`
all_nodes=`get_all_nodes`
port=`get_value port < $cnf`
: ${port:=9929}
-site_cnt=`echo $internal_sites | wc -w`
-arbitrator_cnt=`echo $internal_arbitrators | wc -w`
if [ "$1" = "__netem__" ]; then
shift 1
_JUST_NETEM=1
- local_netem_env $@
+ local_netem_env "$@"
exit
fi
@@ -1314,6 +1314,8 @@ do
eval `get_tkt_settings booth_${i}.conf`
+ # shellcheck disable=SC2154
+ # (T_timeout: defined with get_tkt_settings)
MIN_TIMEOUT=`awk -v tm=$T_timeout 'BEGIN{
if (tm >= 2) print tm;
else print 2*tm;
--
2.18.0.rc2

View File

@ -1,120 +0,0 @@
From 6eb95429bb92cab5616feaef0111733f79164811 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Pokorn=C3=BD?= <jpokorny@redhat.com>
Date: Thu, 19 Jul 2018 19:11:36 +0200
Subject: [PATCH 3/3] maint: ocf + script: eliminate some false positives with
ShellCheck
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
In particular, prevent sed's character classes to be confused with
array-like variable access through specified index, which demonstrates
why it's better to have the ${variable} "enbraced".
Signed-off-by: Jan Pokorný <jpokorny@redhat.com>
---
script/ocf/booth-site | 7 +++++++
script/ocf/geostore | 2 ++
script/ocf/sharedrsc | 5 +++++
script/service-runnable.in | 2 +-
4 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/script/ocf/booth-site b/script/ocf/booth-site
index 809928c..8178e35 100755
--- a/script/ocf/booth-site
+++ b/script/ocf/booth-site
@@ -30,6 +30,7 @@ DEFAULT_BIN="boothd"
DEFAULT_CONF="/etc/booth/booth.conf"
: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}
+# shellcheck source=/usr/lib/ocf/lib/heartbeat/ocf-shellfuncs
. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs
#######################################################################
@@ -140,6 +141,8 @@ booth_site_start() {
$OCF_NOT_RUNNING) ;;
esac
+ # shellcheck disable=SC2154
+ # (OCF_RESKEY_args: injected by CRM)
$OCF_RESKEY_daemon daemon -c $OCF_RESKEY_config $OCF_RESKEY_args ||
return $OCF_ERR_GENERIC
sleep 1
@@ -188,6 +191,8 @@ booth_site_validate_all() {
return $OCF_ERR_INSTALLED
fi
+ # shellcheck disable=SC2154
+ # (OCF_RESKEY_CRM_meta_globally_unique: injected by CRM)
if ocf_is_true $OCF_RESKEY_CRM_meta_globally_unique; then
ocf_log err "$OCF_RESOURCE_INSTANCE must be configured with the globally_unique=false meta attribute"
return $OCF_ERR_CONFIGURED
@@ -198,6 +203,8 @@ booth_site_validate_all() {
: ${OCF_RESKEY_daemon:=$DEFAULT_BIN}
: ${OCF_RESKEY_config:=$DEFAULT_CONF}
+# shellcheck disable=SC2034
+# (OCF_REQUIRED_BINARIES consumed by ocf_rarun)
OCF_REQUIRED_BINARIES=${OCF_RESKEY_daemon}
ocf_rarun $*
diff --git a/script/ocf/geostore b/script/ocf/geostore
index 85842a8..c180418 100755
--- a/script/ocf/geostore
+++ b/script/ocf/geostore
@@ -31,7 +31,9 @@
# Initialization:
: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}
+# shellcheck source=/usr/lib/ocf/lib/heartbeat/ocf-shellfuncs
. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs
+# shellcheck source=script/ocf/geo_attr.sh
. ${OCF_ROOT}/lib/booth/geo_attr.sh
#######################################################################
diff --git a/script/ocf/sharedrsc b/script/ocf/sharedrsc
index 384cfd2..c2ed8ff 100755
--- a/script/ocf/sharedrsc
+++ b/script/ocf/sharedrsc
@@ -36,6 +36,7 @@
# Initialization:
: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}
+# shellcheck source=/usr/lib/ocf/lib/heartbeat/ocf-shellfuncs
. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs
#######################################################################
@@ -148,6 +149,8 @@ sharedrsc_start() {
if ! owner=`runcmd getowner $DIR`; then
owner="... nobody, it's only half-claimed"
fi
+ # shellcheck disable=SC2154
+ # (OCF_RESKEY_dir: injected by CRM)
ocf_log err "eek, $OCF_RESKEY_dir already owned by $owner"
return $OCF_ERR_GENERIC
}
@@ -180,6 +183,8 @@ sharedrsc_validate_all() {
return $OCF_SUCCESS
}
+# shellcheck disable=SC2034
+# (OCF_REQUIRED_PARAMS consumed by ocf_rarun)
OCF_REQUIRED_PARAMS="dir"
ocf_rarun $*
diff --git a/script/service-runnable.in b/script/service-runnable.in
index 9ea33d4..2f58641 100755
--- a/script/service-runnable.in
+++ b/script/service-runnable.in
@@ -30,7 +30,7 @@ fi
if echo "$status" |
sed -n '/^Revised cluster status:/,$p' |
- egrep "^[[:space:]]+$service[[:space:]]+\(.*\):[[:space:]]+Started ([^[:space:]]+) *$" >/dev/null
+ egrep "^[[:space:]]+${service}[[:space:]]+\(.*\):[[:space:]]+Started ([^[:space:]]+) *$" >/dev/null
then
# can be started - we're done.
exit 0
--
2.18.0.rc2

View File

@ -0,0 +1,37 @@
From 4bdd96d767fc38239c4fac9e95404da99f61ac65 Mon Sep 17 00:00:00 2001
From: Jan Friesse <jfriesse@redhat.com>
Date: Wed, 21 Feb 2024 17:40:11 +0100
Subject: [PATCH 1/4] attr: Fix reading of server_reply
read_server_reply first reads boothc header and then rest of packet
which contains hmac info. This should go in memory right after
boothc_header and not after full length of packet, because full length
of packet already contains hmac info.
Solution is to simply use length of header and not length of packet.
Longer term and better solution would be to drop read_server_reply
completely and use recv_auth which is used for everything else but attr
set and delete.
Signed-off-by: Jan Friesse <jfriesse@redhat.com>
---
src/attr.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/attr.c b/src/attr.c
index 44061e3..bc154f0 100644
--- a/src/attr.c
+++ b/src/attr.c
@@ -142,7 +142,7 @@ static int read_server_reply(
return -2;
}
len = ntohl(header->length);
- rv = tpt->recv(site, msg+len, len-sizeof(*header));
+ rv = tpt->recv(site, msg+sizeof(*header), len-sizeof(*header));
if (rv < 0) {
return -1;
}
--
2.44.0

View File

@ -0,0 +1,65 @@
From 91fcfb5708f829ecff7d098ed4c0fc8f2da6d599 Mon Sep 17 00:00:00 2001
From: Jan Friesse <jfriesse@redhat.com>
Date: Wed, 21 Feb 2024 18:12:28 +0100
Subject: [PATCH 2/4] auth: Check result of gcrypt gcry_md_get_algo_dlen
When unknown hash is passed to gcry_md_get_algo_dlen 0 is returned. This
value is then used for memcmp so wrong hmac might be accepted as
correct.
Signed-off-by: Jan Friesse <jfriesse@redhat.com>
---
src/auth.c | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/src/auth.c b/src/auth.c
index 8f86b9a..a3b3d20 100644
--- a/src/auth.c
+++ b/src/auth.c
@@ -28,6 +28,11 @@ int calc_hmac(const void *data, size_t datalen,
{
static gcry_md_hd_t digest;
gcry_error_t err;
+ int hlen;
+
+ hlen = gcry_md_get_algo_dlen(hid);
+ if (!hlen)
+ return -1;
if (!digest) {
err = gcry_md_open(&digest, hid, GCRY_MD_FLAG_HMAC);
@@ -42,7 +47,7 @@ int calc_hmac(const void *data, size_t datalen,
}
}
gcry_md_write(digest, data, datalen);
- memcpy(result, gcry_md_read(digest, 0), gcry_md_get_algo_dlen(hid));
+ memcpy(result, gcry_md_read(digest, 0), hlen);
gcry_md_reset(digest);
return 0;
}
@@ -54,15 +59,20 @@ int verify_hmac(const void *data, size_t datalen,
{
unsigned char *our_hmac;
int rc;
+ int hlen;
+
+ hlen = gcry_md_get_algo_dlen(hid);
+ if (!hlen)
+ return -1;
- our_hmac = malloc(gcry_md_get_algo_dlen(hid));
+ our_hmac = malloc(hlen);
if (!our_hmac)
return -1;
rc = calc_hmac(data, datalen, hid, our_hmac, key, keylen);
if (rc)
goto out_free;
- rc = memcmp(our_hmac, hmac, gcry_md_get_algo_dlen(hid));
+ rc = memcmp(our_hmac, hmac, hlen);
out_free:
if (our_hmac)
--
2.44.0

View File

@ -0,0 +1,106 @@
From 87c8545816cca03d19c2f3ef54031940f7e19d50 Mon Sep 17 00:00:00 2001
From: Jan Friesse <jfriesse@redhat.com>
Date: Fri, 18 Nov 2022 11:57:46 +0100
Subject: [PATCH] config: Add enable-authfile option
This option enables (or disables) usage of authfile. Can be 'yes' or 'no'.
Default is 'no'.
Booth usage of authfile was broken for long time (since commit
da79b8ba28ad4837a0fee13e5f8fb6f89fe0e24c).
Pcs was adding authfile by default, but it was not used. Once booth bug
was fixed problem appears because mixed clusters (with fixed version and
without fixed one) stops working.
This non-upstream option is added and used to allow use of
authfile without breaking compatibility for clusters
consisting of mixed versions (usually happens before all nodes are
updated) of booth (user have to explicitly
enable usage of authfile).
This patch is transitional and will be removed in future major version of
distribution.
Signed-off-by: Jan Friesse <jfriesse@redhat.com>
---
docs/boothd.8.txt | 7 +++++++
src/config.c | 17 +++++++++++++++++
src/config.h | 1 +
src/main.c | 2 +-
4 files changed, 26 insertions(+), 1 deletion(-)
diff --git a/docs/boothd.8.txt b/docs/boothd.8.txt
index 0f3d2c1..c7a8413 100644
--- a/docs/boothd.8.txt
+++ b/docs/boothd.8.txt
@@ -230,6 +230,13 @@ will always bind and listen to both UDP and TCP ports.
parameter to a higher value. The time skew test is performed
only in concert with authentication.
+'enable-authfile'::
+ Enables (or disables) usage of authfile. Can be 'yes' or 'no'.
+ Default is 'no'.
+ This is non-upstream option used to allow use of authfile without
+ breaking compatibility for clusters consisting of mixed
+ versions of booth.
+
'debug'::
Specifies the debug output level. Alternative to
command line argument. Effective only for 'daemon'
diff --git a/src/config.c b/src/config.c
index f0ca4aa..e1f25f0 100644
--- a/src/config.c
+++ b/src/config.c
@@ -732,6 +732,23 @@ no_value:
booth_conf->maxtimeskew = atoi(val);
continue;
}
+
+ if (strcmp(key, "enable-authfile") == 0) {
+ if (strcasecmp(val, "yes") == 0 ||
+ strcasecmp(val, "on") == 0 ||
+ strcasecmp(val, "1") == 0) {
+ booth_conf->enable_authfile = 1;
+ } else if (strcasecmp(val, "no") == 0 ||
+ strcasecmp(val, "off") == 0 ||
+ strcasecmp(val, "0") == 0) {
+ booth_conf->enable_authfile = 0;
+ } else {
+ error = "Expected yes/no value for enable-authfile";
+ goto err;
+ }
+
+ continue;
+ }
#endif
if (strcmp(key, "site") == 0) {
diff --git a/src/config.h b/src/config.h
index bca73bc..da1e917 100644
--- a/src/config.h
+++ b/src/config.h
@@ -297,6 +297,7 @@ struct booth_config {
struct stat authstat;
char authkey[BOOTH_MAX_KEY_LEN];
int authkey_len;
+ int enable_authfile;
/** Maximum time skew between peers allowed */
int maxtimeskew;
diff --git a/src/main.c b/src/main.c
index b4a174f..0fdb295 100644
--- a/src/main.c
+++ b/src/main.c
@@ -364,7 +364,7 @@ static int setup_config(int type)
if (rv < 0)
goto out;
- if (booth_conf->authfile[0] != '\0') {
+ if (booth_conf->authfile[0] != '\0' && booth_conf->enable_authfile) {
rv = read_authkey();
if (rv < 0)
goto out;
--
2.27.0

View File

@ -21,34 +21,18 @@
%bcond_with html_man
%bcond_with glue
%bcond_with run_build_tests
%bcond_without include_unit_test
## User and group to use for nonprivileged services (should be in sync with pacemaker)
%global uname hacluster
%global gname haclient
# Disable automatic compilation of Python files in extra directories
%global _python_bytecompile_extra 0
%global specver 5
%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 f2d38ce3d61502bda2a28e79db103737a691faf4
%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}
@ -56,25 +40,15 @@
%global test_path %{_datadir}/booth/tests
Name: booth
Version: %{boothver}
Release: %{boothrel}%{dist}
Version: 1.1
Release: 1%{?dist}.1
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: 0000-test-remove-superfluous-shebangs-for-import-only-mod.patch
Patch1: 0001-test-do-not-mix-tabs-with-spaces-in-Python-code.patch
Patch2: 0002-test-make-Python-files-supported-_also_-with-Python-.patch
Patch3: 0003-build-parametrize-Python-invocations-in-the-shebangs.patch
Patch4: 0004-test-drop-underqualified-identifier-in-unittest-s-2..patch
Patch5: 0005-test-drop-comment-out-superfluous-imports.patch
Patch6: 0006-test-avoid-dangerous-mutable-sticky-default-value.patch
Patch7: 0007-test-unit-test.py-daemon-will-not-stay-in-foreground.patch
Patch8: 0008-Refactor-fix-strncpy-may-miss-trailing-null-byte-war.patch
Patch9: 0009-maint-lsb-polish-arbitrator-s-initscript-fix-condres.patch
Patch10: 0010-maint-test-polish-live_test.sh.patch
Patch11: 0011-maint-ocf-script-eliminate-some-false-positives-with.patch
Source0: https://github.com/%{github_owner}/%{name}/releases/download/v%{version}/%{name}-%{version}.tar.gz
Patch0: rhel-specific-0001-config-Add-enable-authfile-option.patch
Patch1: RHEL-32613-1-attr-Fix-reading-of-server_reply.patch
Patch2: RHEL-32613-2-auth-Check-result-of-gcrypt-gcry_md_get_algo_dlen.patch
# direct build process dependencies
BuildRequires: autoconf
@ -103,11 +77,17 @@ BuildRequires: pkgconfig(libsystemd)
# check scriptlet (for hostname and killall respectively)
BuildRequires: hostname psmisc
BuildRequires: python3-devel
# For generating tests
BuildRequires: sed
# spec file specifics
## for _unitdir, systemd_requires and specific scriptlet macros
BuildRequires: systemd
## for autosetup
BuildRequires: git
%if 0%{?with_run_build_tests}
# check scriptlet (for perl and netstat)
BuildRequires: perl-interpreter net-tools
%endif
# this is for a composite-requiring-its-components arranged
# as an empty package (empty files section) requiring subpackages
@ -115,7 +95,9 @@ BuildRequires: git
Requires: %{name}-core%{?_isa}
Requires: %{name}-site
%files
# intentionally empty
%license COPYING
%dir %{_datadir}/pkgconfig
%{_datadir}/pkgconfig/booth.pc
%description
Booth manages tickets which authorize cluster sites located
@ -127,7 +109,6 @@ clustering in Pacemaker.
%package core
Summary: Booth core files (executables, etc.)
Group: System Environment/Daemons
# for booth-keygen (chown, dd)
Requires: coreutils
# deal with pre-split arrangement
@ -139,7 +120,6 @@ 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}
@ -151,17 +131,16 @@ Support for running Booth, ticket manager for multi-site clusters,
as an arbitrator.
%post arbitrator
%systemd_post booth@.service booth-arbitrator.service
%systemd_post booth-arbitrator.service
%preun arbitrator
%systemd_preun booth@.service booth-arbitrator.service
%systemd_preun booth-arbitrator.service
%postun arbitrator
%systemd_postun_with_restart booth@.service booth-arbitrator.service
%systemd_postun_with_restart 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
@ -177,7 +156,6 @@ 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
@ -189,7 +167,11 @@ Requires: %{name}-arbitrator = %{version}-%{release}
Requires: %{name}-site = %{version}-%{release}
Requires: gdb
Requires: %{__python3}
%if 0%{?with_include_unit_test}
Requires: python3-pexpect
%endif
# runtests.py suite (for perl and netstat)
Requires: perl-interpreter net-tools
%description test
Automated tests for running Booth, ticket manager for multi-site clusters.
@ -197,7 +179,7 @@ Automated tests for running Booth, ticket manager for multi-site clusters.
# BUILD #
%prep
%autosetup -n %{name}-%{commit} -S git_am
%autosetup -n %{name}-%{version} -S git_am
%build
./autogen.sh
@ -205,8 +187,9 @@ Automated tests for running Booth, ticket manager for multi-site clusters.
--with-initddir=%{_initrddir} \
--docdir=%{_pkgdocdir} \
--enable-user-flags \
%{!?with_html_man:--without-html_man} \
%{!?with_glue:--without-glue}
%{?with_html_man:--with-html_man} \
%{!?with_glue:--without-glue} \
PYTHON=%{__python3}
%{make_build}
%install
@ -225,20 +208,39 @@ rm -rf %{buildroot}/%{_pkgdocdir}/README.upgrade-from-v0.1
rm -rf %{buildroot}/%{_pkgdocdir}/COPYING
# tests
mkdir -p %{buildroot}/%{test_path}
# Copy tests from tarball
cp -a -t %{buildroot}/%{test_path} \
-- conf test unit-tests script/unit-test.py
-- conf test
%if 0%{?with_include_unit_test}
cp -a -t %{buildroot}/%{test_path} \
-- unit-tests script/unit-test.py
%endif
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
# Generate runtests.py and boothtestenv.py
sed -e 's#PYTHON_SHEBANG#%{__python3} -Es#g' \
-e 's#TEST_SRC_DIR#%{test_path}/test#g' \
-e 's#TEST_BUILD_DIR#%{test_path}/test#g' \
%{buildroot}/%{test_path}/test/runtests.py.in > %{buildroot}/%{test_path}/test/runtests.py
chmod +x %{buildroot}/%{test_path}/test/runtests.py
sed -e 's#PYTHON_SHEBANG#%{__python3} -Es#g' \
-e 's#TEST_SRC_DIR#%{test_path}/test#g' \
-e 's#TEST_BUILD_DIR#%{test_path}/test#g' \
%{buildroot}/%{test_path}/test/boothtestenv.py.in > %{buildroot}/%{test_path}/test/boothtestenv.py
# https://fedoraproject.org/wiki/Packaging:Python_Appendix#Manual_byte_compilation
%py_byte_compile %{__python3} %{buildroot}/%{test_path}
%check
# alternatively: test/runtests.py
%if 0%{?with_run_build_tests}
VERBOSE=1 make check
%endif
%files core
%license COPYING
@ -253,6 +255,15 @@ VERBOSE=1 make check
%dir %{_sysconfdir}/booth
%exclude %{_sysconfdir}/booth/booth.conf.example
%dir %attr (750, %{uname}, %{gname}) %{_var}/lib/booth/
%dir %attr (750, %{uname}, %{gname}) %{_var}/lib/booth/cores
# Generated html docs
%if 0%{?with_html_man}
%{_pkgdocdir}/booth-keygen.8.html
%{_pkgdocdir}/boothd.8.html
%endif
%files arbitrator
%{_unitdir}/booth@.service
%{_unitdir}/booth-arbitrator.service
@ -260,27 +271,85 @@ VERBOSE=1 make check
%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
%{_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
%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
# Generated html docs
%if 0%{?with_html_man}
%{_pkgdocdir}/geostore.8.html
%endif
%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
%{_usr}/lib/ocf/resource.d/booth/sharedrsc
%changelog
* Tue Apr 30 2024 Jan Friesse <jfriesse@redhat.com> - 1.1-1.1
- Resolves: RHEL-32613
- attr: Fix reading of server_reply
- auth: Check result of gcrypt gcry_md_get_algo_dlen (fixes CVE-2024-3049)
* Thu Nov 23 2023 Jan Friesse <jfriesse@redhat.com> - 1.1-1
- Resolves: RHEL-15265
- New upstream release (RHEL-15265)
- Upstream releases should now be released regularly, so convert spec
to use them instead of git snapshots (RHEL-15265)
* Mon Nov 21 2022 Jan Friesse <jfriesse@redhat.com> - 1.0-283.1.9d4029a.git
- Resolves: rhbz#2135865
- Update to current snapshot (commit 9d4029a) (rhbz#2135865)
* Wed Aug 03 2022 Jan Friesse <jfriesse@redhat.com> - 1.0-199.2.ac1d34c.git
- Resolves: rhbz#2111668
- Fix authfile directive handling in booth config file
(fixes CVE-2022-2553)
- Add enable-authfile option
* Thu Oct 15 2020 Jan Friesse <jfriesse@redhat.com> - 1.0-199.1.ac1d34c.git
- Resolves: rhbz#1873948
- Resolves: rhbz#1768172
- Fix versioning scheme to handle updates better
- Handle updated exit code of crm_ticket
* Wed Jun 3 2020 Jan Friesse <jfriesse@redhat.com> - 1.0-6.ac1d34c.git.2
- Related: rhbz#1835831
- Do not link with the pcmk libraries
- Generate runtests.py and boothtestenv.py with -Es as make check does
* Tue Jun 2 2020 Jan Friesse <jfriesse@redhat.com> - 1.0-6.ac1d34c.git.1
- Resolves: rhbz#1602455
- Resolves: rhbz#1682122
- Resolves: rhbz#1768369
- Resolves: rhbz#1835831
- Update to current snapshot (commit ac1d34c) to fix test suite,
build warnings and build with gcc10
- Fix hardcoded-library-path
- Package /var/lib/booth where booth can chroot
- Add '?dist' macro to release field
- Pass full path of Python3 to configure
- Add CI tests
- Enable gating
* Wed Sep 19 2018 Tomas Orsava <torsava@redhat.com> - 1.0-5.f2d38ce.git
- Require the Python interpreter directly instead of using the package name
- Related: rhbz#1619153