Make Builder.Build return the builded image

This commit is contained in:
Guillaume J. Charmes 2013-04-25 11:20:45 -07:00
parent 74b9e851f6
commit dade95844f
3 changed files with 33 additions and 21 deletions

View File

@ -120,7 +120,7 @@ func (builder *Builder) clearTmp(containers, images map[string]struct{}) {
} }
} }
func (builder *Builder) Build(dockerfile io.Reader, stdout io.Writer) error { func (builder *Builder) Build(dockerfile io.Reader, stdout io.Writer) (*Image, error) {
var ( var (
image, base *Image image, base *Image
tmpContainers map[string]struct{} = make(map[string]struct{}) tmpContainers map[string]struct{} = make(map[string]struct{})
@ -135,7 +135,7 @@ func (builder *Builder) Build(dockerfile io.Reader, stdout io.Writer) error {
if err == io.EOF { if err == io.EOF {
break break
} }
return err return nil, err
} }
line = strings.TrimSpace(line) line = strings.TrimSpace(line)
// Skip comments and empty line // Skip comments and empty line
@ -144,45 +144,45 @@ func (builder *Builder) Build(dockerfile io.Reader, stdout io.Writer) error {
} }
tmp := strings.SplitN(line, " ", 2) tmp := strings.SplitN(line, " ", 2)
if len(tmp) != 2 { if len(tmp) != 2 {
return fmt.Errorf("Invalid Dockerfile format") return nil, fmt.Errorf("Invalid Dockerfile format")
} }
switch tmp[0] { switch tmp[0] {
case "from": case "from":
fmt.Fprintf(stdout, "FROM %s\n", tmp[1]) fmt.Fprintf(stdout, "FROM %s\n", tmp[1])
image, err = builder.runtime.repositories.LookupImage(tmp[1]) image, err = builder.runtime.repositories.LookupImage(tmp[1])
if err != nil { if err != nil {
return err return nil, err
} }
break break
case "run": case "run":
fmt.Fprintf(stdout, "RUN %s\n", tmp[1]) fmt.Fprintf(stdout, "RUN %s\n", tmp[1])
if image == nil { if image == nil {
return fmt.Errorf("Please provide a source image with `from` prior to run") return nil, fmt.Errorf("Please provide a source image with `from` prior to run")
} }
config, err := ParseRun([]string{image.Id, "/bin/sh", "-c", tmp[1]}, nil, builder.runtime.capabilities) config, err := ParseRun([]string{image.Id, "/bin/sh", "-c", tmp[1]}, nil, builder.runtime.capabilities)
if err != nil { if err != nil {
return err return nil, err
} }
// Create the container and start it // Create the container and start it
c, err := builder.Create(config) c, err := builder.Create(config)
if err != nil { if err != nil {
return err return nil, err
} }
if err := c.Start(); err != nil { if err := c.Start(); err != nil {
return err return nil, err
} }
tmpContainers[c.Id] = struct{}{} tmpContainers[c.Id] = struct{}{}
// Wait for it to finish // Wait for it to finish
if result := c.Wait(); result != 0 { if result := c.Wait(); result != 0 {
return fmt.Errorf("!!! '%s' return non-zero exit code '%d'. Aborting.", tmp[1], result) return nil, fmt.Errorf("!!! '%s' return non-zero exit code '%d'. Aborting.", tmp[1], result)
} }
// Commit the container // Commit the container
base, err = builder.Commit(c, "", "", "", "") base, err = builder.Commit(c, "", "", "", "")
if err != nil { if err != nil {
return err return nil, err
} }
tmpImages[base.Id] = struct{}{} tmpImages[base.Id] = struct{}{}
@ -194,45 +194,45 @@ func (builder *Builder) Build(dockerfile io.Reader, stdout io.Writer) error {
break break
case "copy": case "copy":
if image == nil { if image == nil {
return fmt.Errorf("Please provide a source image with `from` prior to copy") return nil, fmt.Errorf("Please provide a source image with `from` prior to copy")
} }
tmp2 := strings.SplitN(tmp[1], " ", 2) tmp2 := strings.SplitN(tmp[1], " ", 2)
if len(tmp) != 2 { if len(tmp) != 2 {
return fmt.Errorf("Invalid COPY format") return nil, fmt.Errorf("Invalid COPY format")
} }
fmt.Fprintf(stdout, "COPY %s to %s in %s\n", tmp2[0], tmp2[1], base.ShortId()) fmt.Fprintf(stdout, "COPY %s to %s in %s\n", tmp2[0], tmp2[1], base.ShortId())
file, err := Download(tmp2[0], stdout) file, err := Download(tmp2[0], stdout)
if err != nil { if err != nil {
return err return nil, err
} }
defer file.Body.Close() defer file.Body.Close()
config, err := ParseRun([]string{base.Id, "echo", "insert", tmp2[0], tmp2[1]}, nil, builder.runtime.capabilities) config, err := ParseRun([]string{base.Id, "echo", "insert", tmp2[0], tmp2[1]}, nil, builder.runtime.capabilities)
if err != nil { if err != nil {
return err return nil, err
} }
c, err := builder.Create(config) c, err := builder.Create(config)
if err != nil { if err != nil {
return err return nil, err
} }
if err := c.Start(); err != nil { if err := c.Start(); err != nil {
return err return nil, err
} }
// Wait for echo to finish // Wait for echo to finish
if result := c.Wait(); result != 0 { if result := c.Wait(); result != 0 {
return fmt.Errorf("!!! '%s' return non-zero exit code '%d'. Aborting.", tmp[1], result) return nil, fmt.Errorf("!!! '%s' return non-zero exit code '%d'. Aborting.", tmp[1], result)
} }
if err := c.Inject(file.Body, tmp2[1]); err != nil { if err := c.Inject(file.Body, tmp2[1]); err != nil {
return err return nil, err
} }
base, err = builder.Commit(c, "", "", "", "") base, err = builder.Commit(c, "", "", "", "")
if err != nil { if err != nil {
return err return nil, err
} }
fmt.Fprintf(stdout, "===> %s\n", base.ShortId()) fmt.Fprintf(stdout, "===> %s\n", base.ShortId())
break break
@ -252,5 +252,5 @@ func (builder *Builder) Build(dockerfile io.Reader, stdout io.Writer) error {
} else { } else {
fmt.Fprintf(stdout, "An error occured during the build\n") fmt.Fprintf(stdout, "An error occured during the build\n")
} }
return nil return base, nil
} }

View File

@ -137,7 +137,12 @@ func (srv *Server) CmdBuild(stdin io.ReadCloser, stdout rcli.DockerConn, args ..
} else { } else {
file = stdin file = stdin
} }
return NewBuilder(srv.runtime).Build(file, stdout) img, err := NewBuilder(srv.runtime).Build(file, stdout)
if err != nil {
return err
}
fmt.Fprintf(stdout, "%s\n", img.ShortId())
return nil
} }
// 'docker login': login / register a user to registry service. // 'docker login': login / register a user to registry service.

View File

@ -155,6 +155,13 @@ func SelfPath() string {
return path return path
} }
type nopWriter struct {
}
func (w *nopWriter) Write(buf []byte) (int, error) {
return len(buf), nil
}
type nopWriteCloser struct { type nopWriteCloser struct {
io.Writer io.Writer
} }