| 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 |