]> git.rkrishnan.org Git - tahoe-lafs/tahoe-lafs.git/blob - src/allmydata/scripts/runner.py
replace 'queen' with 'introducer' in a lot of places, but not all
[tahoe-lafs/tahoe-lafs.git] / src / allmydata / scripts / runner.py
1 #! /usr/bin/env python
2
3 import os, sys, signal, time
4 from twisted.python import usage
5
6 class StartOptions(usage.Options):
7     optParameters = [
8         ["basedir", "C", ".", "which directory to start the node in"],
9         ]
10
11 class StopOptions(usage.Options):
12     optParameters = [
13         ["basedir", "C", ".", "which directory to stop the node in"],
14         ]
15
16 class RestartOptions(usage.Options):
17     optParameters = [
18         ["basedir", "C", ".", "which directory to restart the node in"],
19         ]
20
21 class CreateClientOptions(usage.Options):
22     optParameters = [
23         ["basedir", "C", None, "which directory to create the client in"],
24         ]
25
26     def parseArgs(self, *args):
27         if len(args) > 0:
28             self['basedir'] = args[0]
29         if len(args) > 1:
30             raise usage.UsageError("I wasn't expecting so many arguments")
31
32     def postOptions(self):
33         if self['basedir'] is None:
34             raise usage.UsageError("<basedir> parameter is required")
35         self['basedir'] = os.path.abspath(self['basedir'])
36
37 class CreateIntroducerOptions(usage.Options):
38     optParameters = [
39         ["basedir", "C", None, "which directory to create the introducer in"],
40         ]
41
42     def parseArgs(self, *args):
43         if len(args) > 0:
44             self['basedir'] = args[0]
45         if len(args) > 1:
46             raise usage.UsageError("I wasn't expecting so many arguments")
47
48     def postOptions(self):
49         if self['basedir'] is None:
50             raise usage.UsageError("<basedir> parameter is required")
51         self['basedir'] = os.path.abspath(self['basedir'])
52
53 client_tac = """
54 # -*- python -*-
55
56 from allmydata import client
57 from twisted.application import service
58
59 c = client.Client()
60
61 application = service.Application("allmydata_client")
62 c.setServiceParent(application)
63 """
64
65 introducer_tac = """
66 # -*- python -*-
67
68 from allmydata import queen
69 from twisted.application import service
70
71 c = queen.Queen()
72
73 application = service.Application("allmydata_introducer")
74 c.setServiceParent(application)
75 """
76
77 class Options(usage.Options):
78     synopsis = "Usage:  allmydata <command> [command options]"
79
80     subCommands = [
81         ["create-client", None, CreateClientOptions, "Create a client node."],
82         ["create-introducer", None, CreateIntroducerOptions, "Create a introducer node."],
83         ["start", None, StartOptions, "Start a node (of any type)."],
84         ["stop", None, StopOptions, "Stop a node."],
85         ["restart", None, RestartOptions, "Restart a node."],
86         ]
87
88     def postOptions(self):
89         if not hasattr(self, 'subOptions'):
90             raise usage.UsageError("must specify a command")
91
92 def run():
93     config = Options()
94     try:
95         config.parseOptions()
96     except usage.error, e:
97         print "%s:  %s" % (sys.argv[0], e)
98         print
99         c = getattr(config, 'subOptions', config)
100         print str(c)
101         sys.exit(1)
102
103     command = config.subCommand
104     so = config.subOptions
105
106     if command == "create-client":
107         rc = create_client(so)
108     elif command == "create-introducer":
109         rc = create_introducer(so)
110     elif command == "start":
111         rc = start(so)
112     elif command == "stop":
113         rc = stop(so)
114     elif command == "restart":
115         rc = restart(so)
116     rc = rc or 0
117     sys.exit(rc)
118
119 def create_client(config):
120     basedir = config['basedir']
121     if os.path.exists(basedir):
122         if os.listdir(basedir):
123             print "The base directory already exists: %s" % basedir
124             print "To avoid clobbering anything, I am going to quit now"
125             print "Please use a different directory, or delete this one"
126             return -1
127         # we're willing to use an empty directory
128     else:
129         os.mkdir(basedir)
130     f = open(os.path.join(basedir, "client.tac"), "w")
131     f.write(client_tac)
132     f.close()
133     print "client created in %s" % basedir
134     print " please copy introducer.furl and vdrive.furl into the directory"
135
136 def create_introducer(config):
137     basedir = config['basedir']
138     if os.path.exists(basedir):
139         if os.listdir(basedir):
140             print "The base directory already exists: %s" % basedir
141             print "To avoid clobbering anything, I am going to quit now"
142             print "Please use a different directory, or delete this one"
143             return -1
144         # we're willing to use an empty directory
145     else:
146         os.mkdir(basedir)
147     f = open(os.path.join(basedir, "introducer.tac"), "w")
148     f.write(introducer_tac)
149     f.close()
150     print "introducer created in %s" % basedir
151
152 def start(config):
153     basedir = config['basedir']
154     if os.path.exists(os.path.join(basedir, "client.tac")):
155         tac = "client.tac"
156         type = "client"
157     elif os.path.exists(os.path.join(basedir, "introducer.tac")):
158         tac = "introducer.tac"
159         type = "introducer"
160     else:
161         print "%s does not look like a node directory" % basedir
162         sys.exit(1)
163     os.chdir(basedir)
164     rc = os.system("twistd -y %s" % tac)
165     if rc == 0:
166         print "%s node probably started" % type
167         return 0
168     else:
169         print "%s node probably not started" % type
170         return 1
171
172 def stop(config):
173     basedir = config['basedir']
174     pidfile = os.path.join(basedir, "twistd.pid")
175     if not os.path.exists(pidfile):
176         print "%s does not look like a running node directory (no twistd.pid)" % basedir
177         return 1
178     pid = open(pidfile, "r").read()
179     pid = int(pid)
180
181     timer = 0
182     os.kill(pid, signal.SIGTERM)
183     time.sleep(0.1)
184     while timer < 5:
185         # poll once per second until twistd.pid goes away, up to 5 seconds
186         try:
187             os.kill(pid, 0)
188         except OSError:
189             print "process %d is dead" % pid
190             return
191         timer += 1
192         time.sleep(1)
193     print "never saw process go away"
194     return 1
195
196 def restart(config):
197     rc = stop(config)
198     if rc:
199         print "not restarting"
200         return rc
201     return start(config)