Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

System Batch UI, Client Status Bar Chart and Client Tab page view #11078

Merged
merged 66 commits into from
Oct 7, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
1f95a67
initial logic for computing client status bar
ChaiWithJai Aug 24, 2021
c4584e7
edit the schema of uniqueNodes returned by the controller
ChaiWithJai Aug 24, 2021
38f764f
refactoring job client status
lgfa29 Aug 24, 2021
29b107b
first implementation of job client status
lgfa29 Aug 24, 2021
051007d
small improvements to the jobClientStatus helper
lgfa29 Aug 26, 2021
42c6b91
display the right number in the client status bar
lgfa29 Aug 26, 2021
2c96d75
create client tab view
ChaiWithJai Aug 27, 2021
04e69f4
Merge remote-tracking branch 'origin/f-sysbatch-ui' into f-sysbatch-u…
lgfa29 Aug 27, 2021
3c50ac7
create sysbatch pages and components
lgfa29 Aug 27, 2021
91a17cb
add line break
lgfa29 Aug 27, 2021
aaac85a
Merge pull request #11094 from hashicorp/f-sysbatch-ui-luiz
ChaiWithJai Aug 30, 2021
6444f6a
filtering in client tab
ChaiWithJai Sep 1, 2021
c0171a4
svg link
ChaiWithJai Sep 2, 2021
d6dd911
refactor client-status-bar to append chart with links
ChaiWithJai Sep 7, 2021
2a2902d
unit test
ChaiWithJai Sep 8, 2021
d89d071
ui: policy system and sysbatch job details clients tab
lgfa29 Sep 10, 2021
ce3c517
client tab test
ChaiWithJai Sep 15, 2021
749828f
client tab test
ChaiWithJai Sep 15, 2021
7ad3e30
lint fixes
ChaiWithJai Sep 15, 2021
d4d6a8a
get all nodes if client tab is first page we land on
ChaiWithJai Sep 15, 2021
7a6db58
Merge branch 'f-sysbatch-ui' into f-sysbatch-ui-clients-tab
ChaiWithJai Sep 15, 2021
8f711a4
add whitespace
ChaiWithJai Sep 15, 2021
96a7e62
Merge pull request #11172 from hashicorp/f-sysbatch-ui-clients-tab
ChaiWithJai Sep 15, 2021
0453eaf
integration test for component
ChaiWithJai Sep 16, 2021
c57db19
acceptance tests for client tab
ChaiWithJai Sep 17, 2021
b727f37
ui: refactor job summary bar click
lgfa29 Sep 21, 2021
27d7a68
ui: set node watcher only if needed
lgfa29 Sep 21, 2021
9687a27
ui: rename some files and components
lgfa29 Sep 21, 2021
d5176f4
ui: only set pointer cursor if the slice has click event
lgfa29 Sep 21, 2021
7e7525f
ui: use existing style for empty job client status placeholder
lgfa29 Sep 21, 2021
00b53bb
ui: revert automatic changes to distribution-bar.hbs
lgfa29 Sep 21, 2021
d0f9108
ui: make job client status summary legend clickable
lgfa29 Sep 23, 2021
eb1bcb0
ui: small fixes
lgfa29 Sep 23, 2021
358a8a9
ui: add system and service jobs to sysbatchSmall mirage scenario
lgfa29 Sep 23, 2021
a7e3568
ui: lint
lgfa29 Sep 24, 2021
41e35bd
ui: rename job details client page node class filter for client class
lgfa29 Sep 24, 2021
081224e
ui: use links for short id in the job details client tab
lgfa29 Sep 24, 2021
6473b97
ui: fix sorting by id and name in the job details client tab
lgfa29 Sep 24, 2021
4ac392d
tmp
lgfa29 Sep 27, 2021
e331503
ui: fix pagination on job details client tab
lgfa29 Sep 28, 2021
619938f
ui: add TODO for job status client facet tests
lgfa29 Sep 28, 2021
5577d0d
ui: fix tests for job client status in job details page
lgfa29 Sep 29, 2021
c36396b
ui: fix linting
lgfa29 Sep 29, 2021
d19b8d7
ui: add help tooltip to summary bar legend
lgfa29 Sep 30, 2021
807a3eb
ui: add sysbatch as a job list filter option
lgfa29 Oct 4, 2021
f80d97f
ui: add parameterized and periodic sysbatch jobs to mirage
lgfa29 Oct 4, 2021
3f42a63
Merge remote-tracking branch 'origin/main' into f-sysbatch-ui
lgfa29 Oct 4, 2021
d5d069a
ui: fix merge
lgfa29 Oct 4, 2021
967c350
ui: force namespace query param in job details tabs
lgfa29 Oct 4, 2021
d6932bd
ui: filter out old allocations when computing job status in client
lgfa29 Oct 5, 2021
05e5f59
ui: remove some of the redundant help messages for job status in client
lgfa29 Oct 5, 2021
fa0d48a
ui: fix distribution bar click event listener
lgfa29 Oct 5, 2021
a8cd04a
edited dependent keys in job client status helper
ChaiWithJai Oct 5, 2021
6d7735d
Merge pull request #11266 from hashicorp/f-ui-node-watcher-bug
ChaiWithJai Oct 6, 2021
86a1e14
edit observable for node in job client status
ChaiWithJai Oct 6, 2021
91bb5b1
add conditional rendering logic for child jobs
ChaiWithJai Oct 6, 2021
15c9d82
Merge pull request #11275 from hashicorp/f-ui-client-update-bug
ChaiWithJai Oct 6, 2021
620b8d0
ui: fix job client status summary navigation for jobs with namespace
lgfa29 Oct 6, 2021
7ca852b
ui: add missing computed property dependency
lgfa29 Oct 6, 2021
452835d
refactor forceCollapsed logic to use hasClientStatus prop
ChaiWithJai Oct 6, 2021
7bb2478
Merge pull request #11281 from hashicorp/f-final-changes
ChaiWithJai Oct 6, 2021
309e599
ui: revert automated code formating
lgfa29 Oct 6, 2021
c38c0a5
ui: small fixes for job client status
lgfa29 Oct 7, 2021
dc22c75
ui: fix job-client-status bar tests
lgfa29 Oct 7, 2021
0dbf4a0
ui: fix child job client status slice click
lgfa29 Oct 7, 2021
8c8c3fd
ui: add job client status help message
lgfa29 Oct 7, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 80 additions & 0 deletions ui/app/components/client-status-bar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { computed } from '@ember/object';
import DistributionBar from './distribution-bar';
import classic from 'ember-classic-decorator';
import { countBy } from 'lodash';

