1package interfaces
2
3import (
4	"context"
5	"time"
6
7	"github.com/hashicorp/nomad/client/allocdir"
8	"github.com/hashicorp/nomad/client/allocrunner/taskrunner/interfaces"
9	cstructs "github.com/hashicorp/nomad/client/structs"
10	"github.com/hashicorp/nomad/client/taskenv"
11	"github.com/hashicorp/nomad/nomad/structs"
12	"github.com/hashicorp/nomad/plugins/drivers"
13)
14
15/*
16
17                            Restart
18      +--------------------------------------------------------+
19      |                                                        |
20      |                      *Update                           |
21      |                     +-------+                          |
22      |                     |       |                          |
23      |                     |       |                          |
24      |                  +---v-------+----+                    |
25 +----v----+             |    Running     |               +----+-----+           +--------------+
26 |         | *Prestart   |----------------|      *Exited  |          |  *Stop    |              |
27 | Pending +-------------> *Poststart run +---^-----------> Exited   +----------->  Terminal    |
28 |         |             |  upon entering |   |           |          | NoRestart |              |
29 +---------+             |  running       |   |           +----------+           +--------------+
30                         |                |   |
31                         +--------+-------+   |
32                                  |           |
33                                  +-----------+
34                                     *Kill
35                                (forces terminal)
36
37Link: http://stable.ascii-flow.appspot.com/#Draw4489375405966393064/1824429135
38*/
39
40// TaskHook is a lifecycle hook into the life cycle of a task runner.
41type TaskHook interface {
42	Name() string
43}
44
45type TaskPrestartRequest struct {
46	// PreviousState is previously set data by the hook. It must be copied
47	// to State below to be maintained across restarts.
48	PreviousState map[string]string
49
50	// Task is the task to run
51	Task *structs.Task
52
53	// TaskResources is the resources assigned to the task
54	TaskResources *structs.AllocatedTaskResources
55
56	// Vault token may optionally be set if a Vault token is available
57	VaultToken string
58
59	// TaskDir contains the task's directory tree on the host
60	TaskDir *allocdir.TaskDir
61
62	// TaskEnv is the task's environment
63	TaskEnv *taskenv.TaskEnv
64}
65
66type TaskPrestartResponse struct {
67	// Env is the environment variables to set for the task
68	Env map[string]string
69
70	// Mounts is the set of host volumes to mount into the task
71	Mounts []*drivers.MountConfig
72
73	// Devices are the set of devices to mount into the task
74	Devices []*drivers.DeviceConfig
75
76	// State allows the hook to emit data to be passed in the next time it is
77	// run. Hooks must copy relevant PreviousState to State to maintain it
78	// across restarts.
79	State map[string]string
80
81	// Done lets the hook indicate that it completed successfully and
82	// should not be run again.
83	Done bool
84}
85
86type TaskPrestartHook interface {
87	TaskHook
88
89	// Prestart is called before the task is started including after every
90	// restart. Prestart is not called if the allocation is terminal.
91	//
92	// The context is cancelled if the task is killed or shutdown.
93	Prestart(context.Context, *TaskPrestartRequest, *TaskPrestartResponse) error
94}
95
96// DriverStats is the interface implemented by DriverHandles to return task stats.
97type DriverStats interface {
98	Stats(context.Context, time.Duration) (<-chan *cstructs.TaskResourceUsage, error)
99}
100
101type TaskPoststartRequest struct {
102	// Exec hook (may be nil)
103	DriverExec interfaces.ScriptExecutor
104
105	// Network info (may be nil)
106	DriverNetwork *drivers.DriverNetwork
107
108	// TaskEnv is the task's environment
109	TaskEnv *taskenv.TaskEnv
110
111	// Stats collector
112	DriverStats DriverStats
113}
114type TaskPoststartResponse struct{}
115
116type TaskPoststartHook interface {
117	TaskHook
118
119	// Poststart is called after the task has started. Poststart is not
120	// called if the allocation is terminal.
121	//
122	// The context is cancelled if the task is killed.
123	Poststart(context.Context, *TaskPoststartRequest, *TaskPoststartResponse) error
124}
125
126type TaskPreKillRequest struct{}
127type TaskPreKillResponse struct{}
128
129type TaskPreKillHook interface {
130	TaskHook
131
132	// PreKilling is called right before a task is going to be killed or
133	// restarted. They are called concurrently with TaskRunner.Run and may
134	// be called without Prestart being called.
135	PreKilling(context.Context, *TaskPreKillRequest, *TaskPreKillResponse) error
136}
137
138type TaskExitedRequest struct{}
139type TaskExitedResponse struct{}
140
141type TaskExitedHook interface {
142	TaskHook
143
144	// Exited is called after a task exits and may or may not be restarted.
145	// Prestart may or may not have been called.
146	//
147	// The context is cancelled if the task is killed.
148	Exited(context.Context, *TaskExitedRequest, *TaskExitedResponse) error
149}
150
151type TaskUpdateRequest struct {
152	VaultToken string
153
154	// Alloc is the current version of the allocation (may have been
155	// updated since the hook was created)
156	Alloc *structs.Allocation
157
158	// TaskEnv is the task's environment
159	TaskEnv *taskenv.TaskEnv
160}
161type TaskUpdateResponse struct{}
162
163type TaskUpdateHook interface {
164	TaskHook
165
166	// Update is called when the servers have updated the Allocation for
167	// this task. Updates are concurrent with all other task hooks and
168	// therefore hooks that implement this interface must be completely
169	// safe for concurrent access.
170	//
171	// The context is cancelled if the task is killed.
172	Update(context.Context, *TaskUpdateRequest, *TaskUpdateResponse) error
173}
174
175type TaskStopRequest struct {
176	// ExistingState is previously set hook data and should only be
177	// read. Stop hooks cannot alter state.
178	ExistingState map[string]string
179}
180
181type TaskStopResponse struct{}
182
183type TaskStopHook interface {
184	TaskHook
185
186	// Stop is called after the task has exited and will not be started
187	// again. It is the only hook guaranteed to be executed whenever
188	// TaskRunner.Run is called (and not gracefully shutting down).
189	// Therefore it may be called even when prestart and the other hooks
190	// have not.
191	//
192	// Stop hooks must be idempotent. The context is cancelled if the task
193	// is killed.
194	Stop(context.Context, *TaskStopRequest, *TaskStopResponse) error
195}
196