@@ -42,6 +42,8 @@ type OCIDownloader interface {
4242 Download (image , tag , file string ) (reader io.Reader , err error )
4343}
4444
45+ type OICDownloaderOption func (* DefaultOCIDownloader )
46+
4547type PlatformAwareOCIDownloader interface {
4648 OCIDownloader
4749 WithOS (string )
@@ -51,29 +53,41 @@ type PlatformAwareOCIDownloader interface {
5153 WithImagePrefix (string )
5254}
5355
54- type defaultOCIDownloader struct {
56+ type DefaultOCIDownloader struct {
5557 ctx context.Context
5658 timeout time.Duration
5759 serviceURL string
5860 registry string
5961 rawImage string
6062 protocol string
6163 roundTripper http.RoundTripper
64+ skipLayer func (layer * Layer ) bool
6265}
6366
64- func NewDefaultOCIDownloader () OCIDownloader {
65- return & defaultOCIDownloader {
67+ func NewDefaultOCIDownloader (opts ... OICDownloaderOption ) OCIDownloader {
68+ downloader := & DefaultOCIDownloader {
6669 protocol : "https" ,
6770 timeout : time .Minute ,
6871 ctx : context .Background (),
6972 }
73+
74+ for _ , opt := range opts {
75+ opt (downloader )
76+ }
77+
78+ if downloader .skipLayer == nil {
79+ downloader .skipLayer = func (layer * Layer ) bool {
80+ return false
81+ }
82+ }
83+ return downloader
7084}
7185
72- func (d * defaultOCIDownloader ) WithBasicAuth (username string , password string ) {
86+ func (d * DefaultOCIDownloader ) WithBasicAuth (username string , password string ) {
7387 fmt .Println ("not support yet" )
7488}
7589
76- func (d * defaultOCIDownloader ) Download (image , tag , file string ) (reader io.Reader , err error ) {
90+ func (d * DefaultOCIDownloader ) Download (image , tag , file string ) (reader io.Reader , err error ) {
7791 fmt .Println ("start to download" , image )
7892
7993 if d .registry == "" {
@@ -128,7 +142,7 @@ func (d *defaultOCIDownloader) Download(image, tag, file string) (reader io.Read
128142 }
129143
130144 for _ , layer := range manifest .Layers {
131- if v , ok := layer .Annotations ["org.opencontainers.image.title" ]; ok && v == file {
145+ if v , ok := layer .Annotations ["org.opencontainers.image.title" ]; ok && v == file && ! d . skipLayer ( & layer ) {
132146 reader , err = d .downloadLayer (d .rawImage , layer .Digest , authStr )
133147 return
134148 }
@@ -139,33 +153,67 @@ func (d *defaultOCIDownloader) Download(image, tag, file string) (reader io.Read
139153 return
140154}
141155
142- func (d * defaultOCIDownloader ) WithRegistry (registry string ) {
156+ func (d * DefaultOCIDownloader ) WithRegistry (registry string ) {
143157 d .registry = registry
144158}
145159
146- func (d * defaultOCIDownloader ) WithInsecure (insecure bool ) {
160+ func WithRegistry (registry string ) OICDownloaderOption {
161+ return func (d * DefaultOCIDownloader ) {
162+ d .registry = registry
163+ }
164+ }
165+
166+ func WithInsecure (insecure bool ) OICDownloaderOption {
167+ return func (d * DefaultOCIDownloader ) {
168+ if insecure {
169+ d .protocol = "http"
170+ } else {
171+ d .protocol = "https"
172+ }
173+ }
174+ }
175+
176+ func WithTimeout (timeout time.Duration ) OICDownloaderOption {
177+ return func (d * DefaultOCIDownloader ) {
178+ d .timeout = timeout
179+ }
180+ }
181+
182+ func WithContext (ctx context.Context ) OICDownloaderOption {
183+ return func (d * DefaultOCIDownloader ) {
184+ d .ctx = ctx
185+ }
186+ }
187+
188+ func WithRoundTripper (rt http.RoundTripper ) OICDownloaderOption {
189+ return func (d * DefaultOCIDownloader ) {
190+ d .roundTripper = rt
191+ }
192+ }
193+
194+ func (d * DefaultOCIDownloader ) WithInsecure (insecure bool ) {
147195 if insecure {
148196 d .protocol = "http"
149197 } else {
150198 d .protocol = "https"
151199 }
152200}
153201
154- func (d * defaultOCIDownloader ) WithTimeout (timeout time.Duration ) {
202+ func (d * DefaultOCIDownloader ) WithTimeout (timeout time.Duration ) {
155203 d .timeout = timeout
156204}
157205
158- func (d * defaultOCIDownloader ) WithContext (ctx context.Context ) {
206+ func (d * DefaultOCIDownloader ) WithContext (ctx context.Context ) {
159207 d .ctx = ctx
160208}
161209
162- func (d * defaultOCIDownloader ) WithRoundTripper (rt http.RoundTripper ) {
210+ func (d * DefaultOCIDownloader ) WithRoundTripper (rt http.RoundTripper ) {
163211 d .roundTripper = rt
164212}
165213
166214// getLatestTag returns the latest artifact tag
167215// we assume the artifact tags do not have the prefix `v`
168- func (d * defaultOCIDownloader ) getLatestTag (image , authToken string ) (tag string , err error ) {
216+ func (d * DefaultOCIDownloader ) getLatestTag (image , authToken string ) (tag string , err error ) {
169217 var req * http.Request
170218 if req , err = http .NewRequest (http .MethodGet , fmt .Sprintf ("%s://%s/v2/%s/tags/list" , d .protocol , d .registry , image ), nil ); err != nil {
171219 return
@@ -209,7 +257,7 @@ func (d *defaultOCIDownloader) getLatestTag(image, authToken string) (tag string
209257 return
210258}
211259
212- func (d * defaultOCIDownloader ) getHTTPClient () (client * http.Client ) {
260+ func (d * DefaultOCIDownloader ) getHTTPClient () (client * http.Client ) {
213261 client = & http.Client {
214262 Timeout : d .timeout ,
215263 Transport : d .roundTripper ,
@@ -222,7 +270,7 @@ type ImageTagList struct {
222270 Tags []string `json:"tags"`
223271}
224272
225- func (d * defaultOCIDownloader ) downloadLayer (image , digest , authToken string ) (reader io.Reader , err error ) {
273+ func (d * DefaultOCIDownloader ) downloadLayer (image , digest , authToken string ) (reader io.Reader , err error ) {
226274 layerURL := fmt .Sprintf ("%s://%s/v2/%s/blobs/%s" , d .protocol , d .registry , image , digest )
227275 buffer := bytes .NewBuffer (nil )
228276
@@ -281,7 +329,7 @@ const (
281329 HeaderWWWAuthenticate = "www-authenticate"
282330)
283331
284- func (d * defaultOCIDownloader ) auth (image string ) (authToken string , err error ) {
332+ func (d * DefaultOCIDownloader ) auth (image string ) (authToken string , err error ) {
285333 var authURL string
286334 if authURL , d .serviceURL , err = detectAuthURL (d .protocol , fmt .Sprintf ("%s/%s" , d .registry , d .rawImage )); err != nil {
287335 return
@@ -314,7 +362,9 @@ type RegistryAuth struct {
314362}
315363
316364type Manifest struct {
317- Layers []Layer `json:"layers"`
365+ Config map [string ]string `json:"config"`
366+ Layers []Layer `json:"layers"`
367+ Annotations map [string ]string `json:"annotations"`
318368}
319369
320370type Layer struct {
0 commit comments