Merge "Fail if swift binary are missing"

This commit is contained in:
Zuul 2020-12-15 22:15:10 +00:00 committed by Gerrit Code Review
commit 28cef6767f
2 changed files with 171 additions and 25 deletions

View File

@ -25,6 +25,7 @@ import re
import six
from swift import gettext_ as _
import tempfile
from distutils.spawn import find_executable
from swift.common.utils import search_tree, remove_file, write_file, readconf
from swift.common.exceptions import InvalidPidFileException
@ -98,8 +99,10 @@ def command(func):
func.publicly_accessible = True
@functools.wraps(func)
def wrapped(*a, **kw):
rv = func(*a, **kw)
def wrapped(self, *a, **kw):
if getattr(self, 'missing_binaries', False):
return 1
rv = func(self, *a, **kw)
return 1 if rv else 0
return wrapped
@ -174,6 +177,37 @@ def kill_group(pid, sig):
os.kill(-pid, sig)
def format_server_name(servername):
"""
Formats server name as swift compatible server names
E.g. swift-object-server
:param servername: server name
:returns: swift compatible server name and its binary name
"""
if '-' not in servername:
servername = '%s-server' % servername
cmd = 'swift-%s' % servername
return servername, cmd
def verify_server(server):
"""
Check whether the server is among swift servers or not, and also
checks whether the server's binaries are installed or not.
:param server: name of the server
:returns: True, when the server name is valid and its binaries are found.
False, otherwise.
"""
if not server:
return False
_, cmd = format_server_name(server)
if find_executable(cmd) is None:
return False
return True
class UnknownCommandError(Exception):
pass
@ -188,6 +222,7 @@ class Manager(object):
def __init__(self, servers, run_dir=RUN_DIR):
self.server_names = set()
self._default_strict = True
self.missing_binaries = False
for server in servers:
if server in ALIASES:
self.server_names.update(ALIASES[server])
@ -203,7 +238,10 @@ class Manager(object):
self.servers = set()
for name in self.server_names:
if verify_server(name):
self.servers.add(Server(name, run_dir))
else:
self.missing_binaries = True
def __iter__(self):
return iter(self.servers)
@ -446,10 +484,8 @@ class Server(object):
self.server, self.conf = self.server.rsplit('.', 1)
else:
self.conf = None
if '-' not in self.server:
self.server = '%s-server' % self.server
self.server, self.cmd = format_server_name(self.server)
self.type = self.server.rsplit('-', 1)[0]
self.cmd = 'swift-%s' % self.server
self.procs = []
self.run_dir = run_dir

View File

