From 6a0ffc4aa2075f0d11a4587045126d313b850eb4 Mon Sep 17 00:00:00 2001 From: Sam Abed Date: Tue, 25 Aug 2015 14:17:42 -0700 Subject: [PATCH] Show pull progress in terminal for inflight pull requests Based on #12874 from Sam Abed . 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 --- progressreader/progressstatus.go | 72 ++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 progressreader/progressstatus.go diff --git a/progressreader/progressstatus.go b/progressreader/progressstatus.go new file mode 100644 index 0000000..f536b84 --- /dev/null +++ b/progressreader/progressstatus.go @@ -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 +}