github.com/anth0d/nomad@v0.0.0-20221214183521-ae3a0a2cad06/nomad/mock/lifecycle.go (about) 1 package mock 2 3 import ( 4 "fmt" 5 "time" 6 7 "github.com/hashicorp/nomad/helper/uuid" 8 "github.com/hashicorp/nomad/nomad/structs" 9 ) 10 11 func LifecycleSideTask(resources structs.Resources, i int) *structs.Task { 12 return &structs.Task{ 13 Name: fmt.Sprintf("side-%d", i), 14 Driver: "exec", 15 Config: map[string]interface{}{ 16 "command": "/bin/date", 17 }, 18 Lifecycle: &structs.TaskLifecycleConfig{ 19 Hook: structs.TaskLifecycleHookPrestart, 20 Sidecar: true, 21 }, 22 LogConfig: structs.DefaultLogConfig(), 23 Resources: &resources, 24 } 25 } 26 27 func LifecycleInitTask(resources structs.Resources, i int) *structs.Task { 28 return &structs.Task{ 29 Name: fmt.Sprintf("init-%d", i), 30 Driver: "exec", 31 Config: map[string]interface{}{ 32 "command": "/bin/date", 33 }, 34 Lifecycle: &structs.TaskLifecycleConfig{ 35 Hook: structs.TaskLifecycleHookPrestart, 36 Sidecar: false, 37 }, 38 LogConfig: structs.DefaultLogConfig(), 39 Resources: &resources, 40 } 41 } 42 43 func LifecycleMainTask(resources structs.Resources, i int) *structs.Task { 44 return &structs.Task{ 45 Name: fmt.Sprintf("main-%d", i), 46 Driver: "exec", 47 Config: map[string]interface{}{ 48 "command": "/bin/date", 49 }, 50 LogConfig: structs.DefaultLogConfig(), 51 Resources: &resources, 52 } 53 } 54 55 type LifecycleTaskDef struct { 56 Name string 57 RunFor string 58 ExitCode int 59 Hook string 60 IsSidecar bool 61 } 62 63 // LifecycleAllocFromTasks generates an Allocation with mock tasks that have 64 // the provided lifecycles. 65 func LifecycleAllocFromTasks(tasks []LifecycleTaskDef) *structs.Allocation { 66 alloc := LifecycleAlloc() 67 alloc.Job.TaskGroups[0].Tasks = []*structs.Task{} 68 for _, task := range tasks { 69 var lc *structs.TaskLifecycleConfig 70 if task.Hook != "" { 71 // TODO: task coordinator doesn't treat nil and empty structs the same 72 lc = &structs.TaskLifecycleConfig{ 73 Hook: task.Hook, 74 Sidecar: task.IsSidecar, 75 } 76 } 77 78 alloc.Job.TaskGroups[0].Tasks = append(alloc.Job.TaskGroups[0].Tasks, 79 &structs.Task{ 80 Name: task.Name, 81 Driver: "mock_driver", 82 Config: map[string]interface{}{ 83 "run_for": task.RunFor, 84 "exit_code": task.ExitCode}, 85 Lifecycle: lc, 86 LogConfig: structs.DefaultLogConfig(), 87 Resources: &structs.Resources{CPU: 100, MemoryMB: 256}, 88 }, 89 ) 90 alloc.TaskResources[task.Name] = &structs.Resources{CPU: 100, MemoryMB: 256} 91 alloc.AllocatedResources.Tasks[task.Name] = &structs.AllocatedTaskResources{ 92 Cpu: structs.AllocatedCpuResources{CpuShares: 100}, 93 Memory: structs.AllocatedMemoryResources{MemoryMB: 256}, 94 } 95 } 96 return alloc 97 } 98 99 func LifecycleAlloc() *structs.Allocation { 100 alloc := &structs.Allocation{ 101 ID: uuid.Generate(), 102 EvalID: uuid.Generate(), 103 NodeID: "12345678-abcd-efab-cdef-123456789abc", 104 Namespace: structs.DefaultNamespace, 105 TaskGroup: "web", 106 107 // TODO Remove once clientv2 gets merged 108 Resources: &structs.Resources{ 109 CPU: 500, 110 MemoryMB: 256, 111 }, 112 TaskResources: map[string]*structs.Resources{ 113 "web": { 114 CPU: 1000, 115 MemoryMB: 256, 116 }, 117 "init": { 118 CPU: 1000, 119 MemoryMB: 256, 120 }, 121 "side": { 122 CPU: 1000, 123 MemoryMB: 256, 124 }, 125 "poststart": { 126 CPU: 1000, 127 MemoryMB: 256, 128 }, 129 }, 130 131 AllocatedResources: &structs.AllocatedResources{ 132 Tasks: map[string]*structs.AllocatedTaskResources{ 133 "web": { 134 Cpu: structs.AllocatedCpuResources{ 135 CpuShares: 1000, 136 }, 137 Memory: structs.AllocatedMemoryResources{ 138 MemoryMB: 256, 139 }, 140 }, 141 "init": { 142 Cpu: structs.AllocatedCpuResources{ 143 CpuShares: 1000, 144 }, 145 Memory: structs.AllocatedMemoryResources{ 146 MemoryMB: 256, 147 }, 148 }, 149 "side": { 150 Cpu: structs.AllocatedCpuResources{ 151 CpuShares: 1000, 152 }, 153 Memory: structs.AllocatedMemoryResources{ 154 MemoryMB: 256, 155 }, 156 }, 157 "poststart": { 158 Cpu: structs.AllocatedCpuResources{ 159 CpuShares: 1000, 160 }, 161 Memory: structs.AllocatedMemoryResources{ 162 MemoryMB: 256, 163 }, 164 }, 165 }, 166 }, 167 Job: LifecycleJob(), 168 DesiredStatus: structs.AllocDesiredStatusRun, 169 ClientStatus: structs.AllocClientStatusPending, 170 } 171 alloc.JobID = alloc.Job.ID 172 return alloc 173 } 174 175 func LifecycleJobWithPoststopDeploy() *structs.Job { 176 job := &structs.Job{ 177 Region: "global", 178 ID: fmt.Sprintf("mock-service-%s", uuid.Generate()), 179 Name: "my-job", 180 Namespace: structs.DefaultNamespace, 181 Type: structs.JobTypeBatch, 182 Priority: 50, 183 AllAtOnce: false, 184 Datacenters: []string{"dc1"}, 185 Constraints: []*structs.Constraint{ 186 { 187 LTarget: "${attr.kernel.name}", 188 RTarget: "linux", 189 Operand: "=", 190 }, 191 }, 192 TaskGroups: []*structs.TaskGroup{ 193 { 194 Name: "web", 195 Count: 1, 196 Migrate: structs.DefaultMigrateStrategy(), 197 RestartPolicy: &structs.RestartPolicy{ 198 Attempts: 0, 199 Interval: 10 * time.Minute, 200 Delay: 1 * time.Minute, 201 Mode: structs.RestartPolicyModeFail, 202 }, 203 Tasks: []*structs.Task{ 204 { 205 Name: "web", 206 Driver: "mock_driver", 207 Config: map[string]interface{}{ 208 "run_for": "1s", 209 }, 210 LogConfig: structs.DefaultLogConfig(), 211 Resources: &structs.Resources{ 212 CPU: 1000, 213 MemoryMB: 256, 214 }, 215 }, 216 { 217 Name: "side", 218 Driver: "mock_driver", 219 Config: map[string]interface{}{ 220 "run_for": "1s", 221 }, 222 Lifecycle: &structs.TaskLifecycleConfig{ 223 Hook: structs.TaskLifecycleHookPrestart, 224 Sidecar: true, 225 }, 226 LogConfig: structs.DefaultLogConfig(), 227 Resources: &structs.Resources{ 228 CPU: 1000, 229 MemoryMB: 256, 230 }, 231 }, 232 { 233 Name: "post", 234 Driver: "mock_driver", 235 Config: map[string]interface{}{ 236 "run_for": "1s", 237 }, 238 Lifecycle: &structs.TaskLifecycleConfig{ 239 Hook: structs.TaskLifecycleHookPoststop, 240 }, 241 LogConfig: structs.DefaultLogConfig(), 242 Resources: &structs.Resources{ 243 CPU: 1000, 244 MemoryMB: 256, 245 }, 246 }, 247 { 248 Name: "init", 249 Driver: "mock_driver", 250 Config: map[string]interface{}{ 251 "run_for": "1s", 252 }, 253 Lifecycle: &structs.TaskLifecycleConfig{ 254 Hook: structs.TaskLifecycleHookPrestart, 255 Sidecar: false, 256 }, 257 LogConfig: structs.DefaultLogConfig(), 258 Resources: &structs.Resources{ 259 CPU: 1000, 260 MemoryMB: 256, 261 }, 262 }, 263 }, 264 }, 265 }, 266 Meta: map[string]string{ 267 "owner": "armon", 268 }, 269 Status: structs.JobStatusPending, 270 Version: 0, 271 CreateIndex: 42, 272 ModifyIndex: 99, 273 JobModifyIndex: 99, 274 } 275 job.Canonicalize() 276 return job 277 } 278 279 func LifecycleJobWithPoststartDeploy() *structs.Job { 280 job := &structs.Job{ 281 Region: "global", 282 ID: fmt.Sprintf("mock-service-%s", uuid.Generate()), 283 Name: "my-job", 284 Namespace: structs.DefaultNamespace, 285 Type: structs.JobTypeBatch, 286 Priority: 50, 287 AllAtOnce: false, 288 Datacenters: []string{"dc1"}, 289 Constraints: []*structs.Constraint{ 290 { 291 LTarget: "${attr.kernel.name}", 292 RTarget: "linux", 293 Operand: "=", 294 }, 295 }, 296 TaskGroups: []*structs.TaskGroup{ 297 { 298 Name: "web", 299 Count: 1, 300 Migrate: structs.DefaultMigrateStrategy(), 301 RestartPolicy: &structs.RestartPolicy{ 302 Attempts: 0, 303 Interval: 10 * time.Minute, 304 Delay: 1 * time.Minute, 305 Mode: structs.RestartPolicyModeFail, 306 }, 307 Tasks: []*structs.Task{ 308 { 309 Name: "web", 310 Driver: "mock_driver", 311 Config: map[string]interface{}{ 312 "run_for": "1s", 313 }, 314 LogConfig: structs.DefaultLogConfig(), 315 Resources: &structs.Resources{ 316 CPU: 1000, 317 MemoryMB: 256, 318 }, 319 }, 320 { 321 Name: "side", 322 Driver: "mock_driver", 323 Config: map[string]interface{}{ 324 "run_for": "1s", 325 }, 326 Lifecycle: &structs.TaskLifecycleConfig{ 327 Hook: structs.TaskLifecycleHookPrestart, 328 Sidecar: true, 329 }, 330 LogConfig: structs.DefaultLogConfig(), 331 Resources: &structs.Resources{ 332 CPU: 1000, 333 MemoryMB: 256, 334 }, 335 }, 336 { 337 Name: "post", 338 Driver: "mock_driver", 339 Config: map[string]interface{}{ 340 "run_for": "1s", 341 }, 342 Lifecycle: &structs.TaskLifecycleConfig{ 343 Hook: structs.TaskLifecycleHookPoststart, 344 }, 345 LogConfig: structs.DefaultLogConfig(), 346 Resources: &structs.Resources{ 347 CPU: 1000, 348 MemoryMB: 256, 349 }, 350 }, 351 { 352 Name: "init", 353 Driver: "mock_driver", 354 Config: map[string]interface{}{ 355 "run_for": "1s", 356 }, 357 Lifecycle: &structs.TaskLifecycleConfig{ 358 Hook: structs.TaskLifecycleHookPrestart, 359 Sidecar: false, 360 }, 361 LogConfig: structs.DefaultLogConfig(), 362 Resources: &structs.Resources{ 363 CPU: 1000, 364 MemoryMB: 256, 365 }, 366 }, 367 }, 368 }, 369 }, 370 Meta: map[string]string{ 371 "owner": "armon", 372 }, 373 Status: structs.JobStatusPending, 374 Version: 0, 375 CreateIndex: 42, 376 ModifyIndex: 99, 377 JobModifyIndex: 99, 378 } 379 job.Canonicalize() 380 return job 381 } 382 383 func LifecycleAllocWithPoststopDeploy() *structs.Allocation { 384 alloc := &structs.Allocation{ 385 ID: uuid.Generate(), 386 EvalID: uuid.Generate(), 387 NodeID: "12345678-abcd-efab-cdef-123456789abc", 388 Namespace: structs.DefaultNamespace, 389 TaskGroup: "web", 390 391 // TODO Remove once clientv2 gets merged 392 Resources: &structs.Resources{ 393 CPU: 500, 394 MemoryMB: 256, 395 }, 396 TaskResources: map[string]*structs.Resources{ 397 "web": { 398 CPU: 1000, 399 MemoryMB: 256, 400 }, 401 "init": { 402 CPU: 1000, 403 MemoryMB: 256, 404 }, 405 "side": { 406 CPU: 1000, 407 MemoryMB: 256, 408 }, 409 "post": { 410 CPU: 1000, 411 MemoryMB: 256, 412 }, 413 }, 414 415 AllocatedResources: &structs.AllocatedResources{ 416 Tasks: map[string]*structs.AllocatedTaskResources{ 417 "web": { 418 Cpu: structs.AllocatedCpuResources{ 419 CpuShares: 1000, 420 }, 421 Memory: structs.AllocatedMemoryResources{ 422 MemoryMB: 256, 423 }, 424 }, 425 "init": { 426 Cpu: structs.AllocatedCpuResources{ 427 CpuShares: 1000, 428 }, 429 Memory: structs.AllocatedMemoryResources{ 430 MemoryMB: 256, 431 }, 432 }, 433 "side": { 434 Cpu: structs.AllocatedCpuResources{ 435 CpuShares: 1000, 436 }, 437 Memory: structs.AllocatedMemoryResources{ 438 MemoryMB: 256, 439 }, 440 }, 441 "post": { 442 Cpu: structs.AllocatedCpuResources{ 443 CpuShares: 1000, 444 }, 445 Memory: structs.AllocatedMemoryResources{ 446 MemoryMB: 256, 447 }, 448 }, 449 }, 450 }, 451 Job: LifecycleJobWithPoststopDeploy(), 452 DesiredStatus: structs.AllocDesiredStatusRun, 453 ClientStatus: structs.AllocClientStatusPending, 454 } 455 alloc.JobID = alloc.Job.ID 456 return alloc 457 } 458 459 func LifecycleAllocWithPoststartDeploy() *structs.Allocation { 460 alloc := &structs.Allocation{ 461 ID: uuid.Generate(), 462 EvalID: uuid.Generate(), 463 NodeID: "12345678-abcd-efab-cdef-123456789xyz", 464 Namespace: structs.DefaultNamespace, 465 TaskGroup: "web", 466 467 // TODO Remove once clientv2 gets merged 468 Resources: &structs.Resources{ 469 CPU: 500, 470 MemoryMB: 256, 471 }, 472 TaskResources: map[string]*structs.Resources{ 473 "web": { 474 CPU: 1000, 475 MemoryMB: 256, 476 }, 477 "init": { 478 CPU: 1000, 479 MemoryMB: 256, 480 }, 481 "side": { 482 CPU: 1000, 483 MemoryMB: 256, 484 }, 485 "post": { 486 CPU: 1000, 487 MemoryMB: 256, 488 }, 489 }, 490 491 AllocatedResources: &structs.AllocatedResources{ 492 Tasks: map[string]*structs.AllocatedTaskResources{ 493 "web": { 494 Cpu: structs.AllocatedCpuResources{ 495 CpuShares: 1000, 496 }, 497 Memory: structs.AllocatedMemoryResources{ 498 MemoryMB: 256, 499 }, 500 }, 501 "init": { 502 Cpu: structs.AllocatedCpuResources{ 503 CpuShares: 1000, 504 }, 505 Memory: structs.AllocatedMemoryResources{ 506 MemoryMB: 256, 507 }, 508 }, 509 "side": { 510 Cpu: structs.AllocatedCpuResources{ 511 CpuShares: 1000, 512 }, 513 Memory: structs.AllocatedMemoryResources{ 514 MemoryMB: 256, 515 }, 516 }, 517 "post": { 518 Cpu: structs.AllocatedCpuResources{ 519 CpuShares: 1000, 520 }, 521 Memory: structs.AllocatedMemoryResources{ 522 MemoryMB: 256, 523 }, 524 }, 525 }, 526 }, 527 Job: LifecycleJobWithPoststartDeploy(), 528 DesiredStatus: structs.AllocDesiredStatusRun, 529 ClientStatus: structs.AllocClientStatusPending, 530 } 531 alloc.JobID = alloc.Job.ID 532 return alloc 533 } 534 535 func VariableLifecycleJob(resources structs.Resources, main int, init int, side int) *structs.Job { 536 var tasks []*structs.Task 537 for i := 0; i < main; i++ { 538 tasks = append(tasks, LifecycleMainTask(resources, i)) 539 } 540 for i := 0; i < init; i++ { 541 tasks = append(tasks, LifecycleInitTask(resources, i)) 542 } 543 for i := 0; i < side; i++ { 544 tasks = append(tasks, LifecycleSideTask(resources, i)) 545 } 546 job := &structs.Job{ 547 Region: "global", 548 ID: fmt.Sprintf("mock-service-%s", uuid.Generate()), 549 Name: "my-job", 550 Namespace: structs.DefaultNamespace, 551 Type: structs.JobTypeService, 552 Priority: 50, 553 AllAtOnce: false, 554 Datacenters: []string{"dc1"}, 555 Constraints: []*structs.Constraint{ 556 { 557 LTarget: "${attr.kernel.name}", 558 RTarget: "linux", 559 Operand: "=", 560 }, 561 }, 562 TaskGroups: []*structs.TaskGroup{ 563 { 564 Name: "web", 565 Count: 1, 566 Tasks: tasks, 567 }, 568 }, 569 Meta: map[string]string{ 570 "owner": "armon", 571 }, 572 Status: structs.JobStatusPending, 573 Version: 0, 574 CreateIndex: 42, 575 ModifyIndex: 99, 576 JobModifyIndex: 99, 577 } 578 job.Canonicalize() 579 return job 580 } 581 582 func LifecycleJob() *structs.Job { 583 job := &structs.Job{ 584 Region: "global", 585 ID: fmt.Sprintf("mock-service-%s", uuid.Generate()), 586 Name: "my-job", 587 Namespace: structs.DefaultNamespace, 588 Type: structs.JobTypeBatch, 589 Priority: 50, 590 AllAtOnce: false, 591 Datacenters: []string{"dc1"}, 592 Constraints: []*structs.Constraint{ 593 { 594 LTarget: "${attr.kernel.name}", 595 RTarget: "linux", 596 Operand: "=", 597 }, 598 }, 599 TaskGroups: []*structs.TaskGroup{ 600 { 601 Name: "web", 602 Count: 1, 603 RestartPolicy: &structs.RestartPolicy{ 604 Attempts: 0, 605 Interval: 10 * time.Minute, 606 Delay: 1 * time.Minute, 607 Mode: structs.RestartPolicyModeFail, 608 }, 609 Tasks: []*structs.Task{ 610 { 611 Name: "web", 612 Driver: "mock_driver", 613 Config: map[string]interface{}{ 614 "run_for": "1s", 615 }, 616 LogConfig: structs.DefaultLogConfig(), 617 Resources: &structs.Resources{ 618 CPU: 1000, 619 MemoryMB: 256, 620 }, 621 }, 622 { 623 Name: "side", 624 Driver: "mock_driver", 625 Config: map[string]interface{}{ 626 "run_for": "1s", 627 }, 628 Lifecycle: &structs.TaskLifecycleConfig{ 629 Hook: structs.TaskLifecycleHookPrestart, 630 Sidecar: true, 631 }, 632 LogConfig: structs.DefaultLogConfig(), 633 Resources: &structs.Resources{ 634 CPU: 1000, 635 MemoryMB: 256, 636 }, 637 }, 638 { 639 Name: "init", 640 Driver: "mock_driver", 641 Config: map[string]interface{}{ 642 "run_for": "1s", 643 }, 644 Lifecycle: &structs.TaskLifecycleConfig{ 645 Hook: structs.TaskLifecycleHookPrestart, 646 Sidecar: false, 647 }, 648 LogConfig: structs.DefaultLogConfig(), 649 Resources: &structs.Resources{ 650 CPU: 1000, 651 MemoryMB: 256, 652 }, 653 }, 654 { 655 Name: "poststart", 656 Driver: "mock_driver", 657 Config: map[string]interface{}{ 658 "run_for": "1s", 659 }, 660 Lifecycle: &structs.TaskLifecycleConfig{ 661 Hook: structs.TaskLifecycleHookPoststart, 662 Sidecar: false, 663 }, 664 LogConfig: structs.DefaultLogConfig(), 665 Resources: &structs.Resources{ 666 CPU: 1000, 667 MemoryMB: 256, 668 }, 669 }, 670 }, 671 }, 672 }, 673 Meta: map[string]string{ 674 "owner": "armon", 675 }, 676 Status: structs.JobStatusPending, 677 Version: 0, 678 CreateIndex: 42, 679 ModifyIndex: 99, 680 JobModifyIndex: 99, 681 } 682 job.Canonicalize() 683 return job 684 }