@@ -3,9 +3,11 @@ package cache
33
44import (
55 "errors"
6+ "io"
67
78 "github.com/google/go-containerregistry/pkg/logs"
89 v1 "github.com/google/go-containerregistry/pkg/v1"
10+ "github.com/google/go-containerregistry/pkg/v1/types"
911)
1012
1113// Cache encapsulates methods to interact with cached layers.
@@ -55,46 +57,66 @@ func (i *image) Layers() ([]v1.Layer, error) {
5557
5658 var out []v1.Layer
5759 for _ , l := range ls {
58- // Check if this layer is present in the cache in compressed
59- // form.
60- digest , err := l .Digest ()
61- if err != nil {
62- return nil , err
63- }
64- if cl , err := i .c .Get (digest ); err == nil {
65- // Layer found in the cache.
66- logs .Progress .Printf ("Layer %s found (compressed) in cache" , digest )
67- out = append (out , cl )
68- continue
69- } else if err != nil && err != ErrNotFound {
70- return nil , err
71- }
60+ out = append (out , & lazyLayer {inner : l , c : i .c })
61+ }
62+ return out , nil
63+ }
7264
73- // Check if this layer is present in the cache in
74- // uncompressed form.
75- diffID , err := l .DiffID ()
76- if err != nil {
77- return nil , err
78- }
79- if cl , err := i .c .Get (diffID ); err == nil {
80- // Layer found in the cache.
81- logs .Progress .Printf ("Layer %s found (uncompressed) in cache" , diffID )
82- out = append (out , cl )
83- } else if err != nil && err != ErrNotFound {
84- return nil , err
85- }
65+ type lazyLayer struct {
66+ inner v1.Layer
67+ c Cache
68+ }
8669
87- // Not cached, fall through to real layer.
88- l , err = i .c .Put (l )
89- if err != nil {
90- return nil , err
91- }
92- out = append (out , l )
70+ func (l * lazyLayer ) Compressed () (io.ReadCloser , error ) {
71+ digest , err := l .inner .Digest ()
72+ if err != nil {
73+ return nil , err
74+ }
9375
76+ if cl , err := l .c .Get (digest ); err == nil {
77+ // Layer found in the cache.
78+ logs .Progress .Printf ("Layer %s found (compressed) in cache" , digest )
79+ return cl .Compressed ()
80+ } else if err != nil && err != ErrNotFound {
81+ return nil , err
9482 }
95- return out , nil
83+
84+ // Not cached, pull and return the real layer.
85+ logs .Progress .Printf ("Layer %s not found (compressed) in cache, getting" , digest )
86+ rl , err := l .c .Put (l .inner )
87+ if err != nil {
88+ return nil , err
89+ }
90+ return rl .Compressed ()
9691}
9792
93+ func (l * lazyLayer ) Uncompressed () (io.ReadCloser , error ) {
94+ diffID , err := l .inner .DiffID ()
95+ if err != nil {
96+ return nil , err
97+ }
98+ if cl , err := l .c .Get (diffID ); err == nil {
99+ // Layer found in the cache.
100+ logs .Progress .Printf ("Layer %s found (uncompressed) in cache" , diffID )
101+ return cl .Uncompressed ()
102+ } else if err != nil && err != ErrNotFound {
103+ return nil , err
104+ }
105+
106+ // Not cached, pull and return the real layer.
107+ logs .Progress .Printf ("Layer %s not found (uncompressed) in cache, getting" , diffID )
108+ rl , err := l .c .Put (l .inner )
109+ if err != nil {
110+ return nil , err
111+ }
112+ return rl .Uncompressed ()
113+ }
114+
115+ func (l * lazyLayer ) Size () (int64 , error ) { return l .inner .Size () }
116+ func (l * lazyLayer ) DiffID () (v1.Hash , error ) { return l .inner .DiffID () }
117+ func (l * lazyLayer ) Digest () (v1.Hash , error ) { return l .inner .Digest () }
118+ func (l * lazyLayer ) MediaType () (types.MediaType , error ) { return l .inner .MediaType () }
119+
98120func (i * image ) LayerByDigest (h v1.Hash ) (v1.Layer , error ) {
99121 l , err := i .c .Get (h )
100122 if err == ErrNotFound {
0 commit comments