2018-10-04 19:08:20 +00:00
|
|
|
package taskrunner
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2019-04-28 21:22:53 +00:00
|
|
|
"fmt"
|
2018-10-04 19:08:20 +00:00
|
|
|
"time"
|
|
|
|
|
|
|
|
cstructs "github.com/hashicorp/nomad/client/structs"
|
|
|
|
"github.com/hashicorp/nomad/nomad/structs"
|
|
|
|
"github.com/hashicorp/nomad/plugins/drivers"
|
|
|
|
)
|
|
|
|
|
2018-10-10 03:01:20 +00:00
|
|
|
// NewDriverHandle returns a handle for task operations on a specific task
|
2019-01-04 23:01:35 +00:00
|
|
|
func NewDriverHandle(driver drivers.DriverPlugin, taskID string, task *structs.Task, net *drivers.DriverNetwork) *DriverHandle {
|
2018-10-10 03:01:20 +00:00
|
|
|
return &DriverHandle{
|
2020-12-17 23:21:46 +00:00
|
|
|
driver: driver,
|
|
|
|
net: net,
|
|
|
|
taskID: taskID,
|
|
|
|
killSignal: task.KillSignal,
|
|
|
|
killTimeout: task.KillTimeout,
|
2018-10-04 19:08:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-10 03:01:20 +00:00
|
|
|
// DriverHandle encapsulates a driver plugin client and task identifier and exposes
|
|
|
|
// an api to perform driver operations on the task
|
|
|
|
type DriverHandle struct {
|
2020-12-17 23:21:46 +00:00
|
|
|
driver drivers.DriverPlugin
|
|
|
|
net *drivers.DriverNetwork
|
|
|
|
taskID string
|
|
|
|
killSignal string
|
|
|
|
killTimeout time.Duration
|
2018-10-04 19:08:20 +00:00
|
|
|
}
|
|
|
|
|
2018-10-10 03:01:20 +00:00
|
|
|
func (h *DriverHandle) ID() string {
|
2018-10-04 19:08:20 +00:00
|
|
|
return h.taskID
|
|
|
|
}
|
|
|
|
|
2018-10-10 03:01:20 +00:00
|
|
|
func (h *DriverHandle) WaitCh(ctx context.Context) (<-chan *drivers.ExitResult, error) {
|
2018-10-04 19:08:20 +00:00
|
|
|
return h.driver.WaitTask(ctx, h.taskID)
|
|
|
|
}
|
|
|
|
|
2020-12-17 23:21:46 +00:00
|
|
|
// SetKillSignal allows overriding the signal sent to kill the task.
|
|
|
|
func (h *DriverHandle) SetKillSignal(signal string) {
|
|
|
|
h.killSignal = signal
|
2018-10-04 19:08:20 +00:00
|
|
|
}
|
|
|
|
|
2018-10-10 03:01:20 +00:00
|
|
|
func (h *DriverHandle) Kill() error {
|
2020-12-17 23:21:46 +00:00
|
|
|
return h.driver.StopTask(h.taskID, h.killTimeout, h.killSignal)
|
2018-10-04 19:08:20 +00:00
|
|
|
}
|
|
|
|
|
2018-12-11 20:27:50 +00:00
|
|
|
func (h *DriverHandle) Stats(ctx context.Context, interval time.Duration) (<-chan *cstructs.TaskResourceUsage, error) {
|
|
|
|
return h.driver.TaskStats(ctx, h.taskID, interval)
|
2018-10-04 19:08:20 +00:00
|
|
|
}
|
|
|
|
|
2018-10-10 03:01:20 +00:00
|
|
|
func (h *DriverHandle) Signal(s string) error {
|
2018-10-04 19:08:20 +00:00
|
|
|
return h.driver.SignalTask(h.taskID, s)
|
|
|
|
}
|
|
|
|
|
2019-04-28 21:22:53 +00:00
|
|
|
// Exec is the handled used by client endpoint handler to invoke the appropriate task driver exec.
|
2018-10-10 03:01:20 +00:00
|
|
|
func (h *DriverHandle) Exec(timeout time.Duration, cmd string, args []string) ([]byte, int, error) {
|
2018-10-04 19:08:20 +00:00
|
|
|
command := append([]string{cmd}, args...)
|
|
|
|
res, err := h.driver.ExecTask(h.taskID, command, timeout)
|
|
|
|
if err != nil {
|
|
|
|
return nil, 0, err
|
|
|
|
}
|
|
|
|
return res.Stdout, res.ExitResult.ExitCode, res.ExitResult.Err
|
|
|
|
}
|
|
|
|
|
2019-04-28 21:22:53 +00:00
|
|
|
// ExecStreaming is the handled used by client endpoint handler to invoke the appropriate task driver exec.
|
|
|
|
// while allowing to stream input and output
|
|
|
|
func (h *DriverHandle) ExecStreaming(ctx context.Context,
|
|
|
|
command []string,
|
|
|
|
tty bool,
|
|
|
|
stream drivers.ExecTaskStream) error {
|
|
|
|
|
|
|
|
if impl, ok := h.driver.(drivers.ExecTaskStreamingRawDriver); ok {
|
|
|
|
return impl.ExecTaskStreamingRaw(ctx, h.taskID, command, tty, stream)
|
|
|
|
}
|
|
|
|
|
|
|
|
d, ok := h.driver.(drivers.ExecTaskStreamingDriver)
|
|
|
|
if !ok {
|
|
|
|
return fmt.Errorf("task driver does not support exec")
|
|
|
|
}
|
|
|
|
|
|
|
|
execOpts, doneCh := drivers.StreamToExecOptions(
|
|
|
|
ctx, command, tty, stream)
|
|
|
|
|
|
|
|
result, err := d.ExecTaskStreaming(ctx, h.taskID, execOpts)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
execOpts.Stdout.Close()
|
|
|
|
execOpts.Stderr.Close()
|
|
|
|
|
|
|
|
select {
|
|
|
|
case err = <-doneCh:
|
|
|
|
case <-ctx.Done():
|
|
|
|
err = fmt.Errorf("exec task timed out: %v", ctx.Err())
|
|
|
|
}
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return stream.Send(drivers.NewExecStreamingResponseExit(result.ExitCode))
|
|
|
|
}
|
|
|
|
|
2019-01-04 23:01:35 +00:00
|
|
|
func (h *DriverHandle) Network() *drivers.DriverNetwork {
|
2018-10-04 19:08:20 +00:00
|
|
|
return h.net
|
|
|
|
}
|