@classic
export default class ClientStatusBar extends DistributionBar {
layoutName = 'components/distribution-bar';

'data-test-client-status-bar' = true;
allocationContainer = null;
nodes = null;
totalNodes = null;

@computed('nodes')
get data() {
const statuses = {
queued: 0,
'not scheduled': this.totalNodes - this.nodes.length,
starting: 0,
running: 0,
complete: 0,
degraded: 0,
failed: 0,
lost: 0,
};
for (const node of this.nodes) {
const concatenatedAllocationStatuses = [].concat(...Object.values(node));
console.log(concatenatedAllocationStatuses);
// there is a bug that counts nodes multiple times in this part of the loop
for (const status of concatenatedAllocationStatuses) {
const val = str => str;
const statusCount = countBy(concatenatedAllocationStatuses, val);
if (Object.keys(statusCount).length === 1) {
if (statusCount.running > 0) {
statuses.running++;
}
if (statusCount.failed > 0) {
statuses.failed++;
}
if (statusCount.lost > 0) {
statuses.lost++;
}
if (statusCount.complete > 0) {
statuses.complete++;
}
} else if (Object.keys(statusCount).length !== 1 && !!statusCount.running) {
if (!!statusCount.failed || !!statusCount.lost) {
statuses.degraded++;
}
} else if (Object.keys(statusCount).length !== 1 && !!statusCount.pending) {
statuses.starting++;
} else {
statuses.queued++;
}
}
}

console.log('statuses\n\n', statuses);
return [
{ label: 'Not Scheduled', value: statuses['not scheduled'], className: 'not-scheduled' },
{ label: 'Queued', value: statuses.queued, className: 'queued' },
{
label: 'Starting',
value: statuses.starting,
className: 'starting',
layers: 2,
},
{ label: 'Running', value: statuses.running, className: 'running' },
{
label: 'Complete',
value: statuses.complete,
className: 'complete',
},
{ label: 'Degraded', value: statuses.degraded, className: 'degraded' },
{ label: 'Failed', value: statuses.failed, className: 'failed' },
{ label: 'Lost', value: statuses.lost, className: 'lost' },
];
}
}
24 changes: 24 additions & 0 deletions ui/app/controllers/jobs/job/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { inject as service } from '@ember/service';
import { alias } from '@ember/object/computed';
import { computed } from '@ember/object';
import Controller from '@ember/controller';
import WithNamespaceResetting from 'nomad-ui/mixins/with-namespace-resetting';
import { action } from '@ember/object';
Expand All @@ -8,6 +9,29 @@ import classic from 'ember-classic-decorator';
@classic
export default class IndexController extends Controller.extend(WithNamespaceResetting) {
@service system;
@service store;

@computed('job')
get uniqueNodes() {
// add datacenter filter
const allocs = this.job.allocations;
const nodes = allocs.mapBy('node');
const uniqueNodes = nodes.uniqBy('id').toArray();
return uniqueNodes.map(nodeId => {
return {
[nodeId.get('id')]: allocs
.toArray()
.filter(alloc => nodeId.get('id') === alloc.get('node.id'))
.map(alloc => alloc.getProperties('clientStatus'))
.map(alloc => alloc.clientStatus),
};
});
}

@computed('node')
get totalNodes() {
return this.store.peekAll('node').toArray().length;
}

queryParams = [
{
Expand Down
9 changes: 9 additions & 0 deletions ui/app/routes/jobs/job/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ import { watchRecord, watchRelationship, watchAll } from 'nomad-ui/utils/propert
import WithWatchers from 'nomad-ui/mixins/with-watchers';

export default class IndexRoute extends Route.extend(WithWatchers) {
async model() {
// Optimizing future node look ups by preemptively loading everything
await this.store.findAll('node');
return this.modelFor('jobs.job');
}

startWatchers(controller, model) {
if (!model) {
return;
Expand All @@ -16,6 +22,7 @@ export default class IndexRoute extends Route.extend(WithWatchers) {
latestDeployment:
model.get('supportsDeployments') && this.watchLatestDeployment.perform(model),
list: model.get('hasChildren') && this.watchAll.perform(),
nodes: /*model.type === 'sysbatch' && */ this.watchNodes.perform(),
});
}

Expand All @@ -33,6 +40,7 @@ export default class IndexRoute extends Route.extend(WithWatchers) {

@watchRecord('job') watch;
@watchAll('job') watchAll;
@watchAll('node') watchNodes;
@watchRecord('job-summary') watchSummary;
@watchRelationship('allocations') watchAllocations;
@watchRelationship('evaluations') watchEvaluations;
Expand All @@ -41,6 +49,7 @@ export default class IndexRoute extends Route.extend(WithWatchers) {
@collect(
'watch',
'watchAll',
'watchNodes',
'watchSummary',
'watchAllocations',
'watchEvaluations',
Expand Down
18 changes: 18 additions & 0 deletions ui/app/styles/charts/colors.scss
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ $running: $primary;
$complete: $nomad-green-dark;
$failed: $danger;
$lost: $dark;
$not-scheduled: $grey-darker;
$degraded: $warning;

.chart {
.queued {
Expand Down Expand Up @@ -37,6 +39,14 @@ $lost: $dark;
.lost {
fill: $lost;
}

.not-scheduled {
fill: $not-scheduled;
}

.degraded {
fill: $degraded;
}
}

.color-swatch {
Expand Down Expand Up @@ -102,6 +112,14 @@ $lost: $dark;
background: $lost;
}

&.not-scheduled {
fill: $not-scheduled;
}

&.degraded {
fill: $degraded;
}

@each $name, $pair in $colors {
$color: nth($pair, 1);

Expand Down
58 changes: 58 additions & 0 deletions ui/app/templates/components/job-page/parts/summary.hbs
Original file line number Diff line number Diff line change
@@ -1,4 +1,62 @@
<ListAccordion data-test-job-summary @source={{array this.job}} @key="id" @startExpanded={{this.isExpanded}} @onToggle={{action this.persist}} as |a|>
<a.head @buttonLabel={{if a.isOpen "collapse" "expand"}}>
<div class="columns">
<div class="column is-minimum nowrap">
{{#if a.item.hasChildren}}
Children Status
<span class="badge {{if a.isOpen "is-white" "is-light"}}">
{{a.item.summary.totalChildren}}
</span>
{{else}}
Client Status
<span class="badge {{if a.isOpen "is-white" "is-light"}}">
{{a.item.summary.totalAllocs}}
</span>
{{/if}}
</div>

{{#unless a.isOpen}}
<div class="column">
<div class="inline-chart bumper-left">
{{#if a.item.hasChildren}}
{{#if (gt a.item.totalChildren 0)}}
<ChildrenStatusBar @job={{a.item}} @isNarrow={{true}} />
{{else}}
<em class="is-faded">No Children</em>
{{/if}}
{{else}}
<ClientStatusBar @nodes={{this.nodes}} @allocationContainer={{a.item}} @isNarrow={{true}} />
{{/if}}
</div>
</div>
{{/unless}}
</div>
</a.head>
<a.body>
{{#component (if a.item.hasChildren "children-status-bar" "client-status-bar")
allocationContainer=a.item.summary
job=a.item.summary
nodes=this.nodes
totalNodes=this.totalNodes
class="split-view" as |chart|}}
<ol data-test-legend class="legend">
{{#each chart.data as |datum index|}}
<li class="{{datum.className}} {{if (eq datum.label chart.activeDatum.label) "is-active"}} {{if (eq datum.value 0) "is-empty"}}">
<span class="color-swatch {{if datum.className datum.className (concat "swatch-" index)}}" />
<span class="value" data-test-legend-value="{{datum.className}}">{{datum.value}}</span>
<span class="label">
{{datum.label}}
</span>
</li>
{{/each}}
</ol>
{{/component}}
</a.body>
</ListAccordion>

<br/>

<ListAccordion data-test-job-summary @source={{array this.job}} @key="id" @startExpanded={{false}} @onToggle={{action this.persist}} as |a|>
<a.head @buttonLabel={{if a.isOpen "collapse" "expand"}}>
<div class="columns">
<div class="column is-minimum nowrap">
Expand Down
2 changes: 1 addition & 1 deletion ui/app/templates/components/job-page/service.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
{{/each}}
{{/if}}

<JobPage::Parts::Summary @job={{this.job}} />
<JobPage::Parts::Summary @job={{this.job}} @totalNodes={{this.totalNodes}} @nodes={{this.nodes}} />

<JobPage::Parts::PlacementFailures @job={{this.job}} />

Expand Down
2 changes: 1 addition & 1 deletion ui/app/templates/components/job-page/system.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
{{/each}}
{{/if}}

<JobPage::Parts::Summary @job={{this.job}} />
<JobPage::Parts::Summary @job={{this.job}} @nodes={{this.nodes}} />

<JobPage::Parts::PlacementFailures @job={{this.job}} />

Expand Down
2 changes: 2 additions & 0 deletions ui/app/templates/jobs/job/index.hbs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
{{page-title "Job " this.model.name}}
{{component (concat "job-page/" this.model.templateType)
job=this.model
nodes=this.uniqueNodes
totalNodes=this.totalNodes
sortProperty=this.sortProperty
sortDescending=this.sortDescending
currentPage=this.currentPage
Expand Down