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

Commit 0705429

Browse files
authored
Merge pull request #209 from nkubala/metadata_diff
Add metadata diffing
2 parents aba837f + e590619 commit 0705429

File tree

10 files changed

+139
-9
lines changed

10 files changed

+139
-9
lines changed

cmd/analyze.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ func analyzeImage(imageName string, analyzerArgs []string) error {
8787
return fmt.Errorf("Error performing image analysis: %s", err)
8888
}
8989

90-
output.PrintToStdErr("Retrieving analyses")
90+
output.PrintToStdErr("Retrieving analyses\n")
9191
outputResults(analyses)
9292

9393
if save {

cmd/diff.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ func diffImages(image1Arg, image2Arg string, diffArgs []string) error {
113113
defer pkgutil.CleanupImage(*imageMap[image2Arg])
114114
}
115115

116-
output.PrintToStdErr("Computing diffs")
116+
output.PrintToStdErr("Computing diffs\n")
117117
req := differs.DiffRequest{
118118
Image1: *imageMap[image1Arg],
119119
Image2: *imageMap[image2Arg],
@@ -125,7 +125,7 @@ func diffImages(image1Arg, image2Arg string, diffArgs []string) error {
125125
outputResults(diffs)
126126

127127
if filename != "" {
128-
output.PrintToStdErr("Computing filename diffs")
128+
output.PrintToStdErr("Computing filename diffs\n")
129129
err := diffFile(imageMap[image1Arg], imageMap[image2Arg])
130130
if err != nil {
131131
return err

differs/differs.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,13 @@ type Analyzer interface {
4242
}
4343

4444
var Analyzers = map[string]Analyzer{
45-
"history": HistoryAnalyzer{},
46-
"file": FileAnalyzer{},
47-
"apt": AptAnalyzer{},
48-
"rpm": RPMAnalyzer{},
49-
"pip": PipAnalyzer{},
50-
"node": NodeAnalyzer{},
45+
"history": HistoryAnalyzer{},
46+
"metadata": MetadataAnalyzer{},
47+
"file": FileAnalyzer{},
48+
"apt": AptAnalyzer{},
49+
"rpm": RPMAnalyzer{},
50+
"pip": PipAnalyzer{},
51+
"node": NodeAnalyzer{},
5152
}
5253

5354
func (req DiffRequest) GetDiff() (map[string]util.Result, error) {

differs/metadata_diff.go

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
Copyright 2017 Google, Inc. All rights reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package differs
18+
19+
import (
20+
pkgutil "github.com/GoogleCloudPlatform/container-diff/pkg/util"
21+
"github.com/GoogleCloudPlatform/container-diff/util"
22+
)
23+
24+
type MetadataAnalyzer struct {
25+
}
26+
27+
type MetadataDiff struct {
28+
Adds []string
29+
Dels []string
30+
}
31+
32+
func (a MetadataAnalyzer) Name() string {
33+
return "MetadataAnalyzer"
34+
}
35+
36+
func (a MetadataAnalyzer) Diff(image1, image2 pkgutil.Image) (util.Result, error) {
37+
diff, err := getMetadataDiff(image1, image2)
38+
return &util.MetadataDiffResult{
39+
Image1: image1.Source,
40+
Image2: image2.Source,
41+
DiffType: "Metadata",
42+
Diff: diff,
43+
}, err
44+
}
45+
46+
func (a MetadataAnalyzer) Analyze(image pkgutil.Image) (util.Result, error) {
47+
analysis := getMetadataList(image)
48+
return &util.ListAnalyzeResult{
49+
Image: image.Source,
50+
AnalyzeType: "Metadata",
51+
Analysis: analysis,
52+
}, nil
53+
}
54+
55+
func getMetadataDiff(image1, image2 pkgutil.Image) (MetadataDiff, error) {
56+
m1 := getMetadataList(image1)
57+
m2 := getMetadataList(image2)
58+
59+
adds := util.GetAdditions(m1, m2)
60+
dels := util.GetDeletions(m1, m2)
61+
return MetadataDiff{adds, dels}, nil
62+
}
63+
64+
func getMetadataList(image pkgutil.Image) []string {
65+
return image.Config.Config.AsList()
66+
}

pkg/util/image_prep_utils.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"archive/tar"
2121
"encoding/json"
2222
"errors"
23+
"fmt"
2324
"io/ioutil"
2425
"os"
2526
"strings"
@@ -94,6 +95,18 @@ type ConfigObject struct {
9495
Labels map[string]string `json:"Labels"`
9596
}
9697

98+
func (c ConfigObject) AsList() []string {
99+
return []string{
100+
fmt.Sprintf("Env: %s", strings.Join(c.Env, ",")),
101+
fmt.Sprintf("Entrypoint: %s", strings.Join(c.Entrypoint, ",")),
102+
fmt.Sprintf("ExposedPorts: %v", c.ExposedPorts),
103+
fmt.Sprintf("Cmd: %s", strings.Join(c.Cmd, ",")),
104+
fmt.Sprintf("Volumes: %v", c.Volumes),
105+
fmt.Sprintf("Workdir: %s", c.Workdir),
106+
fmt.Sprintf("Labels: %v", c.Labels),
107+
}
108+
}
109+
97110
type ConfigSchema struct {
98111
Config ConfigObject `json:"config"`
99112
History []ImageHistoryItem `json:"history"`

tests/integration_test.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ const (
3939
diffBase = "gcr.io/gcp-runtimes/diff-base"
4040
diffModified = "gcr.io/gcp-runtimes/diff-modified"
4141

42+
metadataBase = "gcr.io/gcp-runtimes/metadata-base"
43+
metadataModified = "gcr.io/gcp-runtimes/metadata-modified"
44+
4245
aptBase = "gcr.io/gcp-runtimes/apt-base"
4346
aptModified = "gcr.io/gcp-runtimes/apt-modified"
4447

@@ -152,6 +155,14 @@ func TestDiffAndAnalysis(t *testing.T) {
152155
differFlags: []string{"--type=history"},
153156
expectedFile: "hist_diff_expected.json",
154157
},
158+
{
159+
description: "metadata differ",
160+
subcommand: "diff",
161+
imageA: metadataBase,
162+
imageB: metadataModified,
163+
differFlags: []string{"--type=metadata"},
164+
expectedFile: "metadata_diff_expected.json",
165+
},
155166
{
156167
description: "apt sorted differ",
157168
subcommand: "diff",

tests/metadata_diff_expected.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
[
2+
{
3+
"Image1": "gcr.io/gcp-runtimes/metadata-base:latest",
4+
"Image2": "gcr.io/gcp-runtimes/metadata-modified:latest",
5+
"DiffType": "Metadata",
6+
"Diff": {
7+
"Adds": [
8+
"Entrypoint: /entrypoint",
9+
"ExposedPorts: map[1234/tcp:{}]"
10+
],
11+
"Dels": [
12+
"Entrypoint: ",
13+
"ExposedPorts: map[1234/tcp:{} 4321/tcp:{}]"
14+
]
15+
}
16+
}
17+
]

util/diff_output_utils.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,16 @@ func (r HistDiffResult) OutputText(diffType string, format string) error {
172172
return TemplateOutputFromFormat(r, "HistDiff", format)
173173
}
174174

175+
type MetadataDiffResult DiffResult
176+
177+
func (r MetadataDiffResult) OutputStruct() interface{} {
178+
return r
179+
}
180+
181+
func (r MetadataDiffResult) OutputText(diffType string, format string) error {
182+
return TemplateOutputFromFormat(r, "MetadataDiff", format)
183+
}
184+
175185
type DirDiffResult DiffResult
176186

177187
func (r DirDiffResult) OutputStruct() interface{} {

util/format_utils.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ var templates = map[string]string{
3232
"SingleVersionPackageDiff": SingleVersionDiffOutput,
3333
"MultiVersionPackageDiff": MultiVersionDiffOutput,
3434
"HistDiff": HistoryDiffOutput,
35+
"MetadataDiff": MetadataDiffOutput,
3536
"DirDiff": FSDiffOutput,
3637
"FilenameDiff": FilenameDiffOutput,
3738
"ListAnalyze": ListAnalysisOutput,

util/template_utils.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,17 @@ Docker history lines found only in {{.Image1}}:{{if not .Diff.Adds}} None{{else}
6565
6666
Docker history lines found only in {{.Image2}}:{{if not .Diff.Dels}} None{{else}}{{block "list2" .Diff.Dels}}{{"\n"}}{{range .}}{{print "-" .}}{{"\n"}}{{end}}{{end}}{{end}}
6767
`
68+
69+
const MetadataDiffOutput = `
70+
-----{{.DiffType}}-----
71+
72+
Image metadata differences between {{.Image1}} and {{.Image2}}:
73+
74+
{{.Image1}}{{if not .Diff.Adds}} None{{else}}{{block "list" .Diff.Adds}}{{"\n"}}{{range .}}{{print "-" .}}{{"\n"}}{{end}}{{end}}{{end}}
75+
76+
{{.Image2}}{{if not .Diff.Dels}} None{{else}}{{block "list2" .Diff.Dels}}{{"\n"}}{{range .}}{{print "-" .}}{{"\n"}}{{end}}{{end}}{{end}}
77+
`
78+
6879
const FilenameDiffOutput = `
6980
-----Diff of {{.Filename}}-----
7081
{{.Description}}

0 commit comments

Comments
 (0)