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
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.
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.
36 PIDFILE = "/tmp/v8-distributed-testing-server.pid"
37 ROOT = os.path.abspath(os.path.dirname(sys.argv[0]))
41 print("""Usage: python %s COMMAND
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.
54 def _IsDaemonRunning():
55 return os.path.exists(PIDFILE)
59 code = subprocess.call(cmd, shell=True)
61 print("Command '%s' returned error code %d" % (cmd, code))
66 # Create directory for private data storage.
67 data_dir = os.path.join(ROOT, "data")
68 if not os.path.exists(data_dir):
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)
76 # Install UltraJSON. It is much faster than Python's builtin json.
78 import ujson #@UnusedImport
80 # Install pip if it doesn't exist.
81 code = subprocess.call("which pip > /dev/null", shell=True)
83 apt_get_code = subprocess.call("which apt-get > /dev/null", shell=True)
85 print("Installing pip...")
86 _Cmd("sudo apt-get install python-pip")
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.")
92 print("Using pip to install UltraJSON...")
93 _Cmd("sudo pip install ujson")
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,
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")
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)
117 path = ("http://v8.googlecode.com/svn/branches/bleeding_edge/"
119 _Cmd("svn checkout --force %s %s" % (path, testrunner_dir))
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))
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)
132 _Cmd("git clone git://github.com/v8/v8.git %s" % v8_dir)
137 # Handle "setup" here, because when executing that we can't import anything
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.")
146 # Other parameters are handled below.
149 #==========================================================
150 # At this point we can assume that the implementation is available,
151 # so we can import it.
153 from testrunner.server import constants
154 from testrunner.server import local_handler
155 from testrunner.server import main
158 print("Failed to import implementation. Have you run 'setup'?")
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'?")
169 if __name__ == "__main__":
170 if len(sys.argv) == 2:
173 daemon = main.Server(PIDFILE, ROOT)
176 daemon = main.Server(PIDFILE, ROOT)
178 elif arg == "restart":
179 daemon = main.Server(PIDFILE, ROOT)
182 elif arg in ("help", "-h", "--help"):
184 elif arg == "status":
185 if not _IsDaemonRunning():
186 print("Server not running.")
188 print(local_handler.LocalQuery([constants.REQUEST_STATUS]))
190 print("Unknown command")
193 elif len(sys.argv) == 3:
196 filename = sys.argv[2]
197 if not os.path.exists(filename):
198 print("%s does not exist.")
200 filename = os.path.abspath(filename)
201 if _IsDaemonRunning():
202 response = local_handler.LocalQuery([constants.ADD_TRUSTED, filename])
204 daemon = main.Server(PIDFILE, ROOT)
205 response = daemon.CopyToTrusted(filename)
206 print("Added certificate %s to trusted certificates." % response)
208 print("Unknown command")
212 print("Unknown command")