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