| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 # Virtual Me2Me implementation. This script runs and manages the processes | 6 # Virtual Me2Me implementation. This script runs and manages the processes |
| 7 # required for a Virtual Me2Me desktop, which are: X server, X desktop | 7 # required for a Virtual Me2Me desktop, which are: X server, X desktop |
| 8 # session, and Host process. | 8 # session, and Host process. |
| 9 # This script is intended to run continuously as a background daemon | 9 # This script is intended to run continuously as a background daemon |
| 10 # process, running under an ordinary (non-root) user account. | 10 # process, running under an ordinary (non-root) user account. |
| (...skipping 15 matching lines...) Expand all Loading... |
| 26 import sys | 26 import sys |
| 27 import tempfile | 27 import tempfile |
| 28 import time | 28 import time |
| 29 import urllib2 | 29 import urllib2 |
| 30 import uuid | 30 import uuid |
| 31 | 31 |
| 32 # Local modules | 32 # Local modules |
| 33 import gaia_auth | 33 import gaia_auth |
| 34 import keygen | 34 import keygen |
| 35 | 35 |
| 36 # By default this script will try to determine the most appropriate X session |
| 37 # command for the system. To use a specific session instead, set this variable |
| 38 # to the executable filename, or a list containing the executable and any |
| 39 # arguments, for example: |
| 40 # XSESSION_COMMAND = "/usr/bin/gnome-session-fallback" |
| 41 # XSESSION_COMMAND = ["/usr/bin/gnome-session", "--session=ubuntu-2d"] |
| 42 XSESSION_COMMAND = None |
| 43 |
| 36 REMOTING_COMMAND = "remoting_me2me_host" | 44 REMOTING_COMMAND = "remoting_me2me_host" |
| 37 | 45 |
| 38 # Command-line switch for passing the config path to remoting_me2me_host. | 46 # Command-line switch for passing the config path to remoting_me2me_host. |
| 39 HOST_CONFIG_SWITCH_NAME = "host-config" | 47 HOST_CONFIG_SWITCH_NAME = "host-config" |
| 40 | 48 |
| 41 # Needs to be an absolute path, since the current working directory is changed | 49 # Needs to be an absolute path, since the current working directory is changed |
| 42 # when this process self-daemonizes. | 50 # when this process self-daemonizes. |
| 43 SCRIPT_PATH = os.path.dirname(sys.argv[0]) | 51 SCRIPT_PATH = os.path.dirname(sys.argv[0]) |
| 44 if SCRIPT_PATH: | 52 if SCRIPT_PATH: |
| 45 SCRIPT_PATH = os.path.abspath(SCRIPT_PATH) | 53 SCRIPT_PATH = os.path.abspath(SCRIPT_PATH) |
| (...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 326 # be started with -noreset otherwise it'll reset as soon as the command | 334 # be started with -noreset otherwise it'll reset as soon as the command |
| 327 # completes, since there are no other X clients running yet. | 335 # completes, since there are no other X clients running yet. |
| 328 proc = subprocess.Popen("setxkbmap -rules evdev", env=self.child_env, | 336 proc = subprocess.Popen("setxkbmap -rules evdev", env=self.child_env, |
| 329 shell=True) | 337 shell=True) |
| 330 pid, retcode = os.waitpid(proc.pid, 0) | 338 pid, retcode = os.waitpid(proc.pid, 0) |
| 331 if retcode != 0: | 339 if retcode != 0: |
| 332 logging.error("Failed to set XKB to 'evdev'") | 340 logging.error("Failed to set XKB to 'evdev'") |
| 333 | 341 |
| 334 def launch_x_session(self): | 342 def launch_x_session(self): |
| 335 # Start desktop session | 343 # Start desktop session |
| 336 # The /dev/null input redirection is necessary to prevent Xsession from | 344 # The /dev/null input redirection is necessary to prevent the X session |
| 337 # reading from stdin. If this code runs as a shell background job in a | 345 # reading from stdin. If this code runs as a shell background job in a |
| 338 # terminal, any reading from stdin causes the job to be suspended. | 346 # terminal, any reading from stdin causes the job to be suspended. |
| 339 # Daemonization would solve this problem by separating the process from the | 347 # Daemonization would solve this problem by separating the process from the |
| 340 # controlling terminal. | 348 # controlling terminal. |
| 341 # | 349 logging.info("Launching X session: %s" % XSESSION_COMMAND) |
| 342 # This assumes that GDM is installed and configured on the system. | 350 self.session_proc = subprocess.Popen(XSESSION_COMMAND, |
| 343 self.session_proc = subprocess.Popen("/etc/gdm/Xsession", | |
| 344 stdin=open(os.devnull, "r"), | 351 stdin=open(os.devnull, "r"), |
| 345 cwd=HOME_DIR, | 352 cwd=HOME_DIR, |
| 346 env=self.child_env) | 353 env=self.child_env) |
| 347 if not self.session_proc.pid: | 354 if not self.session_proc.pid: |
| 348 raise Exception("Could not start X session") | 355 raise Exception("Could not start X session") |
| 349 | 356 |
| 350 def launch_host(self, host): | 357 def launch_host(self, host): |
| 351 # Start remoting host | 358 # Start remoting host |
| 352 args = [locate_executable(REMOTING_COMMAND), | 359 args = [locate_executable(REMOTING_COMMAND), |
| 353 "--%s=%s" % (HOST_CONFIG_SWITCH_NAME, host.config_file)] | 360 "--%s=%s" % (HOST_CONFIG_SWITCH_NAME, host.config_file)] |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 432 | 439 |
| 433 def delete_file(self): | 440 def delete_file(self): |
| 434 """Delete the PID file if it was created by this instance. | 441 """Delete the PID file if it was created by this instance. |
| 435 | 442 |
| 436 This is called on process termination. | 443 This is called on process termination. |
| 437 """ | 444 """ |
| 438 if self.created: | 445 if self.created: |
| 439 os.remove(self.filename) | 446 os.remove(self.filename) |
| 440 | 447 |
| 441 | 448 |
| 449 def choose_x_session(): |
| 450 """Chooses the most appropriate X session command for this system. |
| 451 |
| 452 If XSESSION_COMMAND is already set, its value is returned directly. |
| 453 Otherwise, a session is chosen for this system. |
| 454 |
| 455 Returns: |
| 456 A string containing the command to run, or a list of strings containing |
| 457 the executable program and its arguments, which is suitable for passing as |
| 458 the first parameter of subprocess.Popen(). If a suitable session cannot |
| 459 be found, returns None. |
| 460 """ |
| 461 if XSESSION_COMMAND is not None: |
| 462 return XSESSION_COMMAND |
| 463 |
| 464 # Unity-2d would normally be the preferred choice on Ubuntu 12.04. At the |
| 465 # time of writing, this session does not work properly (missing launcher and |
| 466 # panel), so gnome-session-fallback is used in preference. |
| 467 # "unity-2d-panel" was chosen here simply because it appears in the TryExec |
| 468 # line of the session's .desktop file; other choices might be just as good. |
| 469 for test_file, command in [ |
| 470 ("/usr/bin/gnome-session-fallback", "/usr/bin/gnome-session-fallback"), |
| 471 ("/etc/gdm/Xsession", "/etc/gdm/Xsession"), |
| 472 ("/usr/bin/unity-2d-panel", |
| 473 ["/usr/bin/gnome-session", "--session=ubuntu-2d"]), |
| 474 ]: |
| 475 if os.path.exists(test_file): |
| 476 return command |
| 477 |
| 478 return None |
| 479 |
| 480 |
| 442 def locate_executable(exe_name): | 481 def locate_executable(exe_name): |
| 443 for path in EXE_PATHS_TO_TRY: | 482 for path in EXE_PATHS_TO_TRY: |
| 444 exe_path = os.path.join(SCRIPT_PATH, path, exe_name) | 483 exe_path = os.path.join(SCRIPT_PATH, path, exe_name) |
| 445 if os.path.exists(exe_path): | 484 if os.path.exists(exe_path): |
| 446 return exe_path | 485 return exe_path |
| 447 | 486 |
| 448 raise Exception("Could not locate executable '%s'" % exe_name) | 487 raise Exception("Could not locate executable '%s'" % exe_name) |
| 449 | 488 |
| 450 | 489 |
| 451 def daemonize(log_filename): | 490 def daemonize(log_filename): |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 581 width = int(size_components[0]) | 620 width = int(size_components[0]) |
| 582 height = int(size_components[1]) | 621 height = int(size_components[1]) |
| 583 | 622 |
| 584 # Enforce minimum desktop size, as a sanity-check. The limit of 100 will | 623 # Enforce minimum desktop size, as a sanity-check. The limit of 100 will |
| 585 # detect typos of 2 instead of 3 digits. | 624 # detect typos of 2 instead of 3 digits. |
| 586 if width < 100 or height < 100: | 625 if width < 100 or height < 100: |
| 587 raise ValueError | 626 raise ValueError |
| 588 except ValueError: | 627 except ValueError: |
| 589 parser.error("Width and height should be 100 pixels or greater") | 628 parser.error("Width and height should be 100 pixels or greater") |
| 590 | 629 |
| 630 global XSESSION_COMMAND |
| 631 XSESSION_COMMAND = choose_x_session() |
| 632 if XSESSION_COMMAND is None: |
| 633 print >> sys.stderr, "Unable to choose suitable X session command." |
| 634 return 1 |
| 635 |
| 636 if "--session=ubuntu-2d" in XSESSION_COMMAND: |
| 637 print >> sys.stderr, ( |
| 638 "The Unity 2D desktop session will be used.\n" |
| 639 "If you encounter problems with this choice of desktop, please install\n" |
| 640 "the gnome-session-fallback package, and restart this script.\n") |
| 641 |
| 591 atexit.register(cleanup) | 642 atexit.register(cleanup) |
| 592 | 643 |
| 593 for s in [signal.SIGHUP, signal.SIGINT, signal.SIGTERM, signal.SIGUSR1]: | 644 for s in [signal.SIGHUP, signal.SIGINT, signal.SIGTERM, signal.SIGUSR1]: |
| 594 signal.signal(s, signal_handler) | 645 signal.signal(s, signal_handler) |
| 595 | 646 |
| 596 # Ensure full path to config directory exists. | 647 # Ensure full path to config directory exists. |
| 597 if not os.path.exists(CONFIG_DIR): | 648 if not os.path.exists(CONFIG_DIR): |
| 598 os.makedirs(CONFIG_DIR, mode=0700) | 649 os.makedirs(CONFIG_DIR, mode=0700) |
| 599 | 650 |
| 600 if options.explicit_config: | 651 if options.explicit_config: |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 759 os.remove(host.config_file) | 810 os.remove(host.config_file) |
| 760 return 0 | 811 return 0 |
| 761 elif os.WEXITSTATUS(status) == 4: | 812 elif os.WEXITSTATUS(status) == 4: |
| 762 logging.info("OAuth credentials are invalid - exiting.") | 813 logging.info("OAuth credentials are invalid - exiting.") |
| 763 os.remove(auth.config_file) | 814 os.remove(auth.config_file) |
| 764 return 0 | 815 return 0 |
| 765 | 816 |
| 766 if __name__ == "__main__": | 817 if __name__ == "__main__": |
| 767 logging.basicConfig(level=logging.DEBUG) | 818 logging.basicConfig(level=logging.DEBUG) |
| 768 sys.exit(main()) | 819 sys.exit(main()) |
| OLD | NEW |