]> git.rkrishnan.org Git - tahoe-lafs/tahoe-lafs.git/blob - src/allmydata/scripts/startstop_node.py
startstop_node.py: don't pass config to do_start() and do_stop()
[tahoe-lafs/tahoe-lafs.git] / src / allmydata / scripts / startstop_node.py
1
2 import os, sys, signal, time
3 from twisted.python import usage
4 from allmydata.scripts.common import BasedirMixin
5 from allmydata.util import fileutil
6 from twisted.python.procutils import which
7
8 class StartOptions(BasedirMixin, usage.Options):
9     optParameters = [
10         ["basedir", "C", None, "which directory to start the node in"],
11         ]
12
13 class StopOptions(BasedirMixin, usage.Options):
14     optParameters = [
15         ["basedir", "C", None, "which directory to stop the node in"],
16         ]
17
18 class RestartOptions(BasedirMixin, usage.Options):
19     optParameters = [
20         ["basedir", "C", None, "which directory to restart the node in"],
21         ]
22     optFlags = [
23         ["force", "f", "if the node is not already running, start it "
24          "instead of complaining that you should have used 'start' instead "
25          "of 'restart'"],
26         ]
27
28 def do_start(basedir, out=sys.stdout, err=sys.stderr):
29     print >>out, "STARTING", basedir
30     if os.path.exists(os.path.join(basedir, "client.tac")):
31         tac = "client.tac"
32         type = "client"
33     elif os.path.exists(os.path.join(basedir, "introducer.tac")):
34         tac = "introducer.tac"
35         type = "introducer"
36     else:
37         print >>err, "%s does not look like a node directory" % basedir
38         if not os.path.isdir(basedir):
39             print >>err, " in fact, it doesn't look like a directory at all!"
40         return 1
41     twistds = which("twistd")
42     twistd = twistds and twistds[0]
43     if not twistd:
44         twistd = os.path.join(sys.prefix, 'Scripts', 'twistd.py') 
45     if not os.path.exists(twistd):
46         print "Can't find twistd (it comes with Twisted).  Aborting."
47         sys.exit(1)
48     path, ext = os.path.splitext(twistd)
49     if ext.lower() in [".exe", ".bat",]:
50         cmd = [twistd,]
51     else:
52         cmd = [sys.executable, twistd,]
53     
54     fileutil.make_dirs(os.path.join(basedir, "logs"))
55     cmd.extend(["-y", tac, "--logfile", os.path.join("logs", "twistd.log")])
56     curdir = os.getcwd()
57     try:
58         os.chdir(basedir)
59         rc = os.system(' '.join(cmd))
60     finally:
61         os.chdir(curdir)
62     if rc == 0:
63         print >>out, "%s node probably started" % type
64         return 0
65     else:
66         print >>err, "%s node probably not started" % type
67         return 1
68
69 def do_stop(basedir, out=sys.stdout, err=sys.stderr):
70     print >>out, "STOPPING", basedir
71     pidfile = os.path.join(basedir, "twistd.pid")
72     if not os.path.exists(pidfile):
73         print >>err, "%s does not look like a running node directory (no twistd.pid)" % basedir
74         return 2
75     pid = open(pidfile, "r").read()
76     pid = int(pid)
77
78     timer = 0
79     try:
80         os.kill(pid, signal.SIGINT)
81     except OSError, oserr:
82         if oserr.errno == 3:
83             print oserr.strerror
84             return 1
85         else:
86             raise
87     time.sleep(0.1)
88     while timer < 5:
89         # poll once per second until twistd.pid goes away, up to 5 seconds
90         try:
91             os.kill(pid, 0)
92         except OSError:
93             print >>out, "process %d is dead" % pid
94             return
95         timer += 1
96         time.sleep(1)
97     print >>err, "never saw process go away"
98     return 1
99
100 def start(config, stdout, stderr):
101     rc = 0
102     for basedir in config['basedirs']:
103         rc = do_start(basedir, stdout, stderr) or rc
104     return rc
105
106 def stop(config, stdout, stderr):
107     rc = 0
108     for basedir in config['basedirs']:
109         rc = do_stop(basedir, stdout, stderr) or rc
110     return rc
111
112 def restart(config, stdout, stderr):
113     rc = 0
114     for basedir in config['basedirs']:
115         rc = do_stop(basedir, stdout, stderr) or rc
116     if rc == 2 and config['force']:
117         print >>stderr, "ignoring couldn't-stop"
118         rc = 0
119     if rc:
120         print >>stderr, "not restarting"
121         return rc
122     for basedir in config['basedirs']:
123         rc = do_start(basedir, stdout, stderr) or rc
124     return rc
125
126
127 subCommands = [
128     ["start", None, StartOptions, "Start a node (of any type)."],
129     ["stop", None, StopOptions, "Stop a node."],
130     ["restart", None, RestartOptions, "Restart a node."],
131 ]
132
133 dispatch = {
134     "start": start,
135     "stop": stop,
136     "restart": restart,
137     }