@ -285,6 +285,30 @@ class TestManagerModule(unittest.TestCase):
def test_exc(self):
self.assertTrue(issubclass(manager.UnknownCommandError, Exception))
def test_format_server_name(self):
self.assertEqual(
manager.format_server_name('proxy'),
("proxy-server", "swift-proxy-server"))
self.assertEqual(
manager.format_server_name('Proxy'),
("Proxy-server", "swift-Proxy-server"))
self.assertEqual(
manager.format_server_name(''),
("-server", "swift--server"))
def test_verify_server(self):
# test valid servers
self.assertTrue(manager.verify_server('object'))
self.assertTrue(manager.verify_server('object-server'))
# test invalid servers
self.assertFalse(manager.verify_server('test'))
self.assertFalse(manager.verify_server('test-server'))
self.assertFalse(manager.verify_server('ls'))
self.assertFalse(manager.verify_server(''))
self.assertFalse(manager.verify_server('Object'))
self.assertFalse(manager.verify_server('object1'))
self.assertFalse(manager.verify_server(None))
class TestServer(unittest.TestCase):
@ -1624,14 +1648,17 @@ class TestServer(unittest.TestCase):
class TestManager(unittest.TestCase):
def test_create(self):
@mock.patch.object(manager, 'verify_server',
side_effect=lambda server: 'error' not in server)
def test_create(self, mock_verify):
m = manager.Manager(['test'])
self.assertEqual(len(m.servers), 1)
server = m.servers.pop()
self.assertTrue(isinstance(server, manager.Server))
self.assertEqual(server.server, 'test-server')
# test multi-server and simple dedupe
servers = ['object-replicator', 'object-auditor', 'object-replicator']
servers = ['object-replicator', 'object-auditor',
'object-replicator']
m = manager.Manager(servers)
self.assertEqual(len(m.servers), 2)
for server in m.servers:
@ -1675,6 +1702,22 @@ class TestManager(unittest.TestCase):
for s in m.servers:
self.assertTrue(str(s) in replicators)
# test invalid server
m = manager.Manager(['error'])
self.assertEqual(len(m.servers), 0)
# test valid + invalid server
servers = ['object-server']
m = manager.Manager(['object', 'error'])
self.assertEqual(len(m.servers), 1)
for server in m.servers:
self.assertTrue(server.server in servers)
# test multi-server and invalid server together
servers = ['object-replicator', 'object-auditor', 'error']
m = manager.Manager(servers)
self.assertEqual(len(m.servers), 2)
for server in m.servers:
self.assertTrue(server.server in servers[:2])
def test_iter(self):
m = manager.Manager(['all'])
self.assertEqual(len(list(m)), len(manager.ALL_SERVERS))
@ -1705,8 +1748,16 @@ class TestManager(unittest.TestCase):
else:
return 0
def mock_verify_server(server):
if 'error' in server:
return False
return True
old_verify_server = manager.verify_server
old_server_class = manager.Server
try:
manager.verify_server = mock_verify_server
manager.Server = MockServer
m = manager.Manager(['test'])
status = m.status()
@ -1720,14 +1771,20 @@ class TestManager(unittest.TestCase):
status = m.status(**kwargs)
self.assertEqual(status, 1)
for server in m.servers:
self.assertEqual(server.called_kwargs, [kwargs])
self.assertEqual(server.called_kwargs, [])
finally:
manager.verify_server = old_verify_server
manager.Server = old_server_class
def test_start(self):
def mock_setup_env():
getattr(mock_setup_env, 'called', []).append(True)
def mock_verify_server(server):
if 'error' in server:
return False
return True
class MockServer(object):
def __init__(self, server, run_dir=manager.RUN_DIR):
self.server = server
@ -1759,9 +1816,11 @@ class TestManager(unittest.TestCase):
return 0
old_setup_env = manager.setup_env
old_verify_server = manager.verify_server
old_swift_server = manager.Server
try:
manager.setup_env = mock_setup_env
manager.verify_server = mock_verify_server
manager.Server = MockServer
# test no errors on launch
@ -1776,8 +1835,8 @@ class TestManager(unittest.TestCase):
status = m.start()
self.assertEqual(status, 1)
for server in m.servers:
self.assertEqual(server.called['launch'], [{}])
self.assertEqual(server.called['wait'], [{}])
self.assertEqual(server.called['launch'], [])
self.assertEqual(server.called['wait'], [])
# test interact
m = manager.Manager(['proxy', 'error'])
@ -1785,8 +1844,8 @@ class TestManager(unittest.TestCase):
status = m.start(**kwargs)
self.assertEqual(status, 1)
for server in m.servers:
self.assertEqual(server.called['launch'], [kwargs])
self.assertEqual(server.called['interact'], [kwargs])
self.assertEqual(server.called['launch'], [])
self.assertEqual(server.called['interact'], [])
m = manager.Manager(['raise'])
kwargs = {'daemon': False}
status = m.start(**kwargs)
@ -1889,9 +1948,15 @@ class TestManager(unittest.TestCase):
finally:
manager.setup_env = old_setup_env
manager.verify_server = old_verify_server
manager.Server = old_swift_server
def test_no_wait(self):
def mock_verify_server(server):
if 'error' in server:
return False
return True
class MockServer(object):
def __init__(self, server, run_dir=manager.RUN_DIR):
self.server = server
@ -1906,8 +1971,10 @@ class TestManager(unittest.TestCase):
self.called['wait'].append(kwargs)
return int('error' in self.server)
orig_verify_server = manager.verify_server
orig_swift_server = manager.Server
try:
manager.verify_server = mock_verify_server
manager.Server = MockServer
# test success
init = manager.Manager(['proxy'])
@ -1918,8 +1985,8 @@ class TestManager(unittest.TestCase):
called_kwargs = server.called['launch'][0]
self.assertFalse(called_kwargs['wait'])
self.assertFalse(server.called['wait'])
# test no errocode status even on error
init = manager.Manager(['error'])
# test no errocode status even on invalid
init = manager.Manager(['invalid'])
status = init.no_wait()
self.assertEqual(status, 0)
for server in init.servers:
@ -1929,7 +1996,7 @@ class TestManager(unittest.TestCase):
self.assertFalse(called_kwargs['wait'])
self.assertFalse(server.called['wait'])
# test wait with once option
init = manager.Manager(['updater', 'replicator-error'])
init = manager.Manager(['updater', 'replicator-invalid'])
status = init.no_wait(once=True)
self.assertEqual(status, 0)
for server in init.servers:
@ -1941,9 +2008,15 @@ class TestManager(unittest.TestCase):
self.assertTrue(called_kwargs['once'])
self.assertFalse(server.called['wait'])
finally:
manager.verify_server = orig_verify_server
manager.Server = orig_swift_server
def test_no_daemon(self):
def mock_verify_server(server):
if 'error' in server:
return False
return True
class MockServer(object):
def __init__(self, server, run_dir=manager.RUN_DIR):
@ -1959,28 +2032,36 @@ class TestManager(unittest.TestCase):
self.called['interact'].append(kwargs)
return int('error' in self.server)
orig_verify_server = manager.verify_server
orig_swift_server = manager.Server
try:
manager.Server = MockServer
manager.verify_server = mock_verify_server
# test success
init = manager.Manager(['proxy'])
stats = init.no_daemon()
self.assertEqual(stats, 0)
# test error
init = manager.Manager(['proxy', 'object-error'])
init = manager.Manager(['proxy', 'error'])
stats = init.no_daemon()
self.assertEqual(stats, 1)
# test once
init = manager.Manager(['proxy', 'object-error'])
stats = init.no_daemon()
for server in init.servers:
self.assertEqual(len(server.called['launch']), 1)
self.assertEqual(len(server.called['launch']), 0)
self.assertEqual(len(server.called['wait']), 0)
self.assertEqual(len(server.called['interact']), 1)
self.assertEqual(len(server.called['interact']), 0)
finally:
manager.verify_server = orig_verify_server
manager.Server = orig_swift_server
def test_once(self):
def mock_verify_server(server):
if 'error' in server:
return False
return True
class MockServer(object):
def __init__(self, server, run_dir=manager.RUN_DIR):
@ -1998,15 +2079,17 @@ class TestManager(unittest.TestCase):
self.called['launch'].append(kwargs)
return {1: 'account-reaper'}
orig_verify_server = manager.verify_server
orig_swift_server = manager.Server
try:
manager.Server = MockServer
manager.verify_server = mock_verify_server
# test no errors
init = manager.Manager(['account-reaper'])
status = init.once()
self.assertEqual(status, 0)
# test error code on error
init = manager.Manager(['error-reaper'])
init = manager.Manager(['error'])
status = init.once()
self.assertEqual(status, 1)
for server in init.servers:
@ -2017,8 +2100,14 @@ class TestManager(unittest.TestCase):
self.assertEqual(len(server.called['interact']), 0)
finally:
manager.Server = orig_swift_server
manager.verify_server = orig_verify_server
def test_stop(self):
def mock_verify_server(server):
if 'error' in server:
return False
return True
class MockServerFactory(object):
class MockServer(object):
def __init__(self, pids, run_dir=manager.RUN_DIR):
@ -2046,12 +2135,14 @@ class TestManager(unittest.TestCase):
def mock_kill_group(pid, sig):
self.fail('kill_group should not be called')
_orig_verify_server = manager.verify_server
_orig_server = manager.Server
_orig_watch_server_pids = manager.watch_server_pids
_orig_kill_group = manager.kill_group
try:
manager.watch_server_pids = mock_watch_server_pids
manager.kill_group = mock_kill_group
manager.verify_server = mock_verify_server
# test stop one server
server_pids = {
'test': {1: "dummy.pid"}
@ -2086,6 +2177,7 @@ class TestManager(unittest.TestCase):
self.assertEqual(status, 1)
finally:
manager.verify_server = _orig_verify_server
manager.Server = _orig_server
manager.watch_server_pids = _orig_watch_server_pids
manager.kill_group = _orig_kill_group
@ -2126,12 +2218,19 @@ class TestManager(unittest.TestCase):
def mock_kill_group_oserr_ESRCH(*args):
raise OSError(errno.ESRCH, 'No such process')
def mock_verify_server(server):
if 'error' in server:
return False
return True
_orig_server = manager.Server
_orig_watch_server_pids = manager.watch_server_pids
_orig_kill_group = manager.kill_group
_orig_verify_server = manager.verify_server
try:
manager.watch_server_pids = mock_watch_server_pids
manager.kill_group = mock_kill_group
manager.verify_server = mock_verify_server
# test stop one server
server_pids = {
'test': {None: None}
@ -2165,8 +2264,11 @@ class TestManager(unittest.TestCase):
manager.Server = _orig_server
manager.watch_server_pids = _orig_watch_server_pids
manager.kill_group = _orig_kill_group
manager.verify_server = _orig_verify_server
def test_shutdown(self):
@mock.patch.object(manager, 'verify_server',
side_effect=lambda server: 'error' not in server)
def test_shutdown(self, mock_verify):
m = manager.Manager(['test'])
m.stop_was_called = False
@ -2180,7 +2282,9 @@ class TestManager(unittest.TestCase):
self.assertEqual(status, 0)
self.assertEqual(m.stop_was_called, True)
def test_restart(self):
@mock.patch.object(manager, 'verify_server',
side_effect=lambda server: 'error' not in server)
def test_restart(self, mock_verify):
m = manager.Manager(['test'])
m.stop_was_called = False
@ -2233,7 +2337,9 @@ class TestManager(unittest.TestCase):
do_test(graceful=True)
do_test(graceful=False) # graceful is forced regardless of the kwarg
def test_force_reload(self):
@mock.patch.object(manager, 'verify_server',
side_effect=lambda server: 'error' not in server)
def test_force_reload(self, mock_verify):
m = manager.Manager(['test'])
m.reload_was_called = False
@ -2245,7 +2351,9 @@ class TestManager(unittest.TestCase):
self.assertEqual(status, 0)
self.assertEqual(m.reload_was_called, True)
def test_get_command(self):
@mock.patch.object(manager, 'verify_server',
side_effect=lambda server: 'error' not in server)
def test_get_command(self, mock_verify):
m = manager.Manager(['test'])
self.assertEqual(m.start, m.get_command('start'))
self.assertEqual(m.force_reload, m.get_command('force-reload'))
@ -2263,7 +2371,9 @@ class TestManager(unittest.TestCase):
self.assertTrue(getattr(method, 'publicly_accessible', False))
self.assertEqual(method.__doc__.strip(), help)
def test_run_command(self):
@mock.patch.object(manager, 'verify_server',
side_effect=lambda server: 'error' not in server)
def test_run_command(self, mock_verify):
m = manager.Manager(['test'])
m.cmd_was_called = False