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

Unified Diff: appengine/swarming/elements/res/imp/botpage/bot-page.html

Issue 2408743002: Move elements/ to ui/ (Closed)
Patch Set: rebase again Created 4 years, 2 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 side-by-side diff with in-line comments
Download patch
Index: appengine/swarming/elements/res/imp/botpage/bot-page.html
diff --git a/appengine/swarming/elements/res/imp/botpage/bot-page.html b/appengine/swarming/elements/res/imp/botpage/bot-page.html
deleted file mode 100644
index a6911635c0b543001f87fff1bac54824a7a71415..0000000000000000000000000000000000000000
--- a/appengine/swarming/elements/res/imp/botpage/bot-page.html
+++ /dev/null
@@ -1,616 +0,0 @@
-<!--
- 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-page>
-
- bot-page shows the tasks, events, and dimensions of a bot.
-
- This is a top-level element.
-
- Properties:
- bot_id: String, Used in testing to specify a bot_id
- client_id: String, Oauth 2.0 client id. It will be set by server-side
- template evaluation.
-
- Methods:
- None.
-
- Events:
- None.
--->
-
-<link rel="import" href="/res/imp/bower_components/iron-collapse/iron-collapse.html">
-<link rel="import" href="/res/imp/bower_components/iron-icon/iron-icon.html">
-<link rel="import" href="/res/imp/bower_components/iron-icons/iron-icons.html">
-<link rel="import" href="/res/imp/bower_components/paper-button/paper-button.html">
-<link rel="import" href="/res/imp/bower_components/paper-checkbox/paper-checkbox.html">
-<link rel="import" href="/res/imp/bower_components/paper-dialog/paper-dialog.html">
-<link rel="import" href="/res/imp/bower_components/paper-input/paper-input.html">
-<link rel="import" href="/res/imp/bower_components/paper-tabs/paper-tabs.html">
-<link rel="import" href="/res/imp/bower_components/polymer/polymer.html">
-
-<link rel="import" href="/res/imp/common/error-toast.html">
-<link rel="import" href="/res/imp/common/pageable-data.html">
-<link rel="import" href="/res/imp/common/single-page-style.html">
-<link rel="import" href="/res/imp/common/swarming-app.html">
-<link rel="import" href="/res/imp/common/task-behavior.html">
-<link rel="import" href="/res/imp/common/url-param.html">
-
-<link rel="import" href="bot-page-data.html">
-<link rel="import" href="bot-page-shared-behavior.html">
-<link rel="import" href="bot-page-summary.html">
-
-
-<dom-module id="bot-page">
- <template>
- <style include="iron-flex iron-flex-alignment iron-positioning swarming-app-style single-page-style task-style">
- .message {
- white-space: pre-line;
- font-family: monospace;
- }
-
- .bot_state {
- white-space: pre;
- font-family: monospace;
- margin-bottom: 10px;
- }
-
- .tasks_table,
- .events_table {
- border: 3px solid #1F78B4;
- }
-
- .old_version {
- background-color: #ffffdd;
- }
-
- .stats {
- min-width: 700px;
- flex-grow: 2;
- }
-
- #collapse {
- max-width: 700px;
- }
-
- .cloud {
- white-space: nowrap;
- margin-bottom: 5px;
- margin-top: auto;
- }
-
- paper-checkbox {
- --paper-checkbox-label-color: #fff;
- --paper-checkbox-checked-color: #fff;
- --paper-checkbox-checkmark-color: #000;
- --paper-checkbox-unchecked-color: #fff;
- padding: 3px;
- }
-
- paper-dialog {
- border-radius: 6px;
- }
- </style>
-
- <url-param name="id"
- value="{{bot_id}}">
- </url-param>
- <url-param name="show_all_events"
- value="{{_show_all}}">
- </url-param>
- <url-param name="selected"
- value="{{_selected}}">
- </url-param>
- <url-param name="show_state"
- value="{{_show_state}}">
- </url-param>
-
- <swarming-app
- client_id="[[client_id]]"
- auth_headers="{{_auth_headers}}"
- permissions="{{_permissions}}"
- server_details="{{_server_details}}"
- signed_in="{{_signed_in}}"
-
- busy="[[_or(_busy1,_busy2,_busy3)]]"
- name="Swarming Bot Page">
-
- <h2 hidden$="[[_signed_in]]">You must sign in to see anything useful.</h2>
-
- <div hidden$="[[_not(_signed_in)]]">
-
- <bot-page-data
- id="data"
- auth_headers="[[_auth_headers]]"
- bot_id="[[bot_id]]"
-
- bot="{{_bot}}"
- busy="{{_busy1}}"
- events="{{_events}}"
- tasks="{{_tasks}}"
- on-reload="_clearAndReload">
- </bot-page-data>
-
- <div class="header horizontal layout">
- <paper-input class="id_input" label="Bot id" value="{{bot_id}}"></paper-input>
- <template is="dom-if" if="[[_ccLink(_bot)]]">
- <div class="vertical layout">
- <a href$="[[_ccLink(_bot)]]" class="cloud">Cloud Console</a>
- </div>
- </template>
- <button on-click="_refresh">
- <iron-icon class="refresh" icon="icons:refresh"></iron-icon>
- </button>
- </div>
-
- <div class="horizontal wrap layout">
- <div class="flex">
- <table>
- <tr class$="[[_isDead(_bot)]]" title="Last time the bot contacted the server.">
- <td>Last Seen</td>
- <td title="[[_bot.human_last_seen_ts]]">
- [[_timeDiffExact(_bot.last_seen_ts)]] ago</td>
- <td>
- <!-- dom-ifs are slightly less performant than hidden$=, but
- prevent things from first drawing and then hiding. We prefer to
- not flash buttons or quarantined messages -->
- <template is="dom-if" if="[[_canShutdown(_bot,_permissions)]]">
- <button class="raised" on-click="_promptShutdown">
- Shut Down Gracefully
- </button>
- </template>
- <template is="dom-if" if="[[_canDelete(_bot,_permissions)]]">
- <button class="raised" on-click="_promptDelete">
- Delete
- </button>
- </template>
- </td>
- </tr>
- <template is="dom-if" if="[[_bot.quarantined]]">
- <tr class="quarantined">
- <td>Quarantined</td>
- <td colspan="2" class="message">[[_quarantineMessage(_bot)]]</td>
- </tr>
- </template>
- <tr>
- <td>Current Task</td>
- <td>
- <a target="_blank" rel="noopener"
- href$="[[_taskLink(_bot.task_id)]]">
- [[_task(_bot)]]
- </a>
- </td>
- <td>
- <!-- TODO(kjlubick) add the cancel button when swarming can
- cancel running tasks -->
- </td>
- </tr>
- <tr>
- <td rowspan$="[[_numRows(_bot.dimensions)]]">Dimensions</td>
- </tr>
- <template
- is="dom-repeat"
- items="[[_bot.dimensions]]"
- as="dim">
- <tr>
- <td>[[dim.key]]</td>
- <td>[[_concat(dim.value)]]</td>
- </tr>
- </template>
-
- <tr title="IP address that the server saw the connection from.">
- <td>External IP</td>
- <td><a href$="[[_bot.external_ip]]">[[_bot.external_ip]]</a></td>
- <td></td>
- </tr>
- <tr
- class$="[[_classVersion(_server_details.bot_version,_bot.version)]]"
- title="Version is based on the content of swarming_bot.zip which is the swarming bot code. The bot won't update if quarantined, dead, or busy.">
- <td>Bot Version</td>
- <td>[[_shorten(_bot.version,'8')]]</td>
- <td></td>
- </tr>
- <tr title="The version the server expects the bot to be using.">
- <td>Expected Bot Version</td>
- <td>[[_shorten(_server_details.bot_version,'8')]]</td>
- <td></td>
- </tr>
- <tr title="First time ever a bot with this id contacted the server.">
- <td>First seen</td>
- <td title="[[_bot.human_first_seen_ts]]">
- [[_timeDiffApprox(_bot.first_seen_ts)]] ago
- </td>
- <td></td>
- </tr>
- <tr title="How the bot is authenticated by the server.">
- <td>Authenticated as</td>
- <td colspan=2>[[_bot.authenticated_as]]</td>
- </tr>
- <template is="dom-if" if="[[_bot.lease_id]]">
- <tr>
- <td>Machine Provider Lease ID</td>
- <td colspan=2>
- <a href$="[[_mpLink(_bot,_server_details.machine_provider_template)]]">
- [[_bot.lease_id]]
- </a>
- </td>
- </tr>
- <tr>
- <td>Machine Provider Lease Expires</td>
- <td colspan=2>[[_bot.human_lease_expiration_ts]]</td>
- </tr>
- </template>
- </table>
-
- <span class="title">State</span>
-
- <template is="dom-if" if="[[_not(_show_state)]]">
- <button on-click="_toggleState">
- <iron-icon icon="icons:add-circle-outline"></iron-icon>
- </button>
- </template>
-
- <template is="dom-if" if="[[_show_state]]">
- <button on-click="_toggleState">
- <iron-icon icon="icons:remove-circle-outline"></iron-icon>
- </button>
- </template>
-
- <iron-collapse id="collapse" opened="[[_show_state]]">
- <div class="bot_state">[[_prettyPrint(_bot.state)]]</div>
- </iron-collapse>
- </div>
-
- <div class="stats flex">
- <bot-page-summary
- tasks="[[_tasks]]">
- </bot-page-summary>
- </div>
- </div>
-
- <div class="tabs">
- <paper-tabs selected="{{_selected}}" no-bar>
- <paper-tab>Tasks</paper-tab>
- <paper-tab>Events</paper-tab>
- </paper-tabs>
-
- <template is="dom-if" if="[[_showEvents]]">
- <paper-checkbox checked="{{_show_all}}">
- Show all events
- </paper-checkbox>
- </template>
- </div>
-
- <template is="dom-if" if="[[_not(_showEvents)]]">
- <table class="tasks_table">
- <thead>
- <tr>
- <th>Task</th>
- <th>Started</th>
- <th>Duration</th>
- <th>Result</th>
- </tr>
- </thead>
- <tbody>
- <template is="dom-repeat" items="{{_tasks}}" as="task">
- <tr class$="[[_taskClass(task)]]">
- <td>
- <a target="_blank" rel="noopener"
- href$="[[_taskLink(task.task_id)]]">
- [[task.name]]
- </a>
- </td>
- <td>[[task.human_started_ts]]</td>
- <td title="[[task.human_completed_ts]]">[[task.human_duration]]</td>
- <td>[[task.state]]</td>
- </tr>
- </template>
- </tbody>
- </table>
- </template>
-
- <template is="dom-if" if="[[_showEvents]]">
- <table class="events_table">
- <thead>
- <tr>
- <th>Message</th>
- <th>Type</th>
- <th>Timestamp</th>
- <th>Task ID</th>
- <th>Version</th>
- </tr>
- </thead>
- <tbody>
- <template is="dom-repeat" items="{{_eventList(_show_all,_events.*)}}" as="event">
- <tr>
- <td class="message">[[event.message]]</td>
- <td>[[event.event_type]]</td>
- <td>[[event.human_ts]]</td>
- <td>
- <a target="_blank" rel="noopener"
- href$="[[_taskLink(event.task_id)]]">
- [[event.task_id]]
- </a>
- </td>
- <td class$="[[_classVersion(_server_details.bot_version,event.version)]]">
- [[_shorten(event.version,'8')]]
- </td>
- </tr>
- </template>
- </tbody>
- </table>
- </template>
- <!-- https://github.com/Polymer/polymer/issues/3669 hidden$ doesn't
- respect truthiness, only booleanness, so we have _showEvents
- instead of using _selected directly.-->
- <pageable-data
- id="page_tasks"
- hidden$="[[_showEvents]]"
- busy="{{_busy2}}"
- label="Show more tasks"
- output="{{_tasks}}"
- parse="[[_parseTasks]]">
- </pageable-data>
- <pageable-data
- id="page_events"
- hidden$="[[_not(_showEvents)]]"
- busy="{{_busy3}}"
- label="Show more events"
- output="{{_events}}"
- parse="[[_parseEvents]]">
- </pageable-data>
- </div> <!-- hidden when not signed in-->
- </swarming-app>
-
- <paper-dialog id="prompt" modal on-iron-overlay-closed="_promptClosed">
- <h2>Are you sure?</h2>
- <div>Are you sure you want to [[_dialogPrompt]]?</div>
- <div class="buttons">
- <paper-button dialog-dismiss autofocus>No</paper-button>
- <paper-button dialog-confirm>Yes</paper-button>
- </div>
- </paper-dialog>
-
- <error-toast></error-toast>
-
- </template>
- <script>
- (function(){
-
- Polymer({
- is: 'bot-page',
-
- behaviors: [
- SwarmingBehaviors.BotPageBehavior,
- ],
-
- properties: {
- bot_id: {
- type: String,
- },
- client_id: {
- type: String,
- },
-
- _auth_headers: {
- type: Object,
- observer: "_reload",
- },
- _bot: {
- type: Object,
- },
- _dialogPrompt: {
- type: String,
- value: "",
- },
- _selected: {
- type: Number,
- },
- _show_all: {
- type: Boolean,
- },
- _showEvents: {
- type: Boolean,
- computed: "_truthy(_selected)"
- },
- _show_state: {
- type: Boolean,
- },
-
- _parseEvents: {
- type: Function,
- value: function() {
- return this.$.data.parseEvents.bind(this);
- }
- },
- _parseTasks: {
- type: Function,
- value: function() {
- return this.$.data.parseTasks.bind(this);
- }
- }
- },
-
- _canCancel: function(bot, permissions) {
- return bot && bot.task_id && permissions.cancel_task;
- },
-
- _canDelete: function(bot, permissions) {
- return bot && bot.is_dead && permissions.delete_bot;
- },
-
- _canShutdown: function(bot, permissions){
- return bot && !bot.is_dead && permissions.terminate_bot;
- },
-
- _classVersion: function(serverVersion, otherVersion) {
- if (serverVersion !== otherVersion) {
- return "old_version";
- }
- return "";
- },
-
- _clearAndReload: function(botID) {
- this.$.page_tasks.clear();
- this.$.page_events.clear();
- this._reload();
- },
-
- _ccLink: function(bot) {
- // We create a link to this bot in cloud console if we detect it is
- // on GCE. We look for the zone dimension and create the link using
- // that.
- if (!bot || !bot.dimensions) {
- return false;
- }
- var link;
- bot.dimensions.forEach(function(d){
- if (d.key === "zone") {
- link = this._cloudConsoleLink(d.value[0], bot.bot_id);
- }
- }.bind(this))
- return link;
- },
-
- _concat: function(arr) {
- if (!arr) {
- return "";
- }
- return arr.join(" | ");
- },
-
- _deleteBot: function() {
- swarming.postWithToast("/_ah/api/swarming/v1/bot/"+this.bot_id+"/delete",
- "Deleting "+this.bot_id, this._auth_headers);
- },
-
- _eventList(showAll) {
- if (!this._events) {
- return [];
- }
- return this._events.filter(function(e){
- return showAll || e.message;
- });
- },
-
- _isDead(bot){
- if (bot && bot.is_dead) {
- return "dead";
- }
- return "";
- },
-
- _luciLink: function(revision) {
- if (!revision) {
- return undefined;
- }
- return "https://github.com/luci/luci-py/commit/" + revision;
- },
-
- _mpLink: function(bot, template) {
- if (!bot || !bot.lease_id || !template) {
- return false;
- }
- return template.replace("%s", bot.lease_id);
- },
-
- _numRows: function(arr) {
- if (!arr || !arr.length) {
- return 1;
- }
- return 1 + arr.length;
- },
-
- _prettyPrint: function(obj) {
- obj = obj || {};
- return JSON.stringify(obj, null, 2);
- },
-
- _promptClosed: function(e) {
- if (e.detail.confirmed) {
- if (this._dialogPrompt.startsWith("shut down")) {
- this._shutdownBot();
- } else {
- this._deleteBot();
- }
- }
- },
-
- _promptDelete: function() {
- this.set("_dialogPrompt", "delete "+this.bot_id);
- this.$.prompt.open();
- },
-
- _promptShutdown: function() {
- this.set("_dialogPrompt", "shut down "+this.bot_id);
- this.$.prompt.open();
- },
-
- _quarantineMessage: function(bot) {
- if (bot && bot.quarantined) {
- var msg = bot.state.quarantined;
- // Sometimes, the quarantined message is actually in "error". This
- // happens when the bot code has thrown an exception.
- if (msg === undefined || msg === "true" || msg === true) {
- msg = bot.state && bot.state.error;
- }
- return msg || "True";
- }
- return "";
- },
-
- _refresh: function() {
- this.$.data.request();
- },
-
- _reload: function() {
- if (!this._auth_headers) {
- return;
- }
- var baseUrl = "/_ah/api/swarming/v1/bot/"+this.bot_id;
- // We limit the fields on these two queries to make them faster.
- this.$.page_tasks.load(baseUrl + "/tasks?fields=cursor%2Citems(abandoned_ts%2Cbot_version%2Ccompleted_ts%2Cduration%2Cexit_code%2Cfailure%2Cinternal_failure%2Cmodified_ts%2Cname%2Cstarted_ts%2Cstate%2Ctask_id%2Ctry_number)",
- this._auth_headers, 30);
- this.$.page_events.load(baseUrl + "/events?fields=cursor%2Citems(event_type%2Cmessage%2Cquarantined%2Ctask_id%2Cts%2Cversion)",
- this._auth_headers, 50);
- },
-
- _shorten: function(str, length) {
- if (!str || ! length) {
- return "";
- }
- return str.substring(0, length);
- },
-
- _shutdownBot: function() {
- swarming.postWithToast("/_ah/api/swarming/v1/bot/"+this.bot_id+"/terminate",
- "Shutting down "+this.bot_id, this._auth_headers);
- },
-
- _task: function(bot) {
- return (bot && bot.task_id) || "idle";
- },
-
- _taskClass: function(task) {
- if (task && task.internal_failure) {
- return "bot_died";
- }
- if (task && task.failure) {
- return "failed_task";
- }
- return "";
- },
-
- _toggleState: function() {
- this.set("_show_state", !this._show_state);
- }
-
- });
- })();
- </script>
-</dom-module>

Powered by Google App Engine
This is Rietveld 408576698