New pool details and compute node view

This commit is contained in:
Christian Smith 2017-03-05 14:01:12 +11:00
Родитель 4ad40b67c6
Коммит 759efd4514
5 изменённых файлов: 214 добавлений и 19 удалений

Просмотреть файл

@ -307,6 +307,7 @@
</Compile>
<Compile Include="Models\NewPoolModel.cs" />
<Compile Include="Models\NewSearchModel.cs" />
<Compile Include="Models\PoolDetailsModel.cs" />
<Compile Include="Models\PoolSpec.cs" />
<Compile Include="Models\RespositoryViewModel.cs" />
<Compile Include="Models\VisualizeResultsModel.cs" />
@ -423,6 +424,7 @@
<Content Include="Scripts\jquery-2.1.3.min.map" />
<Content Include="Views\Repositories\Index.cshtml" />
<Content Include="Views\Databases\Index.cshtml" />
<Content Include="Views\Pool\Show.cshtml" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\AzureBlast\AzureBlast.csproj">

Просмотреть файл

@ -1,7 +1,13 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
using System.IO;
using System.Linq;
using System.Net.Mime;
using System.Text;
using System.Web;
using System.Web.Mvc;
using Microsoft.Azure.Batch;
using Microsoft.Azure.Batch.Blast.Configuration;
using Microsoft.Azure.Blast.Web.Models;
@ -10,10 +16,12 @@ namespace Microsoft.Azure.Blast.Web.Controllers
public class PoolController : AuthorizedController
{
private readonly BlastConfiguration _configuration;
private readonly BatchClient _batchClient;
public PoolController(BlastConfiguration configuration)
{
_configuration = configuration;
_batchClient = configuration.BatchClient;
}
public ActionResult Index()
@ -29,5 +37,67 @@ namespace Microsoft.Azure.Blast.Web.Controllers
};
return View(model);
}
[Route("Pool/{poolId}")]
public ActionResult Show(string poolId)
{
var pool = _batchClient.PoolOperations.GetPool(poolId);
if (pool == null)
{
return new HttpNotFoundResult("No such pool");
}
var model = new PoolDetailsModel
{
Pool = pool,
ComputeNodes = _batchClient.PoolOperations.ListComputeNodes(poolId).ToList(),
};
return View(model);
}
[Route("Pool/{poolId}/computenodes/{computeNodeId}/files/{fileName}/{fileExtension}")]
public ActionResult DownloadStartTaskFile(string poolId, string computeNodeId, string fileName, string fileExtension)
{
var pool = _batchClient.PoolOperations.GetPool(poolId);
if (pool == null)
{
return new HttpNotFoundResult("No such pool");
}
var node = _batchClient.PoolOperations.GetComputeNode(poolId, computeNodeId);
if (node == null)
{
return new HttpNotFoundResult("No such node");
}
fileName = fileName + "." + fileExtension;
var filePath = "startup/" + fileName;
var nodeFile = _batchClient.PoolOperations.GetNodeFile(poolId, computeNodeId, filePath);
if (nodeFile == null)
{
return new HttpNotFoundResult("No such node file");
}
var content = nodeFile.ReadAsString();
string filename = Path.GetFileName(fileName);
byte[] filedata = Encoding.UTF8.GetBytes(content);
var cd = new ContentDisposition
{
FileName = filename,
Inline = true,
};
Response.AppendHeader("Content-Disposition", cd.ToString());
return File(filedata, MediaTypeNames.Text.Plain, fileName);
}
}
}

Просмотреть файл

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.Azure.Batch;
namespace Microsoft.Azure.Blast.Web.Models
{
public class PoolDetailsModel
{
public CloudPool Pool { get; set; }
public List<ComputeNode> ComputeNodes { get; set; }
}
}

Просмотреть файл

