Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

client/driver: docker progress detection and monitoring #4192

Merged
merged 7 commits into from
May 7, 2018
Prev Previous commit
Next Next commit
client/driver: add waiting layer status count to pull progress status…
… msg
  • Loading branch information
nickethier committed May 7, 2018
commit e324e86632ca16dd535218a5206580126fa1bec5
36 changes: 23 additions & 13 deletions client/driver/docker_progress.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ const (
// dockerImageProgressReportInterval is the default value set in the
// imageProgressManager when newImageProgressManager is called
dockerImageProgressReportInterval = 10 * time.Second

// dockerImageSlowProgressReportInterval is the default value set in the
// imageProgressManager when newImageProgressManager is called
dockerImageSlowProgressReportInterval = 2 * time.Minute
)

// layerProgress tracks the state and downloaded bytes of a single layer within
Expand Down Expand Up @@ -88,11 +92,16 @@ func (p *imageProgress) get() (string, time.Time) {
return "No progress", p.timestamp
}

var pulled, pulling int
var pulled, pulling, waiting int
for _, l := range p.layers {
if l.status == layerProgressStatusDownloading {
switch {
case l.status == layerProgressStatusStarting ||
l.status == layerProgressStatusWaiting:
waiting++
case l.status == layerProgressStatusDownloading ||
l.status == layerProgressStatusVerifying:
pulling++
} else if l.status > layerProgressStatusVerifying {
case l.status >= layerProgressStatusDownloaded:
pulled++
}
}
Expand All @@ -105,9 +114,9 @@ func (p *imageProgress) get() (string, time.Time) {
est = (elapsed.Nanoseconds() / cur * total) - elapsed.Nanoseconds()
}

return fmt.Sprintf("Pulled %d/%d (%s/%s) pulling %d layers - est %.1fs remaining",
pulled, len(p.layers), units.BytesSize(float64(cur)), units.BytesSize(float64(total)), pulling,
time.Duration(est).Seconds()), p.timestamp
return fmt.Sprintf("Pulled %d/%d (%s/%s) layers: %d waiting/%d pulling - est %.1fs remaining",
pulled, len(p.layers), units.BytesSize(float64(cur)), units.BytesSize(float64(total)),
waiting, pulling, time.Duration(est).Seconds()), p.timestamp
}

// set takes a status message received from the docker engine api during an image
Expand Down Expand Up @@ -160,7 +169,7 @@ func (p *imageProgress) totalBytes() int64 {
return b
}

// progressReporterFunc defines the method for handeling inactivity and report
// progressReporterFunc defines the method for handling inactivity and report
// events from the imageProgressManager. The image name, current status message
// and timestamp of last received status update are passed in.
type progressReporterFunc func(image string, msg string, timestamp time.Time)
Expand Down Expand Up @@ -190,12 +199,13 @@ func newImageProgressManager(
inactivityFunc, reporter, slowReporter progressReporterFunc) *imageProgressManager {

pm := &imageProgressManager{
image: image,
activityDeadline: dockerPullActivityDeadline,
inactivityFunc: inactivityFunc,
reportInterval: dockerImageProgressReportInterval,
reporter: reporter,
slowReporter: slowReporter,
image: image,
activityDeadline: dockerPullActivityDeadline,
inactivityFunc: inactivityFunc,
reportInterval: dockerImageProgressReportInterval,
reporter: reporter,
slowReportInterval: dockerImageSlowProgressReportInterval,
slowReporter: slowReporter,
imageProgress: &imageProgress{
timestamp: time.Now(),
layers: make(map[string]*layerProgress),
Expand Down