#! /usr/bin/env python import subprocess, os, time from twisted.python.filepath import FilePath def create_log_dir(): """ Sets up per-run log directories. The directory name is the time of run initiation. """ logdir = FilePath(os.getcwd()).child('logs').child(str(time.time())[:-3]) logdir.makedirs() return logdir.path def create_introducer(executable, nodedirname): """ Creates and starts a new introducer if one does not exist. If one does exist, restart it. Returns grid furl and log directory (created by call to create_log_dir). """ # Log directory setup logdirname = create_log_dir() print "logdirname: ", logdirname stdoutintro = FilePath(os.path.join(logdirname, 'stdoutgridcreation')).open(mode='a') stderrintro = FilePath(os.path.join(logdirname, 'stderrgridcreation')).open(mode='a') stdinpintro = FilePath(os.path.join(logdirname, 'stdinpgridcreation')).open(mode='a') # Node directory setup, or restart if already exists intronodedir = FilePath(nodedirname) if not intronodedir.exists(): print "Did we execute the introducermaker code?" intronodedir.makedirs() introducermaker = subprocess.Popen([executable , 'create-introducer' , '--node-directory=' + nodedirname] , stdin = stdinpintro , stdout = stdoutintro , stderr = stderrintro) time.sleep(10) furlmaker = subprocess.Popen([executable , 'start' , nodedirname] , stdin = stdinpintro , stdout = stdoutintro , stderr = stderrintro) elif intronodedir.exists(): furlmaker = subprocess.Popen([executable , 'restart' , nodedirname] , stdin = stdinpintro , stdout = stdoutintro , stderr = stderrintro) # Get the furl to share with clients fptointroducerfurl = FilePath(os.path.join(os.path.abspath(nodedirname), 'introducer.furl')) while not fptointroducerfurl.exists(): # Kludge so that the script waits for introducer.furl files to exist before proceeding. time.sleep(10) print "fptointroducerfurl %s does not yet exist." % fptointroducerfurl.path introducerfurl = fptointroducerfurl.getContent().rstrip('\n') return introducerfurl, logdirname def create_node(nodedirname, furl_string, logs, port_number, executable): """ Creates a client node. Requires a grid furl. """ clientdir_fp = FilePath(nodedirname) if not clientdir_fp.exists(): clientdir_fp.makedirs() log_prefix = os.path.join(logs, nodedirname) print "log_prefix: ", log_prefix web_port_string = 'tcp:'+str(port_number)+':interface=127.0.0.1' stdoutclient = FilePath(os.path.abspath(log_prefix+'_stdout')).open(mode='w') stderrclient = FilePath(os.path.abspath(log_prefix+'_stderr')).open(mode='w') stdinpclient = FilePath(os.path.abspath(log_prefix+'_stdinp')).open(mode='w') clientmaker = subprocess.Popen([executable , 'create-node' , '--introducer=' + furl_string , '--node-directory=' + nodedirname , '--webport=' + web_port_string] , stdin = stdinpclient , stdout = stdoutclient , stderr = stderrclient) return nodedirname def main(): print "os.getcwd(): ", os.getcwd() import argparse parser = argparse.ArgumentParser(description='Start or stop a local grid of N nodes, and one introducer.') parser.add_argument('executable', help='which tahoe executable to use', type=str, nargs=1) parser.add_argument('command', help='start or stop the local-grid optionally specify number of servers') parser.add_argument('--number_of_storage_servers', metavar='N', type=int, nargs='?' , dest='num_servers' , default=10 , help='how many storage servers') args = parser.parse_args() print "args: ",args executable = args.executable[0] if args.command == 'start': NUMBEROFNODES = args.num_servers grid_furl, logdirname = create_introducer(executable, 'testintronode') port_number = 3457 for index in range(NUMBEROFNODES): client_name = 'ClientNode'+str(index) target_directory = create_node(client_name, grid_furl, logdirname, port_number + index, executable) client_tac_fp = FilePath(target_directory).child('tahoe-client.tac') while not client_tac_fp.exists(): # Kludge so that the script waits for introducer.furl files to exist before proceeding. time.sleep(10) print "Are we stuck here?" client_starter = subprocess.Popen([executable , 'start' , os.path.abspath(client_name)]) elif args.command == 'stop': stoplogdirname = create_log_dir() print "stoplogdirname: ", stoplogdirname starting_fp = FilePath(os.getcwd()) for child_fp in starting_fp.walk(): if child_fp.isdir() and 'twistd.pid' in child_fp.listdir(): log_prefix = os.path.join(stoplogdirname, starting_fp.basename()) print "starting_fp.path: ", starting_fp.path print "log_prefix: ", log_prefix stdoutstop = FilePath(os.path.abspath(log_prefix+'_stdout_stopping')).open(mode='w') stderrstop = FilePath(os.path.abspath(log_prefix+'_stderr_stopping')).open(mode='w') stdinpstop = FilePath(os.path.abspath(log_prefix+'_stdinp_stopping')).open(mode='w') kill_process = subprocess.Popen([executable , 'stop' , child_fp.path] , stdin = stdinpstop , stdout = stdoutstop , stderr = stderrstop) if __name__ == '__main__': main()