зеркало из 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>
|
||||||
<Compile Include="Models\NewPoolModel.cs" />
|
<Compile Include="Models\NewPoolModel.cs" />
|
||||||
<Compile Include="Models\NewSearchModel.cs" />
|
<Compile Include="Models\NewSearchModel.cs" />
|
||||||
|
<Compile Include="Models\PoolDetailsModel.cs" />
|
||||||
<Compile Include="Models\PoolSpec.cs" />
|
<Compile Include="Models\PoolSpec.cs" />
|
||||||
<Compile Include="Models\RespositoryViewModel.cs" />
|
<Compile Include="Models\RespositoryViewModel.cs" />
|
||||||
<Compile Include="Models\VisualizeResultsModel.cs" />
|
<Compile Include="Models\VisualizeResultsModel.cs" />
|
||||||
|
@ -423,6 +424,7 @@
|
||||||
<Content Include="Scripts\jquery-2.1.3.min.map" />
|
<Content Include="Scripts\jquery-2.1.3.min.map" />
|
||||||
<Content Include="Views\Repositories\Index.cshtml" />
|
<Content Include="Views\Repositories\Index.cshtml" />
|
||||||
<Content Include="Views\Databases\Index.cshtml" />
|
<Content Include="Views\Databases\Index.cshtml" />
|
||||||
|
<Content Include="Views\Pool\Show.cshtml" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\AzureBlast\AzureBlast.csproj">
|
<ProjectReference Include="..\AzureBlast\AzureBlast.csproj">
|
||||||
|
|
|
@ -1,7 +1,13 @@
|
||||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
// Licensed under the MIT License. See License.txt in the project root for license information.
|
// 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 System.Web.Mvc;
|
||||||
|
using Microsoft.Azure.Batch;
|
||||||
using Microsoft.Azure.Batch.Blast.Configuration;
|
using Microsoft.Azure.Batch.Blast.Configuration;
|
||||||
using Microsoft.Azure.Blast.Web.Models;
|
using Microsoft.Azure.Blast.Web.Models;
|
||||||
|
|
||||||
|
@ -10,10 +16,12 @@ namespace Microsoft.Azure.Blast.Web.Controllers
|
||||||
public class PoolController : AuthorizedController
|
public class PoolController : AuthorizedController
|
||||||
{
|
{
|
||||||
private readonly BlastConfiguration _configuration;
|
private readonly BlastConfiguration _configuration;
|
||||||
|
private readonly BatchClient _batchClient;
|
||||||
|
|
||||||
public PoolController(BlastConfiguration configuration)
|
public PoolController(BlastConfiguration configuration)
|
||||||
{
|
{
|
||||||
_configuration = configuration;
|
_configuration = configuration;
|
||||||
|
_batchClient = configuration.BatchClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ActionResult Index()
|
public ActionResult Index()
|
||||||
|
@ -29,5 +37,67 @@ namespace Microsoft.Azure.Blast.Web.Controllers
|
||||||
};
|
};
|
||||||
return View(model);
|
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 () {
|
$(function () {
|
||||||
|
|
||||||
$('#pooltblbody').on('click', 'tr td a', function () {
|
$('#pooltblbody').on('click', 'tr td a', function () {
|
||||||
if (confirm("Are you sure you want to delete the pool: " + $(this).attr('id') + "?")) {
|
if ($(this).text() === 'Delete') {
|
||||||
$.ajax({
|
if (confirm("Are you sure you want to delete the pool: " + $(this).attr('id') + "?")) {
|
||||||
type: 'DELETE',
|
$.ajax({
|
||||||
url: '/api/pools/' + $(this).attr('id'),
|
type: 'DELETE',
|
||||||
contentType: false,
|
url: '/api/pools/' + $(this).attr('id'),
|
||||||
processData: false,
|
contentType: false,
|
||||||
success: function (response) {
|
processData: false,
|
||||||
window.location.href = "/Pool";
|
success: function (response) {
|
||||||
},
|
window.location.href = "/Pool";
|
||||||
error: function (data) {
|
},
|
||||||
$('#btnCreatePool').removeClass("disabled");
|
error: function (data) {
|
||||||
console.log(data);
|
$('#btnCreatePool').removeClass("disabled");
|
||||||
}
|
console.log(data);
|
||||||
});
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$.get('/api/pools', null, function(pools) {
|
$.get('/api/pools', null, function(pools) {
|
||||||
$('progress').hide();
|
$('progress').hide();
|
||||||
|
|
||||||
|
@ -68,7 +70,7 @@
|
||||||
|
|
||||||
var tr = "<tr>\
|
var tr = "<tr>\
|
||||||
<td>\
|
<td>\
|
||||||
" + pool.id + "\
|
<a href='/Pool/" + pool.id + "'>"+pool.id+"</a>\
|
||||||
</td>\
|
</td>\
|
||||||
<td> \
|
<td> \
|
||||||
" + displayName + "\
|
" + displayName + "\
|
||||||
|
@ -88,9 +90,7 @@
|
||||||
<td> \
|
<td> \
|
||||||
" + pool.targetDedicated + "\
|
" + pool.targetDedicated + "\
|
||||||
</td>\
|
</td>\
|
||||||
<td><a id=" + pool.id + " href=\"#\" role=\"button\" class=\"btn btn-danger btn-xs " + disabledClass + "\"> \
|
<td><a id=" + pool.id + " href=\"#\" role=\"button\" class=\"btn btn-danger btn-xs " + disabledClass + "\">Delete</a></td>\
|
||||||
Delete\
|
|
||||||
</a></td>\
|
|
||||||
</tr>;";
|
</tr>;";
|
||||||
|
|
||||||
$('#pooltblbody').append(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>
|
Загрузка…
Ссылка в новой задаче