open-nomad/client/allocrunnerv2/taskrunner/lifecycle.go

102 lines
2.5 KiB
Go
Raw Normal View History

2018-07-12 23:15:33 +00:00
package taskrunner
import (
"context"
"os"
2018-07-12 23:15:33 +00:00
"github.com/hashicorp/nomad/nomad/structs"
)
func (tr *TaskRunner) Restart(ctx context.Context, event *structs.TaskEvent, failure bool) error {
// Grab the handle
handle := tr.getDriverHandle()
// Check it is running
if handle == nil {
return ErrTaskNotRunning
}
// Emit the event since it may take a long time to kill
tr.EmitEvent(event)
// Tell the restart tracker that a restart triggered the exit
tr.restartTracker.SetRestartTriggered(failure)
// Kill the task using an exponential backoff in-case of failures.
destroySuccess, err := tr.handleDestroy(handle)
if !destroySuccess {
// We couldn't successfully destroy the resource created.
tr.logger.Error("failed to kill task. Resources may have been leaked", "error", err)
}
// Drain the wait channel or wait for the request context to be cancelled
select {
case <-handle.WaitCh():
case <-ctx.Done():
return ctx.Err()
}
2018-07-12 23:15:33 +00:00
return nil
}
func (tr *TaskRunner) Signal(event *structs.TaskEvent, s os.Signal) error {
// Grab the handle
handle := tr.getDriverHandle()
// Check it is running
if handle == nil {
return ErrTaskNotRunning
}
// Emit the event
tr.EmitEvent(event)
// Send the signal
return handle.Signal(s)
}
// Kill a task. Blocks until task exits or context is canceled. State is set to
// dead.
func (tr *TaskRunner) Kill(ctx context.Context, event *structs.TaskEvent) error {
// Grab the handle
handle := tr.getDriverHandle()
// Check if the handle is running
if handle == nil {
return ErrTaskNotRunning
}
// Emit the event since it may take a long time to kill
tr.EmitEvent(event)
// Run the hooks prior to killing the task
tr.kill()
// Tell the restart tracker that the task has been killed
tr.restartTracker.SetKilled()
// Kill the task using an exponential backoff in-case of failures.
destroySuccess, destroyErr := tr.handleDestroy(handle)
if !destroySuccess {
// We couldn't successfully destroy the resource created.
tr.logger.Error("failed to kill task. Resources may have been leaked", "error", destroyErr)
}
// Drain the wait channel or wait for the request context to be cancelled
select {
case <-handle.WaitCh():
case <-ctx.Done():
}
// Store that the task has been destroyed and any associated error.
tr.UpdateState(structs.TaskStateDead, structs.NewTaskEvent(structs.TaskKilled).SetKillError(destroyErr))
if destroyErr != nil {
return destroyErr
} else if err := ctx.Err(); err != nil {
return err
}
return nil
2018-07-12 23:15:33 +00:00
}