github.com/anth0d/nomad@v0.0.0-20221214183521-ae3a0a2cad06/ui/app/templates/allocations/allocation/index.hbs (about) 1 {{page-title "Allocation " this.model.name}} 2 <AllocationSubnav @allocation={{this.model}} /> 3 <section class="section"> 4 {{#if this.error}} 5 <div data-test-inline-error class="notification is-danger"> 6 <div class="columns"> 7 <div class="column"> 8 <h3 data-test-inline-error-title class="title is-4"> 9 {{this.error.title}} 10 </h3> 11 <p data-test-inline-error-body> 12 {{this.error.description}} 13 </p> 14 </div> 15 <div class="column is-centered is-minimum"> 16 <button 17 data-test-inline-error-close 18 class="button is-danger" 19 onclick={{action this.onDismiss}} 20 type="button" 21 > 22 Okay 23 </button> 24 </div> 25 </div> 26 </div> 27 {{/if}} 28 <h1 data-test-title class="title with-headroom with-flex"> 29 <div> 30 Allocation 31 {{this.model.name}} 32 <span class="bumper-left tag {{this.model.statusClass}}"> 33 {{this.model.clientStatus}} 34 </span> 35 </div> 36 <div> 37 {{#if this.model.isRunning}} 38 <div class="two-step-button"> 39 <Exec::OpenButton 40 @job={{this.model.job}} 41 @allocation={{this.model}} 42 /> 43 </div> 44 <TwoStepButton 45 data-test-stop 46 @alignRight={{true}} 47 @idleText="Stop Alloc" 48 @cancelText="Cancel Stop" 49 @confirmText="Yes, Stop Alloc" 50 @confirmationMessage="Are you sure? This will reschedule the allocation on a different client." 51 @awaitingConfirmation={{this.stopAllocation.isRunning}} 52 @disabled={{or 53 this.stopAllocation.isRunning 54 this.restartAllocation.isRunning 55 }} 56 @onConfirm={{perform this.stopAllocation}} 57 /> 58 <TwoStepButton 59 data-test-restart 60 @alignRight={{true}} 61 @idleText="Restart Alloc" 62 @cancelText="Cancel Restart" 63 @confirmText="Yes, Restart Alloc" 64 @confirmationMessage="Are you sure? This will restart the tasks that are currently running in-place." 65 @awaitingConfirmation={{this.restartAllocation.isRunning}} 66 @disabled={{or 67 this.stopAllocation.isRunning 68 this.restartAllocation.isRunning 69 }} 70 @onConfirm={{perform this.restartAllocation}} 71 /> 72 <TwoStepButton 73 data-test-restart-all 74 @alignRight={{true}} 75 @idleText="Restart All Tasks" 76 @cancelText="Cancel Restart" 77 @confirmText="Yes, Restart All Tasks" 78 @confirmationMessage="Are you sure? This will restart all tasks in-place." 79 @awaitingConfirmation={{this.restartAllocation.isRunning}} 80 @disabled={{or 81 this.stopAllocation.isRunning 82 this.restartAllocation.isRunning 83 }} 84 @onConfirm={{perform this.restartAll}} 85 /> 86 {{/if}} 87 </div> 88 </h1> 89 <span class="tag is-hollow is-small is-alone no-text-transform"> 90 {{this.model.id}} 91 <CopyButton @clipboardText={{this.model.id}} /> 92 </span> 93 <div class="boxed-section is-small"> 94 <div 95 data-test-allocation-details 96 class="boxed-section-body inline-definitions" 97 > 98 <span class="label"> 99 Allocation Details 100 </span> 101 <span class="pair job-link"> 102 <span class="term"> 103 Job 104 </span> 105 <LinkTo 106 @route="jobs.job" 107 @model={{format-job-id this.model.job.id}} 108 data-test-job-link 109 > 110 {{this.model.job.name}} 111 </LinkTo> 112 </span> 113 <span class="pair node-link"> 114 <span class="term"> 115 Client 116 </span> 117 <Tooltip @text={{this.model.node.name}}> 118 <LinkTo 119 @route="clients.client" 120 @model={{this.model.node}} 121 data-test-client-link 122 > 123 {{this.model.node.shortId}} 124 </LinkTo> 125 </Tooltip> 126 </span> 127 <span class="pair"> 128 <span class="term"> 129 Namespace 130 </span> 131 <span> 132 {{this.model.job.namespace.name}} 133 </span> 134 </span> 135 </div> 136 </div> 137 <div class="boxed-section"> 138 <div class="boxed-section-head is-hollow"> 139 Resource Utilization 140 </div> 141 <div class="boxed-section-body"> 142 {{#if this.model.isRunning}} 143 <div class="columns"> 144 <div class="column"> 145 <PrimaryMetric::Allocation 146 @allocation={{this.model}} 147 @metric="cpu" 148 /> 149 </div> 150 <div class="column"> 151 <PrimaryMetric::Allocation 152 @allocation={{this.model}} 153 @metric="memory" 154 /> 155 </div> 156 </div> 157 {{else}} 158 <div data-test-resource-error class="empty-message"> 159 <h3 data-test-resource-error-headline class="empty-message-headline"> 160 Allocation isn't running 161 </h3> 162 <p class="empty-message-body"> 163 Only running allocations utilize 164 resources. 165 </p> 166 </div> 167 {{/if}} 168 </div> 169 </div> 170 <LifecycleChart @taskStates={{this.model.states}} /> 171 <div class="boxed-section"> 172 <div class="boxed-section-head"> 173 Tasks 174 </div> 175 <div 176 class="boxed-section-body {{if this.sortedStates.length "is-full-bleed"}}" 177 > 178 {{#if this.sortedStates.length}} 179 <ListTable 180 @source={{this.sortedStates}} 181 @sortProperty={{this.sortProperty}} 182 @sortDescending={{this.sortDescending}} 183 @class="is-striped" as |t| 184 > 185 <t.head> 186 <th class="is-narrow"></th> 187 <t.sort-by @prop="name"> 188 Name 189 </t.sort-by> 190 <t.sort-by @prop="state"> 191 State 192 </t.sort-by> 193 <th> 194 Last Event 195 </th> 196 <t.sort-by @prop="events.lastObject.time"> 197 Time 198 </t.sort-by> 199 <th> 200 Volumes 201 </th> 202 <th> 203 CPU 204 </th> 205 <th> 206 Memory 207 </th> 208 </t.head> 209 <t.body as |row|> 210 <TaskRow 211 {{keyboard-shortcut 212 enumerated=true 213 action=(action "taskClick" row.model.allocation row.model) 214 }} 215 @data-test-task-row={{row.model.name}} 216 @task={{row.model}} 217 @onClick={{action "taskClick" row.model.allocation row.model}} 218 /> 219 </t.body> 220 </ListTable> 221 {{else}} 222 <div data-test-empty-tasks-list class="empty-message"> 223 <h3 224 data-test-empty-tasks-list-headline 225 class="empty-message-headline" 226 > 227 No Tasks 228 </h3> 229 <p data-test-empty-tasks-list-body class="empty-message-body"> 230 Allocations will not have tasks until they are in a running state. 231 </p> 232 </div> 233 {{/if}} 234 </div> 235 </div> 236 {{#if this.ports.length}} 237 <div class="boxed-section" data-test-allocation-ports> 238 <div class="boxed-section-head"> 239 Ports 240 </div> 241 <div class="boxed-section-body is-full-bleed"> 242 <ListTable @source={{this.ports}} as |t|> 243 <t.head> 244 <th> 245 Name 246 </th> 247 <th> 248 Host Address 249 </th> 250 <th> 251 Mapped Port 252 </th> 253 </t.head> 254 <t.body as |row|> 255 <tr data-test-allocation-port> 256 <td data-test-allocation-port-name> 257 {{row.model.label}} 258 </td> 259 <td data-test-allocation-port-address> 260 <a 261 href="http://{{row.model.hostIp}}:{{row.model.value}}" 262 target="_blank" 263 rel="noopener noreferrer" 264 > 265 {{row.model.hostIp}}:{{row.model.value}} 266 </a> 267 </td> 268 <td data-test-allocation-port-to> 269 {{row.model.to}} 270 </td> 271 </tr> 272 </t.body> 273 </ListTable> 274 </div> 275 </div> 276 {{/if}} 277 {{#if this.services.length}} 278 <div class="boxed-section"> 279 <div class="boxed-section-head"> 280 Services 281 </div> 282 <div class="boxed-section-body is-full-bleed"> 283 <ListTable class="allocation-services-table" @source={{this.servicesWithHealthChecks}} as |t|> 284 <t.head> 285 <th class="is-narrow"></th> 286 <th> 287 Name 288 </th> 289 <th> 290 Port 291 </th> 292 <td> 293 Tags 294 </td> 295 <td> 296 Health Check Status 297 </td> 298 </t.head> 299 <t.body as |row|> 300 <tr data-test-service class="is-interactive {{if (eq this.activeService row.model) "is-active"}}" 301 {{on "click" (fn this.handleServiceClick row.model)}} 302 {{keyboard-shortcut 303 enumerated=true 304 action=(fn this.handleServiceClick row.model) 305 }} 306 > 307 <td class="is-narrow"> 308 {{#if (eq row.model.provider "nomad")}} 309 <FlightIcon @name="nomad-color" /> 310 {{else}} 311 <FlightIcon @name="consul-color" /> 312 {{#if row.model.connect}} 313 <FlightIcon @name="mesh" @color="#444444" /> 314 {{/if}} 315 {{/if}} 316 </td> 317 <td data-test-service-name class="is-long-text"> 318 {{row.model.name}} 319 </td> 320 <td data-test-service-port> 321 {{row.model.portLabel}} 322 </td> 323 <td data-test-service-tags class="is-long-text"> 324 {{#each row.model.tags as |tag|}} 325 <span class="tag is-service">{{tag}}</span> 326 {{/each}} 327 {{#each row.model.canary_tags as |tag|}} 328 <span class="tag canary is-service">{{tag}}</span> 329 {{/each}} 330 </td> 331 <td data-test-service-health class="is-2"> 332 {{#if (eq row.model.provider "nomad")}} 333 <div class="inline-chart"> 334 <ServiceStatusBar @isNarrow={{true}} @status={{row.model.mostRecentCheckStatus}} /> 335 </div> 336 {{/if}} 337 </td> 338 </tr> 339 </t.body> 340 </ListTable> 341 </div> 342 </div> 343 {{/if}} 344 {{#if this.model.hasRescheduleEvents}} 345 <div class="boxed-section" data-test-reschedule-events> 346 <div class="boxed-section-head is-hollow"> 347 Reschedule Events 348 </div> 349 <div class="boxed-section-body"> 350 <RescheduleEventTimeline @allocation={{this.model}} /> 351 </div> 352 </div> 353 {{/if}} 354 {{#if this.model.wasPreempted}} 355 <div class="boxed-section is-warning" data-test-was-preempted> 356 <div class="boxed-section-head"> 357 Preempted By 358 </div> 359 <div class="boxed-section-body"> 360 {{#if this.preempter}} 361 <div class="boxed-section is-small"> 362 <div class="boxed-section-body inline-definitions"> 363 <span class="pair"> 364 <span 365 data-test-allocation-status 366 class="tag {{this.preempter.statusClass}}" 367 > 368 {{this.preempter.clientStatus}} 369 </span> 370 </span> 371 <span class="pair"> 372 <span class="term" data-test-allocation-name> 373 {{this.preempter.name}} 374 </span> 375 <LinkTo 376 @route="allocations.allocation" 377 @model={{this.preempter}} 378 data-test-allocation-id 379 > 380 {{this.preempter.shortId}} 381 </LinkTo> 382 </span> 383 <span class="pair job-link"> 384 <span class="term"> 385 Job 386 </span> 387 <LinkTo 388 @route="jobs.job" 389 @model={{this.preempter.job}} 390 data-test-job-link 391 > 392 {{this.preempter.job.name}} 393 </LinkTo> 394 </span> 395 <span class="pair job-priority"> 396 <span class="term"> 397 Priority 398 </span> 399 <span data-test-job-priority> 400 {{this.preempter.job.priority}} 401 </span> 402 </span> 403 <span class="pair node-link"> 404 <span class="term"> 405 Client 406 </span> 407 <LinkTo 408 @route="clients.client" 409 @model={{this.preempter.node}} 410 data-test-client-link 411 > 412 {{this.preempter.node.shortId}} 413 </LinkTo> 414 </span> 415 <span class="pair"> 416 <span class="term"> 417 Reserved CPU 418 </span> 419 <span data-test-allocation-cpu> 420 {{format-scheduled-hertz this.preempter.resources.cpu}} 421 </span> 422 </span> 423 <span class="pair"> 424 <span class="term"> 425 Reserved Memory 426 </span> 427 <span data-test-allocation-memory> 428 {{format-scheduled-bytes 429 this.preempter.resources.memory 430 start="MiB" 431 }} 432 </span> 433 </span> 434 </div> 435 </div> 436 {{else}} 437 <div class="empty-message"> 438 <h3 class="empty-message-headline"> 439 Allocation is gone 440 </h3> 441 <p class="empty-message-body"> 442 This allocation has been stopped and 443 garbage collected. 444 </p> 445 </div> 446 {{/if}} 447 </div> 448 </div> 449 {{/if}} 450 {{#if 451 (and 452 this.model.preemptedAllocations.isFulfilled 453 this.model.preemptedAllocations.length 454 ) 455 }} 456 <div class="boxed-section" data-test-preemptions> 457 <div class="boxed-section-head"> 458 Preempted Allocations 459 </div> 460 <div class="boxed-section-body"> 461 <ListTable 462 @source={{this.model.preemptedAllocations}} 463 @class="allocations is-isolated" as |t| 464 > 465 <t.head> 466 <th class="is-narrow"></th> 467 <th> 468 ID 469 </th> 470 <th> 471 Task Group 472 </th> 473 <th> 474 Created 475 </th> 476 <th> 477 Modified 478 </th> 479 <th> 480 Status 481 </th> 482 <th> 483 Version 484 </th> 485 <th> 486 Node 487 </th> 488 <th> 489 CPU 490 </th> 491 <th> 492 Memory 493 </th> 494 </t.head> 495 <t.body as |row|> 496 <AllocationRow 497 @allocation={{row.model}} 498 @context="job" 499 @data-test-allocation={{row.model.id}} 500 /> 501 </t.body> 502 </ListTable> 503 </div> 504 </div> 505 {{/if}} 506 <AllocationServiceSidebar 507 @service={{this.activeService}} 508 @allocation={{this.model}} 509 @fns={{hash 510 closeSidebar=this.closeSidebar 511 }} 512 /> 513 </section>