ef8d284352
This commit is a significant change. TR.Run is now always executed, even for terminal allocations. This was changed to allow TR.Run to cleanup (run stop hooks) if a handle was recovered. This is intended to handle the case of Nomad receiving a DesiredStatus=Stop allocation update, persisting it, but crashing before stopping AR/TR. The commit also renames task runner hook data as it was very easy to accidently set state on Requests instead of Responses using the old field names.
130 lines
3.2 KiB
Go
130 lines
3.2 KiB
Go
package taskrunner
|
|
|
|
import (
|
|
"github.com/hashicorp/nomad/client/allocrunner/taskrunner/state"
|
|
"github.com/hashicorp/nomad/nomad/structs"
|
|
)
|
|
|
|
func (tr *TaskRunner) Alloc() *structs.Allocation {
|
|
tr.allocLock.Lock()
|
|
defer tr.allocLock.Unlock()
|
|
return tr.alloc
|
|
}
|
|
|
|
// setAlloc and task on TaskRunner
|
|
func (tr *TaskRunner) setAlloc(updated *structs.Allocation, task *structs.Task) {
|
|
tr.allocLock.Lock()
|
|
defer tr.allocLock.Unlock()
|
|
|
|
tr.taskLock.Lock()
|
|
defer tr.taskLock.Unlock()
|
|
|
|
tr.alloc = updated
|
|
tr.task = task
|
|
}
|
|
|
|
// IsLeader returns true if this task is the leader of its task group.
|
|
func (tr *TaskRunner) IsLeader() bool {
|
|
return tr.taskLeader
|
|
}
|
|
|
|
func (tr *TaskRunner) Task() *structs.Task {
|
|
tr.taskLock.RLock()
|
|
defer tr.taskLock.RUnlock()
|
|
return tr.task
|
|
}
|
|
|
|
func (tr *TaskRunner) TaskState() *structs.TaskState {
|
|
tr.stateLock.Lock()
|
|
defer tr.stateLock.Unlock()
|
|
return tr.state.Copy()
|
|
}
|
|
|
|
func (tr *TaskRunner) getVaultToken() string {
|
|
tr.vaultTokenLock.Lock()
|
|
defer tr.vaultTokenLock.Unlock()
|
|
return tr.vaultToken
|
|
}
|
|
|
|
// setVaultToken updates the vault token on the task runner as well as in the
|
|
// task's environment. These two places must be set atomically to avoid a task
|
|
// seeing a different token on the task runner and in its environment.
|
|
func (tr *TaskRunner) setVaultToken(token string) {
|
|
tr.vaultTokenLock.Lock()
|
|
defer tr.vaultTokenLock.Unlock()
|
|
|
|
// Update the Vault token on the runner
|
|
tr.vaultToken = token
|
|
|
|
// Update the task's environment
|
|
tr.envBuilder.SetVaultToken(token, tr.task.Vault.Env)
|
|
}
|
|
|
|
// getDriverHandle returns a driver handle.
|
|
func (tr *TaskRunner) getDriverHandle() *DriverHandle {
|
|
tr.handleLock.Lock()
|
|
defer tr.handleLock.Unlock()
|
|
return tr.handle
|
|
}
|
|
|
|
// setDriverHandle sets the driver handle and updates the driver network in the
|
|
// task's environment.
|
|
func (tr *TaskRunner) setDriverHandle(handle *DriverHandle) {
|
|
tr.handleLock.Lock()
|
|
defer tr.handleLock.Unlock()
|
|
tr.handle = handle
|
|
|
|
// Update the environment's driver network
|
|
tr.envBuilder.SetDriverNetwork(handle.net)
|
|
}
|
|
|
|
func (tr *TaskRunner) clearDriverHandle() {
|
|
tr.handleLock.Lock()
|
|
defer tr.handleLock.Unlock()
|
|
if tr.handle != nil {
|
|
tr.driver.DestroyTask(tr.handle.ID(), true)
|
|
}
|
|
tr.handle = nil
|
|
}
|
|
|
|
// setKillErr stores any error that arouse while killing the task
|
|
func (tr *TaskRunner) setKillErr(err error) {
|
|
tr.killErrLock.Lock()
|
|
defer tr.killErrLock.Unlock()
|
|
tr.killErr = err
|
|
}
|
|
|
|
// getKillErr returns any error that arouse while killing the task
|
|
func (tr *TaskRunner) getKillErr() error {
|
|
tr.killErrLock.Lock()
|
|
defer tr.killErrLock.Unlock()
|
|
return tr.killErr
|
|
}
|
|
|
|
// setRunLaunched marks the fact that the Run loop has been started
|
|
func (tr *TaskRunner) setRunLaunched() {
|
|
tr.runLaunchedLock.Lock()
|
|
defer tr.runLaunchedLock.Unlock()
|
|
tr.runLaunched = true
|
|
}
|
|
|
|
// hasRunLaunched returns whether the Run loop has been started
|
|
func (tr *TaskRunner) hasRunLaunched() bool {
|
|
tr.runLaunchedLock.Lock()
|
|
defer tr.runLaunchedLock.Unlock()
|
|
return tr.runLaunched
|
|
}
|
|
|
|
// hookState returns the state for the given hook or nil if no state is
|
|
// persisted for the hook.
|
|
func (tr *TaskRunner) hookState(name string) *state.HookState {
|
|
tr.stateLock.RLock()
|
|
defer tr.stateLock.RUnlock()
|
|
|
|
var s *state.HookState
|
|
if tr.localState.Hooks != nil {
|
|
s = tr.localState.Hooks[name].Copy()
|
|
}
|
|
return s
|
|
}
|