소스 검색

Merge pull request #1030 from dotcloud/builder_display_err_log

*Builder : Display containers logs in case of build failure
Victor Vieux 12 년 전
부모
커밋
70480ce7bc
1개의 변경된 파일28개의 추가작업 그리고 0개의 파일을 삭제
  1. 28 0
      buildfile.go

+ 28 - 0
buildfile.go

@@ -29,6 +29,7 @@ type buildFile struct {
 	config     *Config
 	context    string
 
+	lastContainer *Container
 	tmpContainers map[string]struct{}
 	tmpImages     map[string]struct{}
 
@@ -242,6 +243,7 @@ func (b *buildFile) CmdAdd(args string) error {
 		return err
 	}
 	b.tmpContainers[container.ID] = struct{}{}
+	b.lastContainer = container
 
 	if err := container.EnsureMounted(); err != nil {
 		return err
@@ -277,6 +279,7 @@ func (b *buildFile) run() (string, error) {
 		return "", err
 	}
 	b.tmpContainers[c.ID] = struct{}{}
+	b.lastContainer = c
 	fmt.Fprintf(b.out, " ---> Running in %s\n", utils.TruncateID(c.ID))
 
 	//start the container
@@ -319,6 +322,7 @@ func (b *buildFile) commit(id string, autoCmd []string, comment string) error {
 			return err
 		}
 		b.tmpContainers[container.ID] = struct{}{}
+		b.lastContainer = container
 		fmt.Fprintf(b.out, " ---> Running in %s\n", utils.TruncateID(container.ID))
 		id = container.ID
 		if err := container.EnsureMounted(); err != nil {
@@ -346,6 +350,29 @@ func (b *buildFile) commit(id string, autoCmd []string, comment string) error {
 }
 
 func (b *buildFile) Build(context io.Reader) (string, error) {
+	defer func() {
+		// If we have an error and a container, the display the logs
+		if b.lastContainer != nil {
+			fmt.Fprintf(b.out, "******** Logs from last container (%s) *******\n", b.lastContainer.ShortID())
+
+			cLog, err := b.lastContainer.ReadLog("stdout")
+			if err != nil {
+				utils.Debugf("Error reading logs (stdout): %s", err)
+			}
+			if _, err := io.Copy(b.out, cLog); err != nil {
+				utils.Debugf("Error streaming logs (stdout): %s", err)
+			}
+			cLog, err = b.lastContainer.ReadLog("stderr")
+			if err != nil {
+				utils.Debugf("Error reading logs (stderr): %s", err)
+			}
+			if _, err := io.Copy(b.out, cLog); err != nil {
+				utils.Debugf("Error streaming logs (stderr): %s", err)
+			}
+			fmt.Fprintf(b.out, "************* End of logs for %s *************\n", b.lastContainer.ShortID())
+		}
+	}()
+
 	// FIXME: @creack any reason for using /tmp instead of ""?
 	// FIXME: @creack "name" is a terrible variable name
 	name, err := ioutil.TempDir("/tmp", "docker-build")
@@ -398,6 +425,7 @@ func (b *buildFile) Build(context io.Reader) (string, error) {
 			return "", ret.(error)
 		}
 
+		b.lastContainer = nil
 		fmt.Fprintf(b.out, " ---> %v\n", utils.TruncateID(b.image))
 	}
 	if b.image != "" {