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.
106 lines
2.3 KiB
Go
106 lines
2.3 KiB
Go
package state
|
|
|
|
import (
|
|
"github.com/hashicorp/nomad/helper"
|
|
"github.com/hashicorp/nomad/plugins/drivers"
|
|
)
|
|
|
|
// LocalState is Task state which is persisted for use when restarting Nomad
|
|
// agents.
|
|
type LocalState struct {
|
|
Hooks map[string]*HookState
|
|
|
|
// DriverNetwork is the network information returned by the task
|
|
// driver's Start method
|
|
DriverNetwork *drivers.DriverNetwork
|
|
|
|
// TaskHandle is the handle used to reattach to the task during recovery
|
|
TaskHandle *drivers.TaskHandle
|
|
}
|
|
|
|
func NewLocalState() *LocalState {
|
|
return &LocalState{
|
|
Hooks: make(map[string]*HookState),
|
|
}
|
|
}
|
|
|
|
// Canonicalize ensures LocalState is in a consistent state by initializing
|
|
// Hooks and ensuring no HookState's are nil. Useful for cleaning unmarshalled
|
|
// state which may be in an unknown state.
|
|
func (s *LocalState) Canonicalize() {
|
|
if s.Hooks == nil {
|
|
// Hooks is nil, create it
|
|
s.Hooks = make(map[string]*HookState)
|
|
} else {
|
|
for k, v := range s.Hooks {
|
|
// Remove invalid nil entries from Hooks map
|
|
if v == nil {
|
|
delete(s.Hooks, k)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Copy LocalState. Returns nil if nil.
|
|
func (s *LocalState) Copy() *LocalState {
|
|
if s == nil {
|
|
return nil
|
|
}
|
|
|
|
// Create a copy
|
|
c := &LocalState{
|
|
Hooks: make(map[string]*HookState, len(s.Hooks)),
|
|
DriverNetwork: s.DriverNetwork.Copy(),
|
|
TaskHandle: s.TaskHandle.Copy(),
|
|
}
|
|
|
|
// Copy the hook state
|
|
for h, state := range s.Hooks {
|
|
c.Hooks[h] = state.Copy()
|
|
}
|
|
|
|
return c
|
|
}
|
|
|
|
type HookState struct {
|
|
// Prestart is true if the hook has run Prestart successfully and does
|
|
// not need to run again
|
|
PrestartDone bool
|
|
|
|
// Data allows hooks to persist arbitrary state.
|
|
Data map[string]string
|
|
|
|
// Environment variables set by the hook that will continue to be set
|
|
// even if PrestartDone=true.
|
|
Env map[string]string
|
|
}
|
|
|
|
// Copy HookState. Returns nil if its nil.
|
|
func (h *HookState) Copy() *HookState {
|
|
if h == nil {
|
|
return nil
|
|
}
|
|
|
|
c := new(HookState)
|
|
*c = *h
|
|
c.Data = helper.CopyMapStringString(c.Data)
|
|
c.Env = helper.CopyMapStringString(c.Env)
|
|
return c
|
|
}
|
|
|
|
func (h *HookState) Equal(o *HookState) bool {
|
|
if h == nil || o == nil {
|
|
return h == o
|
|
}
|
|
|
|
if h.PrestartDone != o.PrestartDone {
|
|
return false
|
|
}
|
|
|
|
if !helper.CompareMapStringString(h.Data, o.Data) {
|
|
return false
|
|
}
|
|
|
|
return helper.CompareMapStringString(h.Env, o.Env)
|
|
}
|