| OLD | NEW |
| 1 # Copyright 2014 The LUCI Authors. All rights reserved. | 1 # Copyright 2014 The LUCI Authors. All rights reserved. |
| 2 # Use of this source code is governed under the Apache License, Version 2.0 | 2 # Use of this source code is governed under the Apache License, Version 2.0 |
| 3 # that can be found in the LICENSE file. | 3 # that can be found in the LICENSE file. |
| 4 | 4 |
| 5 """Bot interface used in bot_config.py.""" | 5 """Bot interface used in bot_config.py.""" |
| 6 | 6 |
| 7 import logging | 7 import logging |
| 8 import os | 8 import os |
| 9 import threading | 9 import threading |
| 10 import time | 10 import time |
| 11 | 11 |
| 12 import os_utilities | 12 import os_utilities |
| 13 from utils import net | |
| 14 from utils import zip_package | 13 from utils import zip_package |
| 15 | 14 |
| 16 THIS_FILE = os.path.abspath(zip_package.get_main_script_path()) | 15 THIS_FILE = os.path.abspath(zip_package.get_main_script_path()) |
| 17 | 16 |
| 18 # Method could be a function - pylint: disable=R0201 | 17 # Method could be a function - pylint: disable=R0201 |
| 19 | 18 |
| 20 | 19 |
| 21 class Bot(object): | 20 class Bot(object): |
| 22 def __init__( | 21 def __init__( |
| 23 self, attributes, server, server_version, base_dir, shutdown_hook): | 22 self, remote, attributes, server, server_version, base_dir, |
| 23 shutdown_hook): |
| 24 # Do not expose attributes for now, as attributes may be refactored. | 24 # Do not expose attributes for now, as attributes may be refactored. |
| 25 assert server is None or not server.endswith('/'), server | 25 assert server is None or not server.endswith('/'), server |
| 26 self._attributes = attributes | 26 self._attributes = attributes |
| 27 self._base_dir = base_dir | 27 self._base_dir = base_dir |
| 28 self._remote = remote |
| 28 self._server = server | 29 self._server = server |
| 29 self._server_version = server_version | 30 self._server_version = server_version |
| 30 self._shutdown_hook = shutdown_hook | 31 self._shutdown_hook = shutdown_hook |
| 31 self._timers = [] | 32 self._timers = [] |
| 32 self._timers_dying = False | 33 self._timers_dying = False |
| 33 self._timers_lock = threading.Lock() | 34 self._timers_lock = threading.Lock() |
| 34 | 35 |
| 35 @property | 36 @property |
| 36 def base_dir(self): | 37 def base_dir(self): |
| 37 """Returns the working directory. | 38 """Returns the working directory. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 50 tasks. | 51 tasks. |
| 51 """ | 52 """ |
| 52 return self._attributes.get('dimensions', {}).copy() | 53 return self._attributes.get('dimensions', {}).copy() |
| 53 | 54 |
| 54 @property | 55 @property |
| 55 def id(self): | 56 def id(self): |
| 56 """Returns the bot's ID.""" | 57 """Returns the bot's ID.""" |
| 57 return self.dimensions.get('id', ['unknown'])[0] | 58 return self.dimensions.get('id', ['unknown'])[0] |
| 58 | 59 |
| 59 @property | 60 @property |
| 61 def remote(self): |
| 62 """RemoteClient to talk to the server. |
| 63 |
| 64 Should not be normally used by bot_config.py for now. |
| 65 """ |
| 66 return self._remote |
| 67 |
| 68 @property |
| 60 def server(self): | 69 def server(self): |
| 61 """URL of the swarming server this bot is connected to. | 70 """URL of the swarming server this bot is connected to. |
| 62 | 71 |
| 63 It includes the https:// prefix but without trailing /, so it looks like | 72 It includes the https:// prefix but without trailing /, so it looks like |
| 64 "https://foo-bar.appspot.com". | 73 "https://foo-bar.appspot.com". |
| 65 """ | 74 """ |
| 66 return self._server | 75 return self._server |
| 67 | 76 |
| 68 @property | 77 @property |
| 69 def server_version(self): | 78 def server_version(self): |
| (...skipping 19 matching lines...) Expand all Loading... |
| 89 return swarming_bot.zip since this is the script that must be used when | 98 return swarming_bot.zip since this is the script that must be used when |
| 90 starting up. | 99 starting up. |
| 91 """ | 100 """ |
| 92 return os.path.join(os.path.dirname(THIS_FILE), 'swarming_bot.zip') | 101 return os.path.join(os.path.dirname(THIS_FILE), 'swarming_bot.zip') |
| 93 | 102 |
| 94 def post_event(self, event_type, message): | 103 def post_event(self, event_type, message): |
| 95 """Posts an event to the server.""" | 104 """Posts an event to the server.""" |
| 96 data = self._attributes.copy() | 105 data = self._attributes.copy() |
| 97 data['event'] = event_type | 106 data['event'] = event_type |
| 98 data['message'] = message | 107 data['message'] = message |
| 99 net.url_read_json(self.server + '/swarming/api/v1/bot/event', data=data) | 108 self._remote.url_read_json('/swarming/api/v1/bot/event', data=data) |
| 100 | 109 |
| 101 def post_error(self, message): | 110 def post_error(self, message): |
| 102 """Posts given string as a failure. | 111 """Posts given string as a failure. |
| 103 | 112 |
| 104 This is used in case of internal code error. It traps exception. | 113 This is used in case of internal code error. It traps exception. |
| 105 """ | 114 """ |
| 106 logging.error('Error: %s\n%s', self._attributes, message) | 115 logging.error('Error: %s\n%s', self._attributes, message) |
| 107 try: | 116 try: |
| 108 self.post_event('bot_error', message) | 117 self.post_event('bot_error', message) |
| 109 except Exception: | 118 except Exception: |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 182 if t.isAlive(): | 191 if t.isAlive(): |
| 183 logging.error('Timer thread did not terminate fast enough: %s', t) | 192 logging.error('Timer thread did not terminate fast enough: %s', t) |
| 184 | 193 |
| 185 def update_dimensions(self, new_dimensions): | 194 def update_dimensions(self, new_dimensions): |
| 186 """Called internally to update Bot.dimensions.""" | 195 """Called internally to update Bot.dimensions.""" |
| 187 self._attributes['dimensions'] = new_dimensions | 196 self._attributes['dimensions'] = new_dimensions |
| 188 | 197 |
| 189 def update_state(self, new_state): | 198 def update_state(self, new_state): |
| 190 """Called internally to update Bot.state.""" | 199 """Called internally to update Bot.state.""" |
| 191 self._attributes['state'] = new_state | 200 self._attributes['state'] = new_state |
| OLD | NEW |