mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Remove engine.Job references from builder.CmdBuild
Signed-off-by: David Calavera <david.calavera@gmail.com>
This commit is contained in:
parent
f85eb4baad
commit
9a2c009751
2 changed files with 131 additions and 83 deletions
|
@ -23,6 +23,7 @@ import (
|
|||
"github.com/docker/docker/api"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/autogen/dockerversion"
|
||||
"github.com/docker/docker/builder"
|
||||
"github.com/docker/docker/daemon"
|
||||
"github.com/docker/docker/daemon/networkdriver/bridge"
|
||||
"github.com/docker/docker/engine"
|
||||
|
@ -236,12 +237,12 @@ func writeJSON(w http.ResponseWriter, code int, v interface{}) error {
|
|||
return json.NewEncoder(w).Encode(v)
|
||||
}
|
||||
|
||||
func streamJSON(job *engine.Job, w http.ResponseWriter, flush bool) {
|
||||
func streamJSON(out *engine.Output, w http.ResponseWriter, flush bool) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
if flush {
|
||||
job.Stdout.Add(utils.NewWriteFlusher(w))
|
||||
out.Add(utils.NewWriteFlusher(w))
|
||||
} else {
|
||||
job.Stdout.Add(w)
|
||||
out.Add(w)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -857,7 +858,7 @@ func (s *Server) postImagesPush(eng *engine.Engine, version version.Version, w h
|
|||
job.Setenv("tag", r.Form.Get("tag"))
|
||||
if version.GreaterThan("1.0") {
|
||||
job.SetenvBool("json", true)
|
||||
streamJSON(job, w, true)
|
||||
streamJSON(job.Stdout, w, true)
|
||||
} else {
|
||||
job.Stdout.Add(utils.NewWriteFlusher(w))
|
||||
}
|
||||
|
@ -1207,7 +1208,7 @@ func (s *Server) getContainersByName(eng *engine.Engine, version version.Version
|
|||
if version.LessThan("1.12") {
|
||||
job.SetenvBool("raw", true)
|
||||
}
|
||||
streamJSON(job, w, false)
|
||||
streamJSON(job.Stdout, w, false)
|
||||
return job.Run()
|
||||
}
|
||||
|
||||
|
@ -1232,7 +1233,7 @@ func (s *Server) getImagesByName(eng *engine.Engine, version version.Version, w
|
|||
if version.LessThan("1.12") {
|
||||
job.SetenvBool("raw", true)
|
||||
}
|
||||
streamJSON(job, w, false)
|
||||
streamJSON(job.Stdout, w, false)
|
||||
return job.Run()
|
||||
}
|
||||
|
||||
|
@ -1245,9 +1246,11 @@ func (s *Server) postBuild(eng *engine.Engine, version version.Version, w http.R
|
|||
authConfig = ®istry.AuthConfig{}
|
||||
configFileEncoded = r.Header.Get("X-Registry-Config")
|
||||
configFile = ®istry.ConfigFile{}
|
||||
job = eng.Job("build")
|
||||
job = builder.NewBuildConfig(eng.Logging, eng.Stderr)
|
||||
)
|
||||
|
||||
b := &builder.BuilderJob{eng, getDaemon(eng)}
|
||||
|
||||
// This block can be removed when API versions prior to 1.9 are deprecated.
|
||||
// Both headers will be parsed and sent along to the daemon, but if a non-empty
|
||||
// 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
|
|||
}
|
||||
|
||||
if version.GreaterThanOrEqualTo("1.8") {
|
||||
job.SetenvBool("json", true)
|
||||
streamJSON(job, w, true)
|
||||
job.JSONFormat = true
|
||||
streamJSON(job.Stdout, w, true)
|
||||
} else {
|
||||
job.Stdout.Add(utils.NewWriteFlusher(w))
|
||||
}
|
||||
|
||||
if toBool(r.FormValue("forcerm")) && version.GreaterThanOrEqualTo("1.12") {
|
||||
job.Setenv("rm", "1")
|
||||
job.Remove = true
|
||||
} else if r.FormValue("rm") == "" && version.GreaterThanOrEqualTo("1.12") {
|
||||
job.Setenv("rm", "1")
|
||||
job.Remove = true
|
||||
} else {
|
||||
job.Setenv("rm", r.FormValue("rm"))
|
||||
job.Remove = toBool(r.FormValue("rm"))
|
||||
}
|
||||
if toBool(r.FormValue("pull")) && version.GreaterThanOrEqualTo("1.16") {
|
||||
job.Setenv("pull", "1")
|
||||
job.Pull = true
|
||||
}
|
||||
job.Stdin.Add(r.Body)
|
||||
job.Setenv("remote", r.FormValue("remote"))
|
||||
job.Setenv("dockerfile", r.FormValue("dockerfile"))
|
||||
job.Setenv("t", r.FormValue("t"))
|
||||
job.Setenv("q", r.FormValue("q"))
|
||||
job.Setenv("nocache", r.FormValue("nocache"))
|
||||
job.Setenv("forcerm", r.FormValue("forcerm"))
|
||||
job.SetenvJson("authConfig", authConfig)
|
||||
job.SetenvJson("configFile", configFile)
|
||||
job.Setenv("memswap", r.FormValue("memswap"))
|
||||
job.Setenv("memory", r.FormValue("memory"))
|
||||
job.Setenv("cpusetcpus", r.FormValue("cpusetcpus"))
|
||||
job.Setenv("cpusetmems", r.FormValue("cpusetmems"))
|
||||
job.Setenv("cpushares", r.FormValue("cpushares"))
|
||||
|
||||
// FIXME(calavera): !!!!! Remote might not be used. Solve the mistery before merging
|
||||
//job.Setenv("remote", r.FormValue("remote"))
|
||||
job.DockerfileName = r.FormValue("dockerfile")
|
||||
job.RepoName = r.FormValue("t")
|
||||
job.SuppressOutput = toBool(r.FormValue("q"))
|
||||
job.NoCache = toBool(r.FormValue("nocache"))
|
||||
job.ForceRemove = toBool(r.FormValue("forcerm"))
|
||||
job.AuthConfig = authConfig
|
||||
job.ConfigFile = configFile
|
||||
job.MemorySwap = toInt64(r.FormValue("memswap"))
|
||||
job.Memory = toInt64(r.FormValue("memory"))
|
||||
job.CpuShares = toInt64(r.FormValue("cpushares"))
|
||||
job.CpuSetCpus = r.FormValue("cpusetcpus")
|
||||
job.CpuSetMems = r.FormValue("cpusetmems")
|
||||
|
||||
// Job cancellation. Note: not all job types support this.
|
||||
if closeNotifier, ok := w.(http.CloseNotifier); ok {
|
||||
|
@ -1310,13 +1315,13 @@ func (s *Server) postBuild(eng *engine.Engine, version version.Version, w http.R
|
|||
select {
|
||||
case <-finished:
|
||||
case <-closeNotifier.CloseNotify():
|
||||
logrus.Infof("Client disconnected, cancelling job: %s", job.Name)
|
||||
logrus.Infof("Client disconnected, cancelling job: build")
|
||||
job.Cancel()
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
if err := job.Run(); err != nil {
|
||||
if err := b.CmdBuild(job); err != nil {
|
||||
if !job.Stdout.Used() {
|
||||
return err
|
||||
}
|
||||
|
@ -1676,3 +1681,12 @@ func toBool(s string) bool {
|
|||
s = strings.ToLower(strings.TrimSpace(s))
|
||||
return !(s == "" || s == "0" || s == "no" || s == "false" || s == "none")
|
||||
}
|
||||
|
||||
// FIXME(calavera): This is a copy of the Env.GetInt64
|
||||
func toInt64(s string) int64 {
|
||||
val, err := strconv.ParseInt(s, 10, 64)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
|
144
builder/job.go
144
builder/job.go
|
@ -9,6 +9,7 @@ import (
|
|||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/docker/docker/api"
|
||||
"github.com/docker/docker/builder/parser"
|
||||
|
@ -17,6 +18,7 @@ import (
|
|||
"github.com/docker/docker/graph"
|
||||
"github.com/docker/docker/pkg/archive"
|
||||
"github.com/docker/docker/pkg/httputils"
|
||||
"github.com/docker/docker/pkg/ioutils"
|
||||
"github.com/docker/docker/pkg/parsers"
|
||||
"github.com/docker/docker/pkg/streamformatter"
|
||||
"github.com/docker/docker/pkg/urlutil"
|
||||
|
@ -41,41 +43,73 @@ type BuilderJob struct {
|
|||
Daemon *daemon.Daemon
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
DockerfileName string
|
||||
RemoteURL string
|
||||
RepoName string
|
||||
SuppressOutput bool
|
||||
NoCache bool
|
||||
Remove bool
|
||||
ForceRemove bool
|
||||
Pull bool
|
||||
JSONFormat bool
|
||||
Memory int64
|
||||
MemorySwap int64
|
||||
CpuShares int64
|
||||
CpuSetCpus string
|
||||
CpuSetMems string
|
||||
AuthConfig *registry.AuthConfig
|
||||
ConfigFile *registry.ConfigFile
|
||||
|
||||
Stdout *engine.Output
|
||||
Stderr *engine.Output
|
||||
Stdin *engine.Input
|
||||
// When closed, the job has been cancelled.
|
||||
// Note: not all jobs implement cancellation.
|
||||
// See Job.Cancel() and Job.WaitCancelled()
|
||||
cancelled chan struct{}
|
||||
cancelOnce sync.Once
|
||||
}
|
||||
|
||||
// When called, causes the Job.WaitCancelled channel to unblock.
|
||||
func (b *Config) Cancel() {
|
||||
b.cancelOnce.Do(func() {
|
||||
close(b.cancelled)
|
||||
})
|
||||
}
|
||||
|
||||
// Returns a channel which is closed ("never blocks") when the job is cancelled.
|
||||
func (b *Config) WaitCancelled() <-chan struct{} {
|
||||
return b.cancelled
|
||||
}
|
||||
|
||||
func NewBuildConfig(logging bool, err io.Writer) *Config {
|
||||
c := &Config{
|
||||
Stdout: engine.NewOutput(),
|
||||
Stderr: engine.NewOutput(),
|
||||
Stdin: engine.NewInput(),
|
||||
cancelled: make(chan struct{}),
|
||||
}
|
||||
if logging {
|
||||
c.Stderr.Add(ioutils.NopWriteCloser(err))
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
func (b *BuilderJob) Install() {
|
||||
b.Engine.Register("build", b.CmdBuild)
|
||||
b.Engine.Register("build_config", b.CmdBuildConfig)
|
||||
}
|
||||
|
||||
func (b *BuilderJob) CmdBuild(job *engine.Job) error {
|
||||
if len(job.Args) != 0 {
|
||||
return fmt.Errorf("Usage: %s\n", job.Name)
|
||||
}
|
||||
func (b *BuilderJob) CmdBuild(buildConfig *Config) error {
|
||||
var (
|
||||
dockerfileName = job.Getenv("dockerfile")
|
||||
remoteURL = job.Getenv("remote")
|
||||
repoName = job.Getenv("t")
|
||||
suppressOutput = job.GetenvBool("q")
|
||||
noCache = job.GetenvBool("nocache")
|
||||
rm = job.GetenvBool("rm")
|
||||
forceRm = job.GetenvBool("forcerm")
|
||||
pull = job.GetenvBool("pull")
|
||||
memory = job.GetenvInt64("memory")
|
||||
memorySwap = job.GetenvInt64("memswap")
|
||||
cpuShares = job.GetenvInt64("cpushares")
|
||||
cpuSetCpus = job.Getenv("cpusetcpus")
|
||||
cpuSetMems = job.Getenv("cpusetmems")
|
||||
authConfig = ®istry.AuthConfig{}
|
||||
configFile = ®istry.ConfigFile{}
|
||||
tag string
|
||||
context io.ReadCloser
|
||||
repoName string
|
||||
tag string
|
||||
context io.ReadCloser
|
||||
)
|
||||
|
||||
job.GetenvJson("authConfig", authConfig)
|
||||
job.GetenvJson("configFile", configFile)
|
||||
|
||||
repoName, tag = parsers.ParseRepositoryTag(repoName)
|
||||
repoName, tag = parsers.ParseRepositoryTag(buildConfig.RepoName)
|
||||
if repoName != "" {
|
||||
if err := registry.ValidateRepositoryName(repoName); err != nil {
|
||||
if err := registry.ValidateRepositoryName(buildConfig.RepoName); err != nil {
|
||||
return err
|
||||
}
|
||||
if len(tag) > 0 {
|
||||
|
@ -85,11 +119,11 @@ func (b *BuilderJob) CmdBuild(job *engine.Job) error {
|
|||
}
|
||||
}
|
||||
|
||||
if remoteURL == "" {
|
||||
context = ioutil.NopCloser(job.Stdin)
|
||||
} else if urlutil.IsGitURL(remoteURL) {
|
||||
if !urlutil.IsGitTransport(remoteURL) {
|
||||
remoteURL = "https://" + remoteURL
|
||||
if buildConfig.RemoteURL == "" {
|
||||
context = ioutil.NopCloser(buildConfig.Stdin)
|
||||
} else if urlutil.IsGitURL(buildConfig.RemoteURL) {
|
||||
if !urlutil.IsGitTransport(buildConfig.RemoteURL) {
|
||||
buildConfig.RemoteURL = "https://" + buildConfig.RemoteURL
|
||||
}
|
||||
root, err := ioutil.TempDir("", "docker-build-git")
|
||||
if err != nil {
|
||||
|
@ -97,7 +131,7 @@ func (b *BuilderJob) CmdBuild(job *engine.Job) error {
|
|||
}
|
||||
defer os.RemoveAll(root)
|
||||
|
||||
if output, err := exec.Command("git", "clone", "--recursive", remoteURL, root).CombinedOutput(); err != nil {
|
||||
if output, err := exec.Command("git", "clone", "--recursive", buildConfig.RemoteURL, root).CombinedOutput(); err != nil {
|
||||
return fmt.Errorf("Error trying to use git: %s (%s)", err, output)
|
||||
}
|
||||
|
||||
|
@ -106,8 +140,8 @@ func (b *BuilderJob) CmdBuild(job *engine.Job) error {
|
|||
return err
|
||||
}
|
||||
context = c
|
||||
} else if urlutil.IsURL(remoteURL) {
|
||||
f, err := httputils.Download(remoteURL)
|
||||
} else if urlutil.IsURL(buildConfig.RemoteURL) {
|
||||
f, err := httputils.Download(buildConfig.RemoteURL)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -119,9 +153,9 @@ func (b *BuilderJob) CmdBuild(job *engine.Job) error {
|
|||
|
||||
// When we're downloading just a Dockerfile put it in
|
||||
// the default name - don't allow the client to move/specify it
|
||||
dockerfileName = api.DefaultDockerfileName
|
||||
buildConfig.DockerfileName = api.DefaultDockerfileName
|
||||
|
||||
c, err := archive.Generate(dockerfileName, string(dockerFile))
|
||||
c, err := archive.Generate(buildConfig.DockerfileName, string(dockerFile))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -129,35 +163,35 @@ func (b *BuilderJob) CmdBuild(job *engine.Job) error {
|
|||
}
|
||||
defer context.Close()
|
||||
|
||||
sf := streamformatter.NewStreamFormatter(job.GetenvBool("json"))
|
||||
sf := streamformatter.NewStreamFormatter(buildConfig.JSONFormat)
|
||||
|
||||
builder := &Builder{
|
||||
Daemon: b.Daemon,
|
||||
Engine: b.Engine,
|
||||
OutStream: &streamformatter.StdoutFormater{
|
||||
Writer: job.Stdout,
|
||||
Writer: buildConfig.Stdout,
|
||||
StreamFormatter: sf,
|
||||
},
|
||||
ErrStream: &streamformatter.StderrFormater{
|
||||
Writer: job.Stdout,
|
||||
Writer: buildConfig.Stdout,
|
||||
StreamFormatter: sf,
|
||||
},
|
||||
Verbose: !suppressOutput,
|
||||
UtilizeCache: !noCache,
|
||||
Remove: rm,
|
||||
ForceRemove: forceRm,
|
||||
Pull: pull,
|
||||
OutOld: job.Stdout,
|
||||
Verbose: !buildConfig.SuppressOutput,
|
||||
UtilizeCache: !buildConfig.NoCache,
|
||||
Remove: buildConfig.Remove,
|
||||
ForceRemove: buildConfig.ForceRemove,
|
||||
Pull: buildConfig.Pull,
|
||||
OutOld: buildConfig.Stdout,
|
||||
StreamFormatter: sf,
|
||||
AuthConfig: authConfig,
|
||||
ConfigFile: configFile,
|
||||
dockerfileName: dockerfileName,
|
||||
cpuShares: cpuShares,
|
||||
cpuSetCpus: cpuSetCpus,
|
||||
cpuSetMems: cpuSetMems,
|
||||
memory: memory,
|
||||
memorySwap: memorySwap,
|
||||
cancelled: job.WaitCancelled(),
|
||||
AuthConfig: buildConfig.AuthConfig,
|
||||
ConfigFile: buildConfig.ConfigFile,
|
||||
dockerfileName: buildConfig.DockerfileName,
|
||||
cpuShares: buildConfig.CpuShares,
|
||||
cpuSetCpus: buildConfig.CpuSetCpus,
|
||||
cpuSetMems: buildConfig.CpuSetMems,
|
||||
memory: buildConfig.Memory,
|
||||
memorySwap: buildConfig.MemorySwap,
|
||||
cancelled: buildConfig.WaitCancelled(),
|
||||
}
|
||||
|
||||
id, err := builder.Run(context)
|
||||
|
|
Loading…
Reference in a new issue