PageRenderTime 40ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/third_party/src/github.com/fsouza/go-dockerclient/engine/job.go

https://github.com/zbd0518/kubernetes
Go | 197 lines | 136 code | 30 blank | 31 comment | 15 complexity | c1fadbd0e6a648e45bee1219777dfd54 MD5 | raw file
Possible License(s): Apache-2.0, BSD-3-Clause, LGPL-3.0
  1. // Copyright 2014 Docker authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the DOCKER-LICENSE file.
  4. package engine
  5. import (
  6. "fmt"
  7. "io"
  8. "strings"
  9. "time"
  10. )
  11. // A job is the fundamental unit of work in the docker engine.
  12. // Everything docker can do should eventually be exposed as a job.
  13. // For example: execute a process in a container, create a new container,
  14. // download an archive from the internet, serve the http api, etc.
  15. //
  16. // The job API is designed after unix processes: a job has a name, arguments,
  17. // environment variables, standard streams for input, output and error, and
  18. // an exit status which can indicate success (0) or error (anything else).
  19. //
  20. // One slight variation is that jobs report their status as a string. The
  21. // string "0" indicates success, and any other strings indicates an error.
  22. // This allows for richer error reporting.
  23. //
  24. type Job struct {
  25. Eng *Engine
  26. Name string
  27. Args []string
  28. env *Env
  29. Stdout *Output
  30. Stderr *Output
  31. Stdin *Input
  32. handler Handler
  33. status Status
  34. end time.Time
  35. onExit []func()
  36. }
  37. type Status int
  38. const (
  39. StatusOK Status = 0
  40. StatusErr Status = 1
  41. StatusNotFound Status = 127
  42. )
  43. // Run executes the job and blocks until the job completes.
  44. // If the job returns a failure status, an error is returned
  45. // which includes the status.
  46. func (job *Job) Run() error {
  47. // FIXME: make this thread-safe
  48. // FIXME: implement wait
  49. if !job.end.IsZero() {
  50. return fmt.Errorf("%s: job has already completed", job.Name)
  51. }
  52. // Log beginning and end of the job
  53. job.Eng.Logf("+job %s", job.CallString())
  54. defer func() {
  55. job.Eng.Logf("-job %s%s", job.CallString(), job.StatusString())
  56. }()
  57. var errorMessage string
  58. job.Stderr.AddString(&errorMessage)
  59. if job.handler == nil {
  60. job.Errorf("%s: command not found", job.Name)
  61. job.status = 127
  62. } else {
  63. job.status = job.handler(job)
  64. job.end = time.Now()
  65. }
  66. // Wait for all background tasks to complete
  67. if err := job.Stdout.Close(); err != nil {
  68. return err
  69. }
  70. if err := job.Stderr.Close(); err != nil {
  71. return err
  72. }
  73. if job.status != 0 {
  74. return fmt.Errorf("%s: %s", job.Name, errorMessage)
  75. }
  76. return nil
  77. }
  78. func (job *Job) CallString() string {
  79. return fmt.Sprintf("%s(%s)", job.Name, strings.Join(job.Args, ", "))
  80. }
  81. func (job *Job) StatusString() string {
  82. // If the job hasn't completed, status string is empty
  83. if job.end.IsZero() {
  84. return ""
  85. }
  86. var okerr string
  87. if job.status == StatusOK {
  88. okerr = "OK"
  89. } else {
  90. okerr = "ERR"
  91. }
  92. return fmt.Sprintf(" = %s (%d)", okerr, job.status)
  93. }
  94. // String returns a human-readable description of `job`
  95. func (job *Job) String() string {
  96. return fmt.Sprintf("%s.%s%s", job.Eng, job.CallString(), job.StatusString())
  97. }
  98. func (job *Job) Getenv(key string) (value string) {
  99. return job.env.Get(key)
  100. }
  101. func (job *Job) GetenvBool(key string) (value bool) {
  102. return job.env.GetBool(key)
  103. }
  104. func (job *Job) SetenvBool(key string, value bool) {
  105. job.env.SetBool(key, value)
  106. }
  107. func (job *Job) GetenvInt64(key string) int64 {
  108. return job.env.GetInt64(key)
  109. }
  110. func (job *Job) GetenvInt(key string) int {
  111. return job.env.GetInt(key)
  112. }
  113. func (job *Job) SetenvInt64(key string, value int64) {
  114. job.env.SetInt64(key, value)
  115. }
  116. func (job *Job) SetenvInt(key string, value int) {
  117. job.env.SetInt(key, value)
  118. }
  119. // Returns nil if key not found
  120. func (job *Job) GetenvList(key string) []string {
  121. return job.env.GetList(key)
  122. }
  123. func (job *Job) GetenvJson(key string, iface interface{}) error {
  124. return job.env.GetJson(key, iface)
  125. }
  126. func (job *Job) SetenvJson(key string, value interface{}) error {
  127. return job.env.SetJson(key, value)
  128. }
  129. func (job *Job) SetenvList(key string, value []string) error {
  130. return job.env.SetJson(key, value)
  131. }
  132. func (job *Job) Setenv(key, value string) {
  133. job.env.Set(key, value)
  134. }
  135. // DecodeEnv decodes `src` as a json dictionary, and adds
  136. // each decoded key-value pair to the environment.
  137. //
  138. // If `src` cannot be decoded as a json dictionary, an error
  139. // is returned.
  140. func (job *Job) DecodeEnv(src io.Reader) error {
  141. return job.env.Decode(src)
  142. }
  143. func (job *Job) EncodeEnv(dst io.Writer) error {
  144. return job.env.Encode(dst)
  145. }
  146. func (job *Job) ExportEnv(dst interface{}) (err error) {
  147. return job.env.Export(dst)
  148. }
  149. func (job *Job) ImportEnv(src interface{}) (err error) {
  150. return job.env.Import(src)
  151. }
  152. func (job *Job) Environ() map[string]string {
  153. return job.env.Map()
  154. }
  155. func (job *Job) Logf(format string, args ...interface{}) (n int, err error) {
  156. prefixedFormat := fmt.Sprintf("[%s] %s\n", job, strings.TrimRight(format, "\n"))
  157. return fmt.Fprintf(job.Stderr, prefixedFormat, args...)
  158. }
  159. func (job *Job) Printf(format string, args ...interface{}) (n int, err error) {
  160. return fmt.Fprintf(job.Stdout, format, args...)
  161. }
  162. func (job *Job) Errorf(format string, args ...interface{}) (n int, err error) {
  163. return fmt.Fprintf(job.Stderr, format, args...)
  164. }
  165. func (job *Job) Error(err error) (int, error) {
  166. return fmt.Fprintf(job.Stderr, "%s", err)
  167. }