mirror of
https://github.com/kemko/nomad.git
synced 2026-01-08 19:35:41 +03:00
Add cluster details to the topology page
This commit is contained in:
@@ -42,9 +42,11 @@ export default class TopoViz extends Component {
|
||||
if (this.activeTaskGroup === taskGroup && this.activeJobId === jobId) {
|
||||
this.activeTaskGroup = null;
|
||||
this.activeJobId = null;
|
||||
if (this.args.onAllocationSelect) this.args.onAllocationSelect(null);
|
||||
} else {
|
||||
this.activeTaskGroup = taskGroup;
|
||||
this.activeJobId = jobId;
|
||||
if (this.args.onAllocationSelect) this.args.onAllocationSelect(allocation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
57
ui/app/controllers/topology.js
Normal file
57
ui/app/controllers/topology.js
Normal file
@@ -0,0 +1,57 @@
|
||||
import Controller from '@ember/controller';
|
||||
import { computed } from '@ember/object';
|
||||
import classic from 'ember-classic-decorator';
|
||||
import { reduceToLargestUnit } from 'nomad-ui/helpers/format-bytes';
|
||||
|
||||
@classic
|
||||
export default class TopologyControllers extends Controller {
|
||||
get datacenters() {
|
||||
return Array.from(new Set(this.model.nodes.mapBy('datacenter'))).compact();
|
||||
}
|
||||
|
||||
@computed('model.nodes.@each.resources')
|
||||
get totalMemory() {
|
||||
const mibs = this.model.nodes
|
||||
.mapBy('resources.memory')
|
||||
.reduce((sum, memory) => sum + (memory || 0), 0);
|
||||
return mibs * 1024 * 1024;
|
||||
}
|
||||
|
||||
@computed('model.nodes.@each.resources')
|
||||
get totalCPU() {
|
||||
return this.model.nodes.mapBy('resources.cpu').reduce((sum, cpu) => sum + (cpu || 0), 0);
|
||||
}
|
||||
|
||||
@computed('totalMemory')
|
||||
get totalMemoryFormatted() {
|
||||
return reduceToLargestUnit(this.totalMemory)[0].toFixed(2);
|
||||
}
|
||||
|
||||
@computed('totalCPU')
|
||||
get totalMemoryUnits() {
|
||||
return reduceToLargestUnit(this.totalMemory)[1];
|
||||
}
|
||||
|
||||
@computed('model.allocations.@each.resources')
|
||||
get totalReservedMemory() {
|
||||
const mibs = this.model.allocations
|
||||
.mapBy('resources.memory')
|
||||
.reduce((sum, memory) => sum + (memory || 0), 0);
|
||||
return mibs * 1024 * 1024;
|
||||
}
|
||||
|
||||
@computed('model.allocations.@each.resources')
|
||||
get totalReservedCPU() {
|
||||
return this.model.allocations.mapBy('resources.cpu').reduce((sum, cpu) => sum + (cpu || 0), 0);
|
||||
}
|
||||
|
||||
@computed('totalMemory', 'totalReservedMemory')
|
||||
get reservedMemoryPercent() {
|
||||
return this.totalReservedMemory / this.totalMemory;
|
||||
}
|
||||
|
||||
@computed('totalCPU', 'totalReservedCPU')
|
||||
get reservedCPUPercent() {
|
||||
return this.totalReservedCPU / this.totalCPU;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import Helper from '@ember/component/helper';
|
||||
|
||||
const UNITS = ['Bytes', 'KiB', 'MiB'];
|
||||
const UNITS = ['Bytes', 'KiB', 'MiB', 'GiB'];
|
||||
|
||||
/**
|
||||
* Bytes Formatter
|
||||
@@ -10,7 +10,7 @@ const UNITS = ['Bytes', 'KiB', 'MiB'];
|
||||
* Outputs the bytes reduced to the largest supported unit size for which
|
||||
* bytes is larger than one.
|
||||
*/
|
||||
export function formatBytes([bytes]) {
|
||||
export function reduceToLargestUnit(bytes) {
|
||||
bytes || (bytes = 0);
|
||||
let unitIndex = 0;
|
||||
while (bytes >= 1024 && unitIndex < UNITS.length - 1) {
|
||||
@@ -18,7 +18,12 @@ export function formatBytes([bytes]) {
|
||||
unitIndex++;
|
||||
}
|
||||
|
||||
return `${Math.floor(bytes)} ${UNITS[unitIndex]}`;
|
||||
return [bytes, UNITS[unitIndex]];
|
||||
}
|
||||
|
||||
export function formatBytes([bytes]) {
|
||||
const [number, unit] = reduceToLargestUnit(bytes);
|
||||
return `${Math.floor(number)} ${unit}`;
|
||||
}
|
||||
|
||||
export default Helper.helper(formatBytes);
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
@import './components/codemirror';
|
||||
@import './components/copy-button';
|
||||
@import './components/cli-window';
|
||||
@import './components/dashboard-metric';
|
||||
@import './components/dropdown';
|
||||
@import './components/ember-power-select';
|
||||
@import './components/empty-message';
|
||||
|
||||
31
ui/app/styles/components/dashboard-metric.scss
Normal file
31
ui/app/styles/components/dashboard-metric.scss
Normal file
@@ -0,0 +1,31 @@
|
||||
.dashboard-metric {
|
||||
margin-top: 1.5em;
|
||||
|
||||
.metric {
|
||||
text-align: left;
|
||||
font-weight: $weight-bold;
|
||||
font-size: $size-3;
|
||||
|
||||
.metric-units {
|
||||
font-size: $size-4;
|
||||
}
|
||||
|
||||
.metric-label {
|
||||
font-size: $body-size;
|
||||
font-weight: $weight-normal;
|
||||
}
|
||||
}
|
||||
|
||||
.graphic {
|
||||
padding-bottom: 0;
|
||||
margin-bottom: 0;
|
||||
|
||||
> .column {
|
||||
padding: 0.5rem 0.75rem;
|
||||
}
|
||||
}
|
||||
|
||||
.annotation {
|
||||
margin-top: -0.75rem;
|
||||
}
|
||||
}
|
||||
@@ -24,14 +24,74 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="boxed-section">
|
||||
<div class="boxed-section-head">Cluster Details</div>
|
||||
<div class="boxed-section-head">{{if this.activeAllocation "Allocation" "Cluster"}} Details</div>
|
||||
<div class="boxed-section-body">
|
||||
Aggregate metrics go here.
|
||||
{{#if this.activeAllocation}}
|
||||
Showing alloc details for {{this.activeAllocation.shortId}}
|
||||
{{else}}
|
||||
<div class="metric-group columns is-centered">
|
||||
<div class="metric">
|
||||
<h3 class="label">DCs</h3>
|
||||
<p class="value">{{this.datacenters.length}}</p>
|
||||
</div>
|
||||
<div class="metric">
|
||||
<h3 class="label">Clients</h3>
|
||||
<p class="value">{{this.model.nodes.length}}</p>
|
||||
</div>
|
||||
<div class="metric">
|
||||
<h3 class="label">Allocations</h3>
|
||||
{{! TODO: make sure that this is only the scheduled allocations }}
|
||||
<p class="value">{{this.model.allocations.length}}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dashboard-metric">
|
||||
<p class="metric">{{this.totalMemoryFormatted}} <span class="metric-units">{{this.totalMemoryUnits}}</span> <span class="metric-label">of memory</span></p>
|
||||
<div class="columns graphic">
|
||||
<div class="column">
|
||||
<div class="inline-chart" data-test-percentage-bar>
|
||||
<progress
|
||||
class="progress is-danger is-small"
|
||||
value="{{this.reservedMemoryPercent}}"
|
||||
max="1">
|
||||
{{this.reservedMemoryPercent}}
|
||||
</progress>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column is-minimum">
|
||||
<span class="nowrap" data-test-percentage>{{format-percentage this.reservedMemoryPercent total=1}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="annotation" data-test-absolute-value>
|
||||
<strong>{{format-bytes this.totalReservedMemory}}</strong> / {{format-bytes this.totalMemory}} reserved
|
||||
</div>
|
||||
</div>
|
||||
<div class="dashboard-metric">
|
||||
<p class="metric">{{this.totalCPU}} <span class="metric-units">Mhz</span> <span class="metric-label">of CPU</span></p>
|
||||
<div class="columns graphic">
|
||||
<div class="column">
|
||||
<div class="inline-chart" data-test-percentage-bar>
|
||||
<progress
|
||||
class="progress is-info is-small"
|
||||
value="{{this.reservedCPUPercent}}"
|
||||
max="1">
|
||||
{{this.reservedCPUPercent}}
|
||||
</progress>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column is-minimum">
|
||||
<span class="nowrap" data-test-percentage>{{format-percentage this.reservedCPUPercent total=1}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="annotation" data-test-absolute-value>
|
||||
<strong>{{this.totalReservedCPU}} Mhz</strong> / {{this.totalCPU}} Mhz reserved
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column">
|
||||
<TopoViz @nodes={{this.model.nodes}} @allocations={{this.model.allocations}} />
|
||||
<TopoViz @nodes={{this.model.nodes}} @allocations={{this.model.allocations}} @onAllocationSelect={{action (mut this.activeAllocation)}} />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -17,7 +17,7 @@ export function topoSmall(server) {
|
||||
});
|
||||
|
||||
const jobResources = [
|
||||
['M: 256, C: 150'],
|
||||
['M: 2560, C: 150'],
|
||||
['M: 128, C: 400'],
|
||||
['M: 512, C: 100'],
|
||||
['M: 256, C: 150'],
|
||||
|
||||
Reference in New Issue
Block a user