Show pull progress in terminal for inflight pull requests

Based on #12874 from Sam Abed <sam.abed@gmail.com>. His original commit
was brought up to date by manually porting the changes in pull.go into
the new code in pull_v1.go and pull_v2.go.

Fixes #8385

Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
This commit is contained in:
Sam Abed 2015-08-25 14:17:42 -07:00 committed by Aaron Lehmann
parent 7e6418c6b1
commit 6a0ffc4aa2

View file

@ -0,0 +1,72 @@
package progressreader
import (
"bytes"
"io"
"sync"
"github.com/docker/docker/vendor/src/github.com/Sirupsen/logrus"
)
type ProgressStatus struct {
sync.Mutex
c chan struct{}
observers []io.Writer
history bytes.Buffer
}
func NewProgressStatus() *ProgressStatus {
return &ProgressStatus{
c: make(chan struct{}),
observers: []io.Writer{},
}
}
func (ps *ProgressStatus) Write(p []byte) (n int, err error) {
ps.Lock()
defer ps.Unlock()
ps.history.Write(p)
for _, w := range ps.observers {
// copy paste from MultiWriter, replaced return with continue
n, err = w.Write(p)
if err != nil {
continue
}
if n != len(p) {
err = io.ErrShortWrite
continue
}
}
return len(p), nil
}
func (ps *ProgressStatus) AddObserver(w io.Writer) {
ps.Lock()
defer ps.Unlock()
w.Write(ps.history.Bytes())
ps.observers = append(ps.observers, w)
}
func (ps *ProgressStatus) Done() {
ps.Lock()
close(ps.c)
ps.history.Reset()
ps.Unlock()
}
func (ps *ProgressStatus) Wait(w io.Writer, msg []byte) error {
ps.Lock()
channel := ps.c
ps.Unlock()
if channel == nil {
// defensive
logrus.Debugf("Channel is nil ")
}
if w != nil {
w.Write(msg)
ps.AddObserver(w)
}
<-channel
return nil
}