job.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. package builder
  2. import (
  3. "io"
  4. "io/ioutil"
  5. "os"
  6. "os/exec"
  7. "github.com/docker/docker/api"
  8. "github.com/docker/docker/daemon"
  9. "github.com/docker/docker/engine"
  10. "github.com/docker/docker/graph"
  11. "github.com/docker/docker/pkg/archive"
  12. "github.com/docker/docker/pkg/parsers"
  13. "github.com/docker/docker/pkg/urlutil"
  14. "github.com/docker/docker/registry"
  15. "github.com/docker/docker/utils"
  16. )
  17. type BuilderJob struct {
  18. Engine *engine.Engine
  19. Daemon *daemon.Daemon
  20. }
  21. func (b *BuilderJob) Install() {
  22. b.Engine.Register("build", b.CmdBuild)
  23. }
  24. func (b *BuilderJob) CmdBuild(job *engine.Job) engine.Status {
  25. if len(job.Args) != 0 {
  26. return job.Errorf("Usage: %s\n", job.Name)
  27. }
  28. var (
  29. dockerfileName = job.Getenv("dockerfile")
  30. remoteURL = job.Getenv("remote")
  31. repoName = job.Getenv("t")
  32. suppressOutput = job.GetenvBool("q")
  33. noCache = job.GetenvBool("nocache")
  34. rm = job.GetenvBool("rm")
  35. forceRm = job.GetenvBool("forcerm")
  36. pull = job.GetenvBool("pull")
  37. authConfig = &registry.AuthConfig{}
  38. configFile = &registry.ConfigFile{}
  39. tag string
  40. context io.ReadCloser
  41. )
  42. job.GetenvJson("authConfig", authConfig)
  43. job.GetenvJson("configFile", configFile)
  44. repoName, tag = parsers.ParseRepositoryTag(repoName)
  45. if repoName != "" {
  46. if err := registry.ValidateRepositoryName(repoName); err != nil {
  47. return job.Error(err)
  48. }
  49. if len(tag) > 0 {
  50. if err := graph.ValidateTagName(tag); err != nil {
  51. return job.Error(err)
  52. }
  53. }
  54. }
  55. if dockerfileName == "" {
  56. dockerfileName = api.DefaultDockerfileName
  57. }
  58. if remoteURL == "" {
  59. context = ioutil.NopCloser(job.Stdin)
  60. } else if urlutil.IsGitURL(remoteURL) {
  61. if !urlutil.IsGitTransport(remoteURL) {
  62. remoteURL = "https://" + remoteURL
  63. }
  64. root, err := ioutil.TempDir("", "docker-build-git")
  65. if err != nil {
  66. return job.Error(err)
  67. }
  68. defer os.RemoveAll(root)
  69. if output, err := exec.Command("git", "clone", "--recursive", remoteURL, root).CombinedOutput(); err != nil {
  70. return job.Errorf("Error trying to use git: %s (%s)", err, output)
  71. }
  72. c, err := archive.Tar(root, archive.Uncompressed)
  73. if err != nil {
  74. return job.Error(err)
  75. }
  76. context = c
  77. } else if urlutil.IsURL(remoteURL) {
  78. f, err := utils.Download(remoteURL)
  79. if err != nil {
  80. return job.Error(err)
  81. }
  82. defer f.Body.Close()
  83. dockerFile, err := ioutil.ReadAll(f.Body)
  84. if err != nil {
  85. return job.Error(err)
  86. }
  87. c, err := archive.Generate(dockerfileName, string(dockerFile))
  88. if err != nil {
  89. return job.Error(err)
  90. }
  91. context = c
  92. }
  93. defer context.Close()
  94. sf := utils.NewStreamFormatter(job.GetenvBool("json"))
  95. builder := &Builder{
  96. Daemon: b.Daemon,
  97. Engine: b.Engine,
  98. OutStream: &utils.StdoutFormater{
  99. Writer: job.Stdout,
  100. StreamFormatter: sf,
  101. },
  102. ErrStream: &utils.StderrFormater{
  103. Writer: job.Stdout,
  104. StreamFormatter: sf,
  105. },
  106. Verbose: !suppressOutput,
  107. UtilizeCache: !noCache,
  108. Remove: rm,
  109. ForceRemove: forceRm,
  110. Pull: pull,
  111. OutOld: job.Stdout,
  112. StreamFormatter: sf,
  113. AuthConfig: authConfig,
  114. AuthConfigFile: configFile,
  115. dockerfileName: dockerfileName,
  116. }
  117. id, err := builder.Run(context)
  118. if err != nil {
  119. return job.Error(err)
  120. }
  121. if repoName != "" {
  122. b.Daemon.Repositories().Set(repoName, tag, id, true)
  123. }
  124. return engine.StatusOK
  125. }