Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 #!/usr/bin/python | 1 #!/usr/bin/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 24 matching lines...) Expand all Loading... | |
| 35 import time | 35 import time |
| 36 import uuid | 36 import uuid |
| 37 | 37 |
| 38 LOG_FILE_ENV_VAR = "CHROME_REMOTE_DESKTOP_LOG_FILE" | 38 LOG_FILE_ENV_VAR = "CHROME_REMOTE_DESKTOP_LOG_FILE" |
| 39 | 39 |
| 40 # This script has a sensible default for the initial and maximum desktop size, | 40 # This script has a sensible default for the initial and maximum desktop size, |
| 41 # which can be overridden either on the command-line, or via a comma-separated | 41 # which can be overridden either on the command-line, or via a comma-separated |
| 42 # list of sizes in this environment variable. | 42 # list of sizes in this environment variable. |
| 43 DEFAULT_SIZES_ENV_VAR = "CHROME_REMOTE_DESKTOP_DEFAULT_DESKTOP_SIZES" | 43 DEFAULT_SIZES_ENV_VAR = "CHROME_REMOTE_DESKTOP_DEFAULT_DESKTOP_SIZES" |
| 44 | 44 |
| 45 # By default, this script launches Xvfb as the virtual X display. When this | |
| 46 # environment variable is set, the script will instead launch an instance of | |
| 47 # Xorg using the dummy display driver and void input device. In order for this | |
| 48 # to work, both the dummy display driver and void input device need to be | |
| 49 # installed: | |
| 50 # | |
| 51 # sudo apt-get install xserver-xorg-video-dummy | |
| 52 # sudo apt-get install xserver-xorg-input-void | |
| 53 USE_XORG_ENV_VAR = "CHROME_REMOTE_DESKTOP_USE_XORG" | |
| 54 | |
| 55 # The amount of video RAM the dummy driver should claim to have, which limits | |
| 56 # the maximum possible resolution. | |
| 57 # 1048576 KiB = 1 GiB, which is the amount of video RAM needed to have a | |
| 58 # 16384x16384 pixel frame buffer (the maximum size supported by VP8) with 32 | |
| 59 # bits per pixel. | |
| 60 XORG_DUMMY_VIDEO_RAM = 1048576 # KiB | |
| 61 | |
| 45 # By default, provide a maximum size that is large enough to support clients | 62 # By default, provide a maximum size that is large enough to support clients |
| 46 # with large or multiple monitors. This is a comma-separated list of | 63 # with large or multiple monitors. This is a comma-separated list of |
| 47 # resolutions that will be made available if the X server supports RANDR. These | 64 # resolutions that will be made available if the X server supports RANDR. These |
| 48 # defaults can be overridden in ~/.profile. | 65 # defaults can be overridden in ~/.profile. |
| 49 DEFAULT_SIZES = "1600x1200,3840x2560" | 66 DEFAULT_SIZES = "1600x1200,3840x2560" |
| 50 | 67 |
| 51 # If RANDR is not available, use a smaller default size. Only a single | 68 # If RANDR is not available, use a smaller default size. Only a single |
| 52 # resolution is supported in this case. | 69 # resolution is supported in this case. |
| 53 DEFAULT_SIZE_NO_RANDR = "1600x1200" | 70 DEFAULT_SIZE_NO_RANDR = "1600x1200" |
| 54 | 71 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 95 # session file exist. | 112 # session file exist. |
| 96 if (os.path.isdir(CONFIG_DIR) or os.path.isfile(SESSION_FILE_PATH) or | 113 if (os.path.isdir(CONFIG_DIR) or os.path.isfile(SESSION_FILE_PATH) or |
| 97 os.path.isfile(SYSTEM_SESSION_FILE_PATH)): | 114 os.path.isfile(SYSTEM_SESSION_FILE_PATH)): |
| 98 return True | 115 return True |
| 99 | 116 |
| 100 # The host has been tested only on Ubuntu. | 117 # The host has been tested only on Ubuntu. |
| 101 distribution = platform.linux_distribution() | 118 distribution = platform.linux_distribution() |
| 102 return (distribution[0]).lower() == 'ubuntu' | 119 return (distribution[0]).lower() == 'ubuntu' |
| 103 | 120 |
| 104 | 121 |
| 105 def get_randr_supporting_x_server(): | 122 def locate_xvfb_randr(): |
| 106 """Returns a path to an X server that supports the RANDR extension, if this | 123 """Returns a path to our RANDR-supporting Xvfb server, if it is found on the |
| 107 is found on the system. Otherwise returns None.""" | 124 system. Otherwise returns None.""" |
| 108 | 125 |
| 109 xvfb = "/usr/bin/Xvfb-randr" | 126 xvfb = "/usr/bin/Xvfb-randr" |
| 110 if os.path.exists(xvfb): | 127 if os.path.exists(xvfb): |
| 111 return xvfb | 128 return xvfb |
| 112 | 129 |
| 113 xvfb = os.path.join(SCRIPT_DIR, "Xvfb-randr") | 130 xvfb = os.path.join(SCRIPT_DIR, "Xvfb-randr") |
| 114 if os.path.exists(xvfb): | 131 if os.path.exists(xvfb): |
| 115 return xvfb | 132 return xvfb |
| 116 | 133 |
| 117 return None | 134 return None |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 231 | 248 |
| 232 class Desktop: | 249 class Desktop: |
| 233 """Manage a single virtual desktop""" | 250 """Manage a single virtual desktop""" |
| 234 | 251 |
| 235 def __init__(self, sizes): | 252 def __init__(self, sizes): |
| 236 self.x_proc = None | 253 self.x_proc = None |
| 237 self.session_proc = None | 254 self.session_proc = None |
| 238 self.host_proc = None | 255 self.host_proc = None |
| 239 self.child_env = None | 256 self.child_env = None |
| 240 self.sizes = sizes | 257 self.sizes = sizes |
| 258 self.xorg_conf = None | |
| 241 self.pulseaudio_pipe = None | 259 self.pulseaudio_pipe = None |
| 242 self.server_supports_exact_resize = False | 260 self.server_supports_exact_resize = False |
| 243 self.host_ready = False | 261 self.host_ready = False |
| 244 self.ssh_auth_sockname = None | 262 self.ssh_auth_sockname = None |
| 245 g_desktops.append(self) | 263 g_desktops.append(self) |
| 246 | 264 |
| 247 @staticmethod | 265 @staticmethod |
| 248 def get_unused_display_number(): | 266 def get_unused_display_number(): |
| 249 """Return a candidate display number for which there is currently no | 267 """Return a candidate display number for which there is currently no |
| 250 X Server lock file""" | 268 X Server lock file""" |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 349 self.child_env["PULSE_STATE_PATH"] = pulse_path | 367 self.child_env["PULSE_STATE_PATH"] = pulse_path |
| 350 self.child_env["PULSE_SINK"] = sink_name | 368 self.child_env["PULSE_SINK"] = sink_name |
| 351 self.pulseaudio_pipe = pipe_name | 369 self.pulseaudio_pipe = pipe_name |
| 352 | 370 |
| 353 return True | 371 return True |
| 354 | 372 |
| 355 def _setup_gnubby(self): | 373 def _setup_gnubby(self): |
| 356 self.ssh_auth_sockname = ("/tmp/chromoting.%s.ssh_auth_sock" % | 374 self.ssh_auth_sockname = ("/tmp/chromoting.%s.ssh_auth_sock" % |
| 357 os.environ["USER"]) | 375 os.environ["USER"]) |
| 358 | 376 |
| 377 def _launch_xvfb(self, display, x_auth_file, extra_x_args): | |
| 378 max_width = max([width for width, height in self.sizes]) | |
| 379 max_height = max([height for width, height in self.sizes]) | |
| 380 | |
| 381 xvfb = locate_xvfb_randr() | |
| 382 if xvfb: | |
| 383 self.server_supports_exact_resize = True | |
| 384 else: | |
| 385 xvfb = "Xvfb" | |
| 386 self.server_supports_exact_resize = False | |
| 387 | |
| 388 logging.info("Starting %s on display :%d" % (xvfb, display)) | |
| 389 screen_option = "%dx%dx24" % (max_width, max_height) | |
| 390 self.x_proc = subprocess.Popen( | |
| 391 [xvfb, ":%d" % display, | |
| 392 "-auth", x_auth_file, | |
| 393 "-nolisten", "tcp", | |
| 394 "-noreset", | |
| 395 "-screen", "0", screen_option | |
| 396 ] + extra_x_args) | |
| 397 if not self.x_proc.pid: | |
| 398 raise Exception("Could not start Xvfb.") | |
| 399 | |
| 400 def _launch_xorg(self, display, x_auth_file, extra_x_args): | |
| 401 with tempfile.NamedTemporaryFile( | |
| 402 prefix="chrome_remote_desktop_", | |
| 403 suffix=".conf", delete=False) as config_file: | |
| 404 config_file.write( | |
| 405 # This causes X to load the default GLX module, even if a proprietary | |
|
Lambros
2016/05/10 00:30:15
Optional suggestion:
Declare this config as a Pyth
| |
| 406 # one is installed in a different directory. | |
| 407 'Section "Files"\n' | |
| 408 ' ModulePath "/usr/lib/xorg/modules"\n' | |
| 409 'EndSection\n' | |
| 410 '\n' | |
| 411 # Suppress device probing, which happens by default. | |
| 412 'Section "ServerFlags"\n' | |
| 413 ' Option "AutoAddDevices" "false"\n' | |
| 414 ' Option "AutoEnableDevices" "false"\n' | |
| 415 ' Option "DontVTSwitch" "true"\n' | |
| 416 ' Option "PciForceNone" "true"\n' | |
| 417 'EndSection\n' | |
| 418 '\n' | |
| 419 'Section "InputDevice"\n' | |
| 420 ' Identifier "Chrome Remote Desktop Input"\n' | |
| 421 ' Option "CoreKeyboard" "true"\n' | |
| 422 ' Option "CorePointer" "true"\n' | |
| 423 ' Driver "void"\n' | |
| 424 'EndSection\n' | |
| 425 '\n' | |
| 426 'Section "Device"\n' | |
| 427 ' Identifier "Chrome Remote Desktop Videocard"\n' | |
| 428 ' Driver "dummy"\n' | |
| 429 ' VideoRam {video_ram}\n' | |
| 430 'EndSection\n' | |
| 431 '\n' | |
| 432 'Section "Monitor"\n' | |
| 433 ' Identifier "Chrome Remote Desktop Monitor"\n' | |
| 434 ' HorizSync 3.3\n' | |
| 435 ' VertRefresh 0.1\n' | |
|
Jamie
2016/05/10 00:37:09
HorizSync and VertRefresh should probably also use
| |
| 436 '{modelines}' | |
| 437 'EndSection\n' | |
| 438 '\n' | |
| 439 'Section "Screen"\n' | |
| 440 ' Identifier "Chrome Remote Desktop Screen"\n' | |
| 441 ' Device "Chrome Remote Desktop Videocard"\n' | |
| 442 ' Monitor "Chrome Remote Desktop Monitor"\n' | |
| 443 ' DefaultDepth 24\n' | |
| 444 ' SubSection "Display"\n' | |
| 445 ' Viewport 0 0\n' | |
| 446 ' Depth 24\n' | |
| 447 ' Modes {modes}\n' | |
| 448 ' EndSubSection\n' | |
| 449 'EndSection\n' | |
| 450 '\n' | |
| 451 'Section "ServerLayout"\n' | |
| 452 ' Identifier "Chrome Remote Desktop Layout"\n' | |
| 453 ' Screen "Chrome Remote Desktop Screen"\n' | |
| 454 ' InputDevice "Chrome Remote Desktop Input"\n' | |
| 455 'EndSection\n'.format( | |
| 456 # This Modeline template allows resolutions up to the dummy | |
| 457 # driver's max supported resolution of 32767x32767 without | |
| 458 # additional calculation while meeting the driver's dot clock | |
| 459 # requirements. Note that VP8 (and thus the amount of video RAM | |
| 460 # chosen) only support a maximum resolution of 16384x16384. | |
| 461 # 32767x32767 should be possible if we switch fully to VP9 and | |
| 462 # increase the video RAM to 4GiB. Changing this line requires | |
| 463 # updating HorizSync and VertRefresh to match, above. | |
| 464 modelines="".join( | |
| 465 ' Modeline "{0}x{1}" 108.9 {0} 32998 32999 33000 {1} 32998 ' | |
| 466 '32999 33000\n'.format(w, h) for w, h in self.sizes), | |
| 467 modes=" ".join('"{0}x{1}"'.format(w, h) for w, h in self.sizes), | |
| 468 video_ram=XORG_DUMMY_VIDEO_RAM)) | |
| 469 | |
| 470 # For now, we don't support exact resize with Xorg+dummy | |
| 471 self.server_supports_exact_resize = False | |
| 472 self.xorg_conf = config_file.name | |
| 473 | |
| 474 logging.info("Starting Xorg on display :%d" % display) | |
| 475 # We use the child environment so the Xorg server picks up the Mesa libGL | |
| 476 # instead of any proprietary versions that may be installed, thanks to | |
| 477 # LD_LIBRARY_PATH. | |
| 478 # Note: This prevents any environment variable the user has set from | |
| 479 # affecting the Xorg server. | |
| 480 self.x_proc = subprocess.Popen( | |
| 481 ["Xorg", ":%d" % display, | |
| 482 "-auth", x_auth_file, | |
| 483 "-nolisten", "tcp", | |
| 484 "-noreset", | |
| 485 # Disable logging to a file and instead bump up the stderr verbosity | |
| 486 # so the equivalent information gets logged in our main log file. | |
| 487 "-logfile", "/dev/null", "-verbose", "3", | |
| 488 "-config", config_file.name | |
| 489 ] + extra_x_args, env=self.child_env) | |
| 490 if not self.x_proc.pid: | |
| 491 raise Exception("Could not start Xorg.") | |
| 492 | |
| 359 def _launch_x_server(self, extra_x_args): | 493 def _launch_x_server(self, extra_x_args): |
| 360 x_auth_file = os.path.expanduser("~/.Xauthority") | 494 x_auth_file = os.path.expanduser("~/.Xauthority") |
| 361 self.child_env["XAUTHORITY"] = x_auth_file | 495 self.child_env["XAUTHORITY"] = x_auth_file |
| 362 devnull = open(os.devnull, "r+") | 496 devnull = open(os.devnull, "r+") |
| 363 display = self.get_unused_display_number() | 497 display = self.get_unused_display_number() |
| 364 | 498 |
| 365 # Run "xauth add" with |child_env| so that it modifies the same XAUTHORITY | 499 # Run "xauth add" with |child_env| so that it modifies the same XAUTHORITY |
| 366 # file which will be used for the X session. | 500 # file which will be used for the X session. |
| 367 ret_code = subprocess.call("xauth add :%d . `mcookie`" % display, | 501 ret_code = subprocess.call("xauth add :%d . `mcookie`" % display, |
| 368 env=self.child_env, shell=True) | 502 env=self.child_env, shell=True) |
| 369 if ret_code != 0: | 503 if ret_code != 0: |
| 370 raise Exception("xauth failed with code %d" % ret_code) | 504 raise Exception("xauth failed with code %d" % ret_code) |
| 371 | 505 |
| 372 max_width = max([width for width, height in self.sizes]) | |
| 373 max_height = max([height for width, height in self.sizes]) | |
| 374 | |
| 375 xvfb = get_randr_supporting_x_server() | |
| 376 if xvfb: | |
| 377 self.server_supports_exact_resize = True | |
| 378 else: | |
| 379 xvfb = "Xvfb" | |
| 380 self.server_supports_exact_resize = False | |
| 381 | |
| 382 # Disable the Composite extension iff the X session is the default | 506 # Disable the Composite extension iff the X session is the default |
| 383 # Unity-2D, since it uses Metacity which fails to generate DAMAGE | 507 # Unity-2D, since it uses Metacity which fails to generate DAMAGE |
| 384 # notifications correctly. See crbug.com/166468. | 508 # notifications correctly. See crbug.com/166468. |
| 385 x_session = choose_x_session() | 509 x_session = choose_x_session() |
| 386 if (len(x_session) == 2 and | 510 if (len(x_session) == 2 and |
| 387 x_session[1] == "/usr/bin/gnome-session --session=ubuntu-2d"): | 511 x_session[1] == "/usr/bin/gnome-session --session=ubuntu-2d"): |
| 388 extra_x_args.extend(["-extension", "Composite"]) | 512 extra_x_args.extend(["-extension", "Composite"]) |
| 389 | 513 |
| 390 logging.info("Starting %s on display :%d" % (xvfb, display)) | 514 if USE_XORG_ENV_VAR in os.environ: |
| 391 screen_option = "%dx%dx24" % (max_width, max_height) | 515 self._launch_xorg(display, x_auth_file, extra_x_args) |
| 392 self.x_proc = subprocess.Popen( | 516 else: |
| 393 [xvfb, ":%d" % display, | 517 self._launch_xvfb(display, x_auth_file, extra_x_args) |
| 394 "-auth", x_auth_file, | |
| 395 "-nolisten", "tcp", | |
| 396 "-noreset", | |
| 397 "-screen", "0", screen_option | |
| 398 ] + extra_x_args) | |
| 399 if not self.x_proc.pid: | |
| 400 raise Exception("Could not start Xvfb.") | |
| 401 | 518 |
| 402 self.child_env["DISPLAY"] = ":%d" % display | 519 self.child_env["DISPLAY"] = ":%d" % display |
| 403 self.child_env["CHROME_REMOTE_DESKTOP_SESSION"] = "1" | 520 self.child_env["CHROME_REMOTE_DESKTOP_SESSION"] = "1" |
| 404 | 521 |
| 405 # Use a separate profile for any instances of Chrome that are started in | 522 # Use a separate profile for any instances of Chrome that are started in |
| 406 # the virtual session. Chrome doesn't support sharing a profile between | 523 # the virtual session. Chrome doesn't support sharing a profile between |
| 407 # multiple DISPLAYs, but Chrome Sync allows for a reasonable compromise. | 524 # multiple DISPLAYs, but Chrome Sync allows for a reasonable compromise. |
| 408 chrome_profile = os.path.join(CONFIG_DIR, "chrome-profile") | 525 chrome_profile = os.path.join(CONFIG_DIR, "chrome-profile") |
| 409 self.child_env["CHROME_USER_DATA_DIR"] = chrome_profile | 526 self.child_env["CHROME_USER_DATA_DIR"] = chrome_profile |
| 410 | 527 |
| 411 # Set SSH_AUTH_SOCK to the file name to listen on. | 528 # Set SSH_AUTH_SOCK to the file name to listen on. |
| 412 if self.ssh_auth_sockname: | 529 if self.ssh_auth_sockname: |
| 413 self.child_env["SSH_AUTH_SOCK"] = self.ssh_auth_sockname | 530 self.child_env["SSH_AUTH_SOCK"] = self.ssh_auth_sockname |
| 414 | 531 |
| 415 # Wait for X to be active. | 532 # Wait for X to be active. |
| 416 for _test in range(20): | 533 for _test in range(20): |
| 417 retcode = subprocess.call("xdpyinfo", env=self.child_env, stdout=devnull) | 534 retcode = subprocess.call("xdpyinfo", env=self.child_env, stdout=devnull) |
| 418 if retcode == 0: | 535 if retcode == 0: |
| 419 break | 536 break |
| 420 time.sleep(0.5) | 537 time.sleep(0.5) |
| 421 if retcode != 0: | 538 if retcode != 0: |
| 422 raise Exception("Could not connect to Xvfb.") | 539 raise Exception("Could not connect to X server.") |
| 423 else: | 540 else: |
| 424 logging.info("Xvfb is active.") | 541 logging.info("X server is active.") |
| 425 | 542 |
| 426 # The remoting host expects the server to use "evdev" keycodes, but Xvfb | 543 # The remoting host expects the server to use "evdev" keycodes, but Xvfb |
| 427 # starts configured to use the "base" ruleset, resulting in XKB configuring | 544 # starts configured to use the "base" ruleset, resulting in XKB configuring |
| 428 # for "xfree86" keycodes, and screwing up some keys. See crbug.com/119013. | 545 # for "xfree86" keycodes, and screwing up some keys. See crbug.com/119013. |
| 429 # Reconfigure the X server to use "evdev" keymap rules. The X server must | 546 # Reconfigure the X server to use "evdev" keymap rules. The X server must |
| 430 # be started with -noreset otherwise it'll reset as soon as the command | 547 # be started with -noreset otherwise it'll reset as soon as the command |
| 431 # completes, since there are no other X clients running yet. | 548 # completes, since there are no other X clients running yet. |
| 432 retcode = subprocess.call("setxkbmap -rules evdev", env=self.child_env, | 549 retcode = subprocess.call("setxkbmap -rules evdev", env=self.child_env, |
| 433 shell=True) | 550 shell=True) |
| 434 if retcode != 0: | 551 if retcode != 0: |
| (...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 824 # Close the temporary file-descriptors. | 941 # Close the temporary file-descriptors. |
| 825 os.close(devnull_fd) | 942 os.close(devnull_fd) |
| 826 os.close(log_fd) | 943 os.close(log_fd) |
| 827 | 944 |
| 828 | 945 |
| 829 def cleanup(): | 946 def cleanup(): |
| 830 logging.info("Cleanup.") | 947 logging.info("Cleanup.") |
| 831 | 948 |
| 832 global g_desktops | 949 global g_desktops |
| 833 for desktop in g_desktops: | 950 for desktop in g_desktops: |
| 834 for proc, name in [(desktop.x_proc, "Xvfb"), | 951 for proc, name in [(desktop.x_proc, "X server"), |
| 835 (desktop.session_proc, "session"), | 952 (desktop.session_proc, "session"), |
| 836 (desktop.host_proc, "host")]: | 953 (desktop.host_proc, "host")]: |
| 837 if proc is not None: | 954 if proc is not None: |
| 838 logging.info("Terminating " + name) | 955 logging.info("Terminating " + name) |
| 839 try: | 956 try: |
| 840 psutil_proc = psutil.Process(proc.pid) | 957 psutil_proc = psutil.Process(proc.pid) |
| 841 psutil_proc.terminate() | 958 psutil_proc.terminate() |
| 842 | 959 |
| 843 # Use a short timeout, to avoid delaying service shutdown if the | 960 # Use a short timeout, to avoid delaying service shutdown if the |
| 844 # process refuses to die for some reason. | 961 # process refuses to die for some reason. |
| 845 psutil_proc.wait(timeout=10) | 962 psutil_proc.wait(timeout=10) |
| 846 except psutil.TimeoutExpired: | 963 except psutil.TimeoutExpired: |
| 847 logging.error("Timed out - sending SIGKILL") | 964 logging.error("Timed out - sending SIGKILL") |
| 848 psutil_proc.kill() | 965 psutil_proc.kill() |
| 849 except psutil.Error: | 966 except psutil.Error: |
| 850 logging.error("Error terminating process") | 967 logging.error("Error terminating process") |
| 968 if desktop.xorg_conf is not None: | |
| 969 os.remove(desktop.xorg_conf) | |
| 851 | 970 |
| 852 g_desktops = [] | 971 g_desktops = [] |
| 853 if ParentProcessLogger.instance(): | 972 if ParentProcessLogger.instance(): |
| 854 ParentProcessLogger.instance().release_parent(False) | 973 ParentProcessLogger.instance().release_parent(False) |
| 855 | 974 |
| 856 class SignalHandler: | 975 class SignalHandler: |
| 857 """Reload the config file on SIGHUP. Since we pass the configuration to the | 976 """Reload the config file on SIGHUP. Since we pass the configuration to the |
| 858 host processes via stdin, they can't reload it, so terminate them. They will | 977 host processes via stdin, they can't reload it, so terminate them. They will |
| 859 be relaunched automatically with the new config.""" | 978 be relaunched automatically with the new config.""" |
| 860 | 979 |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1041 def main(): | 1160 def main(): |
| 1042 EPILOG = """This script is not intended for use by end-users. To configure | 1161 EPILOG = """This script is not intended for use by end-users. To configure |
| 1043 Chrome Remote Desktop, please install the app from the Chrome | 1162 Chrome Remote Desktop, please install the app from the Chrome |
| 1044 Web Store: https://chrome.google.com/remotedesktop""" | 1163 Web Store: https://chrome.google.com/remotedesktop""" |
| 1045 parser = optparse.OptionParser( | 1164 parser = optparse.OptionParser( |
| 1046 usage="Usage: %prog [options] [ -- [ X server options ] ]", | 1165 usage="Usage: %prog [options] [ -- [ X server options ] ]", |
| 1047 epilog=EPILOG) | 1166 epilog=EPILOG) |
| 1048 parser.add_option("-s", "--size", dest="size", action="append", | 1167 parser.add_option("-s", "--size", dest="size", action="append", |
| 1049 help="Dimensions of virtual desktop. This can be specified " | 1168 help="Dimensions of virtual desktop. This can be specified " |
| 1050 "multiple times to make multiple screen resolutions " | 1169 "multiple times to make multiple screen resolutions " |
| 1051 "available (if the Xvfb server supports this).") | 1170 "available (if the X server supports this).") |
| 1052 parser.add_option("-f", "--foreground", dest="foreground", default=False, | 1171 parser.add_option("-f", "--foreground", dest="foreground", default=False, |
| 1053 action="store_true", | 1172 action="store_true", |
| 1054 help="Don't run as a background daemon.") | 1173 help="Don't run as a background daemon.") |
| 1055 parser.add_option("", "--start", dest="start", default=False, | 1174 parser.add_option("", "--start", dest="start", default=False, |
| 1056 action="store_true", | 1175 action="store_true", |
| 1057 help="Start the host.") | 1176 help="Start the host.") |
| 1058 parser.add_option("-k", "--stop", dest="stop", default=False, | 1177 parser.add_option("-k", "--stop", dest="stop", default=False, |
| 1059 action="store_true", | 1178 action="store_true", |
| 1060 help="Stop the daemon currently running.") | 1179 help="Stop the daemon currently running.") |
| 1061 parser.add_option("", "--get-status", dest="get_status", default=False, | 1180 parser.add_option("", "--get-status", dest="get_status", default=False, |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1175 watch_for_resolution_changes(options.watch_resolution) | 1294 watch_for_resolution_changes(options.watch_resolution) |
| 1176 return 0 | 1295 return 0 |
| 1177 | 1296 |
| 1178 if not options.start: | 1297 if not options.start: |
| 1179 # If no modal command-line options specified, print an error and exit. | 1298 # If no modal command-line options specified, print an error and exit. |
| 1180 print(EPILOG, file=sys.stderr) | 1299 print(EPILOG, file=sys.stderr) |
| 1181 return 1 | 1300 return 1 |
| 1182 | 1301 |
| 1183 # If a RANDR-supporting Xvfb is not available, limit the default size to | 1302 # If a RANDR-supporting Xvfb is not available, limit the default size to |
| 1184 # something more sensible. | 1303 # something more sensible. |
| 1185 if get_randr_supporting_x_server(): | 1304 if USE_XORG_ENV_VAR not in os.environ and locate_xvfb_randr(): |
| 1186 default_sizes = DEFAULT_SIZES | 1305 default_sizes = DEFAULT_SIZES |
| 1187 else: | 1306 else: |
| 1188 default_sizes = DEFAULT_SIZE_NO_RANDR | 1307 default_sizes = DEFAULT_SIZE_NO_RANDR |
| 1189 | 1308 |
| 1190 # Collate the list of sizes that XRANDR should support. | 1309 # Collate the list of sizes that XRANDR should support. |
| 1191 if not options.size: | 1310 if not options.size: |
| 1192 if DEFAULT_SIZES_ENV_VAR in os.environ: | 1311 if DEFAULT_SIZES_ENV_VAR in os.environ: |
| 1193 default_sizes = os.environ[DEFAULT_SIZES_ENV_VAR] | 1312 default_sizes = os.environ[DEFAULT_SIZES_ENV_VAR] |
| 1194 options.size = default_sizes.split(",") | 1313 options.size = default_sizes.split(",") |
| 1195 | 1314 |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1376 else: | 1495 else: |
| 1377 logging.info("Host exited with status %s." % os.WEXITSTATUS(status)) | 1496 logging.info("Host exited with status %s." % os.WEXITSTATUS(status)) |
| 1378 elif os.WIFSIGNALED(status): | 1497 elif os.WIFSIGNALED(status): |
| 1379 logging.info("Host terminated by signal %s." % os.WTERMSIG(status)) | 1498 logging.info("Host terminated by signal %s." % os.WTERMSIG(status)) |
| 1380 | 1499 |
| 1381 | 1500 |
| 1382 if __name__ == "__main__": | 1501 if __name__ == "__main__": |
| 1383 logging.basicConfig(level=logging.DEBUG, | 1502 logging.basicConfig(level=logging.DEBUG, |
| 1384 format="%(asctime)s:%(levelname)s:%(message)s") | 1503 format="%(asctime)s:%(levelname)s:%(message)s") |
| 1385 sys.exit(main()) | 1504 sys.exit(main()) |
| OLD | NEW |