9 "github.com/Sirupsen/logrus"
10 "github.com/docker/docker/pkg/progress"
11 "github.com/docker/docker/pkg/streamformatter"
14 // WriteDistributionProgress is a helper for writing progress from chan to JSON
15 // stream with an optional cancel function.
16 func WriteDistributionProgress(cancelFunc func(), outStream io.Writer, progressChan <-chan progress.Progress) {
17 progressOutput := streamformatter.NewJSONProgressOutput(outStream, false)
18 operationCancelled := false
20 for prog := range progressChan {
21 if err := progressOutput.WriteProgress(prog); err != nil && !operationCancelled {
22 // don't log broken pipe errors as this is the normal case when a client aborts
23 if isBrokenPipe(err) {
24 logrus.Info("Pull session cancelled")
26 logrus.Errorf("error writing progress to client: %v", err)
29 operationCancelled = true
30 // Don't return, because we need to continue draining
31 // progressChan until it's closed to avoid a deadlock.
36 func isBrokenPipe(e error) bool {
37 if netErr, ok := e.(*net.OpError); ok {
39 if sysErr, ok := netErr.Err.(*os.SyscallError); ok {
43 return e == syscall.EPIPE