@@ -19,26 +19,15 @@ package cmd
19
19
import (
20
20
goflag "flag"
21
21
"fmt"
22
- "io/ioutil"
23
- "net/http"
24
22
"os"
25
23
"path/filepath"
26
24
"sort"
27
25
"strings"
28
- "time"
29
-
30
- "github.com/google/go-containerregistry/pkg/authn"
31
- "github.com/google/go-containerregistry/pkg/name"
32
- "github.com/google/go-containerregistry/pkg/v1/daemon"
33
- "github.com/google/go-containerregistry/pkg/v1/remote"
34
- "github.com/google/go-containerregistry/pkg/v1/tarball"
35
26
36
27
"github.com/GoogleContainerTools/container-diff/differs"
37
28
pkgutil "github.com/GoogleContainerTools/container-diff/pkg/util"
38
29
"github.com/GoogleContainerTools/container-diff/util"
39
- "github.com/google/go-containerregistry/pkg/v1"
40
30
homedir "github.com/mitchellh/go-homedir"
41
- "github.com/pkg/errors"
42
31
"github.com/sirupsen/logrus"
43
32
"github.com/spf13/cobra"
44
33
"github.com/spf13/pflag"
@@ -55,11 +44,6 @@ var format string
55
44
56
45
type validatefxn func (args []string ) error
57
46
58
- const (
59
- DaemonPrefix = "daemon://"
60
- RemotePrefix = "remote://"
61
- )
62
-
63
47
var RootCmd = & cobra.Command {
64
48
Use : "container-diff" ,
65
49
Short : "container-diff is a tool for analyzing and comparing container images" ,
@@ -130,162 +114,27 @@ func checkIfValidAnalyzer(_ []string) error {
130
114
return nil
131
115
}
132
116
133
- // getImageForName infers the source of an image and retrieves a v1.Image reference to it.
134
- // Once a reference is obtained, it attempts to unpack the v1.Image's reader's contents
135
- // into a temp directory on the local filesystem.
136
- func getImageForName (imageName string ) (pkgutil.Image , error ) {
137
- logrus .Infof ("retrieving image: %s" , imageName )
138
- var img v1.Image
139
- var err error
140
- if pkgutil .IsTar (imageName ) {
141
- start := time .Now ()
142
- img , err = tarball .ImageFromPath (imageName , nil )
143
- if err != nil {
144
- return pkgutil.Image {}, errors .Wrap (err , "retrieving tar from path" )
145
- }
146
- elapsed := time .Now ().Sub (start )
147
- logrus .Infof ("retrieving image ref from tar took %f seconds" , elapsed .Seconds ())
148
- } else if strings .HasPrefix (imageName , DaemonPrefix ) {
149
- // remove the daemon prefix
150
- imageName = strings .Replace (imageName , DaemonPrefix , "" , - 1 )
151
-
152
- ref , err := name .ParseReference (imageName , name .WeakValidation )
153
- if err != nil {
154
- return pkgutil.Image {}, errors .Wrap (err , "parsing image reference" )
155
- }
156
-
157
- start := time .Now ()
158
- // TODO(nkubala): specify gzip.NoCompression here when functional options are supported
159
- img , err = daemon .Image (ref , daemon .WithBufferedOpener ())
160
- if err != nil {
161
- return pkgutil.Image {}, errors .Wrap (err , "retrieving image from daemon" )
162
- }
163
- elapsed := time .Now ().Sub (start )
164
- logrus .Infof ("retrieving local image ref took %f seconds" , elapsed .Seconds ())
165
- } else {
166
- // either has remote prefix or has no prefix, in which case we force remote
167
- imageName = strings .Replace (imageName , RemotePrefix , "" , - 1 )
168
- ref , err := name .ParseReference (imageName , name .WeakValidation )
169
- if err != nil {
170
- return pkgutil.Image {}, errors .Wrap (err , "parsing image reference" )
171
- }
172
- auth , err := authn .DefaultKeychain .Resolve (ref .Context ().Registry )
173
- if err != nil {
174
- return pkgutil.Image {}, errors .Wrap (err , "resolving auth" )
175
- }
176
- start := time .Now ()
177
- img , err = remote .Image (ref , remote .WithAuth (auth ), remote .WithTransport (http .DefaultTransport ))
178
- if err != nil {
179
- return pkgutil.Image {}, errors .Wrap (err , "retrieving remote image" )
180
- }
181
- elapsed := time .Now ().Sub (start )
182
- logrus .Infof ("retrieving remote image ref took %f seconds" , elapsed .Seconds ())
183
- }
184
-
185
- // create tempdir and extract fs into it
186
- var layers []pkgutil.Layer
187
- if includeLayers () {
188
- start := time .Now ()
189
- imgLayers , err := img .Layers ()
190
- if err != nil {
191
- return pkgutil.Image {}, errors .Wrap (err , "getting image layers" )
192
- }
193
- for _ , layer := range imgLayers {
194
- layerStart := time .Now ()
195
- digest , err := layer .Digest ()
196
- path , err := getExtractPathForName (digest .String ())
197
- if err != nil {
198
- return pkgutil.Image {
199
- Layers : layers ,
200
- }, errors .Wrap (err , "getting extract path for layer" )
201
- }
202
- if err := pkgutil .GetFileSystemForLayer (layer , path , nil ); err != nil {
203
- return pkgutil.Image {
204
- Layers : layers ,
205
- }, errors .Wrap (err , "getting filesystem for layer" )
117
+ func includeLayers () bool {
118
+ for _ , t := range types {
119
+ for _ , a := range differs .LayerAnalyzers {
120
+ if t == a {
121
+ return true
206
122
}
207
- layers = append (layers , pkgutil.Layer {
208
- FSPath : path ,
209
- Digest : digest ,
210
- })
211
- elapsed := time .Now ().Sub (layerStart )
212
- logrus .Infof ("time elapsed retrieving layer: %fs" , elapsed .Seconds ())
213
123
}
214
- elapsed := time .Now ().Sub (start )
215
- logrus .Infof ("time elapsed retrieving image layers: %fs" , elapsed .Seconds ())
216
- }
217
-
218
- imageDigest , err := getImageDigest (img )
219
- if err != nil {
220
- return pkgutil.Image {}, err
221
- }
222
- path , err := getExtractPathForName (pkgutil .RemoveTag (imageName ) + "@" + imageDigest .String ())
223
- if err != nil {
224
- return pkgutil.Image {}, err
225
- }
226
- // extract fs into provided dir
227
- if err := pkgutil .GetFileSystemForImage (img , path , nil ); err != nil {
228
- return pkgutil.Image {
229
- FSPath : path ,
230
- Layers : layers ,
231
- }, errors .Wrap (err , "getting filesystem for image" )
232
124
}
233
- return pkgutil.Image {
234
- Image : img ,
235
- Source : imageName ,
236
- FSPath : path ,
237
- Digest : imageDigest ,
238
- Layers : layers ,
239
- }, nil
240
- }
241
-
242
- func getImageDigest (image v1.Image ) (digest v1.Hash , err error ) {
243
- start := time .Now ()
244
- digest , err = image .Digest ()
245
- if err != nil {
246
- return digest , err
247
- }
248
- elapsed := time .Now ().Sub (start )
249
- logrus .Infof ("time elapsed retrieving image digest: %fs" , elapsed .Seconds ())
250
- return digest , nil
125
+ return false
251
126
}
252
127
253
- func getExtractPathForName ( name string ) (string , error ) {
254
- var path string
128
+ func getImage ( imageName string ) (pkgutil. Image , error ) {
129
+ var cachePath string
255
130
var err error
256
131
if ! noCache {
257
- path , err = cacheDir (name )
258
- if err != nil {
259
- return "" , err
260
- }
261
- // if cachedir doesn't exist, create it
262
- if _ , err := os .Stat (path ); err != nil && os .IsNotExist (err ) {
263
- err = os .MkdirAll (path , 0700 )
264
- if err != nil {
265
- return "" , err
266
- }
267
- logrus .Infof ("caching filesystem at %s" , path )
268
- }
269
- } else {
270
- // otherwise, create tempdir
271
- logrus .Infof ("skipping caching" )
272
- path , err = ioutil .TempDir ("" , strings .Replace (name , "/" , "" , - 1 ))
132
+ cachePath , err = cacheDir (imageName )
273
133
if err != nil {
274
- return "" , err
275
- }
276
- }
277
- return path , nil
278
- }
279
-
280
- func includeLayers () bool {
281
- for _ , t := range types {
282
- for _ , a := range differs .LayerAnalyzers {
283
- if t == a {
284
- return true
285
- }
134
+ return pkgutil.Image {}, err
286
135
}
287
136
}
288
- return false
137
+ return pkgutil . GetImage ( imageName , includeLayers (), cachePath )
289
138
}
290
139
291
140
func cacheDir (imageName string ) (string , error ) {
0 commit comments