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:
parent
b8626f9667
commit
3282e3885c
@ -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:
|
||||
|
@ -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())
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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):
|
||||
|
Loading…
Reference in New Issue
Block a user