674da96a59
This connects Xterm.js to a Nomad exec websocket so people can interact on clients via live sessions. There are buttons on job, allocation, task group, and task detail pages that open a popup that lets them edit their shell command and start a session. More is to come, as recorded in issues.
268 lines
10 KiB
Handlebars
268 lines
10 KiB
Handlebars
{{title "Allocation " model.name}}
|
|
<section class="section">
|
|
{{#if 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">{{error.title}}</h3>
|
|
<p data-test-inline-error-body>{{error.description}}</p>
|
|
</div>
|
|
<div class="column is-centered is-minimum">
|
|
<button data-test-inline-error-close class="button is-danger" onclick={{action onDismiss}}>Okay</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{{/if}}
|
|
|
|
<h1 data-test-title class="title with-headroom with-flex">
|
|
<div>
|
|
Allocation {{model.name}}
|
|
<span class="bumper-left tag {{model.statusClass}}">{{model.clientStatus}}</span>
|
|
</div>
|
|
<div>
|
|
{{#if model.isRunning}}
|
|
<div class="two-step-button">
|
|
{{exec/open-button job=model.job allocation=model}}
|
|
</div>
|
|
{{two-step-button
|
|
data-test-stop
|
|
idleText="Stop"
|
|
cancelText="Cancel"
|
|
confirmText="Yes, Stop"
|
|
confirmationMessage="Are you sure? This will reschedule the allocation on a different client."
|
|
awaitingConfirmation=stopAllocation.isRunning
|
|
disabled=(or stopAllocation.isRunning restartAllocation.isRunning)
|
|
onConfirm=(perform stopAllocation)}}
|
|
{{two-step-button
|
|
data-test-restart
|
|
idleText="Restart"
|
|
cancelText="Cancel"
|
|
confirmText="Yes, Restart"
|
|
confirmationMessage="Are you sure? This will restart the allocation in-place."
|
|
awaitingConfirmation=restartAllocation.isRunning
|
|
disabled=(or stopAllocation.isRunning restartAllocation.isRunning)
|
|
onConfirm=(perform restartAllocation)}}
|
|
{{/if}}
|
|
</div>
|
|
</h1>
|
|
|
|
<span class="tag is-hollow is-small is-alone no-text-transform">
|
|
{{model.id}}
|
|
{{copy-button clipboardText=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>
|
|
{{#link-to "jobs.job" model.job (query-params jobNamespace=model.job.namespace.id) data-test-job-link}}{{model.job.name}}{{/link-to}}
|
|
</span>
|
|
<span class="pair node-link"><span class="term">Client</span>
|
|
{{#link-to "clients.client" model.node data-test-client-link}}{{model.node.shortId}}{{/link-to}}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="boxed-section">
|
|
<div class="boxed-section-head is-hollow">
|
|
Resource Utilization
|
|
</div>
|
|
<div class="boxed-section-body">
|
|
{{#if model.isRunning}}
|
|
<div class="columns">
|
|
<div class="column">
|
|
{{primary-metric resource=model metric="cpu"}}
|
|
</div>
|
|
<div class="column">
|
|
{{primary-metric resource=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>
|
|
|
|
<div class="boxed-section">
|
|
<div class="boxed-section-head">
|
|
Tasks
|
|
</div>
|
|
<div class="boxed-section-body {{if sortedStates.length "is-full-bleed"}}">
|
|
{{#if sortedStates.length}}
|
|
{{#list-table
|
|
source=sortedStates
|
|
sortProperty=sortProperty
|
|
sortDescending=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>Addresses</th>
|
|
<th>CPU</th>
|
|
<th>Memory</th>
|
|
{{/t.head}}
|
|
{{#t.body as |row|}}
|
|
{{task-row
|
|
data-test-task-row=row.model.name
|
|
task=row.model
|
|
onClick=(action "taskClick" row.model.allocation row.model)}}
|
|
{{/t.body}}
|
|
{{/list-table}}
|
|
{{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 network.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">
|
|
{{#list-table source=network.ports as |t|}}
|
|
{{#t.head}}
|
|
<th class="is-2">Name</th>
|
|
<th class="is-1">Dynamic?</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.name}}</td>
|
|
<td data-test-allocation-port-is-dynamic>{{if row.model.isDynamic "Yes" "No"}}</td>
|
|
<td data-test-allocation-port-address>
|
|
<a href="http://{{network.ip}}:{{row.model.port}}" target="_blank" rel="noopener noreferrer">{{network.ip}}:{{row.model.port}}</a>
|
|
</td>
|
|
<td data-test-allocation-port-to>{{row.model.to}}</td>
|
|
</tr>
|
|
{{/t.body}}
|
|
{{/list-table}}
|
|
</div>
|
|
</div>
|
|
{{/if}}
|
|
|
|
{{#if services.length}}
|
|
<div class="boxed-section">
|
|
<div class="boxed-section-head">
|
|
Services
|
|
</div>
|
|
<div class="boxed-section-body is-full-bleed">
|
|
{{#list-table source=services as |t|}}
|
|
{{#t.head}}
|
|
<th class="is-2">Name</th>
|
|
<th class="is-1">Port</th>
|
|
<td>Tags</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>{{join ", " row.model.tags}}</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}}
|
|
{{/list-table}}
|
|
</div>
|
|
</div>
|
|
{{/if}}
|
|
|
|
{{#if 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">
|
|
{{reschedule-event-timeline allocation=model}}
|
|
</div>
|
|
</div>
|
|
{{/if}}
|
|
|
|
{{#if 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 (not preempter)}}
|
|
<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>
|
|
{{else}}
|
|
<div class="boxed-section is-small">
|
|
<div class="boxed-section-body inline-definitions">
|
|
<span class="pair">
|
|
<span data-test-allocation-status class="tag {{preempter.statusClass}}">
|
|
{{preempter.clientStatus}}
|
|
</span>
|
|
</span>
|
|
<span class="pair">
|
|
<span class="term" data-test-allocation-name>{{preempter.name}}</span>
|
|
{{#link-to "allocations.allocation" preempter data-test-allocation-id}}{{preempter.shortId}}{{/link-to}}
|
|
</span>
|
|
<span class="pair job-link"><span class="term">Job</span>
|
|
{{#link-to "jobs.job" preempter.job (query-params jobNamespace=preempter.job.namespace.id) data-test-job-link}}{{preempter.job.name}}{{/link-to}}
|
|
</span>
|
|
<span class="pair job-priority"><span class="term">Priority</span>
|
|
<span data-test-job-priority>{{preempter.job.priority}}</span>
|
|
</span>
|
|
<span class="pair node-link"><span class="term">Client</span>
|
|
{{#link-to "clients.client" preempter.node data-test-client-link}}{{preempter.node.shortId}}{{/link-to}}
|
|
</span>
|
|
<span class="pair"><span class="term">Reserved CPU</span>
|
|
<span data-test-allocation-cpu>{{preempter.resources.cpu}} MHz</span>
|
|
</span>
|
|
<span class="pair"><span class="term">Reserved Memory</span>
|
|
<span data-test-allocation-memory>{{preempter.resources.memory}} MiB</span>
|
|
</span>
|
|
</div>
|
|
</div>
|
|
{{/if}}
|
|
</div>
|
|
</div>
|
|
{{/if}}
|
|
|
|
{{#if (and model.preemptedAllocations.isFulfilled model.preemptedAllocations.length)}}
|
|
<div class="boxed-section" data-test-preemptions>
|
|
<div class="boxed-section-head">Preempted Allocations</div>
|
|
<div class="boxed-section-body">
|
|
{{#list-table
|
|
source=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|}}
|
|
{{allocation-row allocation=row.model context="job" data-test-allocation=row.model.id}}
|
|
{{/t.body}}
|
|
{{/list-table}}
|
|
</div>
|
|
</div>
|
|
{{/if}}
|
|
</section>
|