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 19 matching lines...) Expand all Loading... | |
30 import time | 30 import time |
31 import uuid | 31 import uuid |
32 | 32 |
33 LOG_FILE_ENV_VAR = "CHROME_REMOTE_DESKTOP_LOG_FILE" | 33 LOG_FILE_ENV_VAR = "CHROME_REMOTE_DESKTOP_LOG_FILE" |
34 | 34 |
35 # This script has a sensible default for the initial and maximum desktop size, | 35 # This script has a sensible default for the initial and maximum desktop size, |
36 # which can be overridden either on the command-line, or via a comma-separated | 36 # which can be overridden either on the command-line, or via a comma-separated |
37 # list of sizes in this environment variable. | 37 # list of sizes in this environment variable. |
38 DEFAULT_SIZES_ENV_VAR = "CHROME_REMOTE_DESKTOP_DEFAULT_DESKTOP_SIZES" | 38 DEFAULT_SIZES_ENV_VAR = "CHROME_REMOTE_DESKTOP_DEFAULT_DESKTOP_SIZES" |
39 | 39 |
40 # By default, provide a relatively small size to handle the case where resize- | 40 # By default, provide a maximum size that is large enough to support clients |
41 # to-client is disabled, and a much larger size to support clients with large | 41 # with large or multiple monitors. This is a comma-separated list of |
42 # or mulitple monitors. These defaults can be overridden in ~/.profile. | 42 # resolutions that will be made available if the X server supports RANDR. These |
43 # defaults can be overridden in ~/.profile. | |
43 DEFAULT_SIZES = "1600x1200,3840x1600" | 44 DEFAULT_SIZES = "1600x1200,3840x1600" |
44 | 45 |
46 # If RANDR is not available, use a smaller default size. Only a single | |
47 # resolution is supported in this case. | |
48 DEFAULT_SIZE_NO_RANDR = "1600x1200" | |
49 | |
45 SCRIPT_PATH = sys.path[0] | 50 SCRIPT_PATH = sys.path[0] |
46 | 51 |
47 IS_INSTALLED = (os.path.basename(sys.argv[0]) != 'linux_me2me_host.py') | 52 IS_INSTALLED = (os.path.basename(sys.argv[0]) != 'linux_me2me_host.py') |
48 | 53 |
49 if IS_INSTALLED: | 54 if IS_INSTALLED: |
50 HOST_BINARY_NAME = "chrome-remote-desktop-host" | 55 HOST_BINARY_NAME = "chrome-remote-desktop-host" |
51 else: | 56 else: |
52 HOST_BINARY_NAME = "remoting_me2me_host" | 57 HOST_BINARY_NAME = "remoting_me2me_host" |
53 | 58 |
54 CHROME_REMOTING_GROUP_NAME = "chrome-remote-desktop" | 59 CHROME_REMOTING_GROUP_NAME = "chrome-remote-desktop" |
(...skipping 16 matching lines...) Expand all Loading... | |
71 | 76 |
72 # Thresholds for switching from fast- to slow-restart and for giving up | 77 # Thresholds for switching from fast- to slow-restart and for giving up |
73 # trying to restart entirely. | 78 # trying to restart entirely. |
74 SHORT_BACKOFF_THRESHOLD = 5 | 79 SHORT_BACKOFF_THRESHOLD = 5 |
75 MAX_LAUNCH_FAILURES = SHORT_BACKOFF_THRESHOLD + 10 | 80 MAX_LAUNCH_FAILURES = SHORT_BACKOFF_THRESHOLD + 10 |
76 | 81 |
77 # Globals needed by the atexit cleanup() handler. | 82 # Globals needed by the atexit cleanup() handler. |
78 g_desktops = [] | 83 g_desktops = [] |
79 g_host_hash = hashlib.md5(socket.gethostname()).hexdigest() | 84 g_host_hash = hashlib.md5(socket.gethostname()).hexdigest() |
80 | 85 |
86 | |
81 def is_supported_platform(): | 87 def is_supported_platform(): |
82 # Always assume that the system is supported if the config directory or | 88 # Always assume that the system is supported if the config directory or |
83 # session file exist. | 89 # session file exist. |
84 if (os.path.isdir(CONFIG_DIR) or os.path.isfile(SESSION_FILE_PATH) or | 90 if (os.path.isdir(CONFIG_DIR) or os.path.isfile(SESSION_FILE_PATH) or |
85 os.path.isfile(SYSTEM_SESSION_FILE_PATH)): | 91 os.path.isfile(SYSTEM_SESSION_FILE_PATH)): |
86 return True | 92 return True |
87 | 93 |
88 # The host has been tested only on Ubuntu. | 94 # The host has been tested only on Ubuntu. |
89 distribution = platform.linux_distribution() | 95 distribution = platform.linux_distribution() |
90 return (distribution[0]).lower() == 'ubuntu' | 96 return (distribution[0]).lower() == 'ubuntu' |
91 | 97 |
98 | |
99 def get_randr_supporting_x_server(): | |
100 """Returns a path to an X server that supports the RANDR extension, if this | |
101 is found on the system. Otherwise returns None.""" | |
102 try: | |
103 xvfb = "/usr/bin/Xvfb-randr" | |
104 if not os.path.exists(xvfb): | |
105 xvfb = locate_executable("Xvfb-randr") | |
106 return xvfb | |
107 except Exception: | |
108 return None | |
109 | |
110 | |
92 class Config: | 111 class Config: |
93 def __init__(self, path): | 112 def __init__(self, path): |
94 self.path = path | 113 self.path = path |
95 self.data = {} | 114 self.data = {} |
96 self.changed = False | 115 self.changed = False |
97 | 116 |
98 def load(self): | 117 def load(self): |
99 """Loads the config from file. | 118 """Loads the config from file. |
100 | 119 |
101 Raises: | 120 Raises: |
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
320 # Run "xauth add" with |child_env| so that it modifies the same XAUTHORITY | 339 # Run "xauth add" with |child_env| so that it modifies the same XAUTHORITY |
321 # file which will be used for the X session. | 340 # file which will be used for the X session. |
322 ret_code = subprocess.call("xauth add :%d . `mcookie`" % display, | 341 ret_code = subprocess.call("xauth add :%d . `mcookie`" % display, |
323 env=self.child_env, shell=True) | 342 env=self.child_env, shell=True) |
324 if ret_code != 0: | 343 if ret_code != 0: |
325 raise Exception("xauth failed with code %d" % ret_code) | 344 raise Exception("xauth failed with code %d" % ret_code) |
326 | 345 |
327 max_width = max([width for width, height in self.sizes]) | 346 max_width = max([width for width, height in self.sizes]) |
328 max_height = max([height for width, height in self.sizes]) | 347 max_height = max([height for width, height in self.sizes]) |
329 | 348 |
330 try: | 349 xvfb = get_randr_supporting_x_server() |
331 # TODO(jamiewalch): This script expects to be installed alongside | 350 if xvfb: |
332 # Xvfb-randr, but that's no longer the case. Fix this once we have | |
333 # a Xvfb-randr package that installs somewhere sensible. | |
334 xvfb = "/usr/bin/Xvfb-randr" | |
335 if not os.path.exists(xvfb): | |
336 xvfb = locate_executable("Xvfb-randr") | |
337 self.server_supports_exact_resize = True | 351 self.server_supports_exact_resize = True |
338 except Exception: | 352 else: |
339 xvfb = "Xvfb" | 353 xvfb = "Xvfb" |
340 self.server_supports_exact_resize = False | 354 self.server_supports_exact_resize = False |
341 | 355 |
342 # Disable the Composite extension iff the X session is the default | 356 # Disable the Composite extension iff the X session is the default |
343 # Unity-2D, since it uses Metacity which fails to generate DAMAGE | 357 # Unity-2D, since it uses Metacity which fails to generate DAMAGE |
344 # notifications correctly. See crbug.com/166468. | 358 # notifications correctly. See crbug.com/166468. |
345 x_session = choose_x_session() | 359 x_session = choose_x_session() |
346 if (len(x_session) == 2 and | 360 if (len(x_session) == 2 and |
347 x_session[1] == "/usr/bin/gnome-session --session=ubuntu-2d"): | 361 x_session[1] == "/usr/bin/gnome-session --session=ubuntu-2d"): |
348 extra_x_args.extend(["-extension", "Composite"]) | 362 extra_x_args.extend(["-extension", "Composite"]) |
(...skipping 662 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1011 | 1025 |
1012 if options.host_version: | 1026 if options.host_version: |
1013 # TODO(sergeyu): Also check RPM package version once we add RPM package. | 1027 # TODO(sergeyu): Also check RPM package version once we add RPM package. |
1014 return os.system(locate_executable(HOST_BINARY_NAME) + " --version") >> 8 | 1028 return os.system(locate_executable(HOST_BINARY_NAME) + " --version") >> 8 |
1015 | 1029 |
1016 if not options.start: | 1030 if not options.start: |
1017 # If no modal command-line options specified, print an error and exit. | 1031 # If no modal command-line options specified, print an error and exit. |
1018 print >> sys.stderr, EPILOG | 1032 print >> sys.stderr, EPILOG |
1019 return 1 | 1033 return 1 |
1020 | 1034 |
1035 # If a RANDR-supporting Xvfb is not available, limit the default size to | |
1036 # something more sensible. | |
1037 if get_randr_supporting_x_server(): | |
Jamie
2014/05/09 16:41:28
Can you just use self.server_supports_exact_resize
Lambros
2014/05/09 19:50:01
Not here, because this is during main() initializa
| |
1038 default_sizes = DEFAULT_SIZES | |
1039 else: | |
1040 default_sizes = DEFAULT_SIZE_NO_RANDR | |
1041 | |
1021 # Collate the list of sizes that XRANDR should support. | 1042 # Collate the list of sizes that XRANDR should support. |
1022 if not options.size: | 1043 if not options.size: |
1023 default_sizes = DEFAULT_SIZES | |
1024 if os.environ.has_key(DEFAULT_SIZES_ENV_VAR): | 1044 if os.environ.has_key(DEFAULT_SIZES_ENV_VAR): |
1025 default_sizes = os.environ[DEFAULT_SIZES_ENV_VAR] | 1045 default_sizes = os.environ[DEFAULT_SIZES_ENV_VAR] |
1026 options.size = default_sizes.split(",") | 1046 options.size = default_sizes.split(",") |
1027 | 1047 |
1028 sizes = [] | 1048 sizes = [] |
1029 for size in options.size: | 1049 for size in options.size: |
1030 size_components = size.split("x") | 1050 size_components = size.split("x") |
1031 if len(size_components) != 2: | 1051 if len(size_components) != 2: |
1032 parser.error("Incorrect size format '%s', should be WIDTHxHEIGHT" % size) | 1052 parser.error("Incorrect size format '%s', should be WIDTHxHEIGHT" % size) |
1033 | 1053 |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1205 else: | 1225 else: |
1206 logging.info("Host exited with status %s." % os.WEXITSTATUS(status)) | 1226 logging.info("Host exited with status %s." % os.WEXITSTATUS(status)) |
1207 elif os.WIFSIGNALED(status): | 1227 elif os.WIFSIGNALED(status): |
1208 logging.info("Host terminated by signal %s." % os.WTERMSIG(status)) | 1228 logging.info("Host terminated by signal %s." % os.WTERMSIG(status)) |
1209 | 1229 |
1210 | 1230 |
1211 if __name__ == "__main__": | 1231 if __name__ == "__main__": |
1212 logging.basicConfig(level=logging.DEBUG, | 1232 logging.basicConfig(level=logging.DEBUG, |
1213 format="%(asctime)s:%(levelname)s:%(message)s") | 1233 format="%(asctime)s:%(levelname)s:%(message)s") |
1214 sys.exit(main()) | 1234 sys.exit(main()) |
OLD | NEW |