blob: e06451dfac3e87ddd7e2c80c6e3ceb296103681f [file] [log] [blame]
Steven Bennetts62fd7252011-11-03 20:56:091#!/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
9import optparse
10import os
11import shutil
12import subprocess
13import 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 Bennetts26178d92011-11-22 18:54:4121# Note: no ~/ for sshfs:
22_DEFAULT_HOST_CHROOT_DIR = "chromeos/chroot"
23_HOST_CHROOT_DIR_FILENAME = os.path.expanduser("~/.chromedir")
Steven Bennetts62fd7252011-11-03 20:56:0924
25RAN_SUDO = False
26
27###############################################################################
28# Utility commands
29
Steven Bennetts26178d92011-11-22 18:54:4130def _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
37def _Confirm(message, default_response="n"):
Steven Bennetts62fd7252011-11-03 20:56:0938 """Request confirmation and return True/False."""
Steven Bennetts26178d92011-11-22 18:54:4139 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 Bennetts62fd7252011-11-03 20:56:0949
50
51def _CheckOverwriteFile(filepath):
52 """Check for a file and request confirmation if it exists."""
53 if os.path.isfile(filepath):
Steven Bennetts26178d92011-11-22 18:54:4154 if not _Confirm("%s already exists. Overwrite?" % filepath):
Steven Bennetts62fd7252011-11-03 20:56:0955 return False
56 return True
57
58
59def _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 Bennetts26178d92011-11-22 18:54:4165 except EnvironmentError as err:
66 _PrintError("Failed to write to file '%s'" % filepath, err)
Steven Bennetts62fd7252011-11-03 20:56:0967 return False
68
69 return True
70
71
Steven Bennetts26178d92011-11-22 18:54:4172def _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 Bennetts62fd7252011-11-03 20:56:0985def _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 Bennetts26178d92011-11-22 18:54:4192 except EnvironmentError as err:
93 _PrintError("Failed to run sudo", err)
Steven Bennetts62fd7252011-11-03 20:56:0994 return False
95 RAN_SUDO = True
96 return True
97
98
99def _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 Bennetts26178d92011-11-22 18:54:41108 except EnvironmentError as err:
109 _PrintError("Failed to run command '%s'" % cmd, err)
Steven Bennetts62fd7252011-11-03 20:56:09110 return False
111 else:
112 if retcode != 0:
Steven Bennetts26178d92011-11-22 18:54:41113 _PrintError("Error running command '%s'" % cmd, "%s" % retcode)
Steven Bennetts62fd7252011-11-03 20:56:09114 return False
115 return True
116
117
118def _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 Bennetts26178d92011-11-22 18:54:41124 except EnvironmentError as err:
125 _PrintError("Failed to run command '%s'" % cmd, err)
Steven Bennetts62fd7252011-11-03 20:56:09126 return None
127 result = result.rstrip('\n')
128 return result
129
130
Steven Bennetts26178d92011-11-22 18:54:41131def _MakeDirectory(dirpath, warn=True):
Steven Bennetts62fd7252011-11-03 20:56:09132 """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 Bennetts26178d92011-11-22 18:54:41137 except EnvironmentError as err:
138 if warn:
139 _PrintError("Failed to create directory '%s'" % dirpath, err)
Steven Bennetts62fd7252011-11-03 20:56:09140 return False
141 return True
142
143
144def _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 Bennetts26178d92011-11-22 18:54:41150 except EnvironmentError as err:
151 _PrintError("Failed to remove file '%s'" % filepath, err)
Steven Bennetts62fd7252011-11-03 20:56:09152 return False
153 return True
154
155
156def _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 Bennetts26178d92011-11-22 18:54:41162 except EnvironmentError as err:
163 _PrintError("Failed to remove dir '%s'" % dirpath, err)
Steven Bennetts62fd7252011-11-03 20:56:09164 return False
165 return True
166
167
168def _DevUser():
169 """Extract the user name from lsb-release."""
Steven Bennetts26178d92011-11-22 18:54:41170 # TODO(stevenjb): Refactor this using python re.
Steven Bennetts62fd7252011-11-03 20:56:09171 awk_expr = """/CHROMEOS_RELEASE_DESCRIPTION/ {"""
Steven Bennettsb28276a2011-11-29 20:29:31172 awk_expr += """ sub(/.*Build - /,"");"""
Steven Bennetts62fd7252011-11-03 20:56:09173 awk_expr += """ sub(/\).*/,"");"""
174 awk_expr += """ print; }"""
175 return _GetCommandOutput(["awk", awk_expr, "/etc/lsb-release"])
176
177
178def _DevHost():
179 """Extract the host name from lsb-release."""
Steven Bennetts26178d92011-11-22 18:54:41180 # TODO(stevenjb): Refactor this using python re.
Steven Bennetts62fd7252011-11-03 20:56:09181 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 Bennetts26178d92011-11-22 18:54:41187
188def _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
197def _GetChrootDir(prompt_for_dir=False):
198 """Get the name for the chrome directory on the host."""
Steven Bennettsb28276a2011-11-29 20:29:31199 if os.path.isfile(_HOST_CHROOT_DIR_FILENAME):
200 chromedir = _ReadFile(_HOST_CHROOT_DIR_FILENAME)
201 else:
Steven Bennetts26178d92011-11-22 18:54:41202 chromedir = _DEFAULT_HOST_CHROOT_DIR
203
204 if prompt_for_dir:
205 host = _DevHost()
Steven Bennettsb28276a2011-11-29 20:29:31206 prompt = ("Chroot directory on %s [ %s ]: " % (host, chromedir))
Steven Bennetts26178d92011-11-22 18:54:41207 inputdir = raw_input(prompt).rstrip()
208 if inputdir:
209 chromedir = inputdir
210 _WriteFile(_HOST_CHROOT_DIR_FILENAME, chromedir)
211
212 return chromedir
213
214
Chris Masone32ee2012011-12-13 16:48:21215def _DaemonizeAndReRunAsRoot(cmd):
216 """Double-fork to become owned by init, then re-exec this tool as root.
217
218 Double-forking is the standard way to detach yourself from a
219 process tree and become owned by init. By doing this, you get to
220 live on even if your parent goes away."""
221 try:
222 pid = os.fork()
223 if pid > 0:
224 sys.exit(0) # Just want to go away silently.
225 except OSError, e:
226 return False
227 try:
228 pid = os.fork()
229 if pid > 0:
230 sys.exit(0) # Just want to go away silently.
231 except OSError, e:
232 return False
233
234 # re-run self as root.
235 try:
236 os.execlp('sudo', sys.executable, __file__, cmd)
237 except OSError, e:
238 _PrintError("Unable to exec self as root: %s", str(e))
239 return False
240
241
Steven Bennetts62fd7252011-11-03 20:56:09242###############################################################################
243# Other Commands
244
245def TestCommand(args):
246 """Test command."""
Steven Bennetts26178d92011-11-22 18:54:41247 _WriteFile("/foo/test", "test")
Steven Bennetts62fd7252011-11-03 20:56:09248 if len(args) == 0:
249 args = ["sudo", "ls", "/"]
250 return _RunCommand(args)
251 return False
252
253
Steven Bennetts26178d92011-11-22 18:54:41254def GetBoard(unused_args=0):
255 """Gets the board name from /etc/lsb-release."""
256 print _DevBoard()
257 return True
258
259
Steven Bennetts62fd7252011-11-03 20:56:09260def GetUser(unused_args=0):
261 """Gets the user name from /etc/lsb-release."""
262 print _DevUser()
263 return True
264
265
266def GetHost(unused_args=0):
267 """Gets the host name from /etc/lsb-release."""
268 print _DevHost()
269 return True
270
271
272def MountWriteable(unused_args=0):
273 """Remounts / as rw."""
274 return _RunCommand(["sudo", "mount", "-o", "remount,rw", "/"])
275
276
277def ShowIP(unused_args=0):
278 """Shows the IP address of the device."""
279 proc1 = subprocess.Popen(["/sbin/ifconfig", "eth0"], stdout=subprocess.PIPE)
280 awk_cmd = """/inet addr/ {"""
281 awk_cmd += """ sub(/.*inet addr:/,""); sub(/ Bcast:.*/,"");"""
282 awk_cmd += """ print; }"""
283 proc2 = subprocess.Popen(
284 ["awk", awk_cmd], stdin=proc1.stdout, stdout=subprocess.PIPE)
285 proc1.stdout.close()
286 result = proc2.communicate()[0].rstrip('\n')
287 print "IP: ", result
288 return True
289
290
291def KillChrome(unused_args=0):
292 """Kills all chrome processes and prevents restarting of chrome."""
293 res = True
Chris Masone649df542012-02-03 21:41:14294 res &= _RunCommand(["touch", "/var/run/disable_chrome_restart"])
Steven Bennetts62fd7252011-11-03 20:56:09295 res &= _RunCommand(["sudo", "pkill", "-9", "chrome"])
296 return res
297
298
Chris Masone32ee2012011-12-13 16:48:21299def ClearOwnership(unused_args=0):
300 """Clears any state related to the device Ownership (NOT TPM ownership)."""
Steven Bennetts62fd7252011-11-03 20:56:09301 res = True
Chris Masone32ee2012011-12-13 16:48:21302 res &= _RunCommand(["sudo", "stop", "ui"])
303
304 whitelist_dir = "/var/lib/whitelist"
305 for file in os.listdir(whitelist_dir):
306 res &= _RemoveFile(os.path.join(whitelist_dir, file))
307
Steven Bennetts62fd7252011-11-03 20:56:09308 res &= _RemoveDirectory("/home/chronos/Local State")
Chris Masone32ee2012011-12-13 16:48:21309 res &= _RemoveFile("/home/chronos/Consent To Send Stats")
310 res &= _RunCommand(["sudo", "start", "ui"])
Steven Bennetts62fd7252011-11-03 20:56:09311
312 if not res:
Chris Masone32ee2012011-12-13 16:48:21313 _PrintError("Errors encountered while clearing ownership state.")
Steven Bennetts62fd7252011-11-03 20:56:09314 return False
Steven Bennetts62fd7252011-11-03 20:56:09315 return True
316
Chris Masone32ee2012011-12-13 16:48:21317
318def ShowOobe(unused_args=0):
319 """Removes .oobe_completed and Local State directory."""
320 res = True
321 res &= _RemoveFile("/home/chronos/.oobe_completed")
322 res &= ClearOwnership()
323
324 if not res:
325 _PrintError("Errors encountered while clearing setting up OOBE mode.")
326 return False
327 return _RunCommand(["sudo", "reboot"])
328
329
Steven Bennetts62fd7252011-11-03 20:56:09330###############################################################################
331# Setup Commands
332
333def SetBash(unused_args):
334 """Sets the default shell to bash."""
335 if not _Sudo():
336 return False
337 if not MountWriteable():
338 return False
339 res = True
340 res &= _RunCommand(["chsh", "-s", "/bin/bash"])
341 res &= _RunCommand(["chsh", "-s", "/bin/bash", "chronos"])
342 return res
343
344
345def SetupBashrc(unused_args):
346 """Sets up .bashrc."""
347 filepath = os.path.expanduser("~/.bashrc")
348 if not _CheckOverwriteFile(filepath):
Steven Bennetts26178d92011-11-22 18:54:41349 return True
Steven Bennetts62fd7252011-11-03 20:56:09350
351 print "Writing to: ", filepath
352 bashrc = "#!/bin/bash\n"
353 bashrc += "# .bashrc file set by %s\n" % _PROG
354 bashrc += "export DISPLAY=:0.0\n"
355 bashrc += "export PATH=$PATH:/sbin:/usr/sbin:/usr/local/sbin\n"
356 bashrc += "/sbin/ifconfig eth0 | grep 'inet addr'\n"
357 if not _WriteFile(filepath, bashrc):
358 return False
359
360 filepath = os.path.expanduser("~/.bash_profile")
361 print "Writing to: ", filepath
362 bashprofile = "#!/bin/bash\n"
363 bashprofile += ". $HOME/.bashrc\n"
364 if not _WriteFile(filepath, bashprofile):
365 return False
366 return True
367
368
369def SetupDev(unused_args):
370 """Developer friendly setup: skip oobe, don't forget usernames,
371\t\tdisable suspend, enable ssh and remote debugging,
372\t\trun commands from /tmp,/home."""
373 if not _Sudo():
374 return False
375 if not MountWriteable():
376 return False
377 res = True
Steven Bennetts26178d92011-11-22 18:54:41378 res &= _WriteFile("/home/chronos/.oobe_completed", "1\n")
Steven Bennettsb28276a2011-11-29 20:29:31379 res &= _RunCommand(["sudo", "rm", "-f", "/root/.forget_usernames"])
Steven Bennetts62fd7252011-11-03 20:56:09380 res &= _MakeDirectory("/usr/share/power_manager")
Steven Bennetts26178d92011-11-22 18:54:41381 res &= _WriteFile("/tmp/disable_idle_suspend", "1\n")
382 res &= _RunCommand(["sudo", "cp", "/tmp/disable_idle_suspend",
383 "/usr/share/power_manager/"])
Steven Bennetts62fd7252011-11-03 20:56:09384 # Enable iptables and system-services for remote debugging
385 for filename in ["iptables", "saft"]:
386 res &= _RunCommand(["sudo", "sed", "-i", "-e",
387 "s/#for_test //", "/etc/init/%s.conf" % filename])
388 # Allow commands to be run from /home and /tmp
389 res &= _RunCommand(["sudo", "sed", "-i", "-e",
390 "s/#mod_for_test#//g", "/sbin/chromeos_startup"])
391 return res
392
393
394def SetupSsh(unused_args):
395 """Sets up ssh configuration so that the dev host can ssh to the device."""
396 if not MountWriteable():
397 return False
398
399 user = _DevUser()
400 host = _DevHost()
401
Steven Bennetts62fd7252011-11-03 20:56:09402 res = True
Steven Bennetts26178d92011-11-22 18:54:41403 if _CheckOverwriteFile(_SSH_KEY_FILEPATH):
404 res &= _RemoveFile(_SSH_KEY_FILEPATH)
405 # Generate an ssh key
406 if _RunCommand(["ssh-keygen", "-f", _SSH_KEY_FILEPATH, "-N", "", "-q"]):
407 host_source_path = "%s@%s:%s" % (user, host, _PUB_KEY_FILENAME)
408 # Copy the ssh key to the host
409 res &= _RunCommand(["scp", host_source_path, _AUTH_KEYS_FILEPATH])
410
Steven Bennetts62fd7252011-11-03 20:56:09411 # Enable ssh to device
412 res &= _RunCommand(
413 ["sudo", "sed", "-i", "s/#for_test //", "/etc/init/openssh-server.conf"])
Steven Bennetts62fd7252011-11-03 20:56:09414
415 return res
416
417
418def AuthorizeSsh(unused_args):
419 """Authorizes this netbook to connect to your dev host.
420\t\t*Only use this on a device in a secure location!*"""
421
422 user = _DevUser()
423 host = _DevHost()
424
Steven Bennetts26178d92011-11-22 18:54:41425 if not os.path.isdir(os.path.expanduser("~/.ssh")):
426 print "Run '%s ssh' to set up .ssh directory first." % _PROG
427 return False
428
429 if not _Confirm("This will append %s to authorized_keys on %s. "
430 "Are you sure?" % (_PUB_KEY_FILENAME, host)):
Steven Bennetts62fd7252011-11-03 20:56:09431 return False
432
433 proc1 = subprocess.Popen(["cat", _PUB_KEY_FILEPATH], stdout=subprocess.PIPE)
434 try:
435 ssh_args = ["ssh", user+"@"+host, "cat >> ~/.ssh/authorized_keys"]
436 proc2 = subprocess.Popen(
437 ssh_args, stdin=proc1.stdout, stdout=subprocess.PIPE)
Steven Bennetts26178d92011-11-22 18:54:41438 except EnvironmentError as err1:
439 _PrintError("Error executing '%s'" % ' '.join(ssh_args), err1)
Steven Bennetts62fd7252011-11-03 20:56:09440 return False
441 try:
442 proc1.stdout.close()
Steven Bennetts26178d92011-11-22 18:54:41443 result, err2 = proc2.communicate()
Steven Bennetts62fd7252011-11-03 20:56:09444 except EnvironmentError:
Steven Bennetts26178d92011-11-22 18:54:41445 _PrintError("Error completing ssh command '%s'" % result, err2)
Steven Bennetts62fd7252011-11-03 20:56:09446 return False
447 return True
448
449
450def SetupSshfsForChrome(unused_args):
451 """<chrome-drir> Sets up sshfs mount to chrome directory on host."""
452
453 user = _DevUser()
454 host = _DevHost()
455
Steven Bennetts26178d92011-11-22 18:54:41456 chrootdir = _GetChrootDir(True)
Steven Bennetts62fd7252011-11-03 20:56:09457
Steven Bennetts26178d92011-11-22 18:54:41458 target = ("%s@%s:%s/var/lib/portage/distfiles-target/chrome-src"
459 % (user, host, chrootdir))
Steven Bennetts62fd7252011-11-03 20:56:09460 print "Setting up sshfs mount to: ", target
461
462 res = True
463 res &= _RunCommand(["sudo", "modprobe", "fuse"])
464 if os.path.isdir(_CHROME_MOUNT_PATH):
Steven Bennetts26178d92011-11-22 18:54:41465 res &= _RunCommand(["fusermount", "-q", "-u", _CHROME_MOUNT_PATH])
Steven Bennetts62fd7252011-11-03 20:56:09466 res &= _RemoveDirectory(_CHROME_MOUNT_PATH)
467 res &= _MakeDirectory(_CHROME_MOUNT_PATH)
468 res &= _RunCommand(["sshfs", target, _CHROME_MOUNT_PATH])
469 res &= _RunCommand(["sudo", "/sbin/iptables",
470 "-A", "INPUT", "-p", "tcp", "--dport", "1234",
471 "-j", "ACCEPT"])
472 return res
473
474###############################################################################
475# Multi-commands (convenience functions)
476
477def Setup(args):
478 """Performs default developer setup (bash,bashrc,dev,ssh)."""
479 if not SetBash(args):
Steven Bennetts26178d92011-11-22 18:54:41480 if not _Confirm("Bash setup failed. Continue?", "y"):
Steven Bennetts62fd7252011-11-03 20:56:09481 return False
482 if not SetupBashrc(args):
Steven Bennetts26178d92011-11-22 18:54:41483 if not _Confirm(".bashrc setup failed. Continue?", "y"):
Steven Bennetts62fd7252011-11-03 20:56:09484 return False
485 if not SetupDev(args):
Steven Bennetts26178d92011-11-22 18:54:41486 if not _Confirm("Dev setup failed. Continue?", "y"):
Steven Bennetts62fd7252011-11-03 20:56:09487 return False
488 if not SetupSsh(args):
489 return False
490 return True
491
492###############################################################################
493
494_SETUP_COMMANDS = {
495 'setup': Setup,
496 'dev': SetupDev,
497 'bash': SetBash,
498 'bashrc': SetupBashrc,
499 'ssh': SetupSsh,
500 'sshauthorize': AuthorizeSsh,
501 'sshfs': SetupSshfsForChrome,
502}
503
504
505_OTHER_COMMANDS = {
506 'mountrw': MountWriteable,
507 'ip': ShowIP,
508 'test': TestCommand,
Steven Bennetts26178d92011-11-22 18:54:41509 'board': GetBoard,
Steven Bennetts62fd7252011-11-03 20:56:09510 'user': GetUser,
511 'host': GetHost,
512}
513
514
Chris Masone32ee2012011-12-13 16:48:21515_CLEANUP_COMMANDS = {
516 'show_oobe': ShowOobe,
517 'clear_owner': ClearOwnership,
518}
519
520
Steven Bennetts62fd7252011-11-03 20:56:09521def GetUsage(commands):
522 """Get the docstring for each command."""
523 usage = ""
524 for cmd in commands.items():
525 usage += " "
526 usage += cmd[0]
527 usage += ":\t"
528 if len(cmd[0]) < 6:
529 usage += "\t"
530 doc = cmd[1].__doc__
531 if doc:
532 usage += doc
533 usage += "\n"
534 return usage
535
536
537###############################################################################
538
539def main():
540 """Main crdev function"""
541 usage = """usage: crdev command [options]
542
Steven Bennetts26178d92011-11-22 18:54:41543Note: Beta! Feature requests / changes can be sent to:
544 [email protected] (for now)
Steven Bennetts62fd7252011-11-03 20:56:09545
546"""
547
548 usage += "Setup Commands:\n"
549 usage += GetUsage(_SETUP_COMMANDS)
550 usage += "Other Commands:\n"
551 usage += GetUsage(_OTHER_COMMANDS)
Chris Masone32ee2012011-12-13 16:48:21552 usage += "Cleanup Commands:\n"
553 usage += GetUsage(_CLEANUP_COMMANDS)
Steven Bennetts62fd7252011-11-03 20:56:09554
555 parser = optparse.OptionParser(usage)
556 args = parser.parse_args()[1]
557
558 if not args:
559 print usage
560 return
561
Steven Bennetts62fd7252011-11-03 20:56:09562 cmd = args[0]
Chris Masone32ee2012011-12-13 16:48:21563 root_ok = cmd in _CLEANUP_COMMANDS.keys()
564 if not root_ok or os.geteuid() != 0:
565 if os.getenv('USER') != 'chronos':
566 _PrintError("%s must be run as chronos." % _PROG)
567 return
568
Steven Bennetts62fd7252011-11-03 20:56:09569 if cmd in _SETUP_COMMANDS.keys():
570 res = _SETUP_COMMANDS[cmd](args[1:])
571 elif cmd in _OTHER_COMMANDS.keys():
572 res = _OTHER_COMMANDS[cmd](args[1:])
Chris Masone32ee2012011-12-13 16:48:21573 elif cmd in _CLEANUP_COMMANDS.keys():
574 if os.geteuid() != 0:
575 _DaemonizeAndReRunAsRoot(cmd)
576 _PrintError("Should never return from DaemonizeAndReRunAsRoot()")
577 return
578 res = _CLEANUP_COMMANDS[cmd](args[1:])
Steven Bennetts62fd7252011-11-03 20:56:09579 else:
580 parser.error("Unknown command: " + cmd)
581 return
582
583 if not res:
Steven Bennetts26178d92011-11-22 18:54:41584 _PrintError("Errors encountered when running '%s'" % ' '.join(args))
Steven Bennetts62fd7252011-11-03 20:56:09585 else:
586 print "Success!"
587
588
589if __name__ == '__main__':
590 main()