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

Side by Side Diff: appengine/swarming/server/bot_management.py

Issue 2220373003: Allow botlist API call to respond to quarantined: and is_dead: (Closed) Base URL: https://chromium.googlesource.com/external/github.com/luci/luci-py@master
Patch Set: Fix one edge case Created 4 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
OLDNEW
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 """Swarming bot management, e.g. list of known bots and their state. 5 """Swarming bot management, e.g. list of known bots and their state.
6 6
7 +---------+ 7 +---------+
8 |BotRoot | 8 |BotRoot |
9 |id=bot_id| 9 |id=bot_id|
10 +---------+ 10 +---------+
(...skipping 10 matching lines...) Expand all
21 happening for the bot. 21 happening for the bot.
22 - BotInfo is a 'dump-only' entity used for UI, it permits quickly show the 22 - BotInfo is a 'dump-only' entity used for UI, it permits quickly show the
23 state of every bots in an single query. It is basically a cache of the last 23 state of every bots in an single query. It is basically a cache of the last
24 BotEvent and additionally updated on poll. It doesn't need to be updated in a 24 BotEvent and additionally updated on poll. It doesn't need to be updated in a
25 transaction. 25 transaction.
26 - BotSettings contains bot-specific settings. It must be updated in a 26 - BotSettings contains bot-specific settings. It must be updated in a
27 transaction and contains admin-provided settings, contrary to the other 27 transaction and contains admin-provided settings, contrary to the other
28 entities which are generated from data provided by the bot itself. 28 entities which are generated from data provided by the bot itself.
29 """ 29 """
30 30
31 import datetime
31 import hashlib 32 import hashlib
32 33
33 from google.appengine.ext import ndb 34 from google.appengine.ext import ndb
34 35
36 import swarming_rpcs
35 from components import datastore_utils 37 from components import datastore_utils
36 from components import utils 38 from components import utils
37 from server import config 39 from server import config
38 from server import task_pack 40 from server import task_pack
39 41
40 42
M-A Ruel 2016/08/09 20:23:13 remove one line
kjlubick 2016/08/09 20:44:44 Done.
43
41 # Margin of randomization of BOT_REBOOT_PERIOD_SECS. Per-bot period will be in 44 # Margin of randomization of BOT_REBOOT_PERIOD_SECS. Per-bot period will be in
42 # range [period * (1 - margin), period * (1 + margin)). 45 # range [period * (1 - margin), period * (1 + margin)).
43 BOT_REBOOT_PERIOD_RANDOMIZATION_MARGIN = 0.2 46 BOT_REBOOT_PERIOD_RANDOMIZATION_MARGIN = 0.2
44 47
45 48
46 ### Models. 49 ### Models.
47 50
48 # There is one BotRoot entity per bot id. Multiple bots could run on a single 51 # There is one BotRoot entity per bot id. Multiple bots could run on a single
49 # host, for example with multiple phones connected to a host. In this case, the 52 # host, for example with multiple phones connected to a host. In this case, the
50 # id is specific to each device acting as a bot. 53 # id is specific to each device acting as a bot.
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
260 if order: 263 if order:
261 query = query.order(BotEvent.key) 264 query = query.order(BotEvent.key)
262 return query 265 return query
263 266
264 267
265 def get_settings_key(bot_id): 268 def get_settings_key(bot_id):
266 """Returns the BotSettings ndb.Key for a known bot.""" 269 """Returns the BotSettings ndb.Key for a known bot."""
267 return ndb.Key(BotSettings, 'settings', parent=get_root_key(bot_id)) 270 return ndb.Key(BotSettings, 'settings', parent=get_root_key(bot_id))
268 271
269 272
273 def filter_dimensions(q, dimensions):
274 """Filters a ndb.Query for BotInfo based on dimensions in the request."""
275 for d in dimensions:
276 parts = d.split(':', 1)
277 if len(parts) != 2 or any(i.strip() != i or not i for i in parts):
278 raise ValueError('Invalid dimensions')
279 q = q.filter(BotInfo.dimensions_flat == d)
280 return q
281
282
283 def filter_availability(q, quarantined, is_dead, now):
284 """Filters a ndb.Query for BotInfo based on quarantined/is_dead."""
285 val = swarming_rpcs.to_bool(quarantined)
M-A Ruel 2016/08/09 20:23:13 actually that's a layering violation :/ Here only
kjlubick 2016/08/09 20:44:44 Done.
286 if val is not None:
287 q = q.filter(BotInfo.quarantined == val)
288
289 dt = datetime.timedelta(seconds=config.settings().bot_death_timeout_secs)
290 timeout = now - dt
291 val = swarming_rpcs.to_bool(is_dead)
292 if val:
293 q = q.filter(BotInfo.last_seen_ts < timeout)
294 elif val is not None:
295 q = q.filter(BotInfo.last_seen_ts > timeout)
296 return q
297
298
270 def bot_event( 299 def bot_event(
271 event_type, bot_id, external_ip, authenticated_as, dimensions, state, 300 event_type, bot_id, external_ip, authenticated_as, dimensions, state,
272 version, quarantined, task_id, task_name, **kwargs): 301 version, quarantined, task_id, task_name, **kwargs):
273 """Records when a bot has queried for work. 302 """Records when a bot has queried for work.
274 303
275 Arguments: 304 Arguments:
276 - event: event type. 305 - event: event type.
277 - bot_id: bot id. 306 - bot_id: bot id.
278 - external_ip: IP address as seen by the HTTP handler. 307 - external_ip: IP address as seen by the HTTP handler.
279 - authenticated_as: bot identity as seen by the HTTP handler. 308 - authenticated_as: bot identity as seen by the HTTP handler.
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
368 Returns: 397 Returns:
369 Tuple (True to restart, text message explaining the reason). 398 Tuple (True to restart, text message explaining the reason).
370 """ 399 """
371 # Periodically reboot bots to workaround OS level leaks (especially on Win). 400 # Periodically reboot bots to workaround OS level leaks (especially on Win).
372 running_time = state.get('running_time', 0) 401 running_time = state.get('running_time', 0)
373 assert isinstance(running_time, (int, float)) 402 assert isinstance(running_time, (int, float))
374 period = get_bot_reboot_period(bot_id, state) 403 period = get_bot_reboot_period(bot_id, state)
375 if period and running_time > period: 404 if period and running_time > period:
376 return True, 'Periodic reboot: running longer than %ds' % period 405 return True, 'Periodic reboot: running longer than %ds' % period
377 return False, '' 406 return False, ''
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698