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:
parent
7e6418c6b1
commit
6a0ffc4aa2
1 changed files with 72 additions and 0 deletions
72
progressreader/progressstatus.go
Normal file
72
progressreader/progressstatus.go
Normal 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
|
||||
}
|
Loading…
Reference in a new issue