github.com/hspak/nomad@v0.7.2-0.20180309000617-bc4ae22a39a5/api/tasks.go (about)

     1  package api
     2  
     3  import (
     4  	"fmt"
     5  	"path"
     6  	"path/filepath"
     7  	"strings"
     8  	"time"
     9  
    10  	"github.com/hashicorp/nomad/helper"
    11  	"github.com/hashicorp/nomad/nomad/structs"
    12  )
    13  
    14  // MemoryStats holds memory usage related stats
    15  type MemoryStats struct {
    16  	RSS            uint64
    17  	Cache          uint64
    18  	Swap           uint64
    19  	MaxUsage       uint64
    20  	KernelUsage    uint64
    21  	KernelMaxUsage uint64
    22  	Measured       []string
    23  }
    24  
    25  // CpuStats holds cpu usage related stats
    26  type CpuStats struct {
    27  	SystemMode       float64
    28  	UserMode         float64
    29  	TotalTicks       float64
    30  	ThrottledPeriods uint64
    31  	ThrottledTime    uint64
    32  	Percent          float64
    33  	Measured         []string
    34  }
    35  
    36  // ResourceUsage holds information related to cpu and memory stats
    37  type ResourceUsage struct {
    38  	MemoryStats *MemoryStats
    39  	CpuStats    *CpuStats
    40  }
    41  
    42  // TaskResourceUsage holds aggregated resource usage of all processes in a Task
    43  // and the resource usage of the individual pids
    44  type TaskResourceUsage struct {
    45  	ResourceUsage *ResourceUsage
    46  	Timestamp     int64
    47  	Pids          map[string]*ResourceUsage
    48  }
    49  
    50  // AllocResourceUsage holds the aggregated task resource usage of the
    51  // allocation.
    52  type AllocResourceUsage struct {
    53  	ResourceUsage *ResourceUsage
    54  	Tasks         map[string]*TaskResourceUsage
    55  	Timestamp     int64
    56  }
    57  
    58  // RestartPolicy defines how the Nomad client restarts
    59  // tasks in a taskgroup when they fail
    60  type RestartPolicy struct {
    61  	Interval *time.Duration
    62  	Attempts *int
    63  	Delay    *time.Duration
    64  	Mode     *string
    65  }
    66  
    67  func (r *RestartPolicy) Merge(rp *RestartPolicy) {
    68  	if rp.Interval != nil {
    69  		r.Interval = rp.Interval
    70  	}
    71  	if rp.Attempts != nil {
    72  		r.Attempts = rp.Attempts
    73  	}
    74  	if rp.Delay != nil {
    75  		r.Delay = rp.Delay
    76  	}
    77  	if rp.Mode != nil {
    78  		r.Mode = rp.Mode
    79  	}
    80  }
    81  
    82  // Reschedule configures how Tasks are rescheduled  when they crash or fail.
    83  type ReschedulePolicy struct {
    84  	// Attempts limits the number of rescheduling attempts that can occur in an interval.
    85  	Attempts *int `mapstructure:"attempts"`
    86  
    87  	// Interval is a duration in which we can limit the number of reschedule attempts.
    88  	Interval *time.Duration `mapstructure:"interval"`
    89  }
    90  
    91  func (r *ReschedulePolicy) Merge(rp *ReschedulePolicy) {
    92  	if rp.Interval != nil {
    93  		r.Interval = rp.Interval
    94  	}
    95  	if rp.Attempts != nil {
    96  		r.Attempts = rp.Attempts
    97  	}
    98  }
    99  
   100  func (r *ReschedulePolicy) Copy() *ReschedulePolicy {
   101  	if r == nil {
   102  		return nil
   103  	}
   104  	nrp := new(ReschedulePolicy)
   105  	*nrp = *r
   106  	return nrp
   107  }
   108  
   109  // CheckRestart describes if and when a task should be restarted based on
   110  // failing health checks.
   111  type CheckRestart struct {
   112  	Limit          int            `mapstructure:"limit"`
   113  	Grace          *time.Duration `mapstructure:"grace"`
   114  	IgnoreWarnings bool           `mapstructure:"ignore_warnings"`
   115  }
   116  
   117  // Canonicalize CheckRestart fields if not nil.
   118  func (c *CheckRestart) Canonicalize() {
   119  	if c == nil {
   120  		return
   121  	}
   122  
   123  	if c.Grace == nil {
   124  		c.Grace = helper.TimeToPtr(1 * time.Second)
   125  	}
   126  }
   127  
   128  // Copy returns a copy of CheckRestart or nil if unset.
   129  func (c *CheckRestart) Copy() *CheckRestart {
   130  	if c == nil {
   131  		return nil
   132  	}
   133  
   134  	nc := new(CheckRestart)
   135  	nc.Limit = c.Limit
   136  	if c.Grace != nil {
   137  		g := *c.Grace
   138  		nc.Grace = &g
   139  	}
   140  	nc.IgnoreWarnings = c.IgnoreWarnings
   141  	return nc
   142  }
   143  
   144  // Merge values from other CheckRestart over default values on this
   145  // CheckRestart and return merged copy.
   146  func (c *CheckRestart) Merge(o *CheckRestart) *CheckRestart {
   147  	if c == nil {
   148  		// Just return other
   149  		return o
   150  	}
   151  
   152  	nc := c.Copy()
   153  
   154  	if o == nil {
   155  		// Nothing to merge
   156  		return nc
   157  	}
   158  
   159  	if o.Limit > 0 {
   160  		nc.Limit = o.Limit
   161  	}
   162  
   163  	if o.Grace != nil {
   164  		nc.Grace = o.Grace
   165  	}
   166  
   167  	if o.IgnoreWarnings {
   168  		nc.IgnoreWarnings = o.IgnoreWarnings
   169  	}
   170  
   171  	return nc
   172  }
   173  
   174  // The ServiceCheck data model represents the consul health check that
   175  // Nomad registers for a Task
   176  type ServiceCheck struct {
   177  	Id            string
   178  	Name          string
   179  	Type          string
   180  	Command       string
   181  	Args          []string
   182  	Path          string
   183  	Protocol      string
   184  	PortLabel     string `mapstructure:"port"`
   185  	AddressMode   string `mapstructure:"address_mode"`
   186  	Interval      time.Duration
   187  	Timeout       time.Duration
   188  	InitialStatus string `mapstructure:"initial_status"`
   189  	TLSSkipVerify bool   `mapstructure:"tls_skip_verify"`
   190  	Header        map[string][]string
   191  	Method        string
   192  	CheckRestart  *CheckRestart `mapstructure:"check_restart"`
   193  }
   194  
   195  // The Service model represents a Consul service definition
   196  type Service struct {
   197  	Id           string
   198  	Name         string
   199  	Tags         []string
   200  	PortLabel    string `mapstructure:"port"`
   201  	AddressMode  string `mapstructure:"address_mode"`
   202  	Checks       []ServiceCheck
   203  	CheckRestart *CheckRestart `mapstructure:"check_restart"`
   204  }
   205  
   206  func (s *Service) Canonicalize(t *Task, tg *TaskGroup, job *Job) {
   207  	if s.Name == "" {
   208  		s.Name = fmt.Sprintf("%s-%s-%s", *job.Name, *tg.Name, t.Name)
   209  	}
   210  
   211  	// Default to AddressModeAuto
   212  	if s.AddressMode == "" {
   213  		s.AddressMode = "auto"
   214  	}
   215  
   216  	// Canonicallize CheckRestart on Checks and merge Service.CheckRestart
   217  	// into each check.
   218  	for i, check := range s.Checks {
   219  		s.Checks[i].CheckRestart = s.CheckRestart.Merge(check.CheckRestart)
   220  		s.Checks[i].CheckRestart.Canonicalize()
   221  	}
   222  }
   223  
   224  // EphemeralDisk is an ephemeral disk object
   225  type EphemeralDisk struct {
   226  	Sticky  *bool
   227  	Migrate *bool
   228  	SizeMB  *int `mapstructure:"size"`
   229  }
   230  
   231  func DefaultEphemeralDisk() *EphemeralDisk {
   232  	return &EphemeralDisk{
   233  		Sticky:  helper.BoolToPtr(false),
   234  		Migrate: helper.BoolToPtr(false),
   235  		SizeMB:  helper.IntToPtr(300),
   236  	}
   237  }
   238  
   239  func (e *EphemeralDisk) Canonicalize() {
   240  	if e.Sticky == nil {
   241  		e.Sticky = helper.BoolToPtr(false)
   242  	}
   243  	if e.Migrate == nil {
   244  		e.Migrate = helper.BoolToPtr(false)
   245  	}
   246  	if e.SizeMB == nil {
   247  		e.SizeMB = helper.IntToPtr(300)
   248  	}
   249  }
   250  
   251  // TaskGroup is the unit of scheduling.
   252  type TaskGroup struct {
   253  	Name             *string
   254  	Count            *int
   255  	Constraints      []*Constraint
   256  	Tasks            []*Task
   257  	RestartPolicy    *RestartPolicy
   258  	ReschedulePolicy *ReschedulePolicy
   259  	EphemeralDisk    *EphemeralDisk
   260  	Update           *UpdateStrategy
   261  	Meta             map[string]string
   262  }
   263  
   264  // NewTaskGroup creates a new TaskGroup.
   265  func NewTaskGroup(name string, count int) *TaskGroup {
   266  	return &TaskGroup{
   267  		Name:  helper.StringToPtr(name),
   268  		Count: helper.IntToPtr(count),
   269  	}
   270  }
   271  
   272  func (g *TaskGroup) Canonicalize(job *Job) {
   273  	if g.Name == nil {
   274  		g.Name = helper.StringToPtr("")
   275  	}
   276  	if g.Count == nil {
   277  		g.Count = helper.IntToPtr(1)
   278  	}
   279  	for _, t := range g.Tasks {
   280  		t.Canonicalize(g, job)
   281  	}
   282  	if g.EphemeralDisk == nil {
   283  		g.EphemeralDisk = DefaultEphemeralDisk()
   284  	} else {
   285  		g.EphemeralDisk.Canonicalize()
   286  	}
   287  
   288  	// Merge the update policy from the job
   289  	if ju, tu := job.Update != nil, g.Update != nil; ju && tu {
   290  		// Merge the jobs and task groups definition of the update strategy
   291  		jc := job.Update.Copy()
   292  		jc.Merge(g.Update)
   293  		g.Update = jc
   294  	} else if ju && !job.Update.Empty() {
   295  		// Inherit the jobs as long as it is non-empty.
   296  		jc := job.Update.Copy()
   297  		g.Update = jc
   298  	}
   299  
   300  	if g.Update != nil {
   301  		g.Update.Canonicalize()
   302  	}
   303  
   304  	// Merge the reschedule policy from the job
   305  	if jr, tr := job.Reschedule != nil, g.ReschedulePolicy != nil; jr && tr {
   306  		jobReschedule := job.Reschedule.Copy()
   307  		jobReschedule.Merge(g.ReschedulePolicy)
   308  		g.ReschedulePolicy = jobReschedule
   309  	} else if jr {
   310  		jobReschedule := job.Reschedule.Copy()
   311  		g.ReschedulePolicy = jobReschedule
   312  	}
   313  
   314  	// Merge with default reschedule policy
   315  	var defaultReschedulePolicy *ReschedulePolicy
   316  	switch *job.Type {
   317  	case "service":
   318  		defaultReschedulePolicy = &ReschedulePolicy{
   319  			Attempts: helper.IntToPtr(structs.DefaultServiceJobReschedulePolicy.Attempts),
   320  			Interval: helper.TimeToPtr(structs.DefaultServiceJobReschedulePolicy.Interval),
   321  		}
   322  	case "batch":
   323  		defaultReschedulePolicy = &ReschedulePolicy{
   324  			Attempts: helper.IntToPtr(structs.DefaultBatchJobReschedulePolicy.Attempts),
   325  			Interval: helper.TimeToPtr(structs.DefaultBatchJobReschedulePolicy.Interval),
   326  		}
   327  	default:
   328  		defaultReschedulePolicy = &ReschedulePolicy{
   329  			Attempts: helper.IntToPtr(0),
   330  			Interval: helper.TimeToPtr(0 * time.Second),
   331  		}
   332  	}
   333  
   334  	if g.ReschedulePolicy != nil {
   335  		defaultReschedulePolicy.Merge(g.ReschedulePolicy)
   336  	}
   337  	g.ReschedulePolicy = defaultReschedulePolicy
   338  
   339  	var defaultRestartPolicy *RestartPolicy
   340  	switch *job.Type {
   341  	case "service", "system":
   342  		defaultRestartPolicy = &RestartPolicy{
   343  			Delay:    helper.TimeToPtr(structs.DefaultServiceJobRestartPolicy.Delay),
   344  			Attempts: helper.IntToPtr(structs.DefaultServiceJobRestartPolicy.Attempts),
   345  			Interval: helper.TimeToPtr(structs.DefaultServiceJobRestartPolicy.Interval),
   346  			Mode:     helper.StringToPtr(structs.DefaultServiceJobRestartPolicy.Mode),
   347  		}
   348  	default:
   349  		defaultRestartPolicy = &RestartPolicy{
   350  			Delay:    helper.TimeToPtr(structs.DefaultBatchJobRestartPolicy.Delay),
   351  			Attempts: helper.IntToPtr(structs.DefaultBatchJobRestartPolicy.Attempts),
   352  			Interval: helper.TimeToPtr(structs.DefaultBatchJobRestartPolicy.Interval),
   353  			Mode:     helper.StringToPtr(structs.DefaultBatchJobRestartPolicy.Mode),
   354  		}
   355  	}
   356  
   357  	if g.RestartPolicy != nil {
   358  		defaultRestartPolicy.Merge(g.RestartPolicy)
   359  	}
   360  	g.RestartPolicy = defaultRestartPolicy
   361  }
   362  
   363  // Constrain is used to add a constraint to a task group.
   364  func (g *TaskGroup) Constrain(c *Constraint) *TaskGroup {
   365  	g.Constraints = append(g.Constraints, c)
   366  	return g
   367  }
   368  
   369  // AddMeta is used to add a meta k/v pair to a task group
   370  func (g *TaskGroup) SetMeta(key, val string) *TaskGroup {
   371  	if g.Meta == nil {
   372  		g.Meta = make(map[string]string)
   373  	}
   374  	g.Meta[key] = val
   375  	return g
   376  }
   377  
   378  // AddTask is used to add a new task to a task group.
   379  func (g *TaskGroup) AddTask(t *Task) *TaskGroup {
   380  	g.Tasks = append(g.Tasks, t)
   381  	return g
   382  }
   383  
   384  // RequireDisk adds a ephemeral disk to the task group
   385  func (g *TaskGroup) RequireDisk(disk *EphemeralDisk) *TaskGroup {
   386  	g.EphemeralDisk = disk
   387  	return g
   388  }
   389  
   390  // LogConfig provides configuration for log rotation
   391  type LogConfig struct {
   392  	MaxFiles      *int `mapstructure:"max_files"`
   393  	MaxFileSizeMB *int `mapstructure:"max_file_size"`
   394  }
   395  
   396  func DefaultLogConfig() *LogConfig {
   397  	return &LogConfig{
   398  		MaxFiles:      helper.IntToPtr(10),
   399  		MaxFileSizeMB: helper.IntToPtr(10),
   400  	}
   401  }
   402  
   403  func (l *LogConfig) Canonicalize() {
   404  	if l.MaxFiles == nil {
   405  		l.MaxFiles = helper.IntToPtr(10)
   406  	}
   407  	if l.MaxFileSizeMB == nil {
   408  		l.MaxFileSizeMB = helper.IntToPtr(10)
   409  	}
   410  }
   411  
   412  // DispatchPayloadConfig configures how a task gets its input from a job dispatch
   413  type DispatchPayloadConfig struct {
   414  	File string
   415  }
   416  
   417  // Task is a single process in a task group.
   418  type Task struct {
   419  	Name            string
   420  	Driver          string
   421  	User            string
   422  	Config          map[string]interface{}
   423  	Constraints     []*Constraint
   424  	Env             map[string]string
   425  	Services        []*Service
   426  	Resources       *Resources
   427  	Meta            map[string]string
   428  	KillTimeout     *time.Duration `mapstructure:"kill_timeout"`
   429  	LogConfig       *LogConfig     `mapstructure:"logs"`
   430  	Artifacts       []*TaskArtifact
   431  	Vault           *Vault
   432  	Templates       []*Template
   433  	DispatchPayload *DispatchPayloadConfig
   434  	Leader          bool
   435  	ShutdownDelay   time.Duration `mapstructure:"shutdown_delay"`
   436  	KillSignal      string        `mapstructure:"kill_signal"`
   437  }
   438  
   439  func (t *Task) Canonicalize(tg *TaskGroup, job *Job) {
   440  	if t.Resources == nil {
   441  		t.Resources = &Resources{}
   442  	}
   443  	t.Resources.Canonicalize()
   444  	if t.KillTimeout == nil {
   445  		t.KillTimeout = helper.TimeToPtr(5 * time.Second)
   446  	}
   447  	if t.LogConfig == nil {
   448  		t.LogConfig = DefaultLogConfig()
   449  	} else {
   450  		t.LogConfig.Canonicalize()
   451  	}
   452  	for _, artifact := range t.Artifacts {
   453  		artifact.Canonicalize()
   454  	}
   455  	if t.Vault != nil {
   456  		t.Vault.Canonicalize()
   457  	}
   458  	for _, tmpl := range t.Templates {
   459  		tmpl.Canonicalize()
   460  	}
   461  	for _, s := range t.Services {
   462  		s.Canonicalize(t, tg, job)
   463  	}
   464  }
   465  
   466  // TaskArtifact is used to download artifacts before running a task.
   467  type TaskArtifact struct {
   468  	GetterSource  *string           `mapstructure:"source"`
   469  	GetterOptions map[string]string `mapstructure:"options"`
   470  	GetterMode    *string           `mapstructure:"mode"`
   471  	RelativeDest  *string           `mapstructure:"destination"`
   472  }
   473  
   474  func (a *TaskArtifact) Canonicalize() {
   475  	if a.GetterMode == nil {
   476  		a.GetterMode = helper.StringToPtr("any")
   477  	}
   478  	if a.GetterSource == nil {
   479  		// Shouldn't be possible, but we don't want to panic
   480  		a.GetterSource = helper.StringToPtr("")
   481  	}
   482  	if a.RelativeDest == nil {
   483  		switch *a.GetterMode {
   484  		case "file":
   485  			// File mode should default to local/filename
   486  			dest := *a.GetterSource
   487  			dest = path.Base(dest)
   488  			dest = filepath.Join("local", dest)
   489  			a.RelativeDest = &dest
   490  		default:
   491  			// Default to a directory
   492  			a.RelativeDest = helper.StringToPtr("local/")
   493  		}
   494  	}
   495  }
   496  
   497  type Template struct {
   498  	SourcePath   *string        `mapstructure:"source"`
   499  	DestPath     *string        `mapstructure:"destination"`
   500  	EmbeddedTmpl *string        `mapstructure:"data"`
   501  	ChangeMode   *string        `mapstructure:"change_mode"`
   502  	ChangeSignal *string        `mapstructure:"change_signal"`
   503  	Splay        *time.Duration `mapstructure:"splay"`
   504  	Perms        *string        `mapstructure:"perms"`
   505  	LeftDelim    *string        `mapstructure:"left_delimiter"`
   506  	RightDelim   *string        `mapstructure:"right_delimiter"`
   507  	Envvars      *bool          `mapstructure:"env"`
   508  	VaultGrace   *time.Duration `mapstructure:"vault_grace"`
   509  }
   510  
   511  func (tmpl *Template) Canonicalize() {
   512  	if tmpl.SourcePath == nil {
   513  		tmpl.SourcePath = helper.StringToPtr("")
   514  	}
   515  	if tmpl.DestPath == nil {
   516  		tmpl.DestPath = helper.StringToPtr("")
   517  	}
   518  	if tmpl.EmbeddedTmpl == nil {
   519  		tmpl.EmbeddedTmpl = helper.StringToPtr("")
   520  	}
   521  	if tmpl.ChangeMode == nil {
   522  		tmpl.ChangeMode = helper.StringToPtr("restart")
   523  	}
   524  	if tmpl.ChangeSignal == nil {
   525  		if *tmpl.ChangeMode == "signal" {
   526  			tmpl.ChangeSignal = helper.StringToPtr("SIGHUP")
   527  		} else {
   528  			tmpl.ChangeSignal = helper.StringToPtr("")
   529  		}
   530  	} else {
   531  		sig := *tmpl.ChangeSignal
   532  		tmpl.ChangeSignal = helper.StringToPtr(strings.ToUpper(sig))
   533  	}
   534  	if tmpl.Splay == nil {
   535  		tmpl.Splay = helper.TimeToPtr(5 * time.Second)
   536  	}
   537  	if tmpl.Perms == nil {
   538  		tmpl.Perms = helper.StringToPtr("0644")
   539  	}
   540  	if tmpl.LeftDelim == nil {
   541  		tmpl.LeftDelim = helper.StringToPtr("{{")
   542  	}
   543  	if tmpl.RightDelim == nil {
   544  		tmpl.RightDelim = helper.StringToPtr("}}")
   545  	}
   546  	if tmpl.Envvars == nil {
   547  		tmpl.Envvars = helper.BoolToPtr(false)
   548  	}
   549  	if tmpl.VaultGrace == nil {
   550  		tmpl.VaultGrace = helper.TimeToPtr(15 * time.Second)
   551  	}
   552  }
   553  
   554  type Vault struct {
   555  	Policies     []string
   556  	Env          *bool
   557  	ChangeMode   *string `mapstructure:"change_mode"`
   558  	ChangeSignal *string `mapstructure:"change_signal"`
   559  }
   560  
   561  func (v *Vault) Canonicalize() {
   562  	if v.Env == nil {
   563  		v.Env = helper.BoolToPtr(true)
   564  	}
   565  	if v.ChangeMode == nil {
   566  		v.ChangeMode = helper.StringToPtr("restart")
   567  	}
   568  	if v.ChangeSignal == nil {
   569  		v.ChangeSignal = helper.StringToPtr("SIGHUP")
   570  	}
   571  }
   572  
   573  // NewTask creates and initializes a new Task.
   574  func NewTask(name, driver string) *Task {
   575  	return &Task{
   576  		Name:   name,
   577  		Driver: driver,
   578  	}
   579  }
   580  
   581  // Configure is used to configure a single k/v pair on
   582  // the task.
   583  func (t *Task) SetConfig(key string, val interface{}) *Task {
   584  	if t.Config == nil {
   585  		t.Config = make(map[string]interface{})
   586  	}
   587  	t.Config[key] = val
   588  	return t
   589  }
   590  
   591  // SetMeta is used to add metadata k/v pairs to the task.
   592  func (t *Task) SetMeta(key, val string) *Task {
   593  	if t.Meta == nil {
   594  		t.Meta = make(map[string]string)
   595  	}
   596  	t.Meta[key] = val
   597  	return t
   598  }
   599  
   600  // Require is used to add resource requirements to a task.
   601  func (t *Task) Require(r *Resources) *Task {
   602  	t.Resources = r
   603  	return t
   604  }
   605  
   606  // Constraint adds a new constraints to a single task.
   607  func (t *Task) Constrain(c *Constraint) *Task {
   608  	t.Constraints = append(t.Constraints, c)
   609  	return t
   610  }
   611  
   612  // SetLogConfig sets a log config to a task
   613  func (t *Task) SetLogConfig(l *LogConfig) *Task {
   614  	t.LogConfig = l
   615  	return t
   616  }
   617  
   618  // TaskState tracks the current state of a task and events that caused state
   619  // transitions.
   620  type TaskState struct {
   621  	State       string
   622  	Failed      bool
   623  	Restarts    uint64
   624  	LastRestart time.Time
   625  	StartedAt   time.Time
   626  	FinishedAt  time.Time
   627  	Events      []*TaskEvent
   628  }
   629  
   630  const (
   631  	TaskSetup                  = "Task Setup"
   632  	TaskSetupFailure           = "Setup Failure"
   633  	TaskDriverFailure          = "Driver Failure"
   634  	TaskDriverMessage          = "Driver"
   635  	TaskReceived               = "Received"
   636  	TaskFailedValidation       = "Failed Validation"
   637  	TaskStarted                = "Started"
   638  	TaskTerminated             = "Terminated"
   639  	TaskKilling                = "Killing"
   640  	TaskKilled                 = "Killed"
   641  	TaskRestarting             = "Restarting"
   642  	TaskNotRestarting          = "Not Restarting"
   643  	TaskDownloadingArtifacts   = "Downloading Artifacts"
   644  	TaskArtifactDownloadFailed = "Failed Artifact Download"
   645  	TaskSiblingFailed          = "Sibling Task Failed"
   646  	TaskSignaling              = "Signaling"
   647  	TaskRestartSignal          = "Restart Signaled"
   648  	TaskLeaderDead             = "Leader Task Dead"
   649  	TaskBuildingTaskDir        = "Building Task Directory"
   650  )
   651  
   652  // TaskEvent is an event that effects the state of a task and contains meta-data
   653  // appropriate to the events type.
   654  type TaskEvent struct {
   655  	Type           string
   656  	Time           int64
   657  	DisplayMessage string
   658  	Details        map[string]string
   659  	// DEPRECATION NOTICE: The following fields are all deprecated. see TaskEvent struct in structs.go for details.
   660  	FailsTask        bool
   661  	RestartReason    string
   662  	SetupError       string
   663  	DriverError      string
   664  	DriverMessage    string
   665  	ExitCode         int
   666  	Signal           int
   667  	Message          string
   668  	KillReason       string
   669  	KillTimeout      time.Duration
   670  	KillError        string
   671  	StartDelay       int64
   672  	DownloadError    string
   673  	ValidationError  string
   674  	DiskLimit        int64
   675  	DiskSize         int64
   676  	FailedSibling    string
   677  	VaultError       string
   678  	TaskSignalReason string
   679  	TaskSignal       string
   680  	GenericSource    string
   681  }