Skip to content

Commit b3641dc

Browse files
committed
adds an indicator for the current download progress
The original patch of muhdsalm helped in this commit.
1 parent 93a077c commit b3641dc

File tree

1 file changed

+69
-2
lines changed

1 file changed

+69
-2
lines changed

client.go

Lines changed: 69 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"github.com/containers/buildah/define"
2323
"github.com/containers/buildah/imagebuildah"
2424
"github.com/containers/image/v5/copy"
25+
"github.com/containers/image/v5/manifest"
2526
"github.com/containers/image/v5/signature"
2627
"github.com/containers/image/v5/storage"
2728
"github.com/containers/image/v5/transports/alltransports"
@@ -78,14 +79,33 @@ func (p *Prometheus) PullImage(imageName, dstName string) (*OciManifest, error)
7879
defer close(progressCh)
7980
defer close(manifestCh)
8081

81-
err := p.pullImage(imageName, dstName, progressCh, manifestCh)
82+
manifest, err := p.PullManifestOnly(imageName)
83+
if err != nil {
84+
return nil, fmt.Errorf("failed to pull manifest %w", err)
85+
}
86+
87+
// +1 to account for manifest
88+
layersAll := len(manifest.LayerInfos()) + 1
89+
layersDone := 0
90+
91+
err = p.pullImage(imageName, dstName, progressCh, manifestCh)
8292
if err != nil {
8393
return nil, err
8494
}
8595
for {
8696
select {
8797
case report := <-progressCh:
88-
fmt.Printf("%s: %v/%v\n", report.Artifact.Digest.Encoded()[:12], report.Offset, report.Artifact.Size)
98+
digestShort := report.Artifact.Digest.Encoded()[:12]
99+
switch report.Event {
100+
case types.ProgressEventNewArtifact:
101+
fmt.Printf("[%v/%v] %s: %s\n", layersDone, layersAll, digestShort, "new")
102+
case types.ProgressEventDone, types.ProgressEventSkipped:
103+
layersDone += 1
104+
fmt.Printf("[%v/%v] %s: %s\n", layersDone, layersAll, digestShort, "done")
105+
case types.ProgressEventRead:
106+
percentDone := 100 * float64(report.Offset) / float64(report.Artifact.Size)
107+
fmt.Printf("[%v/%v] %s: %v%%\n", layersDone, layersAll, digestShort, int(percentDone))
108+
}
89109
case manifest := <-manifestCh:
90110
return &manifest, nil
91111
}
@@ -246,3 +266,50 @@ func (p *Prometheus) BuildContainerFile(dockerfilePath string, imageName string)
246266

247267
return image, nil
248268
}
269+
270+
func (p *Prometheus) PullManifestOnly(imageName string) (manifest.Manifest, error) {
271+
systemCtx := &types.SystemContext{}
272+
ctx := context.Background()
273+
274+
var outputManifest manifest.Manifest
275+
276+
srcRef, err := alltransports.ParseImageName(fmt.Sprintf("docker://%s", imageName))
277+
if err != nil {
278+
return outputManifest, fmt.Errorf("failed to parse image name: %w", err)
279+
}
280+
281+
source, err := srcRef.NewImageSource(ctx, systemCtx)
282+
if err != nil {
283+
return outputManifest, fmt.Errorf("failed to create image source: %w", err)
284+
}
285+
defer source.Close()
286+
287+
manRaw, manMime, err := source.GetManifest(ctx, nil)
288+
if err != nil {
289+
return outputManifest, fmt.Errorf("failed to fetch manifest: %w", err)
290+
}
291+
292+
if manMime == manifest.DockerV2ListMediaType || manMime == "application/vnd.oci.image.index.v1+json" {
293+
list, err := manifest.ListFromBlob(manRaw, manMime)
294+
if err != nil {
295+
return outputManifest, fmt.Errorf("failed to parse manifest list: %w", err)
296+
}
297+
298+
instanceDigest, err := list.ChooseInstance(systemCtx)
299+
if err != nil {
300+
return outputManifest, fmt.Errorf("failed to select platform instance: %w", err)
301+
}
302+
303+
manRaw, manMime, err = source.GetManifest(ctx, &instanceDigest)
304+
if err != nil {
305+
return outputManifest, fmt.Errorf("failed to fetch platform manifest: %w", err)
306+
}
307+
}
308+
309+
outputManifest, err = manifest.FromBlob(manRaw, manMime)
310+
if err != nil {
311+
return outputManifest, fmt.Errorf("failed to parse platform specific manifest: %w", err)
312+
}
313+
314+
return outputManifest, nil
315+
}

0 commit comments

Comments
 (0)