Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 # Copyright 2015 The LUCI Authors. All rights reserved. | 1 # Copyright 2015 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 """This module defines Swarming Server endpoints handlers.""" | 5 """This module defines Swarming Server endpoints handlers.""" |
| 6 | 6 |
| 7 import datetime | 7 import datetime |
| 8 import logging | 8 import logging |
| 9 | 9 |
| 10 from google.appengine.api import datastore_errors | 10 from google.appengine.api import datastore_errors |
| (...skipping 590 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 601 message_conversion.task_result_to_rpc( | 601 message_conversion.task_result_to_rpc( |
| 602 r, request.include_performance_stats) | 602 r, request.include_performance_stats) |
| 603 for r in items | 603 for r in items |
| 604 ], | 604 ], |
| 605 now=now) | 605 now=now) |
| 606 | 606 |
| 607 | 607 |
| 608 @swarming_api.api_class(resource_name='bots', path='bots') | 608 @swarming_api.api_class(resource_name='bots', path='bots') |
| 609 class SwarmingBotsService(remote.Service): | 609 class SwarmingBotsService(remote.Service): |
| 610 """Bots-related API.""" | 610 """Bots-related API.""" |
| 611 | |
| 611 @gae_ts_mon.instrument_endpoint() | 612 @gae_ts_mon.instrument_endpoint() |
| 612 @auth.endpoints_method( | 613 @auth.endpoints_method( |
| 613 swarming_rpcs.BotsRequest, swarming_rpcs.BotList, | 614 swarming_rpcs.BotsRequest, swarming_rpcs.BotList, |
| 614 http_method='GET') | 615 http_method='GET') |
| 615 @auth.require(acl.is_privileged_user) | 616 @auth.require(acl.is_privileged_user) |
| 616 def list(self, request): | 617 def list(self, request): |
| 617 """Provides list of known bots. | 618 """Provides list of known bots. |
| 618 | 619 |
| 619 Deleted bots will not be listed. | 620 Deleted bots will not be listed. |
| 620 """ | 621 """ |
| 621 logging.info('%s', request) | 622 logging.info('%s', request) |
| 622 now = utils.utcnow() | 623 now = utils.utcnow() |
| 623 q = bot_management.BotInfo.query().order(bot_management.BotInfo.key) | 624 q = bot_management.BotInfo.query() |
| 624 for d in request.dimensions: | 625 try: |
| 625 if not ':' in d: | 626 q = bot_management.filter_dimensions(q, request.dimensions) |
| 626 raise endpoints.BadRequestException('Invalid dimensions') | 627 q = bot_management.filter_availability( |
| 627 parts = d.split(':', 1) | 628 q, swarming_rpcs.to_bool(request.quarantined), |
| 628 if len(parts) != 2 or any(i.strip() != i or not i for i in parts): | 629 swarming_rpcs.to_bool(request.is_dead), now) |
| 629 raise endpoints.BadRequestException('Invalid dimensions') | 630 except ValueError as e: |
| 630 q = q.filter(bot_management.BotInfo.dimensions_flat == d) | 631 raise endpoints.BadRequestException('%s' % e) |
| 632 | |
| 631 bots, cursor = datastore_utils.fetch_page(q, request.limit, request.cursor) | 633 bots, cursor = datastore_utils.fetch_page(q, request.limit, request.cursor) |
| 632 return swarming_rpcs.BotList( | 634 return swarming_rpcs.BotList( |
| 633 cursor=cursor, | 635 cursor=cursor, |
| 634 death_timeout=config.settings().bot_death_timeout_secs, | 636 death_timeout=config.settings().bot_death_timeout_secs, |
| 635 items=[message_conversion.bot_info_to_rpc(bot, now) for bot in bots], | 637 items=[message_conversion.bot_info_to_rpc(bot, now) for bot in bots], |
| 636 now=now) | 638 now=now) |
| 637 | 639 |
| 638 @gae_ts_mon.instrument_endpoint() | 640 @gae_ts_mon.instrument_endpoint() |
| 639 @auth.endpoints_method( | 641 @auth.endpoints_method( |
| 640 swarming_rpcs.BotsRequest, swarming_rpcs.BotsCount, | 642 swarming_rpcs.BotsRequest, swarming_rpcs.BotsCount, |
| 641 http_method='GET') | 643 http_method='GET') |
| 642 @auth.require(acl.is_privileged_user) | 644 @auth.require(acl.is_privileged_user) |
| 643 def count(self, request): | 645 def count(self, request): |
| 644 """Counts number of bots with given dimensions.""" | 646 """Counts number of bots with given dimensions.""" |
| 645 logging.info('%s', request) | 647 logging.info('%s', request) |
| 646 now = utils.utcnow() | 648 now = utils.utcnow() |
| 647 q = bot_management.BotInfo.query() | 649 q = bot_management.BotInfo.query() |
| 648 for d in request.dimensions: | 650 try: |
| 649 parts = d.split(':', 1) | 651 q = bot_management.filter_dimensions(q, request.dimensions) |
| 650 if len(parts) != 2 or any(i.strip() != i or not i for i in parts): | 652 except ValueError as e: |
| 651 raise endpoints.BadRequestException('Invalid dimensions: %s' % d) | 653 raise endpoints.BadRequestException(str(e)) |
| 652 q = q.filter(bot_management.BotInfo.dimensions_flat == d) | 654 |
| 653 f_count = q.count_async() | 655 f_count = q.count_async() |
| 654 dt = datetime.timedelta(seconds=config.settings().bot_death_timeout_secs) | 656 f_dead = (bot_management.filter_availability(q, None, True, now) |
| 655 timeout = now - dt | 657 .count_async()) |
| 656 f_dead = q.filter( | 658 f_quarantined = (bot_management.filter_availability(q, True, None, now) |
| 657 bot_management.BotInfo.last_seen_ts < timeout).count_async() | 659 .count_async()) |
| 658 f_quarantined = q.filter( | |
| 659 bot_management.BotInfo.quarantined == True).count_async() | |
| 660 f_busy = q.filter(bot_management.BotInfo.is_busy == True).count_async() | 660 f_busy = q.filter(bot_management.BotInfo.is_busy == True).count_async() |
| 661 return swarming_rpcs.BotsCount( | 661 return swarming_rpcs.BotsCount( |
| 662 count=f_count.get_result(), | 662 count=f_count.get_result(), |
| 663 quarantined=f_quarantined.get_result(), | 663 quarantined=f_quarantined.get_result(), |
| 664 dead=f_dead.get_result(), | 664 dead=f_dead.get_result(), |
| 665 busy=f_busy.get_result(), | 665 busy=f_busy.get_result(), |
| 666 now=now) | 666 now=now) |
| 667 | 667 |
| 668 | |
|
M-A Ruel
2016/08/10 12:38:33
remove
| |
| 668 @gae_ts_mon.instrument_endpoint() | 669 @gae_ts_mon.instrument_endpoint() |
| 669 @auth.endpoints_method( | 670 @auth.endpoints_method( |
| 670 message_types.VoidMessage, swarming_rpcs.BotsDimensions, | 671 message_types.VoidMessage, swarming_rpcs.BotsDimensions, |
| 671 http_method='GET') | 672 http_method='GET') |
| 672 @auth.require(acl.is_privileged_user) | 673 @auth.require(acl.is_privileged_user) |
| 673 def dimensions(self, _request): | 674 def dimensions(self, _request): |
| 674 """Returns the cached set of dimensions currently in use in the fleet.""" | 675 """Returns the cached set of dimensions currently in use in the fleet.""" |
| 675 dims = bot_management.DimensionAggregation.KEY.get() | 676 dims = bot_management.DimensionAggregation.KEY.get() |
| 676 fd = [ | 677 fd = [ |
| 677 swarming_rpcs.StringListPair(key=d.dimension, value=d.values) | 678 swarming_rpcs.StringListPair(key=d.dimension, value=d.values) |
| 678 for d in dims.dimensions | 679 for d in dims.dimensions |
| 679 ] | 680 ] |
| 680 return swarming_rpcs.BotsDimensions(bots_dimensions=fd, ts=dims.ts) | 681 return swarming_rpcs.BotsDimensions(bots_dimensions=fd, ts=dims.ts) |
| 681 | 682 |
| 682 | 683 |
| 683 def get_routes(): | 684 def get_routes(): |
| 684 return ( | 685 return ( |
| 685 endpoints_webapp2.api_routes(SwarmingServerService) + | 686 endpoints_webapp2.api_routes(SwarmingServerService) + |
| 686 endpoints_webapp2.api_routes(SwarmingTaskService) + | 687 endpoints_webapp2.api_routes(SwarmingTaskService) + |
| 687 endpoints_webapp2.api_routes(SwarmingTasksService) + | 688 endpoints_webapp2.api_routes(SwarmingTasksService) + |
| 688 endpoints_webapp2.api_routes(SwarmingBotService) + | 689 endpoints_webapp2.api_routes(SwarmingBotService) + |
| 689 endpoints_webapp2.api_routes(SwarmingBotsService) + | 690 endpoints_webapp2.api_routes(SwarmingBotsService) + |
| 690 # components.config endpoints for validation and configuring of luci-config | 691 # components.config endpoints for validation and configuring of luci-config |
| 691 # service URL. | 692 # service URL. |
| 692 endpoints_webapp2.api_routes(config.ConfigApi)) | 693 endpoints_webapp2.api_routes(config.ConfigApi)) |
| OLD | NEW |