Add --run-dir switch to swift-init

- Add ability to specify an alternative run_dir than the default
  /var/run/swift.
- DocImpact

Change-Id: I17677588f2c8da563b7fec2dc4fdc52da87126ed
This commit is contained in:
Chmouel Boudjnah 2013-01-10 15:08:10 +01:00 committed by Chmouel Boudjnah
parent b8626f9667
commit 3282e3885c
6 changed files with 78 additions and 43 deletions

View File

@ -17,8 +17,8 @@
import sys
from optparse import OptionParser
from swift.common.manager import Server, Manager, UnknownCommandError, \
KILL_WAIT
from swift.common.manager import Manager, UnknownCommandError, \
KILL_WAIT, RUN_DIR
USAGE = """%prog <server> [<server> ...] <command> [options]
@ -46,6 +46,11 @@ def main():
parser.add_option('-k', '--kill-wait', metavar="N", type="int",
dest="kill_wait", default=KILL_WAIT,
help="wait N seconds for processes to die (default 15)")
parser.add_option('-r', '--run-dir', type="str",
dest="run_dir", default=RUN_DIR,
help="alternative directory to store running pid files "
"default: %s" % RUN_DIR)
options, args = parser.parse_args()
if len(args) < 2:
@ -62,7 +67,7 @@ def main():
servers.append(command)
command = servers.pop(0)
manager = Manager(servers)
manager = Manager(servers, run_dir=options.run_dir)
try:
status = manager.run_command(command, **options.__dict__)
except UnknownCommandError:

View File

@ -6,6 +6,7 @@ import signal
import subprocess
import sys
from swift.common.manager import RUN_DIR
if __name__ == '__main__':
parser = optparse.OptionParser(usage='''%prog [options]
@ -28,10 +29,15 @@ Example (sends SIGTERM to all orphaned Swift processes older than two hours):
parser.add_option('-w', '--wide', dest='wide', default=False,
action='store_true',
help="don't clip the listing at 80 characters")
parser.add_option('-r', '--run-dir', type="str",
dest="run_dir", default=RUN_DIR,
help="alternative directory to store running pid files "
"default: %s" % RUN_DIR)
(options, args) = parser.parse_args()
pids = []
for root, directories, files in os.walk('/var/run/swift'):
for root, directories, files in os.walk(options.run_dir):
for name in files:
if name.endswith('.pid'):
pids.append(open(os.path.join(root, name)).read().strip())

View File

@ -108,6 +108,7 @@ allows one to use the keywords such as "all", "main" and "rest" for the <server>
.IP "-g, --graceful \t\t send SIGHUP to supporting servers
.IP "-c N, --config-num=N \t send command to the Nth server only
.IP "-k N, --kill-wait=N \t wait N seconds for processes to die (default 15)
.IP "-r RUN_DIR, --run-dir=RUN_DIR directory where the pids will be stored (default /var/run/swift)
.PD
.RE

View File

@ -25,16 +25,17 @@
.SH SYNOPSIS
.LP
.B swift-orphans
[-h|--help] [-a|--age] [-k|--kill] [-w|--wide]
[-h|--help] [-a|--age] [-k|--kill] [-w|--wide] [-r|--run-dir]
.SH DESCRIPTION
.PP
Lists and optionally kills orphaned Swift processes. This is done by scanning
/var/run/swift for .pid files and listing any processes that look like Swift
processes but aren't associated with the pids in those .pid files. Any Swift
processes running with the 'once' parameter are ignored, as those are usually
for full-speed audit scans and such.
/var/run/swift or the directory specified to the -r switch for .pid files and
listing any processes that look like Swift processes but aren't associated with
the pids in those .pid files. Any Swift processes running with the 'once'
parameter are ignored, as those are usually for full-speed audit scans and
such.
Example (sends SIGTERM to all orphaned Swift processes older than two hours):
swift-orphans -a 2 -k TERM

View File

@ -129,7 +129,7 @@ class Manager():
"""
def __init__(self, servers):
def __init__(self, servers, run_dir=RUN_DIR):
server_names = set()
for server in servers:
if server == 'all':
@ -147,7 +147,7 @@ class Manager():
self.servers = set()
for name in server_names:
self.servers.add(Server(name))
self.servers.add(Server(name, run_dir))
@command
def status(self, **kwargs):
@ -316,13 +316,14 @@ class Server():
:param server: name of server
"""
def __init__(self, server):
def __init__(self, server, run_dir=RUN_DIR):
if '-' not in server:
server = '%s-server' % server
self.server = server.lower()
self.type = server.rsplit('-', 1)[0]
self.cmd = 'swift-%s' % server
self.procs = []
self.run_dir = run_dir
def __str__(self):
return self.server
@ -348,7 +349,7 @@ class Server():
"""
return conf_file.replace(
os.path.normpath(SWIFT_DIR), RUN_DIR, 1).replace(
os.path.normpath(SWIFT_DIR), self.run_dir, 1).replace(
'%s-server' % self.type, self.server, 1).rsplit(
'.conf', 1)[0] + '.pid'
@ -362,11 +363,11 @@ class Server():
"""
if self.server in STANDALONE_SERVERS:
return pid_file.replace(
os.path.normpath(RUN_DIR), SWIFT_DIR, 1)\
os.path.normpath(self.run_dir), SWIFT_DIR, 1)\
.rsplit('.pid', 1)[0] + '.conf'
else:
return pid_file.replace(
os.path.normpath(RUN_DIR), SWIFT_DIR, 1).replace(
os.path.normpath(self.run_dir), SWIFT_DIR, 1).replace(
self.server, '%s-server' % self.type, 1).rsplit(
'.pid', 1)[0] + '.conf'
@ -411,7 +412,7 @@ class Server():
:returns: list of pid files
"""
pid_files = search_tree(RUN_DIR, '%s*' % self.server, '.pid')
pid_files = search_tree(self.run_dir, '%s*' % self.server, '.pid')
if kwargs.get('number', 0):
conf_files = self.conf_files(**kwargs)
# filter pid_files to match the index of numbered conf_file

