1 | #! /usr/bin/env python |
---|
2 | |
---|
3 | import subprocess, os, time |
---|
4 | from twisted.python.filepath import FilePath |
---|
5 | |
---|
6 | def create_log_dir(): |
---|
7 | """ |
---|
8 | Sets up per-run log directories. The directory name is the time of run initiation. |
---|
9 | """ |
---|
10 | logdir = FilePath(os.getcwd()).child('logs').child(str(time.time())[:-3]) |
---|
11 | logdir.makedirs() |
---|
12 | return logdir.path |
---|
13 | |
---|
14 | def create_introducer(executable, nodedirname): |
---|
15 | """ |
---|
16 | Creates and starts a new introducer if one does not exist. If one does exist, restart |
---|
17 | it. Returns grid furl and log directory (created by call to create_log_dir). |
---|
18 | """ |
---|
19 | # Log directory setup |
---|
20 | logdirname = create_log_dir() |
---|
21 | print "logdirname: ", logdirname |
---|
22 | stdoutintro = FilePath(os.path.join(logdirname, 'stdoutgridcreation')).open(mode='a') |
---|
23 | stderrintro = FilePath(os.path.join(logdirname, 'stderrgridcreation')).open(mode='a') |
---|
24 | stdinpintro = FilePath(os.path.join(logdirname, 'stdinpgridcreation')).open(mode='a') |
---|
25 | |
---|
26 | # Node directory setup, or restart if already exists |
---|
27 | intronodedir = FilePath(nodedirname) |
---|
28 | if not intronodedir.exists(): |
---|
29 | print "Did we execute the introducermaker code?" |
---|
30 | intronodedir.makedirs() |
---|
31 | introducermaker = subprocess.Popen([executable |
---|
32 | , 'create-introducer' |
---|
33 | , '--node-directory=' + nodedirname] |
---|
34 | , stdin = stdinpintro |
---|
35 | , stdout = stdoutintro |
---|
36 | , stderr = stderrintro) |
---|
37 | time.sleep(10) |
---|
38 | |
---|
39 | furlmaker = subprocess.Popen([executable |
---|
40 | , 'start' |
---|
41 | , nodedirname] |
---|
42 | , stdin = stdinpintro |
---|
43 | , stdout = stdoutintro |
---|
44 | , stderr = stderrintro) |
---|
45 | elif intronodedir.exists(): |
---|
46 | furlmaker = subprocess.Popen([executable |
---|
47 | , 'restart' |
---|
48 | , nodedirname] |
---|
49 | , stdin = stdinpintro |
---|
50 | , stdout = stdoutintro |
---|
51 | , stderr = stderrintro) |
---|
52 | |
---|
53 | # Get the furl to share with clients |
---|
54 | fptointroducerfurl = FilePath(os.path.join(os.path.abspath(nodedirname), 'introducer.furl')) |
---|
55 | while not fptointroducerfurl.exists(): |
---|
56 | # Kludge so that the script waits for introducer.furl files to exist before proceeding. |
---|
57 | time.sleep(10) |
---|
58 | print "fptointroducerfurl %s does not yet exist." % fptointroducerfurl.path |
---|
59 | introducerfurl = fptointroducerfurl.getContent().rstrip('\n') |
---|
60 | return introducerfurl, logdirname |
---|
61 | |
---|
62 | def create_node(nodedirname, furl_string, logs, port_number, executable): |
---|
63 | """ |
---|
64 | Creates a client node. Requires a grid furl. |
---|
65 | """ |
---|
66 | clientdir_fp = FilePath(nodedirname) |
---|
67 | if not clientdir_fp.exists(): |
---|
68 | clientdir_fp.makedirs() |
---|
69 | log_prefix = os.path.join(logs, nodedirname) |
---|
70 | print "log_prefix: ", log_prefix |
---|
71 | web_port_string = 'tcp:'+str(port_number)+':interface=127.0.0.1' |
---|
72 | stdoutclient = FilePath(os.path.abspath(log_prefix+'_stdout')).open(mode='w') |
---|
73 | stderrclient = FilePath(os.path.abspath(log_prefix+'_stderr')).open(mode='w') |
---|
74 | stdinpclient = FilePath(os.path.abspath(log_prefix+'_stdinp')).open(mode='w') |
---|
75 | clientmaker = subprocess.Popen([executable |
---|
76 | , 'create-node' |
---|
77 | , '--introducer=' + furl_string |
---|
78 | , '--node-directory=' + nodedirname |
---|
79 | , '--webport=' + web_port_string] |
---|
80 | , stdin = stdinpclient |
---|
81 | , stdout = stdoutclient |
---|
82 | , stderr = stderrclient) |
---|
83 | return nodedirname |
---|
84 | |
---|
85 | def main(): |
---|
86 | print "os.getcwd(): ", os.getcwd() |
---|
87 | import argparse |
---|
88 | parser = argparse.ArgumentParser(description='Start or stop a local grid of N nodes, and one introducer.') |
---|
89 | parser.add_argument('executable', help='which tahoe executable to use', type=str, nargs=1) |
---|
90 | parser.add_argument('command', help='start or stop the local-grid optionally specify number of servers') |
---|
91 | parser.add_argument('--number_of_storage_servers', metavar='N', type=int, nargs='?' |
---|
92 | , dest='num_servers' |
---|
93 | , default=10 |
---|
94 | , help='how many storage servers') |
---|
95 | args = parser.parse_args() |
---|
96 | print "args: ",args |
---|
97 | executable = args.executable[0] |
---|
98 | if args.command == 'start': |
---|
99 | NUMBEROFNODES = args.num_servers |
---|
100 | grid_furl, logdirname = create_introducer(executable, 'testintronode') |
---|
101 | port_number = 3457 |
---|
102 | for index in range(NUMBEROFNODES): |
---|
103 | client_name = 'ClientNode'+str(index) |
---|
104 | target_directory = create_node(client_name, grid_furl, logdirname, port_number + index, executable) |
---|
105 | client_tac_fp = FilePath(target_directory).child('tahoe-client.tac') |
---|
106 | while not client_tac_fp.exists(): |
---|
107 | # Kludge so that the script waits for introducer.furl files to exist before proceeding. |
---|
108 | time.sleep(10) |
---|
109 | print "Are we stuck here?" |
---|
110 | client_starter = subprocess.Popen([executable |
---|
111 | , 'start' |
---|
112 | , os.path.abspath(client_name)]) |
---|
113 | elif args.command == 'stop': |
---|
114 | stoplogdirname = create_log_dir() |
---|
115 | print "stoplogdirname: ", stoplogdirname |
---|
116 | starting_fp = FilePath(os.getcwd()) |
---|
117 | for child_fp in starting_fp.walk(): |
---|
118 | if child_fp.isdir() and 'twistd.pid' in child_fp.listdir(): |
---|
119 | log_prefix = os.path.join(stoplogdirname, starting_fp.basename()) |
---|
120 | print "starting_fp.path: ", starting_fp.path |
---|
121 | print "log_prefix: ", log_prefix |
---|
122 | stdoutstop = FilePath(os.path.abspath(log_prefix+'_stdout_stopping')).open(mode='w') |
---|
123 | stderrstop = FilePath(os.path.abspath(log_prefix+'_stderr_stopping')).open(mode='w') |
---|
124 | stdinpstop = FilePath(os.path.abspath(log_prefix+'_stdinp_stopping')).open(mode='w') |
---|
125 | kill_process = subprocess.Popen([executable |
---|
126 | , 'stop' |
---|
127 | , child_fp.path] |
---|
128 | , stdin = stdinpstop |
---|
129 | , stdout = stdoutstop |
---|
130 | , stderr = stderrstop) |
---|
131 | if __name__ == '__main__': |
---|
132 | main() |
---|