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