OLD | NEW |
---|---|
(Empty) | |
1 #!/usr/bin/env python | |
2 # | |
3 # Copyright 2012 the V8 project authors. All rights reserved. | |
4 # Redistribution and use in source and binary forms, with or without | |
5 # modification, are permitted provided that the following conditions are | |
6 # met: | |
7 # | |
8 # * Redistributions of source code must retain the above copyright | |
9 # notice, this list of conditions and the following disclaimer. | |
10 # * Redistributions in binary form must reproduce the above | |
11 # copyright notice, this list of conditions and the following | |
12 # disclaimer in the documentation and/or other materials provided | |
13 # with the distribution. | |
14 # * Neither the name of Google Inc. nor the names of its | |
15 # contributors may be used to endorse or promote products derived | |
16 # from this software without specific prior written permission. | |
17 # | |
18 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
19 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
20 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
21 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
22 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
23 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
24 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
25 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
26 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
27 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
28 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
29 | |
30 | |
31 import os | |
32 import subprocess | |
33 import sys | |
34 | |
35 | |
36 PIDFILE = "/tmp/v8-distributed-testing-server.pid" | |
37 ROOT = os.path.abspath(os.path.dirname(sys.argv[0])) | |
38 | |
39 | |
40 def _PrintUsage(): | |
41 print("""Usage: python %s COMMAND | |
42 | |
43 Where COMMAND can be any of: | |
44 start Starts the server. Forks to the background. | |
45 stop Stops the server. | |
46 restart Stops, then restarts the server. | |
47 setup Creates or updates the environment for the server to run. | |
48 update Alias for "setup". | |
49 trust <keyfile> Adds the given public key to the list of trusted keys. | |
50 help Displays this help text. | |
51 """ % sys.argv[0]) | |
52 | |
53 | |
54 def _IsDaemonRunning(): | |
55 return os.path.exists(PIDFILE) | |
56 | |
57 | |
58 def _Cmd(cmd): | |
59 code = subprocess.call(cmd, shell=True) | |
60 if code != 0: | |
61 print("Command '%s' returned error code %d" % (cmd, code)) | |
62 sys.exit(code) | |
63 | |
64 | |
65 def Update(): | |
66 # Create directory for private data storage. | |
67 data_dir = os.path.join(ROOT, "data") | |
68 if not os.path.exists(data_dir): | |
69 os.makedirs(data_dir) | |
70 | |
71 # Create directory for trusted public keys of peers (and self). | |
72 trusted_dir = os.path.join(ROOT, "trusted") | |
73 if not os.path.exists(trusted_dir): | |
74 os.makedirs(trusted_dir) | |
75 | |
76 # Install UltraJSON. It is much faster than Python's builtin json. | |
77 try: | |
78 import ujson #@UnusedImport | |
79 except ImportError: | |
80 # Install pip if it doesn't exist. | |
81 code = subprocess.call("which pip", shell=True) | |
82 if code != 0: | |
83 apt_get_code = subprocess.call("which apt-get", shell=True) | |
84 if apt_get_code == 0: | |
85 print("Installing pip...") | |
86 _Cmd("sudo apt-get install python-pip") | |
87 print("Updating pip using itself...") | |
88 _Cmd("sudo pip install --upgrade pip") | |
89 else: | |
90 print("Please install pip on your machine. You can get it at: " | |
91 "http://www.pip-installer.org/en/latest/installing.html " | |
92 "or via your distro's package manager.") | |
93 sys.exit(1) | |
94 print("Using pip to install UltraJSON...") | |
95 _Cmd("sudo pip install ujson") | |
96 | |
97 # Make sure we have a key pair for signing binaries. | |
98 privkeyfile = os.path.expanduser("~/.ssh/v8_dtest") | |
Michael Starzinger
2012/09/21 13:24:33
I am not sure if we should put this key into the u
Jakob Kummerow
2012/09/21 17:02:24
Actually, there's a good reason to keep it in a kn
| |
99 if not os.path.exists(privkeyfile): | |
100 _Cmd("ssh-keygen -t rsa -f %s -N '' -q" % privkeyfile) | |
101 fingerprint = subprocess.check_output("ssh-keygen -lf %s" % privkeyfile, | |
102 shell=True) | |
103 fingerprint = fingerprint.split(" ")[1].replace(":", "")[:16] | |
104 pubkeyfile = os.path.join(trusted_dir, "%s.pem" % fingerprint) | |
105 if (not os.path.exists(pubkeyfile) or | |
106 os.path.getmtime(pubkeyfile) < os.path.getmtime(privkeyfile)): | |
107 _Cmd("openssl rsa -in %s -out %s -pubout" % (privkeyfile, pubkeyfile)) | |
108 with open(pubkeyfile, "a") as f: | |
109 f.write(fingerprint + "\n") | |
110 datafile = os.path.join(data_dir, "mypubkey") | |
111 with open(datafile, "w") as f: | |
112 f.write(fingerprint + "\n") | |
113 | |
114 # Check out or update the server implementation in the current directory. | |
115 testrunner_dir = os.path.join(ROOT, "testrunner") | |
116 if os.path.exists(os.path.join(testrunner_dir, "server/daemon.py")): | |
117 _Cmd("cd %s; svn up" % testrunner_dir) | |
118 else: | |
119 path = ("http://v8.googlecode.com/svn/branches/bleeding_edge/" | |
120 "tools/testrunner") | |
121 _Cmd("svn checkout --force %s %s" % (path, testrunner_dir)) | |
122 | |
123 # Update this very script. | |
124 path = ("http://v8.googlecode.com/svn/branches/bleeding_edge/" | |
125 "tools/server.py") | |
126 scriptname = os.path.abspath(sys.argv[0]) | |
127 _Cmd("svn cat %s > %s" % (path, scriptname)) | |
128 | |
129 # Check out or update V8. | |
130 v8_dir = os.path.join(ROOT, "v8") | |
131 if os.path.exists(v8_dir): | |
132 _Cmd("cd %s; git fetch" % v8_dir) | |
133 else: | |
134 _Cmd("git clone git://github.com/v8/v8.git %s" % v8_dir) | |
135 | |
136 print("Finished.") | |
137 | |
138 | |
139 # Handle "setup" here, because when executing that we can't import anything | |
140 # else yet. | |
141 if __name__ == "__main__" and len(sys.argv) == 2: | |
142 if sys.argv[1] in ("setup", "update"): | |
143 if _IsDaemonRunning(): | |
144 print("Please stop the server before updating. Exiting.") | |
145 sys.exit(1) | |
146 Update() | |
147 sys.exit(0) | |
148 # Other parameters are handled below. | |
149 | |
150 | |
Michael Starzinger
2012/09/21 13:20:40
We probably should add a separating comment line h
Jakob Kummerow
2012/09/21 17:02:24
Done.
| |
151 try: | |
152 from testrunner.server import constants | |
153 from testrunner.server import local_handler | |
154 from testrunner.server import main | |
155 except Exception, e: | |
156 print(e) | |
157 print("Failed to import implementation. Have you run 'setup'?") | |
158 sys.exit(1) | |
159 | |
160 | |
161 def _StartDaemon(daemon): | |
162 if not os.path.isdir(os.path.join(ROOT, "v8")): | |
163 print("No 'v8' working directory found. Have you run 'setup'?") | |
164 sys.exit(1) | |
165 daemon.start() | |
166 | |
167 | |
168 if __name__ == "__main__": | |
169 if len(sys.argv) == 2: | |
170 arg = sys.argv[1] | |
171 if arg == "start": | |
172 daemon = main.Server(PIDFILE, ROOT) | |
173 _StartDaemon(daemon) | |
174 elif arg == "stop": | |
175 daemon = main.Server(PIDFILE, ROOT) | |
176 daemon.stop() | |
177 elif arg == "restart": | |
178 daemon = main.Server(PIDFILE, ROOT) | |
179 daemon.stop() | |
180 _StartDaemon(daemon) | |
181 elif arg in ("help", "-h", "--help"): | |
182 _PrintUsage() | |
183 elif arg == "status": | |
184 if not _IsDaemonRunning(): | |
185 print("Server not running.") | |
186 else: | |
187 print(local_handler.LocalQuery([constants.REQUEST_STATUS])) | |
188 else: | |
189 print("Unknown command") | |
190 _PrintUsage() | |
191 sys.exit(2) | |
192 elif len(sys.argv) == 3: | |
193 arg = sys.argv[1] | |
194 if arg == "approve": | |
195 filename = sys.argv[2] | |
196 if not os.path.exists(filename): | |
197 print("%s does not exist.") | |
198 sys.exit(1) | |
199 filename = os.path.abspath(filename) | |
200 if _IsDaemonRunning(): | |
201 response = local_handler.LocalQuery([constants.ADD_TRUSTED, filename]) | |
202 else: | |
203 daemon = main.Server(PIDFILE, ROOT) | |
204 response = daemon.CopyToTrusted(filename) | |
205 print("Added certificate %s to trusted certificates." % response) | |
206 else: | |
207 print("Unknown command") | |
208 _PrintUsage() | |
209 sys.exit(2) | |
210 else: | |
211 print("Unknown command") | |
212 _PrintUsage() | |
213 sys.exit(2) | |
214 sys.exit(0) | |
OLD | NEW |