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

Commit ad78c06

Browse files
committed
Adding single image analysis
1 parent 38f78ae commit ad78c06

32 files changed

+679
-504
lines changed

.container-diff-tests.sh

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,11 @@ while IFS=$' \n\r' read -r flag differ image1 image2 file; do
77
fi
88
done < tests/differ_runs.txt
99

10-
while IFS=$' \n\r' read -r preprocess json; do
11-
python $preprocess $json
12-
if [[ $? -ne 0 ]]; then
13-
echo "Could not preprocess" "$json" "for diff comparison"
14-
exit 1
15-
fi
16-
done < tests/preprocess_files.txt
17-
1810
success=0
1911
while IFS=$' \n\r' read -r differ actual expected; do
2012
diff=$(jq --argfile a "$actual" --argfile b "$expected" -n 'def walk(f): . as $in | if type == "object" then reduce keys[] as $key ( {}; . + { ($key): ($in[$key] | walk(f)) } ) | f elif type == "array" then map( walk(f) ) | f else f end; ($a | walk(if type == "array" then sort else . end)) as $a | ($b | walk(if type == "array" then sort else . end)) as $b | $a == $b')
2113
if ! "$diff" ; then
22-
echo "container diff" "$differ" "diff output is not as expected"
14+
echo "container-diff" "$differ" "diff output is not as expected"
2315
success=1
2416
fi
2517
done < tests/diff_comparisons.txt

cmd/root.go

Lines changed: 138 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ var file bool
2525
var history bool
2626
var pip bool
2727

