github.com/ferranbt/nomad@v0.9.3-0.20190607002617-85c449b7667c/website/source/docs/internals/plugins/task-drivers.html.md (about) 1 --- 2 layout: "docs" 3 page_title: "Task Driver Plugins" 4 sidebar_current: "docs-internals-plugins-task-drivers" 5 description: |- 6 Learn about how to author a Nomad plugin. 7 --- 8 9 # Task Drivers 10 11 Task drivers in Nomad are the runtime components that execute workloads. For 12 a real world example of a Nomad task driver plugin implementation see the [LXC 13 driver source][lxcdriver]. 14 15 ## Authoring Task Driver Plugins 16 17 Authoring a task driver (shortened to driver in this documentation) in Nomad 18 consists of implementing the [DriverPlugin][driverplugin] interface and adding 19 a main package to launch the plugin. A driver plugin is long lived and its 20 lifetime is not bound to the Nomad client. This means that the Nomad client can 21 be restarted without the restarting the driver. Nomad will ensure that one 22 instance of the driver is running, meaning if the driver crashes or otherwise 23 terminates, Nomad will launch another instance of it. 24 25 Drivers should maintain as little state as possible. State for a task is stored 26 by the Nomad client on task creation. This enables a pattern where the driver 27 can maintain an in-memory state of the running tasks, and if necessary the 28 Nomad client can recover tasks into the driver state. 29 30 ## Task Driver Plugin API 31 32 The [base plugin][baseplugin] must be implement in addition to the following 33 functions. 34 35 ### `TaskConfigSchema() (*hclspec.Spec, error)` 36 37 This function returns the schema for the driver configuration of the task. For 38 more information on `hclspec.Spec` see the HCL section in the [base 39 plugin][baseplugin] documentation. 40 41 ### `Capabilities() (*Capabilities, error)` 42 43 Capabilities define what features the driver implements. Example: 44 45 ```go 46 Capabilities { 47 // Does the driver support sending OS signals to the task? 48 SendSignals: true, 49 // Does the driver support executing a command within the task execution 50 // environment? 51 Exec: true, 52 // What filesystem isolation is supported by the driver. Options include 53 // FSIsolationImage, FSIsolationChroot, and FSIsolationNone 54 FSIsolation: FSIsolationImage, 55 } 56 ``` 57 58 ### `Fingerprint(context.Context) (<-chan *Fingerprint, error)` 59 60 This function is called by the client when the plugin is started. It allows the 61 driver to indicate its health to the client. The channel returned should 62 immediately send an initial Fingerprint, then send periodic updates at an 63 interval that is appropriate for the driver until the context is canceled. 64 65 The fingerprint consists of a `HealthState` and `HealthDescription` to inform 66 the client about its health. Additionally an `Attributes` field is available 67 for the driver to add additional attributes to the client node. The fingerprint 68 `HealthState` can be one of three states. 69 70 - `HealthStateUndetected`: Indicates that the necessary dependencies for the 71 driver are not detected on the system. Ex. java runtime for the java driver 72 - `HealthStateUnhealthy`: Indicates that something is wrong with the driver 73 runtime. Ex. docker daemon stopped for the Docker driver 74 - `HealthStateHealthy`: All systems go 75 76 ### `StartTask(*TaskConfig) (*TaskHandle, *DriverNetwork, error)` 77 78 This function takes a [`TaskConfig`][taskconfig] which includes all of the configuration 79 needed to launch the task. Additionally the driver configuration can be decoded 80 from the `TaskConfig` by calling `*TaskConfig.DecodeDriverConfig(t interface{})` 81 passing in a pointer to the driver specific configuration struct. The 82 `TaskConfig` includes an `ID` field which future operations on the task will be 83 referenced by. 84 85 Drivers return a [`*TaskHandle`][taskhandle] which contains 86 the required information for the driver to reattach to the running task in the 87 case of plugin crashes or restarts. Some of this required state 88 will be specific to the driver implementation, thus a `DriverState` field 89 exists to allow the driver to encode custom state into the struct. Helper 90 fields exist on the `TaskHandle` to `GetDriverState` and `SetDriverState` 91 removing the need for the driver to handle serialization. 92 93 A `*DriverNetwork` can optionally be returned to describe the network of the 94 task if it is modified by the driver. An example of this is in the Docker 95 driver where tasks can be attached to a specific Docker network. 96 97 If an error occurs, it is expected that the driver will cleanup any created 98 resources prior to returning the error. 99 100 #### Logging 101 102 Nomad handles all rotation and plumbing of task logs. In order for task stdout 103 and stderr to be received by Nomad, they must be written to the correct 104 location. Prior to starting the task through the driver, the Nomad client 105 creates FIFOs for stdout and stderr. These paths are given to the driver in the 106 `TaskConfig`. The [`fifo` package][fifopackage] can be used to support 107 cross platform writing to these paths. 108 109 #### TaskHandle Schema Versioning 110 111 A `Version` field is available on the TaskHandle struct to facilitate backwards 112 compatible recovery of tasks. This field is opaque to Nomad, but allows the 113 driver to handle recover tasks that were created by an older version of the 114 plugin. 115 116 ### `RecoverTask(*TaskHandle) error` 117 118 When a driver is restarted it is not expected to persist any internal state to 119 disk. To support this, Nomad will attempt to recover a task that was 120 previously started if the driver does not recognize the task ID. During task 121 recovery, Nomad calls `RecoverTask` passing the `TaskHandle` that was 122 returned by the `StartTask` function. If no error was returned, it is 123 expected that the driver can now operate on the task by referencing the task 124 ID. If an error occurs, the Nomad client will mark the task as `lost`. 125 126 ### `WaitTask(ctx context.Context, id string) (<-chan *ExitResult, error)` 127 128 The `WaitTask` function is expected to return a channel that will send an 129 `*ExitResult` when the task exits or close the channel when the context is 130 canceled. It is also expected that calling `WaitTask` on an exited task will 131 immediately send an `*ExitResult` on the returned channel. 132 133 ### `StopTask(taskID string, timeout time.Duration, signal string) error` 134 135 The `StopTask` function is expected to stop a running task by sending the given 136 signal to it. If the task does not stop during the given timeout, the driver 137 must forcefully kill the task. 138 139 `StopTask` does not clean up resources of the task or remove it from the 140 driver's internal state. A call to `WaitTask` after `StopTask` is valid and 141 should be handled. 142 143 ### `DestroyTask(taskID string, force bool) error` 144 145 The `DestroyTask` function cleans up and removes a task that has terminated. If 146 force is set to true, the driver must destroy the task even if it is still 147 running. If `WaitTask` is called after `DestroyTask`, it should return 148 `drivers.ErrTaskNotFound` as no task state should exist after `DestroyTask` is 149 called. 150 151 ### `InspectTask(taskID string) (*TaskStatus, error)` 152 153 The `InspectTask` function returns detailed status information for the 154 referenced `taskID`. 155 156 ### `TaskStats(ctx context.Context, id string, i time.Duration) (<-chan *cstructs.TaskResourceUsage, error)` 157 158 The `TaskStats` function returns a channel which the driver should send stats 159 to at the given interval. The driver must send stats at the given interval 160 until the given context is canceled or the task terminates. 161 162 ### `TaskEvents(context.Context) (<-chan *TaskEvent, error)` 163 164 The Nomad client publishes events associated with an allocation. The 165 `TaskEvents` function allows the driver to publish driver specific events about 166 tasks and the Nomad client will associate them with the correct allocation. 167 168 An `Eventer` utility is available in the 169 `github.com/hashicorp/nomad/drivers/shared/eventer` package implements an 170 event loop and publishing mechanism for use in the `TaskEvents` function. 171 172 ### `SignalTask(taskID string, signal string) error` 173 174 > Optional - can be skipped by embedding `drivers.DriverSignalTaskNotSupported` 175 176 The `SignalTask` function is used by drivers which support sending OS signals 177 (`SIGHUP`, `SIGKILL`, `SIGUSR1` etc.) to the task. It is an optional function 178 and is listed as a capability in the driver `Capabilities` struct. 179 180 ### `ExecTask(taskID string, cmd []string, timeout time.Duration) (*ExecTaskResult, error)` 181 182 > Optional - can be skipped by embedding `drivers.DriverExecTaskNotSupported` 183 184 The `ExecTask` function is used by the Nomad client to execute commands inside 185 the task execution context. For example, the Docker driver executes commands 186 inside the running container. `ExecTask` is called for Consul script checks. 187 188 189 190 [lxcdriver]: https://github.com/hashicorp/nomad-driver-lxc 191 [DriverPlugin]: https://github.com/hashicorp/nomad/blob/v0.9.0-beta2/plugins/drivers/driver.go#L39-L57 192 [baseplugin]: /docs/internals/plugins/base.html 193 [taskconfig]: https://godoc.org/github.com/hashicorp/nomad/plugins/drivers#TaskConfig 194 [taskhandle]: https://godoc.org/github.com/hashicorp/nomad/plugins/drivers#TaskHandle 195 [fifopackage]: https://godoc.org/github.com/hashicorp/nomad/client/lib/fifo