3 import os, subprocess, sys, signal, time
4 from twisted.python import usage
6 from twisted.python.procutils import which
10 return subprocess.call(["python", loc,], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
16 for maybetwistd in which("twistd"):
17 ret = testtwistd(maybetwistd)
23 for maybetwistd in which("twistd.py"):
24 ret = testtwistd(maybetwistd)
30 maybetwistd = os.path.join(sys.prefix, 'Scripts', 'twistd')
31 ret = testtwistd(maybetwistd)
36 maybetwistd = os.path.join(sys.prefix, 'Scripts', 'twistd.py')
37 ret = testtwistd(maybetwistd)
42 print "Can't find twistd (it comes with Twisted). Aborting."
46 def postOptions(self):
47 if self['basedir'] is None:
48 raise usage.UsageError("<basedir> parameter is required")
49 self['basedir'] = os.path.abspath(os.path.expanduser(self['basedir']))
51 class StartOptions(BasedirMixin, usage.Options):
53 ["basedir", "C", ".", "which directory to start the node in"],
56 class StopOptions(BasedirMixin, usage.Options):
58 ["basedir", "C", ".", "which directory to stop the node in"],
61 class RestartOptions(BasedirMixin, usage.Options):
63 ["basedir", "C", ".", "which directory to restart the node in"],
66 class CreateClientOptions(BasedirMixin, usage.Options):
68 ["basedir", "C", None, "which directory to create the client in"],
71 ["quiet", "q", "operate silently"],
74 def parseArgs(self, *args):
76 self['basedir'] = args[0]
78 raise usage.UsageError("I wasn't expecting so many arguments")
80 class CreateIntroducerOptions(BasedirMixin, usage.Options):
82 ["basedir", "C", None, "which directory to create the introducer in"],
85 ["quiet", "q", "operate silently"],
88 def parseArgs(self, *args):
90 self['basedir'] = args[0]
92 raise usage.UsageError("I wasn't expecting so many arguments")
97 from allmydata import client
98 from twisted.application import service
102 application = service.Application("allmydata_client")
103 c.setServiceParent(application)
109 from allmydata import introducer_and_vdrive
110 from twisted.application import service
112 c = introducer_and_vdrive.IntroducerAndVdrive()
114 application = service.Application("allmydata_introducer")
115 c.setServiceParent(application)
118 class Options(usage.Options):
119 synopsis = "Usage: allmydata <command> [command options]"
122 ["create-client", None, CreateClientOptions, "Create a client node."],
123 ["create-introducer", None, CreateIntroducerOptions, "Create a introducer node."],
124 ["start", None, StartOptions, "Start a node (of any type)."],
125 ["stop", None, StopOptions, "Stop a node."],
126 ["restart", None, RestartOptions, "Restart a node."],
129 def postOptions(self):
130 if not hasattr(self, 'subOptions'):
131 raise usage.UsageError("must specify a command")
133 def runner(argv, run_by_human=True):
136 config.parseOptions(argv)
137 except usage.error, e:
140 print "%s: %s" % (sys.argv[0], e)
142 c = getattr(config, 'subOptions', config)
146 command = config.subCommand
147 so = config.subOptions
149 if command == "create-client":
150 rc = create_client(so)
151 elif command == "create-introducer":
152 rc = create_introducer(so)
153 elif command == "start":
155 elif command == "stop":
157 elif command == "restart":
163 rc = runner(sys.argv[1:])
166 def create_client(config):
167 basedir = config['basedir']
168 if os.path.exists(basedir):
169 if os.listdir(basedir):
170 print "The base directory already exists: %s" % basedir
171 print "To avoid clobbering anything, I am going to quit now"
172 print "Please use a different directory, or delete this one"
174 # we're willing to use an empty directory
177 f = open(os.path.join(basedir, "client.tac"), "w")
180 if not config['quiet']:
181 print "client created in %s" % basedir
182 print " please copy introducer.furl and vdrive.furl into the directory"
184 def create_introducer(config):
185 basedir = config['basedir']
186 if os.path.exists(basedir):
187 if os.listdir(basedir):
188 print "The base directory already exists: %s" % basedir
189 print "To avoid clobbering anything, I am going to quit now"
190 print "Please use a different directory, or delete this one"
192 # we're willing to use an empty directory
195 f = open(os.path.join(basedir, "introducer.tac"), "w")
196 f.write(introducer_tac)
198 if not config['quiet']:
199 print "introducer created in %s" % basedir
202 basedir = config['basedir']
203 if os.path.exists(os.path.join(basedir, "client.tac")):
206 elif os.path.exists(os.path.join(basedir, "introducer.tac")):
207 tac = "introducer.tac"
210 print "%s does not look like a node directory" % basedir
211 if not os.path.isdir(basedir):
212 print " in fact, it doesn't look like a directory at all!"
215 rc = subprocess.call(["python", twistd, "-y", tac,])
217 print "%s node probably started" % type
220 print "%s node probably not started" % type
224 basedir = config['basedir']
225 pidfile = os.path.join(basedir, "twistd.pid")
226 if not os.path.exists(pidfile):
227 print "%s does not look like a running node directory (no twistd.pid)" % basedir
229 pid = open(pidfile, "r").read()
233 os.kill(pid, signal.SIGTERM)
236 # poll once per second until twistd.pid goes away, up to 5 seconds
240 print "process %d is dead" % pid
244 print "never saw process go away"
250 print "not restarting"