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 > /dev/null", shell=True) | |
82 if code != 0: | |
83 apt_get_code = subprocess.call("which apt-get > /dev/null", shell=True) | |
84 if apt_get_code == 0: | |
85 print("Installing pip...") | |
86 _Cmd("sudo apt-get install python-pip") | |
87 else: | |
88 print("Please install pip on your machine. You can get it at: " | |
89 "http://www.pip-installer.org/en/latest/installing.html " | |
90 "or via your distro's package manager.") | |
91 sys.exit(1) | |
92 print("Using pip to install UltraJSON...") | |
93 _Cmd("sudo pip install ujson") | |
94 | |
95 # Make sure we have a key pair for signing binaries. | |
96 privkeyfile = os.path.expanduser("~/.ssh/v8_dtest") | |
97 if not os.path.exists(privkeyfile): | |
98 _Cmd("ssh-keygen -t rsa -f %s -N '' -q" % privkeyfile) | |
99 fingerprint = subprocess.check_output("ssh-keygen -lf %s" % privkeyfile, | |
100 shell=True) | |
101 fingerprint = fingerprint.split(" ")[1].replace(":", "")[:16] | |
102 pubkeyfile = os.path.join(trusted_dir, "%s.pem" % fingerprint) | |
103 if (not os.path.exists(pubkeyfile) or | |
104 os.path.getmtime(pubkeyfile) < os.path.getmtime(privkeyfile)): | |
105 _Cmd("openssl rsa -in %s -out %s -pubout" % (privkeyfile, pubkeyfile)) | |
106 with open(pubkeyfile, "a") as f: | |
107 f.write(fingerprint + "\n") | |
108 datafile = os.path.join(data_dir, "mypubkey") | |
109 with open(datafile, "w") as f: | |
110 f.write(fingerprint + "\n") | |
111 | |
112 # Check out or update the server implementation in the current directory. | |
113 testrunner_dir = os.path.join(ROOT, "testrunner") | |
114 if os.path.exists(os.path.join(testrunner_dir, "server/daemon.py")): | |
115 _Cmd("cd %s; svn up" % testrunner_dir) | |
116 else: | |
117 path = ("http://v8.googlecode.com/svn/branches/bleeding_edge/" | |
118 "tools/testrunner") | |
119 _Cmd("svn checkout --force %s %s" % (path, testrunner_dir)) | |
120 | |
121 # Update this very script. | |
122 path = ("http://v8.googlecode.com/svn/branches/bleeding_edge/" | |
123 "tools/test-server.py") | |
124 scriptname = os.path.abspath(sys.argv[0]) | |
125 _Cmd("svn cat %s > %s" % (path, scriptname)) | |
126 | |
127 # Check out or update V8. | |
128 v8_dir = os.path.join(ROOT, "v8") | |
129 if os.path.exists(v8_dir): | |
130 _Cmd("cd %s; git fetch" % v8_dir) | |
131 else: | |
132 _Cmd("git clone git://github.com/v8/v8.git %s" % v8_dir) | |
133 | |
134 print("Finished.") | |
135 | |
136 | |
137 # Handle "setup" here, because when executing that we can't import anything | |
138 # else yet. | |
139 if __name__ == "__main__" and len(sys.argv) == 2: | |
140 if sys.argv[1] in ("setup", "update"): | |
141 if _IsDaemonRunning(): | |
142 print("Please stop the server before updating. Exiting.") | |
143 sys.exit(1) | |
144 Update() | |
145 sys.exit(0) | |
146 # Other parameters are handled below. | |
147 | |
148 | |
149 #========================================================== | |
150 # At this point we can assume that the implementation is available, | |
151 # so we can import it. | |
152 try: | |
153 from testrunner.server import constants | |
154 from testrunner.server import local_handler | |
155 from testrunner.server import main | |
156 except Exception, e: | |
157 print(e) | |
158 print("Failed to import implementation. Have you run 'setup'?") | |
159 sys.exit(1) | |
160 | |
161 | |
162 def _StartDaemon(daemon): | |
163 if not os.path.isdir(os.path.join(ROOT, "v8")): | |
164 print("No 'v8' working directory found. Have you run 'setup'?") | |
165 sys.exit(1) | |
166 daemon.start() | |
167 | |
168 | |
169 if __name__ == "__main__": | |
170 if len(sys.argv) == 2: | |
171 arg = sys.argv[1] | |
172 if arg == "start": | |
173 daemon = main.Server(PIDFILE, ROOT) | |
174 _StartDaemon(daemon) | |
175 elif arg == "stop": | |
176 daemon = main.Server(PIDFILE, ROOT) | |
177 daemon.stop() | |
178 elif arg == "restart": | |
179 daemon = main.Server(PIDFILE, ROOT) | |
180 daemon.stop() | |
181 _StartDaemon(daemon) | |
182 elif arg in ("help", "-h", "--help"): | |
183 _PrintUsage() | |
184 elif arg == "status": | |
185 if not _IsDaemonRunning(): | |
186 print("Server not running.") | |
187 else: | |
188 print(local_handler.LocalQuery([constants.REQUEST_STATUS])) | |
189 else: | |
190 print("Unknown command") | |
191 _PrintUsage() | |
192 sys.exit(2) | |
193 elif len(sys.argv) == 3: | |
194 arg = sys.argv[1] | |
195 if arg == "approve": | |
196 filename = sys.argv[2] | |
197 if not os.path.exists(filename): | |
198 print("%s does not exist.") | |
199 sys.exit(1) | |
200 filename = os.path.abspath(filename) | |
201 if _IsDaemonRunning(): | |
202 response = local_handler.LocalQuery([constants.ADD_TRUSTED, filename]) | |
203 else: | |
204 daemon = main.Server(PIDFILE, ROOT) | |
205 response = daemon.CopyToTrusted(filename) | |
206 print("Added certificate %s to trusted certificates." % response) | |
207 else: | |
208 print("Unknown command") | |
209 _PrintUsage() | |
210 sys.exit(2) | |
211 else: | |
212 print("Unknown command") | |
213 _PrintUsage() | |
214 sys.exit(2) | |
215 sys.exit(0) | |
OLD | NEW |