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  }