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 484 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 495 | 495 |
| 496 self.host_proc = subprocess.Popen(args, env=self.child_env, | 496 self.host_proc = subprocess.Popen(args, env=self.child_env, |
| 497 stdin=subprocess.PIPE) | 497 stdin=subprocess.PIPE) |
| 498 logging.info(args) | 498 logging.info(args) |
| 499 if not self.host_proc.pid: | 499 if not self.host_proc.pid: |
| 500 raise Exception("Could not start Chrome Remote Desktop host") | 500 raise Exception("Could not start Chrome Remote Desktop host") |
| 501 self.host_proc.stdin.write(json.dumps(host_config.data)) | 501 self.host_proc.stdin.write(json.dumps(host_config.data)) |
| 502 self.host_proc.stdin.close() | 502 self.host_proc.stdin.close() |
| 503 | 503 |
| 504 | 504 |
| 505 def get_daemon_pid(): | 505 def get_daemon_proc(): |
| 506 """Checks if there is already an instance of this script running, and returns | 506 """Checks if there is already an instance of this script running, and returns |
| 507 its PID. | 507 a psutil.Process instance for it. |
| 508 | 508 |
| 509 Returns: | 509 Returns: |
| 510 The process ID of the existing daemon process, or 0 if the daemon is not | 510 A Process instance for the existing daemon process, or None if the daemon |
| 511 running. | 511 is not running. |
| 512 """ | 512 """ |
| 513 | |
| 513 uid = os.getuid() | 514 uid = os.getuid() |
| 514 this_pid = os.getpid() | 515 this_pid = os.getpid() |
| 515 | 516 |
| 516 # Support new & old psutil API. This is the right way to check, according to | 517 # Support new & old psutil API. This is the right way to check, according to |
| 517 # http://grodola.blogspot.com/2014/01/psutil-20-porting.html | 518 # http://grodola.blogspot.com/2014/01/psutil-20-porting.html |
| 518 if psutil.version_info >= (2, 0): | 519 if psutil.version_info >= (2, 0): |
| 519 psget = lambda x: x() | 520 psget = lambda x: x() |
| 520 else: | 521 else: |
| 521 psget = lambda x: x | 522 psget = lambda x: x |
| 522 | 523 |
| 523 for process in psutil.process_iter(): | 524 for process in psutil.process_iter(): |
| 524 # Skip any processes that raise an exception, as processes may terminate | 525 # Skip any processes that raise an exception, as processes may terminate |
| 525 # during iteration over the list. | 526 # during iteration over the list. |
| 526 try: | 527 try: |
| 527 # Skip other users' processes. | 528 # Skip other users' processes. |
| 528 if psget(process.uids).real != uid: | 529 if psget(process.uids).real != uid: |
| 529 continue | 530 continue |
| 530 | 531 |
| 531 # Skip the process for this instance. | 532 # Skip the process for this instance. |
| 532 if process.pid == this_pid: | 533 if process.pid == this_pid: |
| 533 continue | 534 continue |
| 534 | 535 |
| 535 # |cmdline| will be [python-interpreter, script-file, other arguments...] | 536 # |cmdline| will be [python-interpreter, script-file, other arguments...] |
| 536 cmdline = psget(process.cmdline) | 537 cmdline = psget(process.cmdline) |
| 537 if len(cmdline) < 2: | 538 if len(cmdline) < 2: |
| 538 continue | 539 continue |
| 539 if cmdline[0] == sys.executable and cmdline[1] == sys.argv[0]: | 540 if cmdline[0] == sys.executable and cmdline[1] == sys.argv[0]: |
| 540 return process.pid | 541 return process |
| 541 except (psutil.NoSuchProcess, psutil.AccessDenied): | 542 except (psutil.NoSuchProcess, psutil.AccessDenied): |
| 542 continue | 543 continue |
| 543 | 544 |
| 544 return 0 | 545 return None |
| 545 | 546 |
| 546 | 547 |
| 547 def choose_x_session(): | 548 def choose_x_session(): |
| 548 """Chooses the most appropriate X session command for this system. | 549 """Chooses the most appropriate X session command for this system. |
| 549 | 550 |
| 550 Returns: | 551 Returns: |
| 551 A string containing the command to run, or a list of strings containing | 552 A string containing the command to run, or a list of strings containing |
| 552 the executable program and its arguments, which is suitable for passing as | 553 the executable program and its arguments, which is suitable for passing as |
| 553 the first parameter of subprocess.Popen(). If a suitable session cannot | 554 the first parameter of subprocess.Popen(). If a suitable session cannot |
| 554 be found, returns None. | 555 be found, returns None. |
| (...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 972 help="Prints version of the host.") | 973 help="Prints version of the host.") |
| 973 (options, args) = parser.parse_args() | 974 (options, args) = parser.parse_args() |
| 974 | 975 |
| 975 # Determine the filename of the host configuration and PID files. | 976 # Determine the filename of the host configuration and PID files. |
| 976 if not options.config: | 977 if not options.config: |
| 977 options.config = os.path.join(CONFIG_DIR, "host#%s.json" % g_host_hash) | 978 options.config = os.path.join(CONFIG_DIR, "host#%s.json" % g_host_hash) |
| 978 | 979 |
| 979 # Check for a modal command-line option (start, stop, etc.) | 980 # Check for a modal command-line option (start, stop, etc.) |
| 980 | 981 |
| 981 if options.get_status: | 982 if options.get_status: |
| 982 pid = get_daemon_pid() | 983 proc = get_daemon_proc() |
| 983 if pid != 0: | 984 if proc is not None: |
|
Sergey Ulanov
2014/06/18 00:23:58
nit: why not 'proc != None'?
Or I would prefer 'if
Lambros
2014/06/18 00:44:57
I'm following the advice from the Google Python st
Sergey Ulanov
2014/06/18 08:01:27
I didn't know about this. Still, the guide says th
| |
| 984 print "STARTED" | 985 print "STARTED" |
| 985 elif is_supported_platform(): | 986 elif is_supported_platform(): |
| 986 print "STOPPED" | 987 print "STOPPED" |
| 987 else: | 988 else: |
| 988 print "NOT_IMPLEMENTED" | 989 print "NOT_IMPLEMENTED" |
| 989 return 0 | 990 return 0 |
| 990 | 991 |
| 991 # TODO(sergeyu): Remove --check-running once NPAPI plugin and NM host are | 992 # TODO(sergeyu): Remove --check-running once NPAPI plugin and NM host are |
| 992 # updated to always use get-status flag instead. | 993 # updated to always use get-status flag instead. |
| 993 if options.check_running: | 994 if options.check_running: |
| 994 pid = get_daemon_pid() | 995 proc = get_daemon_proc() |
| 995 return 0 if pid != 0 else 1 | 996 return 1 if proc is None else 0 |
| 996 | 997 |
| 997 if options.stop: | 998 if options.stop: |
| 998 pid = get_daemon_pid() | 999 proc = get_daemon_proc() |
| 999 if pid == 0: | 1000 if proc is None: |
| 1000 print "The daemon is not currently running" | 1001 print "The daemon is not currently running" |
| 1001 else: | 1002 else: |
| 1002 print "Killing process %s" % pid | 1003 print "Killing process %s" % proc.pid |
| 1003 os.kill(pid, signal.SIGTERM) | 1004 proc.terminate() |
| 1005 try: | |
| 1006 proc.wait(timeout=30) | |
| 1007 except psutil.TimeoutExpired: | |
| 1008 print "Timed out trying to kill daemon process" | |
| 1009 return 1 | |
| 1004 return 0 | 1010 return 0 |
| 1005 | 1011 |
| 1006 if options.reload: | 1012 if options.reload: |
| 1007 pid = get_daemon_pid() | 1013 proc = get_daemon_proc() |
| 1008 if pid == 0: | 1014 if proc is None: |
| 1009 return 1 | 1015 return 1 |
| 1010 os.kill(pid, signal.SIGHUP) | 1016 proc.send_signal(signal.SIGHUP) |
| 1011 return 0 | 1017 return 0 |
| 1012 | 1018 |
| 1013 if options.add_user: | 1019 if options.add_user: |
| 1014 user = getpass.getuser() | 1020 user = getpass.getuser() |
| 1015 try: | 1021 try: |
| 1016 if user in grp.getgrnam(CHROME_REMOTING_GROUP_NAME).gr_mem: | 1022 if user in grp.getgrnam(CHROME_REMOTING_GROUP_NAME).gr_mem: |
| 1017 logging.info("User '%s' is already a member of '%s'." % | 1023 logging.info("User '%s' is already a member of '%s'." % |
| 1018 (user, CHROME_REMOTING_GROUP_NAME)) | 1024 (user, CHROME_REMOTING_GROUP_NAME)) |
| 1019 return 0 | 1025 return 0 |
| 1020 except KeyError: | 1026 except KeyError: |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1092 auth = Authentication() | 1098 auth = Authentication() |
| 1093 auth_config_valid = auth.copy_from(host_config) | 1099 auth_config_valid = auth.copy_from(host_config) |
| 1094 host = Host() | 1100 host = Host() |
| 1095 host_config_valid = host.copy_from(host_config) | 1101 host_config_valid = host.copy_from(host_config) |
| 1096 if not host_config_valid or not auth_config_valid: | 1102 if not host_config_valid or not auth_config_valid: |
| 1097 logging.error("Failed to load host configuration.") | 1103 logging.error("Failed to load host configuration.") |
| 1098 return 1 | 1104 return 1 |
| 1099 | 1105 |
| 1100 # Determine whether a desktop is already active for the specified host | 1106 # Determine whether a desktop is already active for the specified host |
| 1101 # host configuration. | 1107 # host configuration. |
| 1102 pid = get_daemon_pid() | 1108 proc = get_daemon_proc() |
| 1103 if pid != 0: | 1109 if proc is not None: |
| 1104 # Debian policy requires that services should "start" cleanly and return 0 | 1110 # Debian policy requires that services should "start" cleanly and return 0 |
| 1105 # if they are already running. | 1111 # if they are already running. |
| 1106 print "Service already running." | 1112 print "Service already running." |
| 1107 return 0 | 1113 return 0 |
| 1108 | 1114 |
| 1109 # Detach a separate "daemon" process to run the session, unless specifically | 1115 # Detach a separate "daemon" process to run the session, unless specifically |
| 1110 # requested to run in the foreground. | 1116 # requested to run in the foreground. |
| 1111 if not options.foreground: | 1117 if not options.foreground: |
| 1112 daemonize() | 1118 daemonize() |
| 1113 | 1119 |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1234 else: | 1240 else: |
| 1235 logging.info("Host exited with status %s." % os.WEXITSTATUS(status)) | 1241 logging.info("Host exited with status %s." % os.WEXITSTATUS(status)) |
| 1236 elif os.WIFSIGNALED(status): | 1242 elif os.WIFSIGNALED(status): |
| 1237 logging.info("Host terminated by signal %s." % os.WTERMSIG(status)) | 1243 logging.info("Host terminated by signal %s." % os.WTERMSIG(status)) |
| 1238 | 1244 |
| 1239 | 1245 |
| 1240 if __name__ == "__main__": | 1246 if __name__ == "__main__": |
| 1241 logging.basicConfig(level=logging.DEBUG, | 1247 logging.basicConfig(level=logging.DEBUG, |
| 1242 format="%(asctime)s:%(levelname)s:%(message)s") | 1248 format="%(asctime)s:%(levelname)s:%(message)s") |
| 1243 sys.exit(main()) | 1249 sys.exit(main()) |
| OLD | NEW |