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