28-
var diffFlagMap = map[string]*bool{
28+
var analyzeFlagMap = map[string]*bool{
2929
"apt": &apt,
3030
"node": &node,
3131
"file": &file,
@@ -45,99 +45,158 @@ var RootCmd = &cobra.Command{
4545

4646
utils.SetDockerEngine(eng)
4747

48-
img1Arg := args[0]
49-
img2Arg := args[1]
50-
diffArgs := []string{}
51-
allDiffers := getAllDiffers()
52-
for _, name := range allDiffers {
53-
if *diffFlagMap[name] == true {
54-
diffArgs = append(diffArgs, name)
48+
analyzeArgs := []string{}
49+
allAnalyzers := getAllAnalyzers()
50+
for _, name := range allAnalyzers {
51+
if *analyzeFlagMap[name] == true {
52+
analyzeArgs = append(analyzeArgs, name)
5553
}
5654
}
57-
// If no differs are specified, perform all diffs as the default
58-
if len(diffArgs) == 0 {
59-
diffArgs = allDiffers
55+
56+
// If no differs/analyzers are specified, perform them all as the default
57+
if len(analyzeArgs) == 0 {
58+
analyzeArgs = allAnalyzers
6059
}
6160

62-
var wg sync.WaitGroup
63-
wg.Add(2)
61+
if len(args) == 1 {
62+
analyzeImage(args[0], analyzeArgs)
63+
} else {
64+
diffImages(args[0], args[1], analyzeArgs)
65+
}
66+
},
67+
}
6468

65-
glog.Infof("Starting diff on images %s and %s, using differs: %s", img1Arg, img2Arg, diffArgs)
69+
func diffImages(image1Arg, image2Arg string, diffArgs []string) {
70+
var wg sync.WaitGroup
71+
wg.Add(2)
6672

67-
var image1, image2 utils.Image
68-
var err error
69-
go func() {
70-
defer wg.Done()
71-
image1, err = utils.ImagePrepper{img1Arg}.GetImage()
72-
if err != nil {
73-
glog.Error(err.Error())
74-
os.Exit(1)
75-
}
76-
}()
73+
glog.Infof("Starting diff on images %s and %s, using differs: %s", image1Arg, image2Arg, diffArgs)
7774

78-
go func() {
79-
defer wg.Done()
80-
image2, err = utils.ImagePrepper{img2Arg}.GetImage()
81-
if err != nil {
82-
glog.Error(err.Error())
83-
os.Exit(1)
84-
}
85-
}()
75+
var image1, image2 utils.Image
76+
var err error
77+
go func() {
78+
defer wg.Done()
79+
image1, err = utils.ImagePrepper{image1Arg}.GetImage()
80+
if err != nil {
81+
glog.Error(err.Error())
82+
os.Exit(1)
83+
}
84+
}()
8685

87-
diffTypes, err := differs.GetDiffers(diffArgs)
86+
go func() {
87+
defer wg.Done()
88+
image2, err = utils.ImagePrepper{image2Arg}.GetImage()
8889
if err != nil {
8990
glog.Error(err.Error())
9091
os.Exit(1)
9192
}
92-
wg.Wait()
93-
94-
req := differs.DiffRequest{image1, image2, diffTypes}
95-
if diffs, err := req.GetDiff(); err == nil {
96-
// Outputs diff results in alphabetical order by differ name
97-
diffTypes := []string{}
98-
for name := range diffs {
99-
diffTypes = append(diffTypes, name)
100-
}
101-
sort.Strings(diffTypes)
102-
glog.Info("Retrieving diffs")
103-
diffResults := []utils.DiffResult{}
104-
for _, diffType := range diffTypes {
105-
diff := diffs[diffType]
106-
if json {
107-
diffResults = append(diffResults, diff.GetStruct())
108-
} else {
109-
err = diff.OutputText(diffType)
110-
if err != nil {
111-
glog.Error(err)
112-
}
93+
}()
94+
95+
diffTypes, err := differs.GetAnalyzers(diffArgs)
96+
if err != nil {
97+
glog.Error(err.Error())
98+
os.Exit(1)
99+
}
100+
wg.Wait()
101+
102+
req := differs.DiffRequest{image1, image2, diffTypes}
103+
if diffs, err := req.GetDiff(); err == nil {
104+
// Outputs diff results in alphabetical order by differ name
105+
sortedTypes := []string{}
106+
for name := range diffs {
107+
sortedTypes = append(sortedTypes, name)
108+
}
109+
sort.Strings(sortedTypes)
110+
glog.Info("Retrieving diffs")
111+
diffResults := []utils.DiffResult{}
112+
for _, diffType := range sortedTypes {
113+
diff := diffs[diffType]
114+
if json {
115+
diffResults = append(diffResults, diff.GetStruct())
116+
} else {
117+
err = diff.OutputText(diffType)
118+
if err != nil {
119+
glog.Error(err)
113120
}
114121
}
122+
}
123+
if json {
124+
err = utils.JSONify(diffResults)
125+
if err != nil {
126+
glog.Error(err)
127+
}
128+
}
129+
fmt.Println()
130+
glog.Info("Removing image file system directories from system")
131+
errMsg := remove(image1.FSPath, true)
132+
errMsg += remove(image2.FSPath, true)
133+
if errMsg != "" {
134+
glog.Error(errMsg)
135+
}
136+
} else {
137+
glog.Error(err.Error())
138+
os.Exit(1)
139+
}
140+
}
141+
142+
func analyzeImage(imageArg string, analyzerArgs []string) {
143+
image, err := utils.ImagePrepper{imageArg}.GetImage()
144+
if err != nil {
145+
glog.Error(err.Error())
146+
os.Exit(1)
147+
}
148+
analyzeTypes, err := differs.GetAnalyzers(analyzerArgs)
149+
if err != nil {
150+
glog.Error(err.Error())
151+
os.Exit(1)
152+
}
153+
154+
req := differs.SingleRequest{image, analyzeTypes}
155+
if analyses, err := req.GetAnalysis(); err == nil {
156+
// Outputs analysis results in alphabetical order by differ name
157+
sortedTypes := []string{}
158+
for name := range analyses {
159+
sortedTypes = append(sortedTypes, name)
160+
}
161+
sort.Strings(sortedTypes)
162+
glog.Info("Retrieving diffs")
163+
analyzeResults := []utils.AnalyzeResult{}
164+
for _, analyzeType := range sortedTypes {
165+
analysis := analyses[analyzeType]
115166
if json {
116-
err = utils.JSONify(diffResults)
167+
analyzeResults = append(analyzeResults, analysis.GetStruct())
168+
} else {
169+
err = analysis.OutputText(analyzeType)
117170
if err != nil {
118171
glog.Error(err)
119172
}
120173
}
121-
fmt.Println()
122-
glog.Info("Removing image file system directories from system")
123-
errMsg := remove(image1.FSPath, true)
124-
errMsg += remove(image2.FSPath, true)
125-
if errMsg != "" {
126-
glog.Error(errMsg)
174+
}
175+
if json {
176+
err = utils.JSONify(analyzeResults)
177+
if err != nil {
178+
glog.Error(err)
127179
}
128-
} else {
129-
glog.Error(err.Error())
130-
os.Exit(1)
131180
}
132-
},
181+
fmt.Println()
182+
glog.Info("Removing image file system directories from system")
183+
errMsg := remove(image.FSPath, true)
184+
if errMsg != "" {
185+
glog.Error(errMsg)
186+
}
187+
} else {
188+
glog.Error(err.Error())
189+
os.Exit(1)
190+
}
191+
133192
}
134193

135-
func getAllDiffers() []string {
136-
allDiffers := []string{}
137-
for name := range diffFlagMap {
138-
allDiffers = append(allDiffers, name)
194+
func getAllAnalyzers() []string {
195+
allAnalyzers := []string{}
196+
for name := range analyzeFlagMap {
197+
allAnalyzers = append(allAnalyzers, name)
139198
}
140-
return allDiffers
199+
return allAnalyzers
141200
}
142201

143202
func validateArgs(args []string) (bool, error) {
@@ -158,11 +217,11 @@ func validateArgs(args []string) (bool, error) {
158217

159218
func checkArgNum(args []string) (bool, error) {
160219
var errMessage string
161-
if len(args) < 2 {
162-
errMessage = "Too few arguments. Should have two images as arguments: [IMAGE1] [IMAGE2]."
220+
if len(args) < 1 {
221+
errMessage = "Too few arguments. Should have one or two images as arguments."
163222
return false, errors.New(errMessage)
164223
} else if len(args) > 2 {
165-
errMessage = "Too many arguments. Should have two images as arguments: [IMAGE1] [IMAGE2]."
224+
errMessage = "Too many arguments. Should have at most two images as arguments."
166225
return false, errors.New(errMessage)
167226
} else {
168227
return true, nil
@@ -179,15 +238,12 @@ func checkImage(arg string) bool {
179238
func checkArgType(args []string) (bool, error) {
180239
var buffer bytes.Buffer
181240
valid := true
182-
if !checkImage(args[0]) {
183-
valid = false
184-
errMessage := fmt.Sprintf("Argument %s is not an image ID, URL, or tar\n", args[0])
185-
buffer.WriteString(errMessage)
186-
}
187-
if !checkImage(args[1]) {
188-
valid = false
189-
errMessage := fmt.Sprintf("Argument %s is not an image ID, URL, or tar\n", args[1])
190-
buffer.WriteString(errMessage)
241+
for _, arg := range args {
242+
if !checkImage(arg) {
243+
valid = false
244+
errMessage := fmt.Sprintf("Argument %s is not an image ID, URL, or tar\n", args[0])
245+
buffer.WriteString(errMessage)
246+
}
191247
}
192248
if !valid {
193249
return false, errors.New(buffer.String())

cmd/root_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ type testpair struct {
1111

1212
var argNumTests = []testpair{
1313
{[]string{}, false},
14-
{[]string{"one"}, false},
14+
{[]string{"one"}, true},
1515
{[]string{"one", "two"}, true},
1616
{[]string{"one", "two", "three"}, false},
1717
}

differs/aptDiff.go

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,21 @@ import (
1010
"github.com/golang/glog"
1111
)
1212

13-
type AptDiffer struct {
13+
type AptAnalyzer struct {
1414
}
1515

1616
// AptDiff compares the packages installed by apt-get.
17-
func (d AptDiffer) Diff(image1, image2 utils.Image) (utils.DiffResult, error) {
18-
diff, err := singleVersionDiff(image1, image2, d)
17+
func (a AptAnalyzer) Diff(image1, image2 utils.Image) (utils.DiffResult, error) {
18+
diff, err := singleVersionDiff(image1, image2, a)
1919
return diff, err
2020
}
2121

22-
func (d AptDiffer) getPackages(image utils.Image) (map[string]utils.PackageInfo, error) {
22+
func (a AptAnalyzer) Analyze(image utils.Image) (utils.AnalyzeResult, error) {
23+
analysis, err := singleVersionAnalysis(image, a)
24+
return analysis, err
25+
}
26+
27+
func (a AptAnalyzer) getPackages(image utils.Image) (map[string]utils.PackageInfo, error) {
2328
path := image.FSPath
2429
packages := make(map[string]utils.PackageInfo)
2530
if _, err := os.Stat(path); err != nil {

differs/aptDiff_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ func TestGetAptPackages(t *testing.T) {
104104
},
105105
}
106106
for _, test := range testCases {
107-
d := AptDiffer{}
107+
d := AptAnalyzer{}
108108
image := utils.Image{FSPath: test.path}
109109
packages, err := d.getPackages(image)
110110
if err != nil && !test.err {

0 commit comments

Comments
 (0)