@@ -3,9 +3,11 @@ package cache
3
3
4
4
import (
5
5
"errors"
6
+ "io"
6
7
7
8
"github.com/google/go-containerregistry/pkg/logs"
8
9
v1 "github.com/google/go-containerregistry/pkg/v1"
10
+ "github.com/google/go-containerregistry/pkg/v1/types"
9
11
)
10
12
11
13
// Cache encapsulates methods to interact with cached layers.
@@ -55,46 +57,66 @@ func (i *image) Layers() ([]v1.Layer, error) {
55
57
56
58
var out []v1.Layer
57
59
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
+ }
72
64
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
+ }
86
69
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
+ }
93
75
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
94
82
}
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 ()
96
91
}
97
92
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
+
98
120
func (i * image ) LayerByDigest (h v1.Hash ) (v1.Layer , error ) {
99
121
l , err := i .c .Get (h )
100
122
if err == ErrNotFound {
0 commit comments