Skip to content
This repository was archived by the owner on Mar 27, 2024. It is now read-only.

Commit 8621bc5

Browse files
committed
Handle error gracefully when we can't retrieve an image
1 parent 509496e commit 8621bc5

File tree

4 files changed

+71
-42
lines changed

4 files changed

+71
-42
lines changed

cmd/analyze.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,13 @@ limitations under the License.
1717
package cmd
1818

1919
import (
20-
"errors"
2120
"fmt"
2221
"os"
2322

2423
"github.com/GoogleContainerTools/container-diff/cmd/util/output"
2524
"github.com/GoogleContainerTools/container-diff/differs"
2625
pkgutil "github.com/GoogleContainerTools/container-diff/pkg/util"
26+
"github.com/pkg/errors"
2727
"github.com/sirupsen/logrus"
2828
"github.com/spf13/cobra"
2929
)
@@ -56,27 +56,27 @@ func checkAnalyzeArgNum(args []string) error {
5656
func analyzeImage(imageName string, analyzerArgs []string) error {
5757
analyzeTypes, err := differs.GetAnalyzers(analyzerArgs)
5858
if err != nil {
59-
return err
59+
return errors.Wrap(err, "getting analyzers")
6060
}
6161

6262
image, err := getImageForName(imageName)
6363
if err != nil {
64-
return err
64+
return errors.Wrapf(err, "error retrieving image %s", imageName)
6565
}
6666

6767
if noCache && !save {
6868
defer pkgutil.CleanupImage(image)
6969
}
7070
if err != nil {
71-
return fmt.Errorf("Error processing image: %s", err)
71+
return fmt.Errorf("error processing image: %s", err)
7272
}
7373

7474
req := differs.SingleRequest{
7575
Image: image,
7676
AnalyzeTypes: analyzeTypes}
7777
analyses, err := req.GetAnalysis()
7878
if err != nil {
79-
return fmt.Errorf("Error performing image analysis: %s", err)
79+
return fmt.Errorf("error performing image analysis: %s", err)
8080
}
8181

8282
logrus.Info("retrieving analyses")

cmd/diff.go

Lines changed: 43 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ limitations under the License.
1717
package cmd
1818

1919
import (
20-
"errors"
2120
"fmt"
2221
"os"
2322
"sync"
@@ -26,6 +25,7 @@ import (
2625
"github.com/GoogleContainerTools/container-diff/differs"
2726
pkgutil "github.com/GoogleContainerTools/container-diff/pkg/util"
2827
"github.com/GoogleContainerTools/container-diff/util"
28+
"github.com/pkg/errors"
2929
"github.com/sirupsen/logrus"
3030
"github.com/spf13/cobra"
3131
)
@@ -69,33 +69,58 @@ func checkFilenameFlag(_ []string) error {
6969
return errors.New("Please include --types=file with the --filename flag")
7070
}
7171

72+
func processImage(imageName string, imageMap map[string]*pkgutil.Image, wg *sync.WaitGroup, errChan chan<- error) {
73+
defer wg.Done()
74+
image, err := getImageForName(imageName)
75+
if image.Image == nil {
76+
errChan <- fmt.Errorf("error retrieving image %s: %s", imageName, err.Error())
77+
return
78+
}
79+
if err != nil {
80+
logrus.Warningf("diff may be inaccurate: %s", err)
81+
}
82+
imageMap[imageName] = &image
83+
}
84+
7285
func diffImages(image1Arg, image2Arg string, diffArgs []string) error {
7386
diffTypes, err := differs.GetAnalyzers(diffArgs)
7487
if err != nil {
75-
return err
88+
return errors.Wrap(err, "getting analyzers")
7689
}
7790

7891
var wg sync.WaitGroup
7992
wg.Add(2)
8093

8194
logrus.Infof("starting diff on images %s and %s, using differs: %s\n", image1Arg, image2Arg, diffArgs)
8295

83-
imageMap := map[string]*pkgutil.Image{
84-
image1Arg: {},
85-
image2Arg: {},
96+
imageMap := map[string]*pkgutil.Image{}
97+
errChan := make(chan error, 2)
98+
99+
go processImage(image1Arg, imageMap, &wg, errChan)
100+
go processImage(image2Arg, imageMap, &wg, errChan)
101+
102+
wg.Wait()
103+
err, ok := <-errChan
104+
errs := []error{}
105+
if ok {
106+
errs = append(errs, err)
86107
}
87-
// TODO: fix error handling here
88-
for imageArg := range imageMap {
89-
go func(imageName string, imageMap map[string]*pkgutil.Image) {
90-
defer wg.Done()
91-
image, err := getImageForName(imageName)
92-
imageMap[imageName] = &image
93-
if err != nil {
94-
logrus.Warningf("Diff may be inaccurate: %s", err)
95-
}
96-
}(imageArg, imageMap)
108+
if len(errs) > 0 {
109+
errStr := ""
110+
for _, err := range errs {
111+
errStr = errStr + err.Error()
112+
}
113+
return errors.New(errStr)
114+
}
115+
116+
img1, ok := imageMap[image1Arg]
117+
if !ok {
118+
return fmt.Errorf("cannot find image %s", image1Arg)
119+
}
120+
img2, ok := imageMap[image2Arg]
121+
if !ok {
122+
return fmt.Errorf("cannot find image %s", image2Arg)
97123
}
98-
wg.Wait()
99124

100125
if noCache && !save {
101126
defer pkgutil.CleanupImage(*imageMap[image1Arg])
@@ -104,8 +129,8 @@ func diffImages(image1Arg, image2Arg string, diffArgs []string) error {
104129

105130
logrus.Info("computing diffs")
106131
req := differs.DiffRequest{
107-
Image1: *imageMap[image1Arg],
108-
Image2: *imageMap[image2Arg],
132+
Image1: *img1,
133+
Image2: *img2,
109134
DiffTypes: diffTypes}
110135
diffs, err := req.GetDiff()
111136
if err != nil {

cmd/root.go

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import (
3838
"github.com/GoogleContainerTools/container-diff/util"
3939
"github.com/google/go-containerregistry/pkg/v1"
4040
homedir "github.com/mitchellh/go-homedir"
41+
"github.com/pkg/errors"
4142
"github.com/sirupsen/logrus"
4243
"github.com/spf13/cobra"
4344
"github.com/spf13/pflag"
@@ -139,17 +140,17 @@ func getImageForName(imageName string) (pkgutil.Image, error) {
139140
start := time.Now()
140141
img, err = tarball.ImageFromPath(imageName, nil)
141142
if err != nil {
142-
return pkgutil.Image{}, err
143+
return pkgutil.Image{}, errors.Wrap(err, "retrieving tar from path")
143144
}
144145
elapsed := time.Now().Sub(start)
145-
logrus.Infof("retrieving image from tar took %f seconds", elapsed.Seconds())
146+
logrus.Infof("retrieving image ref from tar took %f seconds", elapsed.Seconds())
146147
} else if strings.HasPrefix(imageName, DaemonPrefix) {
147148
// remove the daemon prefix
148149
imageName = strings.Replace(imageName, DaemonPrefix, "", -1)
149150

150151
ref, err := name.ParseReference(imageName, name.WeakValidation)
151152
if err != nil {
152-
return pkgutil.Image{}, err
153+
return pkgutil.Image{}, errors.Wrap(err, "parsing image reference")
153154
}
154155

155156
start := time.Now()
@@ -158,28 +159,28 @@ func getImageForName(imageName string) (pkgutil.Image, error) {
158159
Buffer: true,
159160
})
160161
if err != nil {
161-
return pkgutil.Image{}, err
162+
return pkgutil.Image{}, errors.Wrap(err, "retrieving image from daemon")
162163
}
163164
elapsed := time.Now().Sub(start)
164-
logrus.Infof("retrieving image from daemon took %f seconds", elapsed.Seconds())
165+
logrus.Infof("retrieving local image ref took %f seconds", elapsed.Seconds())
165166
} else {
166167
// either has remote prefix or has no prefix, in which case we force remote
167168
imageName = strings.Replace(imageName, RemotePrefix, "", -1)
168169
ref, err := name.ParseReference(imageName, name.WeakValidation)
169170
if err != nil {
170-
return pkgutil.Image{}, err
171+
return pkgutil.Image{}, errors.Wrap(err, "parsing image reference")
171172
}
172173
auth, err := authn.DefaultKeychain.Resolve(ref.Context().Registry)
173174
if err != nil {
174-
return pkgutil.Image{}, err
175+
return pkgutil.Image{}, errors.Wrap(err, "resolving auth")
175176
}
176177
start := time.Now()
177178
img, err = remote.Image(ref, auth, http.DefaultTransport)
178179
if err != nil {
179-
return pkgutil.Image{}, err
180+
return pkgutil.Image{}, errors.Wrap(err, "retrieving remote image")
180181
}
181182
elapsed := time.Now().Sub(start)
182-
logrus.Infof("retrieving remote image took %f seconds", elapsed.Seconds())
183+
logrus.Infof("retrieving remote image ref took %f seconds", elapsed.Seconds())
183184
}
184185

185186
// create tempdir and extract fs into it
@@ -188,7 +189,7 @@ func getImageForName(imageName string) (pkgutil.Image, error) {
188189
start := time.Now()
189190
imgLayers, err := img.Layers()
190191
if err != nil {
191-
return pkgutil.Image{}, err
192+
return pkgutil.Image{}, errors.Wrap(err, "getting image layers")
192193
}
193194
for _, layer := range imgLayers {
194195
layerStart := time.Now()
@@ -197,12 +198,12 @@ func getImageForName(imageName string) (pkgutil.Image, error) {
197198
if err != nil {
198199
return pkgutil.Image{
199200
Layers: layers,
200-
}, err
201+
}, errors.Wrap(err, "getting extract path for layer")
201202
}
202203
if err := pkgutil.GetFileSystemForLayer(layer, path, nil); err != nil {
203204
return pkgutil.Image{
204205
Layers: layers,
205-
}, err
206+
}, errors.Wrap(err, "getting filesystem for layer")
206207
}
207208
layers = append(layers, pkgutil.Layer{
208209
FSPath: path,
@@ -215,12 +216,15 @@ func getImageForName(imageName string) (pkgutil.Image, error) {
215216
}
216217

217218
path, err := getExtractPathForImage(imageName, img)
219+
if err != nil {
220+
return pkgutil.Image{}, err
221+
}
218222
// extract fs into provided dir
219223
if err := pkgutil.GetFileSystemForImage(img, path, nil); err != nil {
220224
return pkgutil.Image{
221225
FSPath: path,
222226
Layers: layers,
223-
}, err
227+
}, errors.Wrap(err, "getting filesystem for image")
224228
}
225229
return pkgutil.Image{
226230
Image: img,

differs/differs.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,13 @@ func (req DiffRequest) GetDiff() (map[string]util.Result, error) {
6363
if diff, err := differ.Diff(img1, img2); err == nil {
6464
results[differ.Name()] = diff
6565
} else {
66-
logrus.Errorf("Error getting diff with %s: %s", differ.Name(), err)
66+
logrus.Errorf("error getting diff with %s: %s", differ.Name(), err)
6767
}
6868
}
6969

7070
var err error
7171
if len(results) == 0 {
72-
err = fmt.Errorf("Could not perform diff on %v and %v", img1, img2)
72+
err = fmt.Errorf("could not perform diff on %v and %v", img1, img2)
7373
} else {
7474
err = nil
7575
}
@@ -87,13 +87,13 @@ func (req SingleRequest) GetAnalysis() (map[string]util.Result, error) {
8787
if analysis, err := analyzer.Analyze(img); err == nil {
8888
results[analyzeName] = analysis
8989
} else {
90-
logrus.Errorf("Error getting analysis with %s: %s", analyzeName, err)
90+
logrus.Errorf("error getting analysis with %s: %s", analyzeName, err)
9191
}
9292
}
9393

9494
var err error
9595
if len(results) == 0 {
96-
err = fmt.Errorf("Could not perform analysis on %v", img)
96+
err = fmt.Errorf("could not perform analysis on %v", img)
9797
} else {
9898
err = nil
9999
}
@@ -107,11 +107,11 @@ func GetAnalyzers(analyzeNames []string) ([]Analyzer, error) {
107107
if a, exists := Analyzers[name]; exists {
108108
analyzeFuncs = append(analyzeFuncs, a)
109109
} else {
110-
return nil, fmt.Errorf("Unknown analyzer/differ specified: %s", name)
110+
return nil, fmt.Errorf("unknown analyzer/differ specified: %s", name)
111111
}
112112
}
113113
if len(analyzeFuncs) == 0 {
114-
return nil, fmt.Errorf("No known analyzers/differs specified")
114+
return nil, fmt.Errorf("no known analyzers/differs specified")
115115
}
116116
return analyzeFuncs, nil
117117
}

0 commit comments

Comments
 (0)