@ -40,23 +40,25 @@
$(function () {
$('#pooltblbody').on('click', 'tr td a', function () {
if (confirm("Are you sure you want to delete the pool: " + $(this).attr('id') + "?")) {
$.ajax({
type: 'DELETE',
url: '/api/pools/' + $(this).attr('id'),
contentType: false,
processData: false,
success: function (response) {
window.location.href = "/Pool";
},
error: function (data) {
$('#btnCreatePool').removeClass("disabled");
console.log(data);
}
});
if ($(this).text() === 'Delete') {
if (confirm("Are you sure you want to delete the pool: " + $(this).attr('id') + "?")) {
$.ajax({
type: 'DELETE',
url: '/api/pools/' + $(this).attr('id'),
contentType: false,
processData: false,
success: function (response) {
window.location.href = "/Pool";
},
error: function (data) {
$('#btnCreatePool').removeClass("disabled");
console.log(data);
}
});
}
}
});
$.get('/api/pools', null, function(pools) {
$('progress').hide();
@ -68,7 +70,7 @@
var tr = "<tr>\
<td>\
" + pool.id + "\
<a href='/Pool/" + pool.id + "'>"+pool.id+"</a>\
</td>\
<td> \
" + displayName + "\
@ -88,9 +90,7 @@
<td> \
" + pool.targetDedicated + "\
</td>\
<td><a id=" + pool.id + " href=\"#\" role=\"button\" class=\"btn btn-danger btn-xs " + disabledClass + "\"> \
Delete\
</a></td>\
<td><a id=" + pool.id + " href=\"#\" role=\"button\" class=\"btn btn-danger btn-xs " + disabledClass + "\">Delete</a></td>\
</tr>;";
$('#pooltblbody').append(tr);

Просмотреть файл

@ -0,0 +1,109 @@
@model Microsoft.Azure.Blast.Web.Models.PoolDetailsModel
@{
ViewBag.Title = "Pool - " + @Model.Pool.Id;
}
<p>&nbsp;</p>
<ol class="breadcrumb">
<li><a href="/Pool">Pools</a></li>
<li class="active">@Model.Pool.Id</li>
</ol>
<div class="panel panel-default">
<div class="panel-heading clearfix">
<h3 class="panel-title pull-left" style="padding-top: 7.5px;">Pool '@Model.Pool.Id' Details</h3>
<div class="btn-group pull-right">
<a id="deleteBtn" href="#" class="btn btn-danger btn-sm">Delete</a>
</div>
</div>
<div class="panel-body">
<form class="form-horizontal">
<div class="form-group">
<label class="col-sm-2 control-label">Name</label>
<div class="col-sm-10">
<p class="form-control-static">@Model.Pool.Id</p>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">Display Name</label>
<div class="col-sm-10">
<p class="form-control-static">@Model.Pool.DisplayName</p>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">State</label>
<div class="col-sm-10">
<p class="form-control-static">@Model.Pool.State</p>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">Allocation State</label>
<div class="col-sm-10">
<p id="searchState" class="form-control-static">@Model.Pool.AllocationState</p>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">VM Size</label>
<div class="col-sm-10">
<p class="form-control-static">@Model.Pool.VirtualMachineSize</p>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">Current Node Count</label>
<div class="col-sm-10">
<p class="form-control-static">@Model.Pool.CurrentDedicated</p>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">Target Node Count</label>
<div class="col-sm-10">
<p class="form-control-static">@Model.Pool.TargetDedicated</p>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">Resize Errors?</label>
<div class="col-sm-10">
<p class="form-control-static">@(Model.Pool.ResizeError == null ? "" : string.Format("{0} - {1}", Model.Pool.ResizeError.Code, Model.Pool.ResizeError.Message))</p>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">Creation Time</label>
<div class="col-sm-10">
<p id="searchStartTime" class="form-control-static">@Model.Pool.CreationTime</p>
</div>
</div>
</form>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">Compute Nodes</div>
<table class="table" id="nodetbl">
<thead>
<tr>
<th>Id</th>
<th>State</th>
<th>Start Task State</th>
<th>Start Task Exit Code</th>
<th>Start Task Scheduling Errors</th>
<th>Start Task StdOut</th>
<th>Start Task StdErr</th>
</tr>
</thead>
<tbody id="resultTableBody">
@foreach (var computeNode in Model.ComputeNodes)
{
<tr>
<td>@computeNode.Id</td>
<td>@computeNode.State</td>
<td>@(computeNode.StartTaskInformation == null ? "" : computeNode.StartTaskInformation.State.ToString())</td>
<td>@(computeNode.StartTaskInformation == null || computeNode.StartTaskInformation.ExitCode == null ? "" : computeNode.StartTaskInformation.ExitCode.ToString())</td>
<td>@(computeNode.StartTaskInformation == null || computeNode.StartTaskInformation.SchedulingError == null ? "" : string.Format("Category: {0}Code: {1}Details: {2}", computeNode.StartTaskInformation.SchedulingError.Category, computeNode.StartTaskInformation.SchedulingError.Code, string.Join(",", computeNode.StartTaskInformation.SchedulingError.Details.Select(detail => detail.Name + ": " + detail.Value))))</td>
<td>@Html.ActionLink("stdout.txt", "DownloadStartTaskFile", "Pool", new { poolId = Model.Pool.Id, computeNodeId = computeNode.Id, fileName = "stdout", fileExtension = "txt" }, null)</td>
<td>@Html.ActionLink("stderr.txt", "DownloadStartTaskFile", "Pool", new { poolId = Model.Pool.Id, computeNodeId = computeNode.Id, fileName = "stderr" , fileExtension = "txt" }, null)</td>
</tr>
}
</tbody>
</table>
</div>