github.com/anth0d/nomad@v0.0.0-20221214183521-ae3a0a2cad06/client/allocrunner/taskrunner/driver_handle.go (about)

     1  package taskrunner
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"time"
     7  
     8  	cstructs "github.com/hashicorp/nomad/client/structs"
     9  	"github.com/hashicorp/nomad/helper"
    10  	"github.com/hashicorp/nomad/nomad/structs"
    11  	"github.com/hashicorp/nomad/plugins/drivers"
    12  )
    13  
    14  // NewDriverHandle returns a handle for task operations on a specific task
    15  func NewDriverHandle(
    16  	driver drivers.DriverPlugin,
    17  	taskID string,
    18  	task *structs.Task,
    19  	maxKillTimeout time.Duration,
    20  	net *drivers.DriverNetwork) *DriverHandle {
    21  	return &DriverHandle{
    22  		driver:      driver,
    23  		net:         net,
    24  		taskID:      taskID,
    25  		killSignal:  task.KillSignal,
    26  		killTimeout: helper.Min(task.KillTimeout, maxKillTimeout),
    27  	}
    28  }
    29  
    30  // DriverHandle encapsulates a driver plugin client and task identifier and exposes
    31  // an api to perform driver operations on the task
    32  type DriverHandle struct {
    33  	driver      drivers.DriverPlugin
    34  	net         *drivers.DriverNetwork
    35  	taskID      string
    36  	killSignal  string
    37  	killTimeout time.Duration
    38  }
    39  
    40  func (h *DriverHandle) ID() string {
    41  	return h.taskID
    42  }
    43  
    44  func (h *DriverHandle) WaitCh(ctx context.Context) (<-chan *drivers.ExitResult, error) {
    45  	return h.driver.WaitTask(ctx, h.taskID)
    46  }
    47  
    48  // SetKillSignal allows overriding the signal sent to kill the task.
    49  func (h *DriverHandle) SetKillSignal(signal string) {
    50  	h.killSignal = signal
    51  }
    52  
    53  func (h *DriverHandle) Kill() error {
    54  	return h.driver.StopTask(h.taskID, h.killTimeout, h.killSignal)
    55  }
    56  
    57  func (h *DriverHandle) Stats(ctx context.Context, interval time.Duration) (<-chan *cstructs.TaskResourceUsage, error) {
    58  	return h.driver.TaskStats(ctx, h.taskID, interval)
    59  }
    60  
    61  func (h *DriverHandle) Signal(s string) error {
    62  	return h.driver.SignalTask(h.taskID, s)
    63  }
    64  
    65  // Exec is the handled used by client endpoint handler to invoke the appropriate task driver exec.
    66  func (h *DriverHandle) Exec(timeout time.Duration, cmd string, args []string) ([]byte, int, error) {
    67  	command := append([]string{cmd}, args...)
    68  	res, err := h.driver.ExecTask(h.taskID, command, timeout)
    69  	if err != nil {
    70  		return nil, 0, err
    71  	}
    72  	return res.Stdout, res.ExitResult.ExitCode, res.ExitResult.Err
    73  }
    74  
    75  // ExecStreaming is the handled used by client endpoint handler to invoke the appropriate task driver exec.
    76  // while allowing to stream input and output
    77  func (h *DriverHandle) ExecStreaming(ctx context.Context,
    78  	command []string,
    79  	tty bool,
    80  	stream drivers.ExecTaskStream) error {
    81  
    82  	if impl, ok := h.driver.(drivers.ExecTaskStreamingRawDriver); ok {
    83  		return impl.ExecTaskStreamingRaw(ctx, h.taskID, command, tty, stream)
    84  	}
    85  
    86  	d, ok := h.driver.(drivers.ExecTaskStreamingDriver)
    87  	if !ok {
    88  		return fmt.Errorf("task driver does not support exec")
    89  	}
    90  
    91  	execOpts, doneCh := drivers.StreamToExecOptions(
    92  		ctx, command, tty, stream)
    93  
    94  	result, err := d.ExecTaskStreaming(ctx, h.taskID, execOpts)
    95  	if err != nil {
    96  		return err
    97  	}
    98  
    99  	execOpts.Stdout.Close()
   100  	execOpts.Stderr.Close()
   101  
   102  	select {
   103  	case err = <-doneCh:
   104  	case <-ctx.Done():
   105  		err = fmt.Errorf("exec task timed out: %v", ctx.Err())
   106  	}
   107  
   108  	if err != nil {
   109  		return err
   110  	}
   111  
   112  	return stream.Send(drivers.NewExecStreamingResponseExit(result.ExitCode))
   113  }
   114  
   115  func (h *DriverHandle) Network() *drivers.DriverNetwork {
   116  	return h.net
   117  }