View File

@ -181,7 +181,7 @@ class TestManagerModule(unittest.TestCase):
class MockServer():
def __init__(self, pids, zombie=0):
def __init__(self, pids, run_dir=manager.RUN_DIR, zombie=0):
self.heartbeat = (pids for _ in range(zombie))
def get_running_pids(self):
@ -311,6 +311,24 @@ class TestServer(unittest.TestCase):
'container-auditor/1/container-auditor.pid')
self.assertEquals(pid_file, server.get_pid_file_name(conf_file))
def test_get_custom_pid_file_name(self):
random_run_dir = "/random/dir"
get_random_run_dir = lambda x: os.path.join(random_run_dir, x)
server = manager.Server('proxy', run_dir=random_run_dir)
conf_file = self.join_swift_dir('proxy-server.conf')
pid_file = get_random_run_dir('proxy-server.pid')
self.assertEquals(pid_file, server.get_pid_file_name(conf_file))
server = manager.Server('object-replicator', run_dir=random_run_dir)
conf_file = self.join_swift_dir('object-server/1.conf')
pid_file = get_random_run_dir('object-replicator/1.pid')
self.assertEquals(pid_file, server.get_pid_file_name(conf_file))
server = manager.Server('container-auditor', run_dir=random_run_dir)
conf_file = self.join_swift_dir(
'container-server/1/container-auditor.conf')
pid_file = get_random_run_dir(
'container-auditor/1/container-auditor.pid')
self.assertEquals(pid_file, server.get_pid_file_name(conf_file))
def test_get_conf_file_name(self):
server = manager.Server('proxy')
conf_file = self.join_swift_dir('proxy-server.conf')
@ -450,7 +468,7 @@ class TestServer(unittest.TestCase):
files, contents = zip(*pid_files)
with temptree(files, contents) as t:
manager.RUN_DIR = t
server = manager.Server('proxy')
server = manager.Server('proxy', run_dir=t)
# test get one file
iter = server.iter_pid_files()
pid_file, pid = iter.next()
@ -459,13 +477,13 @@ class TestServer(unittest.TestCase):
# ... and only one file
self.assertRaises(StopIteration, iter.next)
# test invalid value in pid file
server = manager.Server('auth')
server = manager.Server('auth', run_dir=t)
self.assertRaises(ValueError, server.iter_pid_files().next)
# test object-server doesn't steal pids from object-replicator
server = manager.Server('object')
server = manager.Server('object', run_dir=t)
self.assertRaises(StopIteration, server.iter_pid_files().next)
# test multi-pid iter
server = manager.Server('object-replicator')
server = manager.Server('object-replicator', run_dir=t)
real_map = {
11: self.join_run_dir('object-replicator/1.pid'),
12: self.join_run_dir('object-replicator/2.pid'),
@ -494,7 +512,7 @@ class TestServer(unittest.TestCase):
files, pids = zip(*pid_files)
with temptree(files, pids) as t:
manager.RUN_DIR = t
server = manager.Server('object')
server = manager.Server('object', run_dir=t)
# test get all pid files
real_map = {
1: self.join_run_dir('object-server/1.pid'),
@ -530,7 +548,7 @@ class TestServer(unittest.TestCase):
manager.RUN_DIR = t
# mock os with both pids running
manager.os = MockOs([1, 2])
server = manager.Server('proxy')
server = manager.Server('proxy', run_dir=t)
pids = server.signal_pids(DUMMY_SIG)
self.assertEquals(len(pids), 1)
self.assert_(1 in pids)
@ -562,7 +580,7 @@ class TestServer(unittest.TestCase):
self.join_run_dir('proxy-server.pid')))
# reset mock os with no running pids
manager.os = MockOs([])
server = manager.Server('auth')
server = manager.Server('auth', run_dir=t)
# test verbose warns on removing pid file
pids = server.signal_pids(signal.SIG_DFL, verbose=True)
output = pop_stream(f)
@ -570,7 +588,7 @@ class TestServer(unittest.TestCase):
auth_pid = self.join_run_dir('auth-server.pid')
self.assert_(auth_pid in output)
# test warning with insufficient permissions
server = manager.Server('object')
server = manager.Server('object', run_dir=t)
pids = server.signal_pids(manager.os.RAISE_EPERM_SIG)
output = pop_stream(f)
self.assert_('no permission to signal pid 3' in
@ -586,7 +604,7 @@ class TestServer(unittest.TestCase):
)
with temptree(*zip(*pid_files)) as t:
manager.RUN_DIR = t
server = manager.Server('test-server')
server = manager.Server('test-server', run_dir=t)
# mock os, only pid '1' is running
manager.os = MockOs([1])
running_pids = server.get_running_pids()
@ -620,7 +638,7 @@ class TestServer(unittest.TestCase):
manager.RUN_DIR = t
# all pids are running
manager.os = MockOs(pids)
server = manager.Server('thing-doer')
server = manager.Server('thing-doer', run_dir=t)
running_pids = server.get_running_pids()
# only thing-doer.pid, 1
self.assertEquals(len(running_pids), 1)
@ -636,7 +654,7 @@ class TestServer(unittest.TestCase):
self.assert_(os.path.exists, os.path.join(t, f))
# verify that servers are in fact not running
for server_name in ('thing-sayer', 'other-doer', 'other-sayer'):
server = manager.Server(server_name)
server = manager.Server(server_name, run_dir=t)
running_pids = server.get_running_pids()
self.assertFalse(running_pids)
# and now all OTHER pid files are cleaned out
@ -653,7 +671,7 @@ class TestServer(unittest.TestCase):
files, running_pids = zip(*pid_files)
with temptree(files, running_pids) as t:
manager.RUN_DIR = t
server = manager.Server('object')
server = manager.Server('object', run_dir=t)
# test no servers running
manager.os = MockOs([])
pids = server.kill_running_pids()
@ -661,8 +679,10 @@ class TestServer(unittest.TestCase):
files, running_pids = zip(*pid_files)
with temptree(files, running_pids) as t:
manager.RUN_DIR = t
server.run_dir = t
# start up pid
manager.os = MockOs([1])
server = manager.Server('object', run_dir=t)
# test kill one pid
pids = server.kill_running_pids()
self.assertEquals(len(pids), 1)
@ -682,7 +702,7 @@ class TestServer(unittest.TestCase):
# test multi server kill & ignore graceful on unsupported server
self.assertFalse('object-replicator' in
manager.GRACEFUL_SHUTDOWN_SERVERS)
server = manager.Server('object-replicator')
server = manager.Server('object-replicator', run_dir=t)
pids = server.kill_running_pids(graceful=True)
self.assertEquals(len(pids), 2)
for pid in (11, 12):
@ -713,7 +733,7 @@ class TestServer(unittest.TestCase):
with temptree(files, pids) as t:
manager.RUN_DIR = t
# setup running servers
server = manager.Server('test')
server = manager.Server('test', run_dir=t)
# capture stdio
old_stdout = sys.stdout
try:
@ -812,6 +832,7 @@ class TestServer(unittest.TestCase):
manager.SWIFT_DIR = swift_dir
with temptree([]) as t:
manager.RUN_DIR = t
server.run_dir = t
old_subprocess = manager.subprocess
try:
# test single server process calls spawn once
@ -842,7 +863,7 @@ class TestServer(unittest.TestCase):
conf2 = self.join_swift_dir('test-server/2.conf')
conf3 = self.join_swift_dir('test-server/3.conf')
conf4 = self.join_swift_dir('test-server/4.conf')
server = manager.Server('test')
server = manager.Server('test', run_dir=t)
# test server run once
server.spawn(conf1, once=True)
self.assert_(server.procs)
@ -1080,11 +1101,11 @@ class TestServer(unittest.TestCase):
with open(os.path.join(t, 'output'), 'w+') as f:
sys.stdout = f
# can't start server w/o an conf
server = manager.Server('test')
server = manager.Server('test', run_dir=t)
self.assertFalse(server.launch())
# start mock os running all pids
manager.os = MockOs(pids)
server = manager.Server('proxy')
server = manager.Server('proxy', run_dir=t)
# can't start server if it's already running
self.assertFalse(server.launch())
output = pop_stream(f)
@ -1178,7 +1199,7 @@ class TestServer(unittest.TestCase):
manager.RUN_DIR = t
# start all pids in mock os
manager.os = MockOs(pids)
server = manager.Server('account-reaper')
server = manager.Server('account-reaper', run_dir=t)
# test kill all running pids
pids = server.stop()
self.assertEquals(len(pids), 4)
@ -1269,7 +1290,7 @@ class TestManager(unittest.TestCase):
def test_status(self):
class MockServer():
def __init__(self, server):
def __init__(self, server, run_dir=manager.RUN_DIR):
self.server = server
self.called_kwargs = []
@ -1304,7 +1325,7 @@ class TestManager(unittest.TestCase):
getattr(mock_setup_env, 'called', []).append(True)
class MockServer():
def __init__(self, server):
def __init__(self, server, run_dir=manager.RUN_DIR):
self.server = server
self.called = defaultdict(list)
@ -1366,7 +1387,7 @@ class TestManager(unittest.TestCase):
def test_no_wait(self):
class MockServer():
def __init__(self, server):
def __init__(self, server, run_dir=manager.RUN_DIR):
self.server = server
self.called = defaultdict(list)
@ -1417,7 +1438,7 @@ class TestManager(unittest.TestCase):
def test_no_daemon(self):
class MockServer():
def __init__(self, server):
def __init__(self, server, run_dir=manager.RUN_DIR):
self.server = server
self.called = defaultdict(list)
@ -1452,7 +1473,7 @@ class TestManager(unittest.TestCase):
def test_once(self):
class MockServer():
def __init__(self, server):
def __init__(self, server, run_dir=manager.RUN_DIR):
self.server = server
self.called = defaultdict(list)
@ -1489,16 +1510,16 @@ class TestManager(unittest.TestCase):
def test_stop(self):
class MockServerFactory():
class MockServer():
def __init__(self, pids):
def __init__(self, pids, run_dir=manager.RUN_DIR):
self.pids = pids
def stop(self, **kwargs):
return self.pids
def __init__(self, server_pids):
def __init__(self, server_pids, run_dir=manager.RUN_DIR):
self.server_pids = server_pids
def __call__(self, server):
def __call__(self, server, run_dir=manager.RUN_DIR):
return MockServerFactory.MockServer(self.server_pids[server])
def mock_watch_server_pids(server_pids, **kwargs):