Browse code

Remove engine.Job references from builder.CmdBuild

Signed-off-by: David Calavera <david.calavera@gmail.com>

David Calavera authored on 2015/04/17 03:11:26
Showing 2 changed files
... ...
@@ -23,6 +23,7 @@ import (
23 23
 	"github.com/docker/docker/api"
24 24
 	"github.com/docker/docker/api/types"
25 25
 	"github.com/docker/docker/autogen/dockerversion"
26
+	"github.com/docker/docker/builder"
26 27
 	"github.com/docker/docker/daemon"
27 28
 	"github.com/docker/docker/daemon/networkdriver/bridge"
28 29
 	"github.com/docker/docker/engine"
... ...
@@ -236,12 +237,12 @@ func writeJSON(w http.ResponseWriter, code int, v interface{}) error {
236 236
 	return json.NewEncoder(w).Encode(v)
237 237
 }
238 238
 
239
-func streamJSON(job *engine.Job, w http.ResponseWriter, flush bool) {
239
+func streamJSON(out *engine.Output, w http.ResponseWriter, flush bool) {
240 240
 	w.Header().Set("Content-Type", "application/json")
241 241
 	if flush {
242
-		job.Stdout.Add(utils.NewWriteFlusher(w))
242
+		out.Add(utils.NewWriteFlusher(w))
243 243
 	} else {
244
-		job.Stdout.Add(w)
244
+		out.Add(w)
245 245
 	}
246 246
 }
247 247
 
... ...
@@ -857,7 +858,7 @@ func (s *Server) postImagesPush(eng *engine.Engine, version version.Version, w h
857 857
 	job.Setenv("tag", r.Form.Get("tag"))
858 858
 	if version.GreaterThan("1.0") {
859 859
 		job.SetenvBool("json", true)
860
-		streamJSON(job, w, true)
860
+		streamJSON(job.Stdout, w, true)
861 861
 	} else {
862 862
 		job.Stdout.Add(utils.NewWriteFlusher(w))
863 863
 	}
... ...
@@ -1207,7 +1208,7 @@ func (s *Server) getContainersByName(eng *engine.Engine, version version.Version
1207 1207
 	if version.LessThan("1.12") {
1208 1208
 		job.SetenvBool("raw", true)
1209 1209
 	}
1210
-	streamJSON(job, w, false)
1210
+	streamJSON(job.Stdout, w, false)
1211 1211
 	return job.Run()
1212 1212
 }
1213 1213
 
... ...
@@ -1232,7 +1233,7 @@ func (s *Server) getImagesByName(eng *engine.Engine, version version.Version, w
1232 1232
 	if version.LessThan("1.12") {
1233 1233
 		job.SetenvBool("raw", true)
1234 1234
 	}
1235
-	streamJSON(job, w, false)
1235
+	streamJSON(job.Stdout, w, false)
1236 1236
 	return job.Run()
1237 1237
 }
1238 1238
 
... ...
@@ -1245,9 +1246,11 @@ func (s *Server) postBuild(eng *engine.Engine, version version.Version, w http.R
1245 1245
 		authConfig        = &registry.AuthConfig{}
1246 1246
 		configFileEncoded = r.Header.Get("X-Registry-Config")
1247 1247
 		configFile        = &registry.ConfigFile{}
1248
-		job               = eng.Job("build")
1248
+		job               = builder.NewBuildConfig(eng.Logging, eng.Stderr)
1249 1249
 	)
1250 1250
 
1251
+	b := &builder.BuilderJob{eng, getDaemon(eng)}
1252
+
1251 1253
 	// This block can be removed when API versions prior to 1.9 are deprecated.
1252 1254
 	// Both headers will be parsed and sent along to the daemon, but if a non-empty
1253 1255
 	// ConfigFile is present, any value provided as an AuthConfig directly will
... ...
@@ -1271,36 +1274,38 @@ func (s *Server) postBuild(eng *engine.Engine, version version.Version, w http.R
1271 1271
 	}
1272 1272
 
1273 1273
 	if version.GreaterThanOrEqualTo("1.8") {
1274
-		job.SetenvBool("json", true)
1275
-		streamJSON(job, w, true)
1274
+		job.JSONFormat = true
1275
+		streamJSON(job.Stdout, w, true)
1276 1276
 	} else {
1277 1277
 		job.Stdout.Add(utils.NewWriteFlusher(w))
1278 1278
 	}
1279 1279
 
1280 1280
 	if toBool(r.FormValue("forcerm")) && version.GreaterThanOrEqualTo("1.12") {
1281
-		job.Setenv("rm", "1")
1281
+		job.Remove = true
1282 1282
 	} else if r.FormValue("rm") == "" && version.GreaterThanOrEqualTo("1.12") {
1283
-		job.Setenv("rm", "1")
1283
+		job.Remove = true
1284 1284
 	} else {
1285
-		job.Setenv("rm", r.FormValue("rm"))
1285
+		job.Remove = toBool(r.FormValue("rm"))
1286 1286
 	}
1287 1287
 	if toBool(r.FormValue("pull")) && version.GreaterThanOrEqualTo("1.16") {
1288
-		job.Setenv("pull", "1")
1288
+		job.Pull = true
1289 1289
 	}
1290 1290
 	job.Stdin.Add(r.Body)
1291
-	job.Setenv("remote", r.FormValue("remote"))
1292
-	job.Setenv("dockerfile", r.FormValue("dockerfile"))
1293
-	job.Setenv("t", r.FormValue("t"))
1294
-	job.Setenv("q", r.FormValue("q"))
1295
-	job.Setenv("nocache", r.FormValue("nocache"))
1296
-	job.Setenv("forcerm", r.FormValue("forcerm"))
1297
-	job.SetenvJson("authConfig", authConfig)
1298
-	job.SetenvJson("configFile", configFile)
1299
-	job.Setenv("memswap", r.FormValue("memswap"))
1300
-	job.Setenv("memory", r.FormValue("memory"))
1301
-	job.Setenv("cpusetcpus", r.FormValue("cpusetcpus"))
1302
-	job.Setenv("cpusetmems", r.FormValue("cpusetmems"))
1303
-	job.Setenv("cpushares", r.FormValue("cpushares"))
1291
+
1292
+	// FIXME(calavera): !!!!! Remote might not be used. Solve the mistery before merging
1293
+	//job.Setenv("remote", r.FormValue("remote"))
1294
+	job.DockerfileName = r.FormValue("dockerfile")
1295
+	job.RepoName = r.FormValue("t")
1296
+	job.SuppressOutput = toBool(r.FormValue("q"))
1297
+	job.NoCache = toBool(r.FormValue("nocache"))
1298
+	job.ForceRemove = toBool(r.FormValue("forcerm"))
1299
+	job.AuthConfig = authConfig
1300
+	job.ConfigFile = configFile
1301
+	job.MemorySwap = toInt64(r.FormValue("memswap"))
1302
+	job.Memory = toInt64(r.FormValue("memory"))
1303
+	job.CpuShares = toInt64(r.FormValue("cpushares"))
1304
+	job.CpuSetCpus = r.FormValue("cpusetcpus")
1305
+	job.CpuSetMems = r.FormValue("cpusetmems")
1304 1306
 
1305 1307
 	// Job cancellation. Note: not all job types support this.
1306 1308
 	if closeNotifier, ok := w.(http.CloseNotifier); ok {
... ...
@@ -1310,13 +1315,13 @@ func (s *Server) postBuild(eng *engine.Engine, version version.Version, w http.R
1310 1310
 			select {
1311 1311
 			case <-finished:
1312 1312
 			case <-closeNotifier.CloseNotify():
1313
-				logrus.Infof("Client disconnected, cancelling job: %s", job.Name)
1313
+				logrus.Infof("Client disconnected, cancelling job: build")
1314 1314
 				job.Cancel()
1315 1315
 			}
1316 1316
 		}()
1317 1317
 	}
1318 1318
 
1319
-	if err := job.Run(); err != nil {
1319
+	if err := b.CmdBuild(job); err != nil {
1320 1320
 		if !job.Stdout.Used() {
1321 1321
 			return err
1322 1322
 		}
... ...
@@ -1676,3 +1681,12 @@ func toBool(s string) bool {
1676 1676
 	s = strings.ToLower(strings.TrimSpace(s))
1677 1677
 	return !(s == "" || s == "0" || s == "no" || s == "false" || s == "none")
1678 1678
 }
1679
+
1680
+// FIXME(calavera): This is a copy of the Env.GetInt64
1681
+func toInt64(s string) int64 {
1682
+	val, err := strconv.ParseInt(s, 10, 64)
1683
+	if err != nil {
1684
+		return 0
1685
+	}
1686
+	return val
1687
+}
... ...
@@ -9,6 +9,7 @@ import (
9 9
 	"os"
10 10
 	"os/exec"
11 11
 	"strings"
12
+	"sync"
12 13
 
13 14
 	"github.com/docker/docker/api"
14 15
 	"github.com/docker/docker/builder/parser"
... ...
@@ -17,6 +18,7 @@ import (
17 17
 	"github.com/docker/docker/graph"
18 18
 	"github.com/docker/docker/pkg/archive"
19 19
 	"github.com/docker/docker/pkg/httputils"
20
+	"github.com/docker/docker/pkg/ioutils"
20 21
 	"github.com/docker/docker/pkg/parsers"
21 22
 	"github.com/docker/docker/pkg/streamformatter"
22 23
 	"github.com/docker/docker/pkg/urlutil"
... ...
@@ -41,41 +43,73 @@ type BuilderJob struct {
41 41
 	Daemon *daemon.Daemon
42 42
 }
43 43
 
44
+type Config struct {
45
+	DockerfileName string
46
+	RemoteURL      string
47
+	RepoName       string
48
+	SuppressOutput bool
49
+	NoCache        bool
50
+	Remove         bool
51
+	ForceRemove    bool
52
+	Pull           bool
53
+	JSONFormat     bool
54
+	Memory         int64
55
+	MemorySwap     int64
56
+	CpuShares      int64
57
+	CpuSetCpus     string
58
+	CpuSetMems     string
59
+	AuthConfig     *registry.AuthConfig
60
+	ConfigFile     *registry.ConfigFile
61
+
62
+	Stdout *engine.Output
63
+	Stderr *engine.Output
64
+	Stdin  *engine.Input
65
+	// When closed, the job has been cancelled.
66
+	// Note: not all jobs implement cancellation.
67
+	// See Job.Cancel() and Job.WaitCancelled()
68
+	cancelled  chan struct{}
69
+	cancelOnce sync.Once
70
+}
71
+
72
+// When called, causes the Job.WaitCancelled channel to unblock.
73
+func (b *Config) Cancel() {
74
+	b.cancelOnce.Do(func() {
75
+		close(b.cancelled)
76
+	})
77
+}
78
+
79
+// Returns a channel which is closed ("never blocks") when the job is cancelled.
80
+func (b *Config) WaitCancelled() <-chan struct{} {
81
+	return b.cancelled
82
+}
83
+
84
+func NewBuildConfig(logging bool, err io.Writer) *Config {
85
+	c := &Config{
86
+		Stdout:    engine.NewOutput(),
87
+		Stderr:    engine.NewOutput(),
88
+		Stdin:     engine.NewInput(),
89
+		cancelled: make(chan struct{}),
90
+	}
91
+	if logging {
92
+		c.Stderr.Add(ioutils.NopWriteCloser(err))
93
+	}
94
+	return c
95
+}
96
+
44 97
 func (b *BuilderJob) Install() {
45
-	b.Engine.Register("build", b.CmdBuild)
46 98
 	b.Engine.Register("build_config", b.CmdBuildConfig)
47 99
 }
48 100
 
49
-func (b *BuilderJob) CmdBuild(job *engine.Job) error {
50
-	if len(job.Args) != 0 {
51
-		return fmt.Errorf("Usage: %s\n", job.Name)
52
-	}
101
+func (b *BuilderJob) CmdBuild(buildConfig *Config) error {
53 102
 	var (
54
-		dockerfileName = job.Getenv("dockerfile")
55
-		remoteURL      = job.Getenv("remote")
56
-		repoName       = job.Getenv("t")
57
-		suppressOutput = job.GetenvBool("q")
58
-		noCache        = job.GetenvBool("nocache")
59
-		rm             = job.GetenvBool("rm")
60
-		forceRm        = job.GetenvBool("forcerm")
61
-		pull           = job.GetenvBool("pull")
62
-		memory         = job.GetenvInt64("memory")
63
-		memorySwap     = job.GetenvInt64("memswap")
64
-		cpuShares      = job.GetenvInt64("cpushares")
65
-		cpuSetCpus     = job.Getenv("cpusetcpus")
66
-		cpuSetMems     = job.Getenv("cpusetmems")
67
-		authConfig     = &registry.AuthConfig{}
68
-		configFile     = &registry.ConfigFile{}
69
-		tag            string
70
-		context        io.ReadCloser
103
+		repoName string
104
+		tag      string
105
+		context  io.ReadCloser
71 106
 	)
72 107
 
73
-	job.GetenvJson("authConfig", authConfig)
74
-	job.GetenvJson("configFile", configFile)
75
-
76
-	repoName, tag = parsers.ParseRepositoryTag(repoName)
108
+	repoName, tag = parsers.ParseRepositoryTag(buildConfig.RepoName)
77 109
 	if repoName != "" {
78
-		if err := registry.ValidateRepositoryName(repoName); err != nil {
110
+		if err := registry.ValidateRepositoryName(buildConfig.RepoName); err != nil {
79 111
 			return err
80 112
 		}
81 113
 		if len(tag) > 0 {
... ...
@@ -85,11 +119,11 @@ func (b *BuilderJob) CmdBuild(job *engine.Job) error {
85 85
 		}
86 86
 	}
87 87
 
88
-	if remoteURL == "" {
89
-		context = ioutil.NopCloser(job.Stdin)
90
-	} else if urlutil.IsGitURL(remoteURL) {
91
-		if !urlutil.IsGitTransport(remoteURL) {
92
-			remoteURL = "https://" + remoteURL
88
+	if buildConfig.RemoteURL == "" {
89
+		context = ioutil.NopCloser(buildConfig.Stdin)
90
+	} else if urlutil.IsGitURL(buildConfig.RemoteURL) {
91
+		if !urlutil.IsGitTransport(buildConfig.RemoteURL) {
92
+			buildConfig.RemoteURL = "https://" + buildConfig.RemoteURL
93 93
 		}
94 94
 		root, err := ioutil.TempDir("", "docker-build-git")
95 95
 		if err != nil {
... ...
@@ -97,7 +131,7 @@ func (b *BuilderJob) CmdBuild(job *engine.Job) error {
97 97
 		}
98 98
 		defer os.RemoveAll(root)
99 99
 
100
-		if output, err := exec.Command("git", "clone", "--recursive", remoteURL, root).CombinedOutput(); err != nil {
100
+		if output, err := exec.Command("git", "clone", "--recursive", buildConfig.RemoteURL, root).CombinedOutput(); err != nil {
101 101
 			return fmt.Errorf("Error trying to use git: %s (%s)", err, output)
102 102
 		}
103 103
 
... ...
@@ -106,8 +140,8 @@ func (b *BuilderJob) CmdBuild(job *engine.Job) error {
106 106
 			return err
107 107
 		}
108 108
 		context = c
109
-	} else if urlutil.IsURL(remoteURL) {
110
-		f, err := httputils.Download(remoteURL)
109
+	} else if urlutil.IsURL(buildConfig.RemoteURL) {
110
+		f, err := httputils.Download(buildConfig.RemoteURL)
111 111
 		if err != nil {
112 112
 			return err
113 113
 		}
... ...
@@ -119,9 +153,9 @@ func (b *BuilderJob) CmdBuild(job *engine.Job) error {
119 119
 
120 120
 		// When we're downloading just a Dockerfile put it in
121 121
 		// the default name - don't allow the client to move/specify it
122
-		dockerfileName = api.DefaultDockerfileName
122
+		buildConfig.DockerfileName = api.DefaultDockerfileName
123 123
 
124
-		c, err := archive.Generate(dockerfileName, string(dockerFile))
124
+		c, err := archive.Generate(buildConfig.DockerfileName, string(dockerFile))
125 125
 		if err != nil {
126 126
 			return err
127 127
 		}
... ...
@@ -129,35 +163,35 @@ func (b *BuilderJob) CmdBuild(job *engine.Job) error {
129 129
 	}
130 130
 	defer context.Close()
131 131
 
132
-	sf := streamformatter.NewStreamFormatter(job.GetenvBool("json"))
132
+	sf := streamformatter.NewStreamFormatter(buildConfig.JSONFormat)
133 133
 
134 134
 	builder := &Builder{
135 135
 		Daemon: b.Daemon,
136 136
 		Engine: b.Engine,
137 137
 		OutStream: &streamformatter.StdoutFormater{
138
-			Writer:          job.Stdout,
138
+			Writer:          buildConfig.Stdout,
139 139
 			StreamFormatter: sf,
140 140
 		},
141 141
 		ErrStream: &streamformatter.StderrFormater{
142
-			Writer:          job.Stdout,
142
+			Writer:          buildConfig.Stdout,
143 143
 			StreamFormatter: sf,
144 144
 		},
145
-		Verbose:         !suppressOutput,
146
-		UtilizeCache:    !noCache,
147
-		Remove:          rm,
148
-		ForceRemove:     forceRm,
149
-		Pull:            pull,
150
-		OutOld:          job.Stdout,
145
+		Verbose:         !buildConfig.SuppressOutput,
146
+		UtilizeCache:    !buildConfig.NoCache,
147
+		Remove:          buildConfig.Remove,
148
+		ForceRemove:     buildConfig.ForceRemove,
149
+		Pull:            buildConfig.Pull,
150
+		OutOld:          buildConfig.Stdout,
151 151
 		StreamFormatter: sf,
152
-		AuthConfig:      authConfig,
153
-		ConfigFile:      configFile,
154
-		dockerfileName:  dockerfileName,
155
-		cpuShares:       cpuShares,
156
-		cpuSetCpus:      cpuSetCpus,
157
-		cpuSetMems:      cpuSetMems,
158
-		memory:          memory,
159
-		memorySwap:      memorySwap,
160
-		cancelled:       job.WaitCancelled(),
152
+		AuthConfig:      buildConfig.AuthConfig,
153
+		ConfigFile:      buildConfig.ConfigFile,
154
+		dockerfileName:  buildConfig.DockerfileName,
155
+		cpuShares:       buildConfig.CpuShares,
156
+		cpuSetCpus:      buildConfig.CpuSetCpus,
157
+		cpuSetMems:      buildConfig.CpuSetMems,
158
+		memory:          buildConfig.Memory,
159
+		memorySwap:      buildConfig.MemorySwap,
160
+		cancelled:       buildConfig.WaitCancelled(),
161 161
 	}
162 162
 
163 163
 	id, err := builder.Run(context)