Steven Bennetts | 62fd725 | 2011-11-03 13:56:09 -0700 | [diff] [blame] | 1 | #!/usr/bin/env python |
| 2 | # Copyright (c) 2011 The Chromium OS Authors. All rights reserved. |
| 3 | # Use of this source code is governed by a BSD-style license that can be |
| 4 | # found in the LICENSE file. |
| 5 | |
| 6 | """This script provides a suite of utility functions for the chroot. |
| 7 | """ |
| 8 | |
| 9 | import optparse |
| 10 | import os |
| 11 | import shutil |
| 12 | import subprocess |
| 13 | import sys |
| 14 | |
| 15 | _PROG = "crdev" |
| 16 | _SSH_KEY_FILEPATH = os.path.expanduser("~/.ssh/id_rsa") |
| 17 | _PUB_KEY_FILENAME = "~/.ssh/id_rsa.pub" |
| 18 | _PUB_KEY_FILEPATH = os.path.expanduser(_PUB_KEY_FILENAME) |
| 19 | _AUTH_KEYS_FILEPATH = os.path.expanduser("~/.ssh/authorized_keys") |
| 20 | _CHROME_MOUNT_PATH = "/tmp/chrome" |
Steven Bennetts | 26178d9 | 2011-11-22 10:54:41 -0800 | [diff] [blame] | 21 | # Note: no ~/ for sshfs: |
| 22 | _DEFAULT_HOST_CHROOT_DIR = "chromeos/chroot" |
| 23 | _HOST_CHROOT_DIR_FILENAME = os.path.expanduser("~/.chromedir") |
Steven Bennetts | 62fd725 | 2011-11-03 13:56:09 -0700 | [diff] [blame] | 24 | |
| 25 | RAN_SUDO = False |
| 26 | |
| 27 | ############################################################################### |
| 28 | # Utility commands |
| 29 | |
Steven Bennetts | 26178d9 | 2011-11-22 10:54:41 -0800 | [diff] [blame] | 30 | def _PrintError(msg, err=""): |
| 31 | """Print a message with an optional error message to stderr""" |
| 32 | if err: |
| 33 | print >> sys.stderr, "%s: %s" % (msg, err) |
| 34 | else: |
| 35 | print >> sys.stderr, msg |
| 36 | |
| 37 | def _Confirm(message, default_response="n"): |
Steven Bennetts | 62fd725 | 2011-11-03 13:56:09 -0700 | [diff] [blame] | 38 | """Request confirmation and return True/False.""" |
Steven Bennetts | 26178d9 | 2011-11-22 10:54:41 -0800 | [diff] [blame] | 39 | default_lc = default_response.lower() |
| 40 | if default_lc == "y": |
| 41 | input_msg = "%s [Y/n] " % message |
| 42 | else: |
| 43 | input_msg = "%s [y/N] " % message |
| 44 | |
| 45 | reply = raw_input(input_msg).lower() |
| 46 | if reply: |
| 47 | return reply == "y" |
| 48 | return default_lc == "y" |
Steven Bennetts | 62fd725 | 2011-11-03 13:56:09 -0700 | [diff] [blame] | 49 | |
| 50 | |
| 51 | def _CheckOverwriteFile(filepath): |
| 52 | """Check for a file and request confirmation if it exists.""" |
| 53 | if os.path.isfile(filepath): |
Steven Bennetts | 26178d9 | 2011-11-22 10:54:41 -0800 | [diff] [blame] | 54 | if not _Confirm("%s already exists. Overwrite?" % filepath): |
Steven Bennetts | 62fd725 | 2011-11-03 13:56:09 -0700 | [diff] [blame] | 55 | return False |
| 56 | return True |
| 57 | |
| 58 | |
| 59 | def _WriteFile(filepath, contents): |
| 60 | """Write string |contents| to |filepath|.""" |
| 61 | try: |
| 62 | print "Writing to: ", filepath |
| 63 | with open(filepath,"w") as f_1: |
| 64 | f_1.write(contents) |
Steven Bennetts | 26178d9 | 2011-11-22 10:54:41 -0800 | [diff] [blame] | 65 | except EnvironmentError as err: |
| 66 | _PrintError("Failed to write to file '%s'" % filepath, err) |
Steven Bennetts | 62fd725 | 2011-11-03 13:56:09 -0700 | [diff] [blame] | 67 | return False |
| 68 | |
| 69 | return True |
| 70 | |
| 71 | |
Steven Bennetts | 26178d9 | 2011-11-22 10:54:41 -0800 | [diff] [blame] | 72 | def _ReadFile(filepath): |
| 73 | """Return contents of |filepath| as a string.""" |
| 74 | try: |
| 75 | print "Reading from: " + filepath |
| 76 | with open(filepath,"r") as f_1: |
| 77 | result = f_1.read() |
| 78 | except EnvironmentError as err: |
| 79 | _PrintError("Failed to read from file '%s'" % filepath, err) |
| 80 | return None |
| 81 | |
| 82 | return result.rstrip() |
| 83 | |
| 84 | |
Steven Bennetts | 62fd725 | 2011-11-03 13:56:09 -0700 | [diff] [blame] | 85 | def _Sudo(): |
| 86 | """Request sudo access with message.""" |
| 87 | global RAN_SUDO |
| 88 | if not RAN_SUDO: |
| 89 | print "Executing: sudo -v" |
| 90 | try: |
| 91 | subprocess.call(["sudo", "-v"]) |
Steven Bennetts | 26178d9 | 2011-11-22 10:54:41 -0800 | [diff] [blame] | 92 | except EnvironmentError as err: |
| 93 | _PrintError("Failed to run sudo", err) |
Steven Bennetts | 62fd725 | 2011-11-03 13:56:09 -0700 | [diff] [blame] | 94 | return False |
| 95 | RAN_SUDO = True |
| 96 | return True |
| 97 | |
| 98 | |
| 99 | def _RunCommand(args): |
| 100 | """Pass |args| to subprocess.call() and check the result.""" |
| 101 | cmd = ''.join([x + " " for x in args]) |
| 102 | try: |
| 103 | if args[0] == "sudo": |
| 104 | if _Sudo() == False: |
| 105 | return False |
| 106 | print "Executing: ", cmd |
| 107 | retcode = subprocess.call(args) |
Steven Bennetts | 26178d9 | 2011-11-22 10:54:41 -0800 | [diff] [blame] | 108 | except EnvironmentError as err: |
| 109 | _PrintError("Failed to run command '%s'" % cmd, err) |
Steven Bennetts | 62fd725 | 2011-11-03 13:56:09 -0700 | [diff] [blame] | 110 | return False |
| 111 | else: |
| 112 | if retcode != 0: |
Steven Bennetts | 26178d9 | 2011-11-22 10:54:41 -0800 | [diff] [blame] | 113 | _PrintError("Error running command '%s'" % cmd, "%s" % retcode) |
Steven Bennetts | 62fd725 | 2011-11-03 13:56:09 -0700 | [diff] [blame] | 114 | return False |
| 115 | return True |
| 116 | |
| 117 | |
| 118 | def _GetCommandOutput(args): |
| 119 | """Pass |args| to subprocess.Popen and return the output.""" |
| 120 | cmd = ''.join([x + " " for x in args]) |
| 121 | try: |
| 122 | proc = subprocess.Popen(args, stdout=subprocess.PIPE) |
| 123 | result = proc.communicate()[0] |
Steven Bennetts | 26178d9 | 2011-11-22 10:54:41 -0800 | [diff] [blame] | 124 | except EnvironmentError as err: |
| 125 | _PrintError("Failed to run command '%s'" % cmd, err) |
Steven Bennetts | 62fd725 | 2011-11-03 13:56:09 -0700 | [diff] [blame] | 126 | return None |
| 127 | result = result.rstrip('\n') |
| 128 | return result |
| 129 | |
| 130 | |
Steven Bennetts | 26178d9 | 2011-11-22 10:54:41 -0800 | [diff] [blame] | 131 | def _MakeDirectory(dirpath, warn=True): |
Steven Bennetts | 62fd725 | 2011-11-03 13:56:09 -0700 | [diff] [blame] | 132 | """Create directory |dirpath| if it does not exist.""" |
| 133 | if not os.path.isdir(dirpath): |
| 134 | try: |
| 135 | print "Creating directory: ", dirpath |
| 136 | os.makedirs(dirpath) |
Steven Bennetts | 26178d9 | 2011-11-22 10:54:41 -0800 | [diff] [blame] | 137 | except EnvironmentError as err: |
| 138 | if warn: |
| 139 | _PrintError("Failed to create directory '%s'" % dirpath, err) |
Steven Bennetts | 62fd725 | 2011-11-03 13:56:09 -0700 | [diff] [blame] | 140 | return False |
| 141 | return True |
| 142 | |
| 143 | |
| 144 | def _RemoveFile(filepath): |
| 145 | """Remove file |filepath| if it exists.""" |
| 146 | if os.path.isfile(filepath): |
| 147 | try: |
| 148 | print "Removing file: ", filepath |
| 149 | os.remove(filepath) |
Steven Bennetts | 26178d9 | 2011-11-22 10:54:41 -0800 | [diff] [blame] | 150 | except EnvironmentError as err: |
| 151 | _PrintError("Failed to remove file '%s'" % filepath, err) |
Steven Bennetts | 62fd725 | 2011-11-03 13:56:09 -0700 | [diff] [blame] | 152 | return False |
| 153 | return True |
| 154 | |
| 155 | |
| 156 | def _RemoveDirectory(dirpath): |
| 157 | """Recursively remove directory |dirpath| if it exists.""" |
| 158 | if os.path.isdir(dirpath): |
| 159 | try: |
| 160 | print "Removing directory: ", dirpath |
| 161 | shutil.rmtree(dirpath) |
Steven Bennetts | 26178d9 | 2011-11-22 10:54:41 -0800 | [diff] [blame] | 162 | except EnvironmentError as err: |
| 163 | _PrintError("Failed to remove dir '%s'" % dirpath, err) |
Steven Bennetts | 62fd725 | 2011-11-03 13:56:09 -0700 | [diff] [blame] | 164 | return False |
| 165 | return True |
| 166 | |
| 167 | |
| 168 | def _DevUser(): |
| 169 | """Extract the user name from lsb-release.""" |
Steven Bennetts | 26178d9 | 2011-11-22 10:54:41 -0800 | [diff] [blame] | 170 | # TODO(stevenjb): Refactor this using python re. |
Steven Bennetts | 62fd725 | 2011-11-03 13:56:09 -0700 | [diff] [blame] | 171 | awk_expr = """/CHROMEOS_RELEASE_DESCRIPTION/ {""" |
Steven Bennetts | b28276a | 2011-11-29 12:29:31 -0800 | [diff] [blame^] | 172 | awk_expr += """ sub(/.*Build - /,"");""" |
Steven Bennetts | 62fd725 | 2011-11-03 13:56:09 -0700 | [diff] [blame] | 173 | awk_expr += """ sub(/\).*/,"");""" |
| 174 | awk_expr += """ print; }""" |
| 175 | return _GetCommandOutput(["awk", awk_expr, "/etc/lsb-release"]) |
| 176 | |
| 177 | |
| 178 | def _DevHost(): |
| 179 | """Extract the host name from lsb-release.""" |
Steven Bennetts | 26178d9 | 2011-11-22 10:54:41 -0800 | [diff] [blame] | 180 | # TODO(stevenjb): Refactor this using python re. |
Steven Bennetts | 62fd725 | 2011-11-03 13:56:09 -0700 | [diff] [blame] | 181 | awk_expr = """/CHROMEOS_DEVSERVER/ {""" |
| 182 | awk_expr += """ sub(/.*http:\/\//,"");""" |
| 183 | awk_expr += """ sub(/:8080.*/,"");""" |
| 184 | awk_expr += """ print; }""" |
| 185 | return _GetCommandOutput(["awk", awk_expr, "/etc/lsb-release"]) |
| 186 | |
Steven Bennetts | 26178d9 | 2011-11-22 10:54:41 -0800 | [diff] [blame] | 187 | |
| 188 | def _DevBoard(): |
| 189 | """Extract the board from lsb-release.""" |
| 190 | # TODO(stevenjb): Refactor this using python re. |
| 191 | awk_expr = """/CHROMEOS_RELEASE_BOARD/ {""" |
| 192 | awk_expr += """ sub(/.*=/,"");""" |
| 193 | awk_expr += """ print; }""" |
| 194 | return _GetCommandOutput(["awk", awk_expr, "/etc/lsb-release"]) |
| 195 | |
| 196 | |
| 197 | def _GetChrootDir(prompt_for_dir=False): |
| 198 | """Get the name for the chrome directory on the host.""" |
Steven Bennetts | b28276a | 2011-11-29 12:29:31 -0800 | [diff] [blame^] | 199 | if os.path.isfile(_HOST_CHROOT_DIR_FILENAME): |
| 200 | chromedir = _ReadFile(_HOST_CHROOT_DIR_FILENAME) |
| 201 | else: |
Steven Bennetts | 26178d9 | 2011-11-22 10:54:41 -0800 | [diff] [blame] | 202 | chromedir = _DEFAULT_HOST_CHROOT_DIR |
| 203 | |
| 204 | if prompt_for_dir: |
| 205 | host = _DevHost() |
Steven Bennetts | b28276a | 2011-11-29 12:29:31 -0800 | [diff] [blame^] | 206 | prompt = ("Chroot directory on %s [ %s ]: " % (host, chromedir)) |
Steven Bennetts | 26178d9 | 2011-11-22 10:54:41 -0800 | [diff] [blame] | 207 | inputdir = raw_input(prompt).rstrip() |
| 208 | if inputdir: |
| 209 | chromedir = inputdir |
| 210 | _WriteFile(_HOST_CHROOT_DIR_FILENAME, chromedir) |
| 211 | |
| 212 | return chromedir |
| 213 | |
| 214 | |
Steven Bennetts | 62fd725 | 2011-11-03 13:56:09 -0700 | [diff] [blame] | 215 | ############################################################################### |
| 216 | # Other Commands |
| 217 | |
| 218 | def TestCommand(args): |
| 219 | """Test command.""" |
Steven Bennetts | 26178d9 | 2011-11-22 10:54:41 -0800 | [diff] [blame] | 220 | _WriteFile("/foo/test", "test") |
Steven Bennetts | 62fd725 | 2011-11-03 13:56:09 -0700 | [diff] [blame] | 221 | if len(args) == 0: |
| 222 | args = ["sudo", "ls", "/"] |
| 223 | return _RunCommand(args) |
| 224 | return False |
| 225 | |
| 226 | |
Steven Bennetts | 26178d9 | 2011-11-22 10:54:41 -0800 | [diff] [blame] | 227 | def GetBoard(unused_args=0): |
| 228 | """Gets the board name from /etc/lsb-release.""" |
| 229 | print _DevBoard() |
| 230 | return True |
| 231 | |
| 232 | |
Steven Bennetts | 62fd725 | 2011-11-03 13:56:09 -0700 | [diff] [blame] | 233 | def GetUser(unused_args=0): |
| 234 | """Gets the user name from /etc/lsb-release.""" |
| 235 | print _DevUser() |
| 236 | return True |
| 237 | |
| 238 | |
| 239 | def GetHost(unused_args=0): |
| 240 | """Gets the host name from /etc/lsb-release.""" |
| 241 | print _DevHost() |
| 242 | return True |
| 243 | |
| 244 | |
| 245 | def MountWriteable(unused_args=0): |
| 246 | """Remounts / as rw.""" |
| 247 | return _RunCommand(["sudo", "mount", "-o", "remount,rw", "/"]) |
| 248 | |
| 249 | |
| 250 | def ShowIP(unused_args=0): |
| 251 | """Shows the IP address of the device.""" |
| 252 | proc1 = subprocess.Popen(["/sbin/ifconfig", "eth0"], stdout=subprocess.PIPE) |
| 253 | awk_cmd = """/inet addr/ {""" |
| 254 | awk_cmd += """ sub(/.*inet addr:/,""); sub(/ Bcast:.*/,"");""" |
| 255 | awk_cmd += """ print; }""" |
| 256 | proc2 = subprocess.Popen( |
| 257 | ["awk", awk_cmd], stdin=proc1.stdout, stdout=subprocess.PIPE) |
| 258 | proc1.stdout.close() |
| 259 | result = proc2.communicate()[0].rstrip('\n') |
| 260 | print "IP: ", result |
| 261 | return True |
| 262 | |
| 263 | |
| 264 | def KillChrome(unused_args=0): |
| 265 | """Kills all chrome processes and prevents restarting of chrome.""" |
| 266 | res = True |
| 267 | res &= _RunCommand(["touch", "/tmp/disable_chrome_restart"]) |
| 268 | res &= _RunCommand(["sudo", "pkill", "-9", "chrome"]) |
| 269 | return res |
| 270 | |
| 271 | |
| 272 | def ShowOobe(unused_args=0): |
| 273 | """Removes .oobe_completed and Local State directory.""" |
| 274 | |
| 275 | res = True |
| 276 | res &= KillChrome() |
| 277 | res &= _RemoveFile("/home/chronos/.oobe_completed") |
| 278 | res &= _RemoveDirectory("/home/chronos/Local State") |
| 279 | |
| 280 | if not res: |
Steven Bennetts | 26178d9 | 2011-11-22 10:54:41 -0800 | [diff] [blame] | 281 | _PrintError("Unable to set up OOBE mode.") |
Steven Bennetts | 62fd725 | 2011-11-03 13:56:09 -0700 | [diff] [blame] | 282 | return False |
| 283 | |
| 284 | if _Confirm("Reboot is required to enter OOBE mode. Reboot now?"): |
| 285 | _RunCommand(["sudo", "reboot"]) |
| 286 | return True |
| 287 | |
| 288 | ############################################################################### |
| 289 | # Setup Commands |
| 290 | |
| 291 | def SetBash(unused_args): |
| 292 | """Sets the default shell to bash.""" |
| 293 | if not _Sudo(): |
| 294 | return False |
| 295 | if not MountWriteable(): |
| 296 | return False |
| 297 | res = True |
| 298 | res &= _RunCommand(["chsh", "-s", "/bin/bash"]) |
| 299 | res &= _RunCommand(["chsh", "-s", "/bin/bash", "chronos"]) |
| 300 | return res |
| 301 | |
| 302 | |
| 303 | def SetupBashrc(unused_args): |
| 304 | """Sets up .bashrc.""" |
| 305 | filepath = os.path.expanduser("~/.bashrc") |
| 306 | if not _CheckOverwriteFile(filepath): |
Steven Bennetts | 26178d9 | 2011-11-22 10:54:41 -0800 | [diff] [blame] | 307 | return True |
Steven Bennetts | 62fd725 | 2011-11-03 13:56:09 -0700 | [diff] [blame] | 308 | |
| 309 | print "Writing to: ", filepath |
| 310 | bashrc = "#!/bin/bash\n" |
| 311 | bashrc += "# .bashrc file set by %s\n" % _PROG |
| 312 | bashrc += "export DISPLAY=:0.0\n" |
| 313 | bashrc += "export PATH=$PATH:/sbin:/usr/sbin:/usr/local/sbin\n" |
| 314 | bashrc += "/sbin/ifconfig eth0 | grep 'inet addr'\n" |
| 315 | if not _WriteFile(filepath, bashrc): |
| 316 | return False |
| 317 | |
| 318 | filepath = os.path.expanduser("~/.bash_profile") |
| 319 | print "Writing to: ", filepath |
| 320 | bashprofile = "#!/bin/bash\n" |
| 321 | bashprofile += ". $HOME/.bashrc\n" |
| 322 | if not _WriteFile(filepath, bashprofile): |
| 323 | return False |
| 324 | return True |
| 325 | |
| 326 | |
| 327 | def SetupDev(unused_args): |
| 328 | """Developer friendly setup: skip oobe, don't forget usernames, |
| 329 | \t\tdisable suspend, enable ssh and remote debugging, |
| 330 | \t\trun commands from /tmp,/home.""" |
| 331 | if not _Sudo(): |
| 332 | return False |
| 333 | if not MountWriteable(): |
| 334 | return False |
| 335 | res = True |
Steven Bennetts | 26178d9 | 2011-11-22 10:54:41 -0800 | [diff] [blame] | 336 | res &= _WriteFile("/home/chronos/.oobe_completed", "1\n") |
Steven Bennetts | b28276a | 2011-11-29 12:29:31 -0800 | [diff] [blame^] | 337 | res &= _RunCommand(["sudo", "rm", "-f", "/root/.forget_usernames"]) |
Steven Bennetts | 62fd725 | 2011-11-03 13:56:09 -0700 | [diff] [blame] | 338 | res &= _MakeDirectory("/usr/share/power_manager") |
Steven Bennetts | 26178d9 | 2011-11-22 10:54:41 -0800 | [diff] [blame] | 339 | res &= _WriteFile("/tmp/disable_idle_suspend", "1\n") |
| 340 | res &= _RunCommand(["sudo", "cp", "/tmp/disable_idle_suspend", |
| 341 | "/usr/share/power_manager/"]) |
Steven Bennetts | 62fd725 | 2011-11-03 13:56:09 -0700 | [diff] [blame] | 342 | # Enable iptables and system-services for remote debugging |
| 343 | for filename in ["iptables", "saft"]: |
| 344 | res &= _RunCommand(["sudo", "sed", "-i", "-e", |
| 345 | "s/#for_test //", "/etc/init/%s.conf" % filename]) |
| 346 | # Allow commands to be run from /home and /tmp |
| 347 | res &= _RunCommand(["sudo", "sed", "-i", "-e", |
| 348 | "s/#mod_for_test#//g", "/sbin/chromeos_startup"]) |
| 349 | return res |
| 350 | |
| 351 | |
| 352 | def SetupSsh(unused_args): |
| 353 | """Sets up ssh configuration so that the dev host can ssh to the device.""" |
| 354 | if not MountWriteable(): |
| 355 | return False |
| 356 | |
| 357 | user = _DevUser() |
| 358 | host = _DevHost() |
| 359 | |
Steven Bennetts | 62fd725 | 2011-11-03 13:56:09 -0700 | [diff] [blame] | 360 | res = True |
Steven Bennetts | 26178d9 | 2011-11-22 10:54:41 -0800 | [diff] [blame] | 361 | if _CheckOverwriteFile(_SSH_KEY_FILEPATH): |
| 362 | res &= _RemoveFile(_SSH_KEY_FILEPATH) |
| 363 | # Generate an ssh key |
| 364 | if _RunCommand(["ssh-keygen", "-f", _SSH_KEY_FILEPATH, "-N", "", "-q"]): |
| 365 | host_source_path = "%s@%s:%s" % (user, host, _PUB_KEY_FILENAME) |
| 366 | # Copy the ssh key to the host |
| 367 | res &= _RunCommand(["scp", host_source_path, _AUTH_KEYS_FILEPATH]) |
| 368 | |
Steven Bennetts | 62fd725 | 2011-11-03 13:56:09 -0700 | [diff] [blame] | 369 | # Enable ssh to device |
| 370 | res &= _RunCommand( |
| 371 | ["sudo", "sed", "-i", "s/#for_test //", "/etc/init/openssh-server.conf"]) |
Steven Bennetts | 62fd725 | 2011-11-03 13:56:09 -0700 | [diff] [blame] | 372 | |
| 373 | return res |
| 374 | |
| 375 | |
| 376 | def AuthorizeSsh(unused_args): |
| 377 | """Authorizes this netbook to connect to your dev host. |
| 378 | \t\t*Only use this on a device in a secure location!*""" |
| 379 | |
| 380 | user = _DevUser() |
| 381 | host = _DevHost() |
| 382 | |
Steven Bennetts | 26178d9 | 2011-11-22 10:54:41 -0800 | [diff] [blame] | 383 | if not os.path.isdir(os.path.expanduser("~/.ssh")): |
| 384 | print "Run '%s ssh' to set up .ssh directory first." % _PROG |
| 385 | return False |
| 386 | |
| 387 | if not _Confirm("This will append %s to authorized_keys on %s. " |
| 388 | "Are you sure?" % (_PUB_KEY_FILENAME, host)): |
Steven Bennetts | 62fd725 | 2011-11-03 13:56:09 -0700 | [diff] [blame] | 389 | return False |
| 390 | |
| 391 | proc1 = subprocess.Popen(["cat", _PUB_KEY_FILEPATH], stdout=subprocess.PIPE) |
| 392 | try: |
| 393 | ssh_args = ["ssh", user+"@"+host, "cat >> ~/.ssh/authorized_keys"] |
| 394 | proc2 = subprocess.Popen( |
| 395 | ssh_args, stdin=proc1.stdout, stdout=subprocess.PIPE) |
Steven Bennetts | 26178d9 | 2011-11-22 10:54:41 -0800 | [diff] [blame] | 396 | except EnvironmentError as err1: |
| 397 | _PrintError("Error executing '%s'" % ' '.join(ssh_args), err1) |
Steven Bennetts | 62fd725 | 2011-11-03 13:56:09 -0700 | [diff] [blame] | 398 | return False |
| 399 | try: |
| 400 | proc1.stdout.close() |
Steven Bennetts | 26178d9 | 2011-11-22 10:54:41 -0800 | [diff] [blame] | 401 | result, err2 = proc2.communicate() |
Steven Bennetts | 62fd725 | 2011-11-03 13:56:09 -0700 | [diff] [blame] | 402 | except EnvironmentError: |
Steven Bennetts | 26178d9 | 2011-11-22 10:54:41 -0800 | [diff] [blame] | 403 | _PrintError("Error completing ssh command '%s'" % result, err2) |
Steven Bennetts | 62fd725 | 2011-11-03 13:56:09 -0700 | [diff] [blame] | 404 | return False |
| 405 | return True |
| 406 | |
| 407 | |
| 408 | def SetupSshfsForChrome(unused_args): |
| 409 | """<chrome-drir> Sets up sshfs mount to chrome directory on host.""" |
| 410 | |
| 411 | user = _DevUser() |
| 412 | host = _DevHost() |
| 413 | |
Steven Bennetts | 26178d9 | 2011-11-22 10:54:41 -0800 | [diff] [blame] | 414 | chrootdir = _GetChrootDir(True) |
Steven Bennetts | 62fd725 | 2011-11-03 13:56:09 -0700 | [diff] [blame] | 415 | |
Steven Bennetts | 26178d9 | 2011-11-22 10:54:41 -0800 | [diff] [blame] | 416 | target = ("%s@%s:%s/var/lib/portage/distfiles-target/chrome-src" |
| 417 | % (user, host, chrootdir)) |
Steven Bennetts | 62fd725 | 2011-11-03 13:56:09 -0700 | [diff] [blame] | 418 | print "Setting up sshfs mount to: ", target |
| 419 | |
| 420 | res = True |
| 421 | res &= _RunCommand(["sudo", "modprobe", "fuse"]) |
| 422 | if os.path.isdir(_CHROME_MOUNT_PATH): |
Steven Bennetts | 26178d9 | 2011-11-22 10:54:41 -0800 | [diff] [blame] | 423 | res &= _RunCommand(["fusermount", "-q", "-u", _CHROME_MOUNT_PATH]) |
Steven Bennetts | 62fd725 | 2011-11-03 13:56:09 -0700 | [diff] [blame] | 424 | res &= _RemoveDirectory(_CHROME_MOUNT_PATH) |
| 425 | res &= _MakeDirectory(_CHROME_MOUNT_PATH) |
| 426 | res &= _RunCommand(["sshfs", target, _CHROME_MOUNT_PATH]) |
| 427 | res &= _RunCommand(["sudo", "/sbin/iptables", |
| 428 | "-A", "INPUT", "-p", "tcp", "--dport", "1234", |
| 429 | "-j", "ACCEPT"]) |
| 430 | return res |
| 431 | |
| 432 | ############################################################################### |
| 433 | # Multi-commands (convenience functions) |
| 434 | |
| 435 | def Setup(args): |
| 436 | """Performs default developer setup (bash,bashrc,dev,ssh).""" |
| 437 | if not SetBash(args): |
Steven Bennetts | 26178d9 | 2011-11-22 10:54:41 -0800 | [diff] [blame] | 438 | if not _Confirm("Bash setup failed. Continue?", "y"): |
Steven Bennetts | 62fd725 | 2011-11-03 13:56:09 -0700 | [diff] [blame] | 439 | return False |
| 440 | if not SetupBashrc(args): |
Steven Bennetts | 26178d9 | 2011-11-22 10:54:41 -0800 | [diff] [blame] | 441 | if not _Confirm(".bashrc setup failed. Continue?", "y"): |
Steven Bennetts | 62fd725 | 2011-11-03 13:56:09 -0700 | [diff] [blame] | 442 | return False |
| 443 | if not SetupDev(args): |
Steven Bennetts | 26178d9 | 2011-11-22 10:54:41 -0800 | [diff] [blame] | 444 | if not _Confirm("Dev setup failed. Continue?", "y"): |
Steven Bennetts | 62fd725 | 2011-11-03 13:56:09 -0700 | [diff] [blame] | 445 | return False |
| 446 | if not SetupSsh(args): |
| 447 | return False |
| 448 | return True |
| 449 | |
| 450 | ############################################################################### |
| 451 | |
| 452 | _SETUP_COMMANDS = { |
| 453 | 'setup': Setup, |
| 454 | 'dev': SetupDev, |
| 455 | 'bash': SetBash, |
| 456 | 'bashrc': SetupBashrc, |
| 457 | 'ssh': SetupSsh, |
| 458 | 'sshauthorize': AuthorizeSsh, |
| 459 | 'sshfs': SetupSshfsForChrome, |
| 460 | } |
| 461 | |
| 462 | |
| 463 | _OTHER_COMMANDS = { |
| 464 | 'mountrw': MountWriteable, |
| 465 | 'ip': ShowIP, |
| 466 | 'test': TestCommand, |
Steven Bennetts | 26178d9 | 2011-11-22 10:54:41 -0800 | [diff] [blame] | 467 | 'board': GetBoard, |
Steven Bennetts | 62fd725 | 2011-11-03 13:56:09 -0700 | [diff] [blame] | 468 | 'user': GetUser, |
| 469 | 'host': GetHost, |
| 470 | } |
| 471 | |
| 472 | |
| 473 | def GetUsage(commands): |
| 474 | """Get the docstring for each command.""" |
| 475 | usage = "" |
| 476 | for cmd in commands.items(): |
| 477 | usage += " " |
| 478 | usage += cmd[0] |
| 479 | usage += ":\t" |
| 480 | if len(cmd[0]) < 6: |
| 481 | usage += "\t" |
| 482 | doc = cmd[1].__doc__ |
| 483 | if doc: |
| 484 | usage += doc |
| 485 | usage += "\n" |
| 486 | return usage |
| 487 | |
| 488 | |
| 489 | ############################################################################### |
| 490 | |
| 491 | def main(): |
| 492 | """Main crdev function""" |
| 493 | usage = """usage: crdev command [options] |
| 494 | |
Steven Bennetts | 26178d9 | 2011-11-22 10:54:41 -0800 | [diff] [blame] | 495 | Note: Beta! Feature requests / changes can be sent to: |
| 496 | stevenjb@chromium.org (for now) |
Steven Bennetts | 62fd725 | 2011-11-03 13:56:09 -0700 | [diff] [blame] | 497 | |
| 498 | """ |
| 499 | |
| 500 | usage += "Setup Commands:\n" |
| 501 | usage += GetUsage(_SETUP_COMMANDS) |
| 502 | usage += "Other Commands:\n" |
| 503 | usage += GetUsage(_OTHER_COMMANDS) |
| 504 | |
| 505 | parser = optparse.OptionParser(usage) |
| 506 | args = parser.parse_args()[1] |
| 507 | |
| 508 | if not args: |
| 509 | print usage |
| 510 | return |
| 511 | |
| 512 | if os.getenv('USER') != 'chronos': |
Steven Bennetts | 26178d9 | 2011-11-22 10:54:41 -0800 | [diff] [blame] | 513 | _PrintError("%s must be run as chronos." % _PROG) |
Steven Bennetts | 62fd725 | 2011-11-03 13:56:09 -0700 | [diff] [blame] | 514 | return |
| 515 | |
| 516 | cmd = args[0] |
| 517 | if cmd in _SETUP_COMMANDS.keys(): |
| 518 | res = _SETUP_COMMANDS[cmd](args[1:]) |
| 519 | elif cmd in _OTHER_COMMANDS.keys(): |
| 520 | res = _OTHER_COMMANDS[cmd](args[1:]) |
| 521 | else: |
| 522 | parser.error("Unknown command: " + cmd) |
| 523 | return |
| 524 | |
| 525 | if not res: |
Steven Bennetts | 26178d9 | 2011-11-22 10:54:41 -0800 | [diff] [blame] | 526 | _PrintError("Errors encountered when running '%s'" % ' '.join(args)) |
Steven Bennetts | 62fd725 | 2011-11-03 13:56:09 -0700 | [diff] [blame] | 527 | else: |
| 528 | print "Success!" |
| 529 | |
| 530 | |
| 531 | if __name__ == '__main__': |
| 532 | main() |