Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(160)

Side by Side Diff: remoting/tools/me2me_virtual_host.py

Issue 10824286: Fix DaemonControllerLinux::SetConfigAndStart() to reload config automatically. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « remoting/host/plugin/daemon_controller_mac.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 return self.data[key] 111 return self.data[key]
112 112
113 def __setitem__(self, key, value): 113 def __setitem__(self, key, value):
114 self.data[key] = value 114 self.data[key] = value
115 self.changed = True 115 self.changed = True
116 116
117 def clear_auth(self): 117 def clear_auth(self):
118 del self.data["xmpp_login"] 118 del self.data["xmpp_login"]
119 del self.data["chromoting_auth_token"] 119 del self.data["chromoting_auth_token"]
120 del self.data["xmpp_auth_token"] 120 del self.data["xmpp_auth_token"]
121 del self.data["oauth_refresh_token"]
121 122
122 def clear_host_info(self): 123 def clear_host_info(self):
123 del self.data["host_id"] 124 del self.data["host_id"]
124 del self.data["host_name"] 125 del self.data["host_name"]
125 del self.data["host_secret_hash"] 126 del self.data["host_secret_hash"]
126 del self.data["private_key"] 127 del self.data["private_key"]
127 128
128 class Authentication: 129 class Authentication:
129 """Manage authentication tokens for Chromoting/xmpp""" 130 """Manage authentication tokens for Chromoting/xmpp"""
130 131
131 def __init__(self): 132 def __init__(self):
132 pass 133 self.login = None
134 self.chromoting_auth_token = None
135 self.xmpp_auth_token = None
136 self.oauth_refresh_token = None
133 137
134 def generate_tokens(self): 138 def generate_tokens(self):
135 """Prompt for username/password and use them to generate new authentication 139 """Prompt for username/password and use them to generate new authentication
136 tokens. 140 tokens.
137 141
138 Raises: 142 Raises:
139 Exception: Failed to get new authentication tokens. 143 Exception: Failed to get new authentication tokens.
140 """ 144 """
141 print "Email:", 145 print "Email:",
142 self.login = raw_input() 146 self.login = raw_input()
143 password = getpass.getpass("App-specific password: ") 147 password = getpass.getpass("App-specific password: ")
144 148
145 chromoting_auth = gaia_auth.GaiaAuthenticator('chromoting') 149 chromoting_auth = gaia_auth.GaiaAuthenticator('chromoting')
146 self.chromoting_auth_token = chromoting_auth.authenticate(self.login, 150 self.chromoting_auth_token = chromoting_auth.authenticate(self.login,
147 password) 151 password)
148 152
149 xmpp_authenticator = gaia_auth.GaiaAuthenticator('chromiumsync') 153 xmpp_authenticator = gaia_auth.GaiaAuthenticator('chromiumsync')
150 self.xmpp_auth_token = xmpp_authenticator.authenticate(self.login, 154 self.xmpp_auth_token = xmpp_authenticator.authenticate(self.login,
151 password) 155 password)
152 156
157 def has_chromoting_credentials(self):
158 """Returns True if we have credentials for the directory"""
159 return self.chromoting_auth_token != None
160
161 def has_xmpp_credentials(self):
162 """Returns True if we have credentials to authenticate XMPP connection"""
163 # XMPP connection can be authenticated using either OAuth or XMPP token.
164 return self.oauth_refresh_token != None or self.xmpp_auth_token != None
165
153 def load_config(self, config): 166 def load_config(self, config):
167 """Loads the config and returns false if the config is invalid. After
168 config is loaded caller must use has_xmpp_credentials() and
169 has_chromoting_credentials() to check that the credentials it needs are
170 present in the config."""
171
172 # Host can use different types of auth tokens depending on how the config
173 # was generated. E.g. if the config was created by the webapp it will have
174 # only oauth token. We still consider config to be valid in this case.
175 self.chromoting_auth_token = config.get("chromoting_auth_token")
176 self.oauth_refresh_token = config.get("oauth_refresh_token")
177 self.xmpp_auth_token = config.get("xmpp_auth_token")
178
154 try: 179 try:
155 self.login = config["xmpp_login"] 180 self.login = config["xmpp_login"]
156 self.chromoting_auth_token = config["chromoting_auth_token"]
157 self.xmpp_auth_token = config["xmpp_auth_token"]
158 except KeyError: 181 except KeyError:
159 return False 182 return False
160 return True 183 return True
161 184
162 def save_config(self, config): 185 def save_config(self, config):
163 config["xmpp_login"] = self.login 186 config["xmpp_login"] = self.login
164 config["chromoting_auth_token"] = self.chromoting_auth_token 187 if self.chromoting_auth_token:
165 config["xmpp_auth_token"] = self.xmpp_auth_token 188 config["chromoting_auth_token"] = self.chromoting_auth_token
189 if self.xmpp_auth_token:
190 config["xmpp_auth_token"] = self.xmpp_auth_token
166 191
Lambros 2012/08/15 20:25:58 nit: two blank lines between top-levels (http://go
Sergey Ulanov 2012/08/16 00:52:45 Done.
167 class Host: 192 class Host:
168 """This manages the configuration for a host. 193 """This manages the configuration for a host.
169 194
170 Callers should instantiate a Host object (passing in a filename where the 195 Callers should instantiate a Host object (passing in a filename where the
171 config will be kept), then should call either of the methods: 196 config will be kept), then should call either of the methods:
172 197
173 * register(auth): Create a new Host configuration and register it 198 * register(auth): Create a new Host configuration and register it
174 with the Directory Service (the "auth" parameter is used to 199 with the Directory Service (the "auth" parameter is used to
175 authenticate with the Service). 200 authenticate with the Service).
176 * load_config(): Load a config from disk, with details of an existing Host 201 * load_config(): Load a config from disk, with details of an existing Host
(...skipping 477 matching lines...) Expand 10 before | Expand all | Expand 10 after
654 help="stop the daemon currently running") 679 help="stop the daemon currently running")
655 parser.add_option("-p", "--new-pin", dest="new_pin", default=False, 680 parser.add_option("-p", "--new-pin", dest="new_pin", default=False,
656 action="store_true", 681 action="store_true",
657 help="set new PIN before starting the host") 682 help="set new PIN before starting the host")
658 parser.add_option("", "--check-running", dest="check_running", default=False, 683 parser.add_option("", "--check-running", dest="check_running", default=False,
659 action="store_true", 684 action="store_true",
660 help="return 0 if the daemon is running, or 1 otherwise") 685 help="return 0 if the daemon is running, or 1 otherwise")
661 parser.add_option("", "--silent", dest="silent", default=False, 686 parser.add_option("", "--silent", dest="silent", default=False,
662 action="store_true", 687 action="store_true",
663 help="Start the host without trying to configure it.") 688 help="Start the host without trying to configure it.")
689 parser.add_option("", "--reload", dest="reload", default=False,
690 action="store_true",
691 help="Signal currently running host to reload the config.")
664 (options, args) = parser.parse_args() 692 (options, args) = parser.parse_args()
665 693
666 host_hash = hashlib.md5(socket.gethostname()).hexdigest() 694 host_hash = hashlib.md5(socket.gethostname()).hexdigest()
667 pid_filename = os.path.join(CONFIG_DIR, "host#%s.pid" % host_hash) 695 pid_filename = os.path.join(CONFIG_DIR, "host#%s.pid" % host_hash)
668 696
669 if options.check_running: 697 if options.check_running:
670 running, pid = PidFile(pid_filename).check() 698 running, pid = PidFile(pid_filename).check()
671 return 0 if (running and pid != 0) else 1 699 return 0 if (running and pid != 0) else 1
672 700
673 if options.stop: 701 if options.stop:
674 running, pid = PidFile(pid_filename).check() 702 running, pid = PidFile(pid_filename).check()
675 if not running: 703 if not running:
676 print "The daemon currently is not running" 704 print "The daemon currently is not running"
677 else: 705 else:
678 print "Killing process %s" % pid 706 print "Killing process %s" % pid
679 os.kill(pid, signal.SIGTERM) 707 os.kill(pid, signal.SIGTERM)
680 return 0 708 return 0
681 709
710 if options.reload:
711 running, pid = PidFile(pid_filename).check()
712 if not running:
713 return 1
714 os.kill(pid, signal.SIGUSR1)
715 return 0
716
682 if not options.size: 717 if not options.size:
683 options.size = [DEFAULT_SIZE] 718 options.size = [DEFAULT_SIZE]
684 719
685 sizes = [] 720 sizes = []
686 for size in options.size: 721 for size in options.size:
687 size_components = size.split("x") 722 size_components = size.split("x")
688 if len(size_components) != 2: 723 if len(size_components) != 2:
689 parser.error("Incorrect size format '%s', should be WIDTHxHEIGHT" % size) 724 parser.error("Incorrect size format '%s', should be WIDTHxHEIGHT" % size)
690 725
691 try: 726 try:
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
736 # If we were able to read auth.json then copy its content to the host 771 # If we were able to read auth.json then copy its content to the host
737 # config. 772 # config.
738 if auth_config_loaded: 773 if auth_config_loaded:
739 auth.save_config(host_config) 774 auth.save_config(host_config)
740 host_config.save() 775 host_config.save()
741 776
742 host = Host(auth) 777 host = Host(auth)
743 host_config_loaded = host.load_config(host_config) 778 host_config_loaded = host.load_config(host_config)
744 779
745 if options.silent: 780 if options.silent:
781 # Just validate the config when run with --silent.
746 if not host_config_loaded or not auth_config_loaded: 782 if not host_config_loaded or not auth_config_loaded:
747 logging.error("Failed to load host configuration.") 783 logging.error("Failed to load host configuration.")
748 return 1 784 return 1
785 if not auth.has_xmpp_credentials():
786 logging.error("Auth tokens are not configured.")
787 return 1
749 else: 788 else:
750 need_auth_tokens = not auth_config_loaded 789 need_auth_tokens = \
790 not auth_config_loaded or not auth.has_chromoting_credentials()
Lambros 2012/08/15 20:25:58 nit: Use round brackets instead of backslash (http
Sergey Ulanov 2012/08/16 00:52:45 Done.
751 need_register_host = not host_config_loaded 791 need_register_host = not host_config_loaded
752 # Outside the loop so user doesn't get asked twice. 792 # Outside the loop so user doesn't get asked twice.
753 if need_register_host: 793 if need_register_host:
754 host.ask_pin() 794 host.ask_pin()
755 elif options.new_pin or not host.is_pin_set(): 795 elif options.new_pin or not host.is_pin_set():
756 host.ask_pin() 796 host.ask_pin()
757 host.save_config(host_config) 797 host.save_config(host_config)
758 running, pid = PidFile(pid_filename).check() 798 running, pid = PidFile(pid_filename).check()
759 if running and pid != 0: 799 if running and pid != 0:
760 os.kill(pid, signal.SIGUSR1) 800 os.kill(pid, signal.SIGUSR1)
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
913 host_config.save() 953 host_config.save()
914 return 0 954 return 0
915 elif os.WEXITSTATUS(status) == 5: 955 elif os.WEXITSTATUS(status) == 5:
916 logging.info("Host domain is blocked by policy - exiting.") 956 logging.info("Host domain is blocked by policy - exiting.")
917 os.remove(host.config_file) 957 os.remove(host.config_file)
918 return 0 958 return 0
919 959
920 if __name__ == "__main__": 960 if __name__ == "__main__":
921 logging.basicConfig(level=logging.DEBUG) 961 logging.basicConfig(level=logging.DEBUG)
922 sys.exit(main()) 962 sys.exit(main())
OLDNEW
« no previous file with comments | « remoting/host/plugin/daemon_controller_mac.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698