| Index: appengine/swarming/ui/build/elements.html
|
| diff --git a/appengine/swarming/ui/build/elements.html b/appengine/swarming/ui/build/elements.html
|
| index f21a21d37edafea9c43a7f048346548eac9fe418..cbbc33d61351d940852a97154a0de3acc25f1095 100644
|
| --- a/appengine/swarming/ui/build/elements.html
|
| +++ b/appengine/swarming/ui/build/elements.html
|
| @@ -1195,7 +1195,7 @@ weekdays:"星期日_星期一_星期二_星期三_星期四_星期五_星期六"
|
| }
|
|
|
| });
|
| - })(); </script> </dom-module><dom-module id="interval-timer" assetpath="/res/imp/common/"> <script>!function(){Polymer({is:"interval-timer",properties:{period:{type:Number,value:-1,observer:"_periodChanged"}},_periodChanged:function(e){this._timeout&&window.clearTimeout(this._timeout),e>0&&(this._timeout=window.setTimeout(function(){this.fire("trigger"),this._periodChanged(e)}.bind(this),1e3*e))}})}()</script> </dom-module> <dom-module id="task-page-data" assetpath="/res/imp/taskpage/"> <script>!function(){var t,e=400,s=["abandoned_ts","completed_ts","created_ts","modified_ts","started_ts"];Polymer({is:"task-page-data",behaviors:[SwarmingBehaviors.CommonBehavior,SwarmingBehaviors.TaskBehavior],properties:{auth_headers:{type:Object},task_id:{type:String},busy:{type:Boolean,computed:"_or(_busy1,_busy2,_busy3)",notify:!0},request:{type:Object,computed:"_parseRequest(_request)",notify:!0},result:{type:Object,computed:"_parseResult(_result)",notify:!0},stdout:{type:String,computed:"_parseStdout(_stdout)",notify:!0},task_exists:{type:Boolean,value:!0,notify:!0},_busy1:{type:Boolean,value:!1},_busy2:{type:Boolean,value:!1},_busy3:{type:Boolean,value:!1},_request:{type:Object},_result:{type:Object},_stdout:{type:Object}},observers:["reload(auth_headers,task_id)"],reload:function(){if(!this.task_id||!this.auth_headers)return void console.log("task_id and auth_headers can't be empty");t&&this.cancelAsync(t);var s="/api/swarming/v1/task/"+this.task_id;t=this.async(function(){t=void 0;var e=this._getJsonAsync("_request",s+"/request","_busy1",this.auth_headers);e.then(function(){this.set("task_exists",!0)}.bind(this)).catch(function(t){404===t.status?this.set("task_exists",!1):sk.errorMessage("Http response: "+(t.status||" ")+" "+t.response)}.bind(this)),this._getJsonAsync("_result",s+"/result?include_performance_stats=true","_busy2",this.auth_headers),this.reloadStdout()},e)},_parseRequest:function(t){return t?(t.tagMap={},t.tags=t.tags||[],t.tags.forEach(function(e){var s=e.split(":",1),a=s[0],u=e.substring(a.length+1);t.tagMap[a]=u}),s.forEach(function(e){t[e]&&(t[e]=new Date(t[e]),t["human_"+e]=sk.human.localeTime(t[e]))}),t):{}},_parseResult:function(t){if(!t)return{};var e=new Date;return s.forEach(function(e){t[e]&&(t[e]=new Date(t[e]),t["human_"+e]=sk.human.localeTime(t[e]))}),!t.duration&&t.state===this.RUNNING&&t.started_ts&&(t.duration=(e-t.started_ts)/1e3),t.duration&&(t.human_duration=this._humanDuration(t.duration)),t},_parseStdout:function(t){return t&&t.output?t.output:""},reloadStdout:function(){this._getJsonAsync("_stdout","/api/swarming/v1/task/"+this.task_id+"/stdout","_busy3",this.auth_headers)}})}()</script> </dom-module><dom-module id="task-disambiguation" assetpath="/res/imp/taskpage/"> <template> <style include="swarming-app-style single-page-style task-style"></style> <table> <thead> <tr> <th>Try ID</th> <th>Bot ID</th> <th>Status</th> </tr> </thead> <tbody> <template id="result_list" is="dom-repeat" items="[[_results]]" as="result" observe="task_id bot_id state"> <tr> <td> <a href$="[[_taskLink(result.task_id,'true')]]"> [[result.task_id]] </a> </td> <td> <a href$="[[_botLink(result.bot_id)]]"> [[result.bot_id]] </a> </td> <td class$="[[_stateClass(result)]]">[[state(result)]]</td> </tr> </template> </tbody> </table> </template> <script>Polymer({is:"task-disambiguation",behaviors:[SwarmingBehaviors.CommonBehavior,SwarmingBehaviors.TaskBehavior],properties:{auth_headers:{type:Object},summary_result:{type:Object},task_id:{type:String},busy:{type:Boolean,value:!1,notify:!0},_busyArr:{type:Array,value:function(){return[]}},_results:{type:Array,value:function(){return[]}}},observers:["_fetchRest(auth_headers,task_id,summary_result)","_computeBusy(_busyArr.*)"],_computeBusy:function(){for(var s=0;s<this._busyArr.length;s++)if(this._busyArr[s].status)return!0;return!1},_fetchRest:function(s,r,t){if(s&&r&&t){var e=t.try_number;this.set("_busyArr",[]),this.set("_results",[]);for(var u=r.substring(0,r.length-1),i="/api/swarming/v1/task/",a=0;a<e-1;a++){var n=u+(a+1);this.splice("_busyArr",a,0,{}),this.splice("_results",a,0,{task_id:n}),this._getJsonAsyncArr(a,"_results",i+n+"/result","_busyArr",s)}t.task_id=u+e,this.splice("_results",e-1,1,t)}}})</script> </dom-module><dom-module id="task-page" assetpath="/res/imp/taskpage/"> <template> <style include="iron-flex iron-flex-alignment swarming-app-style single-page-style task-style">.milo{width:calc(100% - 11px);height:2000px}.right{margin-top:8px}.break-all{word-break:break-all}.expand{min-width:3em;vertical-align:middle;padding:.5em}.code{font-family:monospace}.stdout{white-space:pre-wrap;padding:2px}.stdout.wide{white-space:pre;overflow-x:auto}.refresh_input{padding:0 5px}.reproduce{margin-left:5px}.tabbed{border:3px solid #1F78B4;margin-left:5px;min-height:80vh;min-width:550px}.task-info{min-width:500px}.cipd-header{-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;user-select:none;font-weight:700;margin-left:8px}.full-width{min-width:100%}.full-width-container{position:relative}.full-width-container>paper-checkbox{position:absolute;bottom:10px;width:140px;left:5px}.italic{font-style:italic}</style> <url-param name="id" value="{{task_id}}"> </url-param> <url-param name="try_detail" value="{{_try_detail}}"> </url-param> <url-param name="request_detail" value="{{_request_detail}}"> </url-param> <url-param name="show_raw" value="{{_show_raw}}"> </url-param> <url-param name="wide_logs" value="{{_wide_logs}}"> </url-param> <url-param name="refresh" value="{{_refresh_interval}}" default_value="10"> </url-param> <swarming-app client_id="[[client_id]]" auth_headers="{{_auth_headers}}" permissions="{{_permissions}}" profile="{{_profile}}" server_details="{{_server_details}}" signed_in="{{_signed_in}}" busy="[[_or(_busyPageData,_busyTaskDisambiguation,_busyRunningCount,_busyPendingCount,_busyBotCount)]]" name="Swarming Task Page"> <h2 hidden$="[[_signed_in]]">You must sign in to see anything useful.</h2> <div hidden$="[[_not(_signed_in)]]"> <task-page-data id="data" auth_headers="[[_auth_headers]]" task_id="[[task_id]]" busy="{{_busyPageData}}" request="{{_request}}" result="{{_result}}" stdout="{{_stdout}}" task_exists="{{_task_exists}}"> </task-page-data> <div class="horizontal layout wrap"> <div class="left flex"> <div class="horizontal layout"> <paper-input class="id_input" label="Task id" value="{{task_id}}"></paper-input> <button on-click="_refresh"> <iron-icon class="refresh" icon="icons:refresh"></iron-icon> </button> <button on-click="_promptRetry">Retry</button> <template is="dom-if" if="[[_canCancelTask(_result,_permissions)]]"> <button on-click="_promptCancel">Cancel</button> </template> </div> <h2 hidden$="[[_task_exists]]">Task not found.</h2> <template is="dom-if" if="[[_disambiguate(task_id,_result)]]"> <h2>Displaying a summary for a task with multiple tries</h2> <task-disambiguation busy="{{_busyTaskDisambiguation}}" auth_headers="[[_auth_headers]]" task_id="[[task_id]]" summary_result="[[_result]]"> </task-disambiguation> </template> <table class="task-info" hidden$="[[_not(_task_exists)]]"> <tbody> <tr> <td>Name</td> <td>[[_request.name]]</td> </tr> <tr> <td>State</td> <td class$="[[_stateClass(_result)]]">[[state(_result)]]</td> </tr> <template is="dom-if" if="[[_eq(_result.state,'PENDING')]]"> <tr> <td><b>Why Pending?</b></td> <td> <span class$="[[_it(_other_pending.count)]]">[[_otherPending(_other_pending)]]</span> similar pending tasks, <span class$="[[_it(_other_running.count)]]">[[_other_running.count]]</span> similar running tasks </td> </tr> </template> <tr> <td>Fleet Capacity</td> <td> <span class$="[[_it(_bots_count.count)]]">[[_bots_count.count]]</span> <a title="The list of bots that matches the list of dimensions" href$="[[_botListLink(_request.properties.dimensions)]]">bots</a> can run this task (<span class$="[[_it(_bots_count.dead)]]">[[_bots_count.dead]]</span> dead, <span class$="[[_it(_bots_count.dead)]]">[[_bots_count.quarantined]]</span> quarantined) </td> </tr> <tr> <td>Created</td> <td title$="[[_request.created_ts]]">[[_request.human_created_ts]]</td> </tr> <template is="dom-if" if="[[_wasPickedUp(_result)]]"> <tr> <td>Started</td> <td title$="[[_result.started_ts]]">[[_result.human_started_ts]]</td> </tr> </template> <template is="dom-if" if="[[_wasNotPickedUp(_result)]]"> <tr> <td>Expires</td> <td>[[_expires(_request)]]</td> </tr> </template> <template is="dom-if" if="[[_result.human_completed_ts]]"> <tr> <td>Completed</td> <td title$="[[_result.completed_ts]]">[[_result.human_completed_ts]]</td> </tr> </template> <template is="dom-if" if="[[_result.human_abandoned_ts]]"> <tr> <td>Abandoned</td> <td title$="[[_result.abandoned_ts]]">[[_result.human_abandoned_ts]]</td> </tr> </template> <tr> <td>Last Updated</td> <td title$="[[_result.modified_ts]]">[[_result.human_modified_ts]]</td> </tr> <template is="dom-if" if="[[_result.deduped_from]]"> <tr> <td><b>Deduped from</b></td> <td> <a href$="[[_taskLink(_result.deduped_from)]]"> [[_result.deduped_from]] </a> </td> </tr> </template> <tr> <td>Pending Time</td> <td>[[_pending(_result)]]</td> </tr> <tr> <td>Duration</td> <td>[[_result.human_duration]]</td> </tr> <tr> <td>Priority</td> <td>[[_request.priority]]</td> </tr> <tr> <td>User</td> <td>[[_request.user]]</td> </tr> <tr> <td>Authenticated</td> <td>[[_request.authenticated]]</td> </tr> <template is="dom-if" if="[[_request.service_account]]"> <tr> <td>Service Account</td> <td>[[_request.service_account]]</td> </tr> </template> <template is="dom-if" if="[[_request.properties.secret_bytes]]"> <tr> <td>Secret Bytes</td> <td>[[_request.properties.secret_bytes]]</td> </tr> </template> <template is="dom-if" if="[[_request.parent_task_id]]"> <tr> <td>Parent Task</td> <td> <a href$="[[_taskLink(_request.parent_task_id)]]">[[_request.parent_task_id]]</a> </td> </tr> </template> <tr> <td rowspan$="[[_rowspan(_request.properties.dimensions)]]"> <a title="The list of bots that matches the list of dimensions" href$="[[_botListLink(_request.properties.dimensions)]]"> Requested Dimensions </a> </td> </tr> <template is="dom-repeat" items="{{_request.properties.dimensions}}" as="dimension"> <tr> <td><b>[[dimension.key]]:</b> [[_alias(dimension)]]</td> </tr> </template> <tr> <td>Isolated Inputs</td> <td> <a href$="[[_isolateLink(_request.properties.inputs_ref)]]"> [[_request.properties.inputs_ref.isolated]] </a> </td> </tr> <template is="dom-if" if="[[_request.properties.outputs.length]]"> <tr> <td rowspan$="[[_rowspan(_request.properties.outputs)]]">Expected outputs</td> </tr> <template is="dom-repeat" items="{{_request.properties.outputs}}" as="output"> <tr> <td>[[output]]</td> </tr> </template> </template> <template is="dom-if" if="[[_not(_request_detail)]]"> <tr> <td>More Details</td> <td> <button on-click="_toggleDetails"> <iron-icon icon="icons:add-circle-outline"></iron-icon> </button> </td> </tr> </template> <template is="dom-if" if="[[_request_detail]]"> <tr> <td>Hide Details</td> <td> <button on-click="_toggleDetails"> <iron-icon icon="icons:remove-circle-outline"></iron-icon> </button> </td> </tr> </template> </tbody> <tbody id="more_details" hidden$="[[!_request_detail]]"> <tr> <td>Extra Args</td> <td class="code break-all">[[_extraArgs(_request)]]</td> </tr> <tr> <td>Command</td> <td class="code break-all">[[_command(_request)]]</td> </tr> <tr> <td>Idempotent</td> <td>[[_request.properties.idempotent]]</td> </tr> <tr> <td rowspan$="[[_rowspan(_request.tags)]]">Tags</td> </tr> <template is="dom-repeat" items="{{_request.tags}}" as="tag"> <tr> <td class="break-all">[[tag]]</td> </tr> </template> <tr> <td>Execution timeout</td> <td>[[_humanDuration(_request.properties.execution_timeout_secs)]]</td> </tr> <tr> <td>I/O timeout</td> <td>[[_humanDuration(_request.properties.io_timeout_secs)]]</td> </tr> <tr> <td>Grace period</td> <td>[[_humanDuration(_request.properties.grace_period_secs)]]</td> </tr> <tr> <td>CIPD server</td> <td> <a href$="[[_request.properties.cipd_input.server]]"> [[_request.properties.cipd_input.server]] </a> </td> </tr> <tr> <td>CIPD version</td> <td class="break-all">[[_request.properties.cipd_input.client_package.version]]</td> </tr> <template is="dom-if" if="[[_wasPickedUp(_result)]]"> <tr> <td>CIPD package name</td> <td>[[_result.cipd_pins.client_package.package_name]]</td> </tr> </template> <tr hidden$="[[_not(_request.properties.cipd_input)]]"> <td rowspan$="[[_cipdRowspan(_request,_result)]]">CIPD packages</td> </tr> <template is="dom-repeat" items="[[_cipdPackages(_request,_result)]]" as="cipd"> <tr> <td>[[cipd.path]]/</td> </tr> <tr> <td class="break-all"> <span class="cipd-header">Requested: </span>[[cipd.requested]] </td> </tr> <tr hidden$="[[!_hasActualCIPDPackages(_result)]]"> <td class="break-all"> <span class="cipd-header">Actual: </span>[[cipd.actual]] </td> </tr> </template> <tr hidden$="[[_empty(_request.properties.caches)]]"> <td rowspan$="[[_rowspan(_request.properties.caches)]]">Named caches</td> </tr> <template is="dom-repeat" items="[[_request.properties.caches]]" as="cache"> <tr> <td><span>[[cache.name]]</span>:<span>[[cache.path]]</span></td> </tr> </template> </tbody> </table> <div class="title" hidden$="[[_not(_task_exists)]]">Task Execution</div> <template is="dom-if" if="[[_wasPickedUp(_result)]]"> <table hidden$="[[_not(_task_exists)]]"> <tbody><tr> <td>Bot assigned to task</td> <td><a href$="[[_botLink(_result.bot_id)]]">[[_result.bot_id]]</a></td> </tr> <tr> <td rowspan$="[[_rowspan(_result.bot_dimensions)]]"> <a>Bot Dimensions</a> </td> </tr> <template is="dom-repeat" items="[[_result.bot_dimensions]]" as="dimension"> <tr> <td><b>[[dimension.key]]:</b> [[_alias(dimension)]]</td> </tr> </template> <tr> <td>Exit code</td> <td>[[_result.exit_code]]</td> </tr> <tr> <td>Try number</td> <td>[[_result.try_number]]</td> </tr> <tr> <td>Failure</td> <td class$="[[_failureClass(_result.failure)]]">[[_result.failure]]</td> </tr> <tr> <td>Internal Failure</td> <td class$="[[_internalClass(_result.internal_failure)]]">[[_result.internal_failure]]</td> </tr> <tr> <td>Isolated Outputs</td> <td> <a href$="[[_isolateLink(_result.outputs_ref)]]"> [[_result.outputs_ref.isolated]] </a> </td> </tr> <tr> <td>Bot version</td> <td>[[_result.bot_version]]</td> </tr> <tr> <td>Server version</td> <td>[[_result.server_versions]]</td> </tr> </tbody></table> </template> <template is="dom-if" if="[[_wasNotPickedUp(_result)]]"> This space left blank until a bot is assigned to the task. </template> <template is="dom-if" if="[[_result.performance_stats]]"> <div class="title">Performance Stats</div> <table> <tbody><tr> <td title="This includes time taken to download inputs, isolate outputs, and setup CIPD">Total Overhead</td> <td>[[_humanDuration(_result.performance_stats.bot_overhead)]]</td> </tr> <tr> <td>Downloading Inputs From Isolate</td> <td>[[_humanDuration(_result.performance_stats.isolated_download.duration)]]</td> </tr> <tr> <td>Uploading Outputs To Isolate</td> <td>[[_humanDuration(_result.performance_stats.isolated_upload.duration)]]</td> </tr> <tr hidden$="[[!_result.performance_stats.isolated_download.initial_size]]"> <td>Initial bot cache</td> <td>[[_result.performance_stats.isolated_download.initial_number_items]] items; [[_bytes(_result.performance_stats.isolated_download.initial_size)]]</td> </tr> </tbody></table> </template> <div hidden$="[[_not(_task_exists)]]"> <div class="title">Reproducing the task locally</div> <div class="reproduce"> <div>Download inputs files into directory <i>foo</i>:</div> <div class="code"> python isolateserver.py download -I [[_request.properties.inputs_ref.isolatedserver]] --namespace [[_request.properties.inputs_ref.namespace]] -s [[_request.properties.inputs_ref.isolated]] --target foo</div> <br> <div>Run this task locally:</div> <div class="code"> python swarming.py reproduce -S [[_host_url]] [[task_id]]</div> <br> <div>Download output results into directory <i>foo</i>:</div> <div class="code"> python swarming.py collect -S [[_host_url]] --task-output-dir=foo [[task_id]]</div> <br> <div>Looking for <i>swarming.py</i>?</div> <div class="code"> git clone https://github.com/luci/client-py</div> </div> </div> </div> <div class$="flex right [[_classRight(_wide_logs)]]" hidden$="[[_not(_task_exists)]]"> <div class="horizontal layout"> <div class="tabs"> <paper-tabs selected="{{_show_raw}}" no-bar=""> <paper-tab disabled$="[[_noMilo(_request)]]">Milo Output</paper-tab> <paper-tab>Raw Output</paper-tab> </paper-tabs> </div> <paper-input class="refresh_input" label="Refresh Interval (seconds)" value="{{_refresh_interval}}" title="How often to refresh all information about the task" auto-validate="" min="1" max="1000" pattern="[0-9]+"> </paper-input> <div class="full-width-container"> <paper-checkbox checked="{{_wide_logs}}"> Full Width Logs </paper-checkbox> </div> </div> <template is="dom-if" if="[[_supportsMilo(_request,_show_raw)]]"> <div class="milo tabbed" hidden$="[[_isSummaryLink(task_id)]]"> Milo results are only generated for task summaires, that is, tasks whose ids end in 0. Tasks ending in 1 or 2 represent possible retries of tasks. See <a href="//goo.gl/LE4rwV">the docs</a> for more. </div> <iframe id="miloFrame" class="milo tabbed" src$="[[_getDisplayServerLink(_server_details.display_server_url_template,task_id)]]"></iframe> </template> <template is="dom-if" if="[[_show_raw]]"> <div class$="code stdout tabbed break-all [[_classStdout(_wide_logs)]]">[[_rawOutput(_stdout,_result)]]</div> </template> </div> </div> </div> </swarming-app> <paper-dialog id="prompt" modal="" on-iron-overlay-closed="_promptClosed"> <h2>Are you sure?</h2> <div>Are you sure you want to [[_dialog_prompt]]?</div> <div class="buttons"> <paper-button dialog-dismiss="" autofocus="">No</paper-button> <paper-button dialog-confirm="">Yes</paper-button> </div> </paper-dialog> <interval-timer period="[[_refresh_interval]]" on-trigger="_softRefresh"> </interval-timer> </template> <script> (function(){
|
| + })(); </script> </dom-module><dom-module id="interval-timer" assetpath="/res/imp/common/"> <script>!function(){Polymer({is:"interval-timer",properties:{period:{type:Number,value:-1,observer:"_periodChanged"}},_periodChanged:function(e){this._timeout&&window.clearTimeout(this._timeout),e>0&&(this._timeout=window.setTimeout(function(){this.fire("trigger"),this._periodChanged(e)}.bind(this),1e3*e))}})}()</script> </dom-module> <dom-module id="task-page-data" assetpath="/res/imp/taskpage/"> <script>!function(){var t,e=400,s=["abandoned_ts","completed_ts","created_ts","modified_ts","started_ts"];Polymer({is:"task-page-data",behaviors:[SwarmingBehaviors.CommonBehavior,SwarmingBehaviors.TaskBehavior],properties:{auth_headers:{type:Object},task_id:{type:String},busy:{type:Boolean,computed:"_or(_busy1,_busy2,_busy3)",notify:!0},request:{type:Object,computed:"_parseRequest(_request)",notify:!0},result:{type:Object,computed:"_parseResult(_result)",notify:!0},stdout:{type:String,computed:"_parseStdout(_stdout)",notify:!0},task_exists:{type:Boolean,value:!0,notify:!0},_busy1:{type:Boolean,value:!1},_busy2:{type:Boolean,value:!1},_busy3:{type:Boolean,value:!1},_request:{type:Object},_result:{type:Object},_stdout:{type:Object}},observers:["reload(auth_headers,task_id)"],reload:function(){if(!this.task_id||!this.auth_headers)return void console.log("task_id and auth_headers can't be empty");t&&this.cancelAsync(t);var s="/api/swarming/v1/task/"+this.task_id;t=this.async(function(){t=void 0;var e=this._getJsonAsync("_request",s+"/request","_busy1",this.auth_headers);e.then(function(){this.set("task_exists",!0)}.bind(this)).catch(function(t){404===t.status?this.set("task_exists",!1):sk.errorMessage("Http response: "+(t.status||" ")+" "+t.response)}.bind(this)),this._getJsonAsync("_result",s+"/result?include_performance_stats=true","_busy2",this.auth_headers),this.reloadStdout()},e)},_parseRequest:function(t){return t?(t.tagMap={},t.tags=t.tags||[],t.tags.forEach(function(e){var s=e.split(":",1),a=s[0],u=e.substring(a.length+1);t.tagMap[a]=u}),s.forEach(function(e){t[e]&&(t[e]=new Date(t[e]),t["human_"+e]=sk.human.localeTime(t[e]))}),t):{}},_parseResult:function(t){if(!t)return{};var e=new Date;return s.forEach(function(e){t[e]&&(t[e]=new Date(t[e]),t["human_"+e]=sk.human.localeTime(t[e]))}),!t.duration&&t.state===this.RUNNING&&t.started_ts&&(t.duration=(e-t.started_ts)/1e3),t.duration&&(t.human_duration=this._humanDuration(t.duration)),t},_parseStdout:function(t){return t&&t.output?t.output:""},reloadStdout:function(){this._getJsonAsync("_stdout","/api/swarming/v1/task/"+this.task_id+"/stdout","_busy3",this.auth_headers)}})}()</script> </dom-module><dom-module id="task-retry-prompt" assetpath="/res/imp/taskpage/"> <template> <style>:host{display:block}td,th{font-size:16px}paper-input{--paper-input-container-input:{font-family:sans-serif};}</style> <h2>Are you sure you want to retry task [[task_id]]?</h2> <div>If you want to modify any dimensions (e.g. specify a bot's id), do so now.</div> <table> <thead> <tr> <th>Key</th> <th>Value</th> </tr> </thead> <tbody> <template is="dom-repeat" items="[[task_dimensions]]" as="dim"> <tr> <td> <paper-input no-label-float="true" value="[[dim.key]]" on-change="_updateKey"> </paper-input> </td> <td> <paper-input no-label-float="true" value="[[dim.value]]" on-change="_updateValue"> </paper-input> </td> </tr> </template> </tbody> </table> </template> <script>Polymer({is:"task-retry-prompt",properties:{task_id:{type:String},task_dimensions:{type:Array,notify:!0}},setDimensions:function(e){for(e=e||[];e.length<6;)e.push({key:"",value:""});this.set("task_dimensions",e)},_updateKey:function(e){this.set("task_dimensions."+e.model.index+".key",e.currentTarget.value)},_updateValue:function(e){this.set("task_dimensions."+e.model.index+".value",e.currentTarget.value)}})</script> </dom-module><dom-module id="task-disambiguation" assetpath="/res/imp/taskpage/"> <template> <style include="swarming-app-style single-page-style task-style"></style> <table> <thead> <tr> <th>Try ID</th> <th>Bot ID</th> <th>Status</th> </tr> </thead> <tbody> <template id="result_list" is="dom-repeat" items="[[_results]]" as="result" observe="task_id bot_id state"> <tr> <td> <a href$="[[_taskLink(result.task_id,'true')]]"> [[result.task_id]] </a> </td> <td> <a href$="[[_botLink(result.bot_id)]]"> [[result.bot_id]] </a> </td> <td class$="[[_stateClass(result)]]">[[state(result)]]</td> </tr> </template> </tbody> </table> </template> <script>Polymer({is:"task-disambiguation",behaviors:[SwarmingBehaviors.CommonBehavior,SwarmingBehaviors.TaskBehavior],properties:{auth_headers:{type:Object},summary_result:{type:Object},task_id:{type:String},busy:{type:Boolean,value:!1,notify:!0},_busyArr:{type:Array,value:function(){return[]}},_results:{type:Array,value:function(){return[]}}},observers:["_fetchRest(auth_headers,task_id,summary_result)","_computeBusy(_busyArr.*)"],_computeBusy:function(){for(var s=0;s<this._busyArr.length;s++)if(this._busyArr[s].status)return!0;return!1},_fetchRest:function(s,r,t){if(s&&r&&t){var e=t.try_number;this.set("_busyArr",[]),this.set("_results",[]);for(var u=r.substring(0,r.length-1),i="/api/swarming/v1/task/",a=0;a<e-1;a++){var n=u+(a+1);this.splice("_busyArr",a,0,{}),this.splice("_results",a,0,{task_id:n}),this._getJsonAsyncArr(a,"_results",i+n+"/result","_busyArr",s)}t.task_id=u+e,this.splice("_results",e-1,1,t)}}})</script> </dom-module><dom-module id="task-page" assetpath="/res/imp/taskpage/"> <template> <style include="iron-flex iron-flex-alignment swarming-app-style single-page-style task-style">.milo{width:calc(100% - 11px);height:2000px}.right{margin-top:8px}.break-all{word-break:break-all}.expand{min-width:3em;vertical-align:middle;padding:.5em}.code{font-family:monospace}.stdout{white-space:pre-wrap;padding:2px}.stdout.wide{white-space:pre;overflow-x:auto}.refresh_input{padding:0 5px}.reproduce{margin-left:5px}.tabbed{border:3px solid #1F78B4;margin-left:5px;min-height:80vh;min-width:550px}.task-info{min-width:500px}.cipd-header{-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;user-select:none;font-weight:700;margin-left:8px}.full-width{min-width:100%}.full-width-container{position:relative}.full-width-container>paper-checkbox{position:absolute;bottom:10px;width:140px;left:5px}.italic{font-style:italic}</style> <url-param name="id" value="{{task_id}}"> </url-param> <url-param name="try_detail" value="{{_try_detail}}"> </url-param> <url-param name="request_detail" value="{{_request_detail}}"> </url-param> <url-param name="show_raw" value="{{_show_raw}}"> </url-param> <url-param name="wide_logs" value="{{_wide_logs}}"> </url-param> <url-param name="refresh" value="{{_refresh_interval}}" default_value="10"> </url-param> <swarming-app client_id="[[client_id]]" auth_headers="{{_auth_headers}}" permissions="{{_permissions}}" profile="{{_profile}}" server_details="{{_server_details}}" signed_in="{{_signed_in}}" busy="[[_or(_busyPageData,_busyTaskDisambiguation,_busyRunningCount,_busyPendingCount,_busyBotCount)]]" name="Swarming Task Page"> <h2 hidden$="[[_signed_in]]">You must sign in to see anything useful.</h2> <div hidden$="[[_not(_signed_in)]]"> <task-page-data id="data" auth_headers="[[_auth_headers]]" task_id="[[task_id]]" busy="{{_busyPageData}}" request="{{_request}}" result="{{_result}}" stdout="{{_stdout}}" task_exists="{{_task_exists}}"> </task-page-data> <div class="horizontal layout wrap"> <div class="left flex"> <div class="horizontal layout"> <paper-input class="id_input" label="Task id" value="{{task_id}}"></paper-input> <button on-click="_refresh"> <iron-icon class="refresh" icon="icons:refresh"></iron-icon> </button> <button on-click="_promptRetry">Retry</button> <template is="dom-if" if="[[_canCancelTask(_result,_permissions)]]"> <button on-click="_promptCancel">Cancel</button> </template> </div> <h2 hidden$="[[_task_exists]]">Task not found.</h2> <template is="dom-if" if="[[_disambiguate(task_id,_result)]]"> <h2>Displaying a summary for a task with multiple tries</h2> <task-disambiguation busy="{{_busyTaskDisambiguation}}" auth_headers="[[_auth_headers]]" task_id="[[task_id]]" summary_result="[[_result]]"> </task-disambiguation> </template> <table class="task-info" hidden$="[[_not(_task_exists)]]"> <tbody> <tr> <td>Name</td> <td>[[_request.name]]</td> </tr> <tr> <td>State</td> <td class$="[[_stateClass(_result)]]">[[state(_result)]]</td> </tr> <template is="dom-if" if="[[_eq(_result.state,'PENDING')]]"> <tr> <td><b>Why Pending?</b></td> <td> <span class$="[[_it(_other_pending.count)]]">[[_otherPending(_other_pending)]]</span> similar pending tasks, <span class$="[[_it(_other_running.count)]]">[[_other_running.count]]</span> similar running tasks </td> </tr> </template> <tr> <td>Fleet Capacity</td> <td> <span class$="[[_it(_bots_count.count)]]">[[_bots_count.count]]</span> <a title="The list of bots that matches the list of dimensions" href$="[[_botListLink(_request.properties.dimensions)]]">bots</a> can run this task (<span class$="[[_it(_bots_count.dead)]]">[[_bots_count.dead]]</span> dead, <span class$="[[_it(_bots_count.dead)]]">[[_bots_count.quarantined]]</span> quarantined) </td> </tr> <tr> <td>Created</td> <td title$="[[_request.created_ts]]">[[_request.human_created_ts]]</td> </tr> <template is="dom-if" if="[[_wasPickedUp(_result)]]"> <tr> <td>Started</td> <td title$="[[_result.started_ts]]">[[_result.human_started_ts]]</td> </tr> </template> <template is="dom-if" if="[[_wasNotPickedUp(_result)]]"> <tr> <td>Expires</td> <td>[[_expires(_request)]]</td> </tr> </template> <template is="dom-if" if="[[_result.human_completed_ts]]"> <tr> <td>Completed</td> <td title$="[[_result.completed_ts]]">[[_result.human_completed_ts]]</td> </tr> </template> <template is="dom-if" if="[[_result.human_abandoned_ts]]"> <tr> <td>Abandoned</td> <td title$="[[_result.abandoned_ts]]">[[_result.human_abandoned_ts]]</td> </tr> </template> <tr> <td>Last Updated</td> <td title$="[[_result.modified_ts]]">[[_result.human_modified_ts]]</td> </tr> <template is="dom-if" if="[[_result.deduped_from]]"> <tr> <td><b>Deduped from</b></td> <td> <a href$="[[_taskLink(_result.deduped_from)]]"> [[_result.deduped_from]] </a> </td> </tr> </template> <tr> <td>Pending Time</td> <td>[[_pending(_result)]]</td> </tr> <tr> <td>Duration</td> <td>[[_result.human_duration]]</td> </tr> <tr> <td>Priority</td> <td>[[_request.priority]]</td> </tr> <tr> <td>User</td> <td>[[_request.user]]</td> </tr> <tr> <td>Authenticated</td> <td>[[_request.authenticated]]</td> </tr> <template is="dom-if" if="[[_request.service_account]]"> <tr> <td>Service Account</td> <td>[[_request.service_account]]</td> </tr> </template> <template is="dom-if" if="[[_request.properties.secret_bytes]]"> <tr> <td>Secret Bytes</td> <td>[[_request.properties.secret_bytes]]</td> </tr> </template> <template is="dom-if" if="[[_request.parent_task_id]]"> <tr> <td>Parent Task</td> <td> <a href$="[[_taskLink(_request.parent_task_id)]]">[[_request.parent_task_id]]</a> </td> </tr> </template> <tr> <td rowspan$="[[_rowspan(_request.properties.dimensions)]]"> <a title="The list of bots that matches the list of dimensions" href$="[[_botListLink(_request.properties.dimensions)]]"> Requested Dimensions </a> </td> </tr> <template is="dom-repeat" items="{{_request.properties.dimensions}}" as="dimension"> <tr> <td><b>[[dimension.key]]:</b> [[_alias(dimension)]]</td> </tr> </template> <tr> <td>Isolated Inputs</td> <td> <a href$="[[_isolateLink(_request.properties.inputs_ref)]]"> [[_request.properties.inputs_ref.isolated]] </a> </td> </tr> <template is="dom-if" if="[[_request.properties.outputs.length]]"> <tr> <td rowspan$="[[_rowspan(_request.properties.outputs)]]">Expected outputs</td> </tr> <template is="dom-repeat" items="{{_request.properties.outputs}}" as="output"> <tr> <td>[[output]]</td> </tr> </template> </template> <template is="dom-if" if="[[_not(_request_detail)]]"> <tr> <td>More Details</td> <td> <button on-click="_toggleDetails"> <iron-icon icon="icons:add-circle-outline"></iron-icon> </button> </td> </tr> </template> <template is="dom-if" if="[[_request_detail]]"> <tr> <td>Hide Details</td> <td> <button on-click="_toggleDetails"> <iron-icon icon="icons:remove-circle-outline"></iron-icon> </button> </td> </tr> </template> </tbody> <tbody id="more_details" hidden$="[[!_request_detail]]"> <tr> <td>Extra Args</td> <td class="code break-all">[[_extraArgs(_request)]]</td> </tr> <tr> <td>Command</td> <td class="code break-all">[[_command(_request)]]</td> </tr> <tr> <td>Idempotent</td> <td>[[_request.properties.idempotent]]</td> </tr> <tr> <td rowspan$="[[_rowspan(_request.tags)]]">Tags</td> </tr> <template is="dom-repeat" items="{{_request.tags}}" as="tag"> <tr> <td class="break-all">[[tag]]</td> </tr> </template> <tr> <td>Execution timeout</td> <td>[[_humanDuration(_request.properties.execution_timeout_secs)]]</td> </tr> <tr> <td>I/O timeout</td> <td>[[_humanDuration(_request.properties.io_timeout_secs)]]</td> </tr> <tr> <td>Grace period</td> <td>[[_humanDuration(_request.properties.grace_period_secs)]]</td> </tr> <tr> <td>CIPD server</td> <td> <a href$="[[_request.properties.cipd_input.server]]"> [[_request.properties.cipd_input.server]] </a> </td> </tr> <tr> <td>CIPD version</td> <td class="break-all">[[_request.properties.cipd_input.client_package.version]]</td> </tr> <template is="dom-if" if="[[_wasPickedUp(_result)]]"> <tr> <td>CIPD package name</td> <td>[[_result.cipd_pins.client_package.package_name]]</td> </tr> </template> <tr hidden$="[[_not(_request.properties.cipd_input)]]"> <td rowspan$="[[_cipdRowspan(_request,_result)]]">CIPD packages</td> </tr> <template is="dom-repeat" items="[[_cipdPackages(_request,_result)]]" as="cipd"> <tr> <td>[[cipd.path]]/</td> </tr> <tr> <td class="break-all"> <span class="cipd-header">Requested: </span>[[cipd.requested]] </td> </tr> <tr hidden$="[[!_hasActualCIPDPackages(_result)]]"> <td class="break-all"> <span class="cipd-header">Actual: </span>[[cipd.actual]] </td> </tr> </template> <tr hidden$="[[_empty(_request.properties.caches)]]"> <td rowspan$="[[_rowspan(_request.properties.caches)]]">Named caches</td> </tr> <template is="dom-repeat" items="[[_request.properties.caches]]" as="cache"> <tr> <td><span>[[cache.name]]</span>:<span>[[cache.path]]</span></td> </tr> </template> </tbody> </table> <div class="title" hidden$="[[_not(_task_exists)]]">Task Execution</div> <template is="dom-if" if="[[_wasPickedUp(_result)]]"> <table hidden$="[[_not(_task_exists)]]"> <tbody><tr> <td>Bot assigned to task</td> <td><a href$="[[_botLink(_result.bot_id)]]">[[_result.bot_id]]</a></td> </tr> <tr> <td rowspan$="[[_rowspan(_result.bot_dimensions)]]"> <a>Bot Dimensions</a> </td> </tr> <template is="dom-repeat" items="[[_result.bot_dimensions]]" as="dimension"> <tr> <td><b>[[dimension.key]]:</b> [[_alias(dimension)]]</td> </tr> </template> <tr> <td>Exit code</td> <td>[[_result.exit_code]]</td> </tr> <tr> <td>Try number</td> <td>[[_result.try_number]]</td> </tr> <tr> <td>Failure</td> <td class$="[[_failureClass(_result.failure)]]">[[_result.failure]]</td> </tr> <tr> <td>Internal Failure</td> <td class$="[[_internalClass(_result.internal_failure)]]">[[_result.internal_failure]]</td> </tr> <tr> <td>Isolated Outputs</td> <td> <a href$="[[_isolateLink(_result.outputs_ref)]]"> [[_result.outputs_ref.isolated]] </a> </td> </tr> <tr> <td>Bot version</td> <td>[[_result.bot_version]]</td> </tr> <tr> <td>Server version</td> <td>[[_result.server_versions]]</td> </tr> </tbody></table> </template> <template is="dom-if" if="[[_wasNotPickedUp(_result)]]"> This space left blank until a bot is assigned to the task. </template> <template is="dom-if" if="[[_result.performance_stats]]"> <div class="title">Performance Stats</div> <table> <tbody><tr> <td title="This includes time taken to download inputs, isolate outputs, and setup CIPD">Total Overhead</td> <td>[[_humanDuration(_result.performance_stats.bot_overhead)]]</td> </tr> <tr> <td>Downloading Inputs From Isolate</td> <td>[[_humanDuration(_result.performance_stats.isolated_download.duration)]]</td> </tr> <tr> <td>Uploading Outputs To Isolate</td> <td>[[_humanDuration(_result.performance_stats.isolated_upload.duration)]]</td> </tr> <tr hidden$="[[!_result.performance_stats.isolated_download.initial_size]]"> <td>Initial bot cache</td> <td>[[_result.performance_stats.isolated_download.initial_number_items]] items; [[_bytes(_result.performance_stats.isolated_download.initial_size)]]</td> </tr> </tbody></table> </template> <div hidden$="[[_not(_task_exists)]]"> <div class="title">Reproducing the task locally</div> <div class="reproduce"> <div>Download inputs files into directory <i>foo</i>:</div> <div class="code"> python isolateserver.py download -I [[_request.properties.inputs_ref.isolatedserver]] --namespace [[_request.properties.inputs_ref.namespace]] -s [[_request.properties.inputs_ref.isolated]] --target foo</div> <br> <div>Run this task locally:</div> <div class="code"> python swarming.py reproduce -S [[_host_url]] [[task_id]]</div> <br> <div>Download output results into directory <i>foo</i>:</div> <div class="code"> python swarming.py collect -S [[_host_url]] --task-output-dir=foo [[task_id]]</div> <br> <div>Looking for <i>swarming.py</i>?</div> <div class="code"> git clone https://github.com/luci/client-py</div> </div> </div> </div> <div class$="flex right [[_classRight(_wide_logs)]]" hidden$="[[_not(_task_exists)]]"> <div class="horizontal layout"> <div class="tabs"> <paper-tabs selected="{{_show_raw}}" no-bar=""> <paper-tab disabled$="[[_noMilo(_request)]]">Milo Output</paper-tab> <paper-tab>Raw Output</paper-tab> </paper-tabs> </div> <paper-input class="refresh_input" label="Refresh Interval (seconds)" value="{{_refresh_interval}}" title="How often to refresh all information about the task" auto-validate="" min="1" max="1000" pattern="[0-9]+"> </paper-input> <div class="full-width-container"> <paper-checkbox checked="{{_wide_logs}}"> Full Width Logs </paper-checkbox> </div> </div> <template is="dom-if" if="[[_supportsMilo(_request,_show_raw)]]"> <div class="milo tabbed" hidden$="[[_isSummaryLink(task_id)]]"> Milo results are only generated for task summaires, that is, tasks whose ids end in 0. Tasks ending in 1 or 2 represent possible retries of tasks. See <a href="//goo.gl/LE4rwV">the docs</a> for more. </div> <iframe id="miloFrame" class="milo tabbed" src$="[[_getDisplayServerLink(_server_details.display_server_url_template,task_id)]]"></iframe> </template> <template is="dom-if" if="[[_show_raw]]"> <div class$="code stdout tabbed break-all [[_classStdout(_wide_logs)]]">[[_rawOutput(_stdout,_result)]]</div> </template> </div> </div> </div> </swarming-app> <paper-dialog id="prompt" modal="" on-iron-overlay-closed="_promptClosed"> <h2>Are you sure?</h2> <div>Are you sure you want to [[_dialog_prompt]]?</div> <div class="buttons"> <paper-button dialog-dismiss="" autofocus="">No</paper-button> <paper-button dialog-confirm="">Yes</paper-button> </div> </paper-dialog> <paper-dialog id="retry_task" modal="" on-iron-overlay-closed="_retryClosed"> <task-retry-prompt id="retry_task_prompt" task_id="[[task_id]]" task_dimensions="{{_retry_dimensions}}"> </task-retry-prompt> <div class="buttons"> <paper-button dialog-dismiss="">Cancel</paper-button> <paper-button dialog-confirm="">OK</paper-button> </div> </paper-dialog> <interval-timer period="[[_refresh_interval]]" on-trigger="_softRefresh"> </interval-timer> </template> <script> (function(){
|
| Polymer({
|
| is: 'task-page',
|
|
|
| @@ -1280,6 +1280,9 @@ weekdays:"星期日_星期一_星期二_星期三_星期四_星期五_星期六"
|
| _result: {
|
| type: Object,
|
| },
|
| + _retry_dimensions: {
|
| + type: Array,
|
| + },
|
| _server_details: {
|
| type: Object,
|
| },
|
| @@ -1476,11 +1479,7 @@ weekdays:"星期日_星期一_星期二_星期三_星期四_星期五_星期六"
|
|
|
| _promptClosed: function(e) {
|
| if (e.detail.confirmed) {
|
| - if (this._dialog_prompt.startsWith("cancel")) {
|
| - this._cancelTask();
|
| - } else {
|
| - this._retryTask();
|
| - }
|
| + this._cancelTask();
|
| }
|
| },
|
|
|
| @@ -1490,47 +1489,18 @@ weekdays:"星期日_星期一_星期二_星期三_星期四_星期五_星期六"
|
| },
|
|
|
| _promptRetry: function() {
|
| - this.set("_dialog_prompt", "retry task "+this.task_id);
|
| - this.$.prompt.open();
|
| + this.$.retry_task_prompt.setDimensions(this._request.properties.dimensions);
|
| + this.$.retry_task.open();
|
| },
|
|
|
| - _rawOutput: function(stdout, result) {
|
| - if (stdout) {
|
| - return stdout;
|
| - }
|
| - if (result.state === "PENDING" || result.state === "RUNNING") {
|
| - return "[No output yet]";
|
| - }
|
| - return "[No output received]";
|
| - },
|
| -
|
| - _refresh: function() {
|
| - this.$.data.reload();
|
| - },
|
| -
|
| - _requestUpdated: function(request) {
|
| - if (this._noMilo(request)) {
|
| - this.set("_show_raw", 1);
|
| - }
|
| - },
|
| -
|
| - _softRefresh: function() {
|
| - if (this._result && this._result.state !== "RUNNING" &&
|
| - this._result.state !== "PENDING") {
|
| - return;
|
| - }
|
| - this.$.data.reload();
|
| - var miloFrame = this.$$("iframe")
|
| - if (miloFrame) {
|
| - miloFrame.src = this._getDisplayServerLink(this._server_details.display_server_url_template,this.task_id);
|
| - }
|
| - },
|
| -
|
| - _retryTask: function() {
|
| + _retryClosed: function(e) {
|
| if (!this._request) {
|
| sk.errorMessage("Task not yet loaded", 3000);
|
| return;
|
| }
|
| + if (!e.detail.confirmed) {
|
| + return;
|
| + }
|
| var newTask = {
|
| expiration_secs: this._request.expiration_secs,
|
| name: this._request.name +" (retry)",
|
| @@ -1541,6 +1511,14 @@ weekdays:"星期日_星期一_星期二_星期三_星期四_星期五_星期六"
|
| user: this._profile.email,
|
| service_account: this._request.service_account,
|
| }
|
| + newTask.properties.dimensions = this._retry_dimensions.filter(function(d){
|
| + return d && d.key && d.value;
|
| + });
|
| + if (!newTask.properties.dimensions || !newTask.properties.dimensions.length) {
|
| + sk.errorMessage("Your retried task must specify dimensions", 5000);
|
| + return;
|
| + }
|
| + console.log("Retrying with dimensions", newTask.properties.dimensions);
|
| newTask.properties.idempotent = false;
|
| swarming.postWithToast("/api/swarming/v1/tasks/new", "Retrying task " + this.task_id,
|
| this._auth_headers, newTask)
|
| @@ -1557,6 +1535,39 @@ weekdays:"星期日_星期一_星期二_星期三_星期四_星期五_星期六"
|
| );
|
| },
|
|
|
| + _rawOutput: function(stdout, result) {
|
| + if (stdout) {
|
| + return stdout;
|
| + }
|
| + if (result.state === "PENDING" || result.state === "RUNNING") {
|
| + return "[No output yet]";
|
| + }
|
| + return "[No output received]";
|
| + },
|
| +
|
| + _refresh: function() {
|
| + this.$.data.reload();
|
| + },
|
| +
|
| + _requestUpdated: function(request) {
|
| + if (this._noMilo(request)) {
|
| + this.set("_show_raw", 1);
|
| + }
|
| + },
|
| +
|
| + _softRefresh: function() {
|
| + if (this._result && this._result.state !== "RUNNING" &&
|
| + this._result.state !== "PENDING") {
|
| + return;
|
| + }
|
| + this.$.data.reload();
|
| + var miloFrame = this.$$("iframe")
|
| + if (miloFrame) {
|
| + var templ = this._server_details.display_server_url_template;
|
| + miloFrame.src = this._getDisplayServerLink(templ, this.task_id);
|
| + }
|
| + },
|
| +
|
| _rowspan: function(dims) {
|
| dims = dims || [];
|
| return dims.length + 1;
|
|
|