31ab7964bd
Now that tasks that have finished running can be restarted, the UI needs to use the actual task state to determine which CSS class to use when rendering the task lifecycle chart element.
486 lines
14 KiB
Handlebars
486 lines
14 KiB
Handlebars
{{page-title "Allocation " this.model.name}}
|
|
<AllocationSubnav @allocation={{this.model}} />
|
|
<section class="section">
|
|
{{#if this.error}}
|
|
<div data-test-inline-error class="notification is-danger">
|
|
<div class="columns">
|
|
<div class="column">
|
|
<h3 data-test-inline-error-title class="title is-4">
|
|
{{this.error.title}}
|
|
</h3>
|
|
<p data-test-inline-error-body>
|
|
{{this.error.description}}
|
|
</p>
|
|
</div>
|
|
<div class="column is-centered is-minimum">
|
|
<button
|
|
data-test-inline-error-close
|
|
class="button is-danger"
|
|
onclick={{action this.onDismiss}}
|
|
type="button"
|
|
>
|
|
Okay
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{{/if}}
|
|
<h1 data-test-title class="title with-headroom with-flex">
|
|
<div>
|
|
Allocation
|
|
{{this.model.name}}
|
|
<span class="bumper-left tag {{this.model.statusClass}}">
|
|
{{this.model.clientStatus}}
|
|
</span>
|
|
</div>
|
|
<div>
|
|
{{#if this.model.isRunning}}
|
|
<div class="two-step-button">
|
|
<Exec::OpenButton
|
|
@job={{this.model.job}}
|
|
@allocation={{this.model}}
|
|
/>
|
|
</div>
|
|
<TwoStepButton
|
|
data-test-stop
|
|
@alignRight={{true}}
|
|
@idleText="Stop Alloc"
|
|
@cancelText="Cancel Stop"
|
|
@confirmText="Yes, Stop Alloc"
|
|
@confirmationMessage="Are you sure? This will reschedule the allocation on a different client."
|
|
@awaitingConfirmation={{this.stopAllocation.isRunning}}
|
|
@disabled={{or
|
|
this.stopAllocation.isRunning
|
|
this.restartAllocation.isRunning
|
|
}}
|
|
@onConfirm={{perform this.stopAllocation}}
|
|
/>
|
|
<TwoStepButton
|
|
data-test-restart
|
|
@alignRight={{true}}
|
|
@idleText="Restart Alloc"
|
|
@cancelText="Cancel Restart"
|
|
@confirmText="Yes, Restart Alloc"
|
|
@confirmationMessage="Are you sure? This will restart the tasks that are currently running in-place."
|
|
@awaitingConfirmation={{this.restartAllocation.isRunning}}
|
|
@disabled={{or
|
|
this.stopAllocation.isRunning
|
|
this.restartAllocation.isRunning
|
|
}}
|
|
@onConfirm={{perform this.restartAllocation}}
|
|
/>
|
|
<TwoStepButton
|
|
data-test-restart-all
|
|
@alignRight={{true}}
|
|
@idleText="Restart All Tasks"
|
|
@cancelText="Cancel Restart"
|
|
@confirmText="Yes, Restart All Tasks"
|
|
@confirmationMessage="Are you sure? This will restart all tasks in-place."
|
|
@awaitingConfirmation={{this.restartAllocation.isRunning}}
|
|
@disabled={{or
|
|
this.stopAllocation.isRunning
|
|
this.restartAllocation.isRunning
|
|
}}
|
|
@onConfirm={{perform this.restartAll}}
|
|
/>
|
|
{{/if}}
|
|
</div>
|
|
</h1>
|
|
<span class="tag is-hollow is-small is-alone no-text-transform">
|
|
{{this.model.id}}
|
|
<CopyButton @clipboardText={{this.model.id}} />
|
|
</span>
|
|
<div class="boxed-section is-small">
|
|
<div
|
|
data-test-allocation-details
|
|
class="boxed-section-body inline-definitions"
|
|
>
|
|
<span class="label">
|
|
Allocation Details
|
|
</span>
|
|
<span class="pair job-link">
|
|
<span class="term">
|
|
Job
|
|
</span>
|
|
<LinkTo
|
|
@route="jobs.job"
|
|
@model={{format-job-id this.model.job.id}}
|
|
data-test-job-link
|
|
>
|
|
{{this.model.job.name}}
|
|
</LinkTo>
|
|
</span>
|
|
<span class="pair node-link">
|
|
<span class="term">
|
|
Client
|
|
</span>
|
|
<LinkTo
|
|
@route="clients.client"
|
|
@model={{this.model.node}}
|
|
data-test-client-link
|
|
>
|
|
{{this.model.node.shortId}}
|
|
</LinkTo>
|
|
</span>
|
|
</div>
|
|
</div>
|
|
<div class="boxed-section">
|
|
<div class="boxed-section-head is-hollow">
|
|
Resource Utilization
|
|
</div>
|
|
<div class="boxed-section-body">
|
|
{{#if this.model.isRunning}}
|
|
<div class="columns">
|
|
<div class="column">
|
|
<PrimaryMetric::Allocation
|
|
@allocation={{this.model}}
|
|
@metric="cpu"
|
|
/>
|
|
</div>
|
|
<div class="column">
|
|
<PrimaryMetric::Allocation
|
|
@allocation={{this.model}}
|
|
@metric="memory"
|
|
/>
|
|
</div>
|
|
</div>
|
|
{{else}}
|
|
<div data-test-resource-error class="empty-message">
|
|
<h3 data-test-resource-error-headline class="empty-message-headline">
|
|
Allocation isn't running
|
|
</h3>
|
|
<p class="empty-message-body">
|
|
Only running allocations utilize
|
|
resources.
|
|
</p>
|
|
</div>
|
|
{{/if}}
|
|
</div>
|
|
</div>
|
|
<LifecycleChart @taskStates={{this.model.states}} />
|
|
<div class="boxed-section">
|
|
<div class="boxed-section-head">
|
|
Tasks
|
|
</div>
|
|
<div
|
|
class="boxed-section-body {{if this.sortedStates.length "is-full-bleed"}}"
|
|
>
|
|
{{#if this.sortedStates.length}}
|
|
<ListTable
|
|
@source={{this.sortedStates}}
|
|
@sortProperty={{this.sortProperty}}
|
|
@sortDescending={{this.sortDescending}}
|
|
@class="is-striped" as |t|
|
|
>
|
|
<t.head>
|
|
<th class="is-narrow"></th>
|
|
<t.sort-by @prop="name">
|
|
Name
|
|
</t.sort-by>
|
|
<t.sort-by @prop="state">
|
|
State
|
|
</t.sort-by>
|
|
<th>
|
|
Last Event
|
|
</th>
|
|
<t.sort-by @prop="events.lastObject.time">
|
|
Time
|
|
</t.sort-by>
|
|
<th>
|
|
Volumes
|
|
</th>
|
|
<th>
|
|
CPU
|
|
</th>
|
|
<th>
|
|
Memory
|
|
</th>
|
|
</t.head>
|
|
<t.body as |row|>
|
|
<TaskRow
|
|
{{keyboard-shortcut
|
|
enumerated=true
|
|
action=(action "taskClick" row.model.allocation row.model)
|
|
}}
|
|
@data-test-task-row={{row.model.name}}
|
|
@task={{row.model}}
|
|
@onClick={{action "taskClick" row.model.allocation row.model}}
|
|
/>
|
|
</t.body>
|
|
</ListTable>
|
|
{{else}}
|
|
<div data-test-empty-tasks-list class="empty-message">
|
|
<h3
|
|
data-test-empty-tasks-list-headline
|
|
class="empty-message-headline"
|
|
>
|
|
No Tasks
|
|
</h3>
|
|
<p data-test-empty-tasks-list-body class="empty-message-body">
|
|
Allocations will not have tasks until they are in a running state.
|
|
</p>
|
|
</div>
|
|
{{/if}}
|
|
</div>
|
|
</div>
|
|
{{#if this.ports.length}}
|
|
<div class="boxed-section" data-test-allocation-ports>
|
|
<div class="boxed-section-head">
|
|
Ports
|
|
</div>
|
|
<div class="boxed-section-body is-full-bleed">
|
|
<ListTable @source={{this.ports}} as |t|>
|
|
<t.head>
|
|
<th>
|
|
Name
|
|
</th>
|
|
<th>
|
|
Host Address
|
|
</th>
|
|
<th>
|
|
Mapped Port
|
|
</th>
|
|
</t.head>
|
|
<t.body as |row|>
|
|
<tr data-test-allocation-port>
|
|
<td data-test-allocation-port-name>
|
|
{{row.model.label}}
|
|
</td>
|
|
<td data-test-allocation-port-address>
|
|
<a
|
|
href="http://{{row.model.hostIp}}:{{row.model.value}}"
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
>
|
|
{{row.model.hostIp}}:{{row.model.value}}
|
|
</a>
|
|
</td>
|
|
<td data-test-allocation-port-to>
|
|
{{row.model.to}}
|
|
</td>
|
|
</tr>
|
|
</t.body>
|
|
</ListTable>
|
|
</div>
|
|
</div>
|
|
{{/if}}
|
|
{{#if this.services.length}}
|
|
<div class="boxed-section">
|
|
<div class="boxed-section-head">
|
|
Services
|
|
</div>
|
|
<div class="boxed-section-body is-full-bleed">
|
|
<ListTable @source={{this.services}} as |t|>
|
|
<t.head>
|
|
<th class="is-2">
|
|
Name
|
|
</th>
|
|
<th class="is-1">
|
|
Port
|
|
</th>
|
|
<td>
|
|
Tags
|
|
</td>
|
|
<td>
|
|
On Update
|
|
</td>
|
|
<td>
|
|
Connect?
|
|
</td>
|
|
<td>
|
|
Upstreams
|
|
</td>
|
|
</t.head>
|
|
<t.body as |row|>
|
|
<tr data-test-service>
|
|
<td data-test-service-name>
|
|
{{row.model.name}}
|
|
</td>
|
|
<td data-test-service-port>
|
|
{{row.model.portLabel}}
|
|
</td>
|
|
<td data-test-service-tags class="is-long-text">
|
|
{{join ", " row.model.tags}}
|
|
</td>
|
|
<td data-test-service-onupdate>
|
|
{{row.model.onUpdate}}
|
|
</td>
|
|
<td data-test-service-connect>
|
|
{{if row.model.connect "Yes" "No"}}
|
|
</td>
|
|
<td data-test-service-upstreams>
|
|
{{#each
|
|
row.model.connect.sidecarService.proxy.upstreams as |upstream|
|
|
}}
|
|
{{upstream.destinationName}}:{{upstream.localBindPort}}
|
|
{{/each}}
|
|
</td>
|
|
</tr>
|
|
</t.body>
|
|
</ListTable>
|
|
</div>
|
|
</div>
|
|
{{/if}}
|
|
{{#if this.model.hasRescheduleEvents}}
|
|
<div class="boxed-section" data-test-reschedule-events>
|
|
<div class="boxed-section-head is-hollow">
|
|
Reschedule Events
|
|
</div>
|
|
<div class="boxed-section-body">
|
|
<RescheduleEventTimeline @allocation={{this.model}} />
|
|
</div>
|
|
</div>
|
|
{{/if}}
|
|
{{#if this.model.wasPreempted}}
|
|
<div class="boxed-section is-warning" data-test-was-preempted>
|
|
<div class="boxed-section-head">
|
|
Preempted By
|
|
</div>
|
|
<div class="boxed-section-body">
|
|
{{#if this.preempter}}
|
|
<div class="boxed-section is-small">
|
|
<div class="boxed-section-body inline-definitions">
|
|
<span class="pair">
|
|
<span
|
|
data-test-allocation-status
|
|
class="tag {{this.preempter.statusClass}}"
|
|
>
|
|
{{this.preempter.clientStatus}}
|
|
</span>
|
|
</span>
|
|
<span class="pair">
|
|
<span class="term" data-test-allocation-name>
|
|
{{this.preempter.name}}
|
|
</span>
|
|
<LinkTo
|
|
@route="allocations.allocation"
|
|
@model={{this.preempter}}
|
|
data-test-allocation-id
|
|
>
|
|
{{this.preempter.shortId}}
|
|
</LinkTo>
|
|
</span>
|
|
<span class="pair job-link">
|
|
<span class="term">
|
|
Job
|
|
</span>
|
|
<LinkTo
|
|
@route="jobs.job"
|
|
@model={{this.preempter.job}}
|
|
data-test-job-link
|
|
>
|
|
{{this.preempter.job.name}}
|
|
</LinkTo>
|
|
</span>
|
|
<span class="pair job-priority">
|
|
<span class="term">
|
|
Priority
|
|
</span>
|
|
<span data-test-job-priority>
|
|
{{this.preempter.job.priority}}
|
|
</span>
|
|
</span>
|
|
<span class="pair node-link">
|
|
<span class="term">
|
|
Client
|
|
</span>
|
|
<LinkTo
|
|
@route="clients.client"
|
|
@model={{this.preempter.node}}
|
|
data-test-client-link
|
|
>
|
|
{{this.preempter.node.shortId}}
|
|
</LinkTo>
|
|
</span>
|
|
<span class="pair">
|
|
<span class="term">
|
|
Reserved CPU
|
|
</span>
|
|
<span data-test-allocation-cpu>
|
|
{{format-scheduled-hertz this.preempter.resources.cpu}}
|
|
</span>
|
|
</span>
|
|
<span class="pair">
|
|
<span class="term">
|
|
Reserved Memory
|
|
</span>
|
|
<span data-test-allocation-memory>
|
|
{{format-scheduled-bytes
|
|
this.preempter.resources.memory
|
|
start="MiB"
|
|
}}
|
|
</span>
|
|
</span>
|
|
</div>
|
|
</div>
|
|
{{else}}
|
|
<div class="empty-message">
|
|
<h3 class="empty-message-headline">
|
|
Allocation is gone
|
|
</h3>
|
|
<p class="empty-message-body">
|
|
This allocation has been stopped and
|
|
garbage collected.
|
|
</p>
|
|
</div>
|
|
{{/if}}
|
|
</div>
|
|
</div>
|
|
{{/if}}
|
|
{{#if
|
|
(and
|
|
this.model.preemptedAllocations.isFulfilled
|
|
this.model.preemptedAllocations.length
|
|
)
|
|
}}
|
|
<div class="boxed-section" data-test-preemptions>
|
|
<div class="boxed-section-head">
|
|
Preempted Allocations
|
|
</div>
|
|
<div class="boxed-section-body">
|
|
<ListTable
|
|
@source={{this.model.preemptedAllocations}}
|
|
@class="allocations is-isolated" as |t|
|
|
>
|
|
<t.head>
|
|
<th class="is-narrow"></th>
|
|
<th>
|
|
ID
|
|
</th>
|
|
<th>
|
|
Task Group
|
|
</th>
|
|
<th>
|
|
Created
|
|
</th>
|
|
<th>
|
|
Modified
|
|
</th>
|
|
<th>
|
|
Status
|
|
</th>
|
|
<th>
|
|
Version
|
|
</th>
|
|
<th>
|
|
Node
|
|
</th>
|
|
<th>
|
|
CPU
|
|
</th>
|
|
<th>
|
|
Memory
|
|
</th>
|
|
</t.head>
|
|
<t.body as |row|>
|
|
<AllocationRow
|
|
@allocation={{row.model}}
|
|
@context="job"
|
|
@data-test-allocation={{row.model.id}}
|
|
/>
|
|
</t.body>
|
|
</ListTable>
|
|
</div>
|
|
</div>
|
|
{{/if}}
|
|
</section> |