Skip to content

Commit 2ca5152

Browse files
committed
fix: digest processing and retrieve image id directly from repository
1 parent a80264a commit 2ca5152

7 files changed

Lines changed: 69 additions & 48 deletions

File tree

examples/pull/main.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ func main() {
3333
panic(err)
3434
}
3535
//ref, err := reference.ParseDockerRef("quay.io/prometheus/prometheus:latest")
36-
ref, err := reference.ParseDockerRef("localstack/localstack:latest")
36+
ref, err := reference.ParseDockerRef("localstack/localstack:4")
3737
if err != nil {
3838
panic(err)
3939
}
@@ -52,5 +52,5 @@ func main() {
5252
if err != nil {
5353
panic(err)
5454
}
55-
logger.Infof("Digest: %s\n", digest)
55+
logger.Infof("Digest: %s\n", digest.String())
5656
}

pkg/client/pull.go

Lines changed: 51 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -15,72 +15,66 @@ import (
1515
"github.com/silenium-dev/docker-wrapper/pkg/client/pull"
1616
"github.com/silenium-dev/docker-wrapper/pkg/client/pull/events"
1717
"github.com/silenium-dev/docker-wrapper/pkg/client/pull/state"
18+
"go.uber.org/zap"
1819
)
1920

20-
func (c *Client) ImagePullWithEvents(ctx context.Context, ref reference.Named, options image.PullOptions) (chan events.PullEvent, error) {
21+
func (c *Client) ImagePullWithEvents(ctx context.Context, ref reference.Named, options image.PullOptions) (v1.Hash, *v1.Manifest, chan events.PullEvent, error) {
22+
if options.RegistryAuth != "" || options.PrivilegeFunc != nil {
23+
c.logger.WithOptions(zap.AddStacktrace(zap.DPanicLevel)).Warnf("privilege function and registry auth in options are not supported, please use auth provider instead")
24+
options.RegistryAuth = ""
25+
options.PrivilegeFunc = nil
26+
}
2127
var encodedAuth string
2228
var err error
2329
if c.authProvider != nil {
2430
c.logger.Debugf("using configured auth provider")
2531
encodedAuth, err = registry.EncodeAuthConfig(c.authProvider.AuthConfig(ref))
2632
if err != nil {
27-
return nil, err
33+
return v1.Hash{}, nil, nil, err
2834
}
2935
}
3036
options.RegistryAuth = encodedAuth
31-
reader, err := c.Client.ImagePull(ctx, ref.String(), options)
37+
38+
imageId, manifest, err := c.getManifest(ctx, ref, options)
3239
if err != nil {
33-
return nil, err
40+
return v1.Hash{}, nil, nil, err
3441
}
35-
return pull.ParseStream(ctx, reader), nil
36-
}
3742

38-
func (c *Client) ImagePullWithState(ctx context.Context, ref reference.Named, options image.PullOptions) (chan state.Pull, error) {
39-
var platform *v1.Platform
40-
var err error
41-
if options.Platform != "" {
42-
platform, err = v1.ParsePlatform(options.Platform)
43-
if err != nil {
44-
return nil, err
45-
}
46-
}
47-
manifest, err := c.ImageGetManifest(ctx, ref, platform)
43+
reader, err := c.Client.ImagePull(ctx, ref.String(), options)
4844
if err != nil {
49-
return nil, err
45+
return v1.Hash{}, nil, nil, err
5046
}
51-
eventChan, err := c.ImagePullWithEvents(ctx, ref, options)
47+
48+
return imageId, manifest, pull.ParseStream(ctx, reader), nil
49+
}
50+
51+
func (c *Client) ImagePullWithState(ctx context.Context, ref reference.Named, options image.PullOptions) (v1.Hash, *v1.Manifest, chan state.Pull, error) {
52+
id, manifest, eventChan, err := c.ImagePullWithEvents(ctx, ref, options)
5253
if err != nil {
53-
return nil, err
54+
return v1.Hash{}, nil, nil, err
5455
}
55-
return pull.StateFromStream(ctx, ref, eventChan, manifest), nil
56+
57+
return id, manifest, pull.StateFromStream(ctx, ref, eventChan, manifest, id), nil
5658
}
5759

5860
func (c *Client) ImagePull(ctx context.Context, ref reference.Named, options image.PullOptions) (digest.Digest, error) {
59-
eventChan, err := c.ImagePullWithEvents(ctx, ref, options)
61+
dig, _, eventChan, err := c.ImagePullWithEvents(ctx, ref, options)
6062
if err != nil {
6163
return "", err
6264
}
6365

64-
var digestEvent *events.Digest
65-
for event := range eventChan {
66-
if ev, ok := event.(*events.Digest); digestEvent == nil && ok {
67-
c.logger.Debugf("received digest event: %s", ev.String())
68-
digestEvent = ev
69-
}
70-
}
71-
if digestEvent == nil {
72-
return "", fmt.Errorf("no digest event received")
66+
for range eventChan {
7367
}
7468

75-
return digestEvent.Digest, nil
69+
return digest.Digest(dig.String()), nil
7670
}
7771

78-
func (c *Client) ImageGetManifest(ctx context.Context, ref reference.Named, platform *v1.Platform) (*v1.Manifest, error) {
72+
func (c *Client) ImageGetManifest(ctx context.Context, ref reference.Named, platform *v1.Platform) (v1.Hash, *v1.Manifest, error) {
7973
var err error
8074
if platform == nil {
8175
platform, err = c.ImageDefaultPlatform(ctx)
8276
if err != nil {
83-
return nil, err
77+
return v1.Hash{}, nil, err
8478
}
8579
}
8680
opts := []remote.Option{
@@ -91,14 +85,23 @@ func (c *Client) ImageGetManifest(ctx context.Context, ref reference.Named, plat
9185

9286
nameRef, err := name.ParseReference(ref.String())
9387
if err != nil {
94-
return nil, err
88+
return v1.Hash{}, nil, err
9589
}
9690

9791
img, err := remote.Image(nameRef, opts...)
9892
if err != nil {
99-
return nil, fmt.Errorf("failed to get image manifest: %w", err)
93+
return v1.Hash{}, nil, fmt.Errorf("failed to get image manifest: %w", err)
10094
}
101-
return img.Manifest()
95+
manifest, err := img.Manifest()
96+
if err != nil {
97+
return v1.Hash{}, nil, err
98+
}
99+
id, err := img.ConfigName()
100+
if err != nil {
101+
return v1.Hash{}, nil, err
102+
}
103+
104+
return id, manifest, nil
102105
}
103106

104107
func (c *Client) ImageDefaultPlatform(ctx context.Context) (*v1.Platform, error) {
@@ -119,3 +122,15 @@ func (c *Client) ImageDefaultPlatform(ctx context.Context) (*v1.Platform, error)
119122
OSFeatures: normalized.OSFeatures,
120123
}, nil
121124
}
125+
126+
func (c *Client) getManifest(ctx context.Context, ref reference.Named, options image.PullOptions) (v1.Hash, *v1.Manifest, error) {
127+
var platform *v1.Platform
128+
var err error
129+
if options.Platform != "" {
130+
platform, err = v1.ParsePlatform(options.Platform)
131+
if err != nil {
132+
return v1.Hash{}, nil, err
133+
}
134+
}
135+
return c.ImageGetManifest(ctx, ref, platform)
136+
}

pkg/client/pull/events/event.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ func Parse(event base.PullProgressEvent) (PullEvent, error) {
8787
return &PullStarted{}, nil
8888
}
8989
if strings.HasPrefix(event.Status, "Digest:") {
90-
hash := digest.FromString(strings.TrimPrefix(event.Status, "Digest: "))
90+
hash := digest.Digest(strings.TrimPrefix(event.Status, "Digest: "))
9191
return &Digest{hash}, nil
9292
}
9393
if strings.HasPrefix(event.Status, "Status:") {

pkg/client/pull/state.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@ import (
88
"github.com/silenium-dev/docker-wrapper/pkg/client/pull/state"
99
)
1010

11-
func StateFromStream(ctx context.Context, ref reference.Named, ch chan events.PullEvent, manifest *v1.Manifest) chan state.Pull {
11+
func StateFromStream(ctx context.Context, ref reference.Named, ch chan events.PullEvent, manifest *v1.Manifest, dig v1.Hash) chan state.Pull {
1212
out := make(chan state.Pull)
1313

14-
go processEvents(ctx, ref, ch, manifest, out)
14+
go processEvents(ctx, ref, ch, manifest, dig, out)
1515

1616
return out
1717
}
1818

19-
func processEvents(ctx context.Context, ref reference.Named, ch chan events.PullEvent, manifest *v1.Manifest, out chan state.Pull) {
19+
func processEvents(ctx context.Context, ref reference.Named, ch chan events.PullEvent, manifest *v1.Manifest, dig v1.Hash, out chan state.Pull) {
2020
defer close(out)
2121
var current state.Pull
2222
var err error
@@ -30,7 +30,7 @@ func processEvents(ctx context.Context, ref reference.Named, ch chan events.Pull
3030
}
3131
var next state.Pull
3232
if current == nil {
33-
next, err = state.NewPullState(ref, manifest, event)
33+
next, err = state.NewPullState(ref, manifest, dig, event)
3434
} else {
3535
next, err = current.Next(event)
3636
}

pkg/client/pull/state/layer.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,8 @@ func (l *LayerDownloadComplete) Next(event events.LayerEvent) (Layer, error) {
142142
return &LayerErrored{layerBase{event.LayerId()}, event.Error}, nil
143143
case *events.PullComplete:
144144
return &LayerPullComplete{l.layerBase}, nil
145+
case *events.DownloadComplete:
146+
return &LayerPullComplete{l.layerBase}, nil
145147
}
146148
return nil, fmt.Errorf("invalid transition (download-complete + %T)", event)
147149
}

pkg/client/pull/state/pull.go

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,11 @@ func (p *PullInProgress) Status() string {
2121
return "Finishing"
2222
}
2323

24-
func NewPullState(ref reference.Named, manifest *v1.Manifest, event events.PullEvent) (Pull, error) {
24+
func NewPullState(ref reference.Named, manifest *v1.Manifest, dig v1.Hash, event events.PullEvent) (Pull, error) {
2525
base := pullBase{
2626
ref: ref,
2727
manifest: manifest,
28+
digest: dig,
2829
layers: make(map[string]Layer),
2930
}
3031
switch event := event.(type) {
@@ -142,10 +143,6 @@ func (p *PullComplete) Next(event events.PullEvent) (Pull, error) {
142143
return nil, fmt.Errorf("pull already complete (event: %T)", event)
143144
}
144145

145-
func (p *PullComplete) Digest() digest.Digest {
146-
return p.digest
147-
}
148-
149146
func (p *PullComplete) HasDownloadedNewer() bool {
150147
return p.downloadedNewer
151148
}

pkg/client/pull/state/state.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@ package state
33
import (
44
"github.com/distribution/reference"
55
"github.com/google/go-containerregistry/pkg/v1"
6+
"github.com/opencontainers/go-digest"
67
"github.com/silenium-dev/docker-wrapper/pkg/client/pull/events"
78
)
89

910
type Pull interface {
1011
Ref() reference.Named
1112
Manifest() *v1.Manifest
13+
Digest() digest.Digest
1214
Layers() []Layer
1315
Layer(id string) Layer
1416
Next(event events.PullEvent) (Pull, error)
@@ -25,6 +27,7 @@ type pullBase struct {
2527
ref reference.Named
2628
layers map[string]Layer
2729
manifest *v1.Manifest
30+
digest v1.Hash
2831
}
2932

3033
func (p *pullBase) Ref() reference.Named {
@@ -35,6 +38,10 @@ func (p *pullBase) Manifest() *v1.Manifest {
3538
return p.manifest
3639
}
3740

41+
func (p *pullBase) Digest() digest.Digest {
42+
return digest.Digest(p.digest.String())
43+
}
44+
3845
func (p *pullBase) Layers() []Layer {
3946
layers := make([]Layer, 0, len(p.layers))
4047
for _, l := range p.manifest.Layers {

0 commit comments

Comments
 (0)