 Chromium Code Reviews
 Chromium Code Reviews Issue 2182693002:
  Add new botlist for swarming  (Closed) 
  Base URL: https://chromium.googlesource.com/external/github.com/luci/luci-py@app-wrapper
    
  
    Issue 2182693002:
  Add new botlist for swarming  (Closed) 
  Base URL: https://chromium.googlesource.com/external/github.com/luci/luci-py@app-wrapper| Index: appengine/swarming/elements/res/imp/botlist/bot-list-data.html | 
| diff --git a/appengine/swarming/elements/res/imp/botlist/bot-list-data.html b/appengine/swarming/elements/res/imp/botlist/bot-list-data.html | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..ed757bcc76da15247a1a577bb9513600264f8481 | 
| --- /dev/null | 
| +++ b/appengine/swarming/elements/res/imp/botlist/bot-list-data.html | 
| @@ -0,0 +1,179 @@ | 
| +<!-- | 
| + Copyright 2016 The LUCI Authors. All rights reserved. | 
| + Use of this source code is governed under the Apache License, Version 2.0 | 
| + that can be found in the LICENSE file. | 
| + | 
| + This in an HTML Import-able file that contains the definition | 
| + of the following elements: | 
| + | 
| + <bot-list-data> | 
| + | 
| + This makes calls authenticated with Oauth 2 to the swarming apis. It parses | 
| + that data into usable data structures. | 
| + | 
| + Usage: | 
| + | 
| + <bot-list-data></bot-list-data> | 
| + | 
| + Properties: | 
| + // inputs | 
| + auth_headers: Object, the OAuth2 header to include in the request. This | 
| + should come from swarming-app. | 
| + // outputs | 
| + bots: Array<Object>, all bots returned by the botlist. | 
| + busy: Boolean, if the ajax request is in flight. | 
| + primary_map: Object, a mapping of primary keys to secondary items. | 
| + The primary keys are things that can be columns or sorted by. The | 
| + primary values (aka the secondary items) are things that can be filtered | 
| + on. Primary consists of dimensions and state. Secondary contains the | 
| + values primary things can be. | 
| + primary_arr: Array<String>, the display order of the primary keys. | 
| + This is dimensions, then bot properties, then elements from bot.state. | 
| + | 
| + Methods: | 
| + signIn(): Force a signin of the user using OAuth. This happens | 
| + automatically when auth_headers is set. | 
| + | 
| + Events: | 
| + None. | 
| +--> | 
| + | 
| +<link rel="import" href="/res/imp/bower_components/iron-ajax/iron-ajax.html"> | 
| + | 
| +<link rel="import" href="bot-list-shared.html"> | 
| + | 
| +<dom-module id="bot-list-data"> | 
| 
stephana
2016/07/29 14:09:31
What is the benefit of creating a declarative ajax
 
kjlubick
2016/07/29 19:13:25
Using iron-ajax, to me, seems easier to read and h
 | 
| + <template> | 
| + <iron-ajax id="request" | 
| + url="/_ah/api/swarming/v1/bots/list" | 
| + headers="[[auth_headers]]" | 
| + handle-as="json" | 
| + last-response="{{_data}}" | 
| + loading="{{busy}}"> | 
| + </iron-ajax> | 
| + </template> | 
| + <script> | 
| + (function(){ | 
| + var DIMENSIONS = ["cores", "cpu", "id", "os", "pool"]; | 
| + // "gpu" and "devices" are added separately because we need to | 
| + // deal with aliases. | 
| + var BOT_PROPERTIES = ["gpu", "devices", "task", "status"]; | 
| + Polymer({ | 
| + is: 'bot-list-data', | 
| + properties: { | 
| + // inputs | 
| + auth_headers: { | 
| + type: Object, | 
| + observer: "signIn", | 
| + }, | 
| + | 
| + //outputs | 
| + bots: { | 
| + type: Array, | 
| + computed: "_bots(_data)", | 
| + notify: true, | 
| + }, | 
| + busy: { | 
| + type: Boolean, | 
| + notify: true, | 
| + }, | 
| + primary_map: { | 
| + type:Object, | 
| + computed: "_primaryMap(bots)", | 
| + notify: true, | 
| + }, | 
| + primary_arr: { | 
| + type:Array, | 
| + value: function() { | 
| + return DIMENSIONS.concat(BOT_PROPERTIES); | 
| + }, | 
| + notify: true, | 
| + }, | 
| + | 
| + // private | 
| + _data: { | 
| + type: Object, | 
| + }, | 
| + }, | 
| + behaviors: [SwarmingBehaviors.BotListBehavior], | 
| + | 
| + signIn: function(){ | 
| + this.$.request.generateRequest(); | 
| + }, | 
| + | 
| + _bots: function(){ | 
| + if (!this._data || !this._data.items) { | 
| + return []; | 
| + } | 
| + this._data.items.forEach(function(o){ | 
| + o.state = JSON.parse(o.state); | 
| + }); | 
| + return this._data.items; | 
| + }, | 
| + | 
| + _primaryMap: function(bots){ | 
| + // map will keep track of dimensions that we have seen at least once. | 
| + // This will then basically get turned into an array to be used for | 
| + // filtering. | 
| + var map = {}; | 
| + DIMENSIONS.forEach(function(p){ | 
| + map[p] = {}; | 
| + }); | 
| + map["devices"] = {}; | 
| + map["gpu"] = {}; | 
| + bots.forEach(function(b){ | 
| + DIMENSIONS.forEach(function(d){ | 
| + var dims = this._dimension(b, d) || []; | 
| + dims.forEach(function(e){ | 
| + map[d][e] = true; | 
| + }); | 
| + }.bind(this)); | 
| + | 
| + // Add Android devices and their aliases | 
| + this._devices(b).forEach(function(d){ | 
| + var dt = this._deviceType(d); | 
| + var alias = this._androidAlias(d); | 
| + if (dt !== "unknown") { | 
| + dt = this._applyAlias(dt,alias); | 
| + } | 
| + map["devices"][dt] = true; | 
| + }.bind(this)); | 
| + map["devices"]["none"] = true; | 
| + | 
| + // Add GPUs and their aliases | 
| + var gpus = this._dimension(b, "gpu") || []; | 
| + gpus.forEach(function(g){ | 
| + var alias = this._gpuAlias(g); | 
| + if (alias !== "UNKNOWN") { | 
| + map["gpu"][this._applyAlias(g, alias)] = true; | 
| + } else { | 
| + map["gpu"][g] = true; | 
| + } | 
| + | 
| + }.bind(this)); | 
| + }.bind(this)); | 
| + | 
| + // Turn the Map<Object,Map<Boolean>> into a Map<Object,Array<String>> | 
| + // with all of the secondary elements sorted appropriately. | 
| + var pMap = {}; | 
| + for (key in map){ | 
| + pMap[key] = Object.keys(map[key]).sort(function(a,b){ | 
| + // Try numeric, aka "natural" sort first. | 
| + var ns = a - b; | 
| + if (ns) { | 
| + return ns; | 
| + } | 
| + return a.localeCompare(b); | 
| + }); | 
| + } | 
| + | 
| + // Create custom filter options | 
| + pMap["task"] = ["busy", "idle"]; | 
| + pMap["status"] = ["available", "dead", "quarantined"]; | 
| + return pMap; | 
| + }, | 
| + | 
| + }); | 
| + })(); | 
| + </script> | 
| +</dom-module> |