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