зеркало из https://github.com/Azure/azure-hpc.git
New pool details and compute node view
This commit is contained in:
Родитель
4ad40b67c6
Коммит
759efd4514
|
@ -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,6 +40,7 @@
|
|||
$(function () {
|
||||
|
||||
$('#pooltblbody').on('click', 'tr td a', function () {
|
||||
if ($(this).text() === 'Delete') {
|
||||
if (confirm("Are you sure you want to delete the pool: " + $(this).attr('id') + "?")) {
|
||||
$.ajax({
|
||||
type: 'DELETE',
|
||||
|
@ -55,6 +56,7 @@
|
|||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$.get('/api/pools', null, function(pools) {
|
||||
|
@ -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> </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>
|
Загрузка…
Ссылка в новой задаче