115 lines
2.8 KiB
Python
Executable File
115 lines
2.8 KiB
Python
Executable File
#!/usr/bin/env python
|
|
|
|
USAGE="""
|
|
fx-rpc -- run programs written with garry's makeshift sockets api thing
|
|
|
|
more help to come
|
|
"""
|
|
|
|
import os
|
|
import signal
|
|
import sys
|
|
import util
|
|
import time
|
|
import random
|
|
|
|
# note: we're not using fx for parameter parsing right now...
|
|
|
|
if len(sys.argv) <= 1:
|
|
print USAGE
|
|
os.exit(1);
|
|
|
|
do_gdb = False
|
|
args = sys.argv[1:]
|
|
|
|
while True:
|
|
if args[0] == "--gdb":
|
|
args = args[1:]
|
|
do_gdb = True
|
|
else:
|
|
break
|
|
|
|
n = int(args[0])
|
|
if n <= 0:
|
|
print "error: n must be positive"
|
|
os.exit(1)
|
|
|
|
peers = args[1]
|
|
executable = args[2]
|
|
user_args = args[3:]
|
|
cwd = os.getcwd()
|
|
|
|
port = random.randrange(10000, 64000)
|
|
|
|
peerlist = util.readlines(peers)
|
|
|
|
pids = {}
|
|
log = sys.stderr
|
|
rootpid = -1
|
|
rootexitcode = 0
|
|
|
|
try:
|
|
for rank in range(n):
|
|
machinename = peerlist[rank]
|
|
print >> log, "****** CONNECTING TO %s ******" % machinename
|
|
rpc_args = [
|
|
"--rpc/peers=%s"%peers,
|
|
"--rpc/n=%d"%n,
|
|
"--rpc/port=%d"%port,
|
|
"--rpc/rank=%d"%rank]
|
|
chdir_prefix = ["cd", cwd, "&&"]
|
|
if not do_gdb:
|
|
remote_command = [executable] + user_args + rpc_args
|
|
# arguments: -x -T -n means no X11, no standard input, no TTY
|
|
# StrictHostKeyChecking=no means don't prompt "Do you really want to connect?"
|
|
# We turn off number of password prompts. We'd rather SSH die than
|
|
# sit indefinitely waiting for a password.
|
|
argv = ["ssh", "-x", "-T", "-n", "-o", "StrictHostKeyChecking=no",
|
|
"-o", "NumberOfPasswordPrompts=0",
|
|
machinename, " ".join(chdir_prefix + remote_command)]
|
|
else:
|
|
filename = os.path.abspath("fx-rpc.gdb.%d" % rank)
|
|
gdb_command = ["run"] + [util.shellquote(x) for x in user_args + rpc_args]
|
|
util.writelines(filename, [" ".join(gdb_command)])
|
|
remote_command = ["xterm", "-e", "gdb", executable, "-x", filename]
|
|
argv = ["ssh", "-o", "StrictHostKeyChecking=no",
|
|
machinename, " ".join(chdir_prefix + remote_command)]
|
|
|
|
print >> log, " ".join(argv)
|
|
pid = os.fork()
|
|
if not pid:
|
|
os.execvp(argv[0], argv)
|
|
pids[pid] = rank
|
|
time.sleep(0.5)
|
|
|
|
while pids:
|
|
(pid, status) = os.wait()
|
|
rank = pids.pop(pid)
|
|
exitcode = util.getstatus(status)
|
|
if exitcode < 0:
|
|
exitmsg = "killed unexpectedly"
|
|
elif exitcode == 0:
|
|
exitmsg = "finished successfully"
|
|
else:
|
|
exitmsg = "returned an error"
|
|
print >> log, "*********** Machine #%d %s (code %d)" % (rank, exitmsg, exitcode)
|
|
if rank == 0:
|
|
rootexitcode = exitcode
|
|
|
|
finally:
|
|
for pid in pids:
|
|
try:
|
|
os.kill(pid, signal.SIGINT)
|
|
print >> log, "Kill successful for %d" % pid
|
|
except:
|
|
try:
|
|
os.kill(pid, signal.SIGTERM)
|
|
except:
|
|
try:
|
|
os.kill(pid, signal.SIGKILL)
|
|
except:
|
|
print >> log, "Kill failed for %d" % pid
|
|
|
|
sys.exit(exitcode)
|
|
|