Skip to content

Commit 2bb882f

Browse files
tonaimknqyf263
andauthored
feat(image): add uncompressed layer size (fanal#182)
* Add uncompressed layer size This commit will help in getting uncompressed layer sizes. Can sum up these layer sizes to get the actual image size * Removed unnecessary exception * refactor Co-authored-by: knqyf263 <knqyf263@gmail.com>
1 parent a0f5bdc commit 2bb882f

File tree

4 files changed

+37
-1
lines changed

4 files changed

+37
-1
lines changed

applier/docker.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ func ApplyLayers(layers []types.BlobInfo) types.ArtifactDetail {
7171
var mergedLayer types.ArtifactDetail
7272

7373
for _, layer := range layers {
74+
mergedLayer.Size += layer.Size
7475
for _, opqDir := range layer.OpaqueDirs {
7576
_ = nestedMap.DeleteByString(opqDir, sep)
7677
}

artifact/image/image.go

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,11 +178,13 @@ func (a Artifact) inspectLayer(ctx context.Context, diffID string) (types.BlobIn
178178
return types.BlobInfo{}, xerrors.Errorf("unable to get uncompressed layer %s: %w", diffID, err)
179179
}
180180

181+
// below line of code gets the size of uncompressed layer. Will sum up these layer sizes to get the size of image.
182+
cr := newCountingReader(r)
181183
var wg sync.WaitGroup
182184
result := new(analyzer.AnalysisResult)
183185
limit := semaphore.NewWeighted(parallel)
184186

185-
opqDirs, whFiles, err := walker.WalkLayerTar(r, func(filePath string, info os.FileInfo, opener analyzer.Opener) error {
187+
opqDirs, whFiles, err := walker.WalkLayerTar(cr, func(filePath string, info os.FileInfo, opener analyzer.Opener) error {
186188
if err = a.analyzer.AnalyzeFile(ctx, &wg, limit, result, filePath, info, opener); err != nil {
187189
return xerrors.Errorf("failed to analyze %s: %w", filePath, err)
188190
}
@@ -214,6 +216,7 @@ func (a Artifact) inspectLayer(ctx context.Context, diffID string) (types.BlobIn
214216
Misconfigurations: misconfs,
215217
OpaqueDirs: opqDirs,
216218
WhiteoutFiles: whFiles,
219+
Size: cr.Size(),
217220
}
218221
return layerInfo, nil
219222
}
@@ -281,3 +284,22 @@ func (a Artifact) inspectConfig(imageID string, osFound types.OS) error {
281284

282285
return nil
283286
}
287+
288+
type countingReader struct {
289+
reader io.Reader
290+
bytesRead int
291+
}
292+
293+
func newCountingReader(r io.Reader) *countingReader {
294+
return &countingReader{reader: r}
295+
}
296+
297+
func (r *countingReader) Read(p []byte) (n int, err error) {
298+
n, err = r.reader.Read(p)
299+
r.bytesRead += n
300+
return n, err
301+
}
302+
303+
func (r *countingReader) Size() int {
304+
return r.bytesRead
305+
}

artifact/image/image_test.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ func TestArtifact_Inspect(t *testing.T) {
7878
Applications: []types.Application(nil),
7979
OpaqueDirs: []string(nil),
8080
WhiteoutFiles: []string(nil),
81+
Size: 5861888,
8182
},
8283
},
8384
Returns: cache.ArtifactCachePutBlobReturns{},
@@ -137,6 +138,7 @@ func TestArtifact_Inspect(t *testing.T) {
137138
Family: "debian",
138139
Name: "9.9",
139140
},
141+
Size: 3056640,
140142
PackageInfos: []types.PackageInfo{
141143
{
142144
FilePath: "var/lib/dpkg/status.d/base",
@@ -187,6 +189,7 @@ func TestArtifact_Inspect(t *testing.T) {
187189
},
188190
},
189191
},
192+
Size: 15433728,
190193
},
191194
},
192195
},
@@ -197,6 +200,7 @@ func TestArtifact_Inspect(t *testing.T) {
197200
SchemaVersion: 1,
198201
Digest: "",
199202
DiffID: "sha256:24df0d4e20c0f42d3703bf1f1db2bdd77346c7956f74f423603d651e8e5ae8a7",
203+
Size: 29696,
200204
Applications: []types.Application{{Type: "composer", FilePath: "php-app/composer.lock",
201205
Libraries: []types.LibraryInfo{
202206
{Library: depTypes.Library{Name: "guzzlehttp/guzzle", Version: "6.2.0"}},
@@ -287,6 +291,7 @@ func TestArtifact_Inspect(t *testing.T) {
287291
OpaqueDirs: []string{
288292
"ruby-app/",
289293
},
294+
Size: 6656,
290295
},
291296
},
292297
},
@@ -333,6 +338,7 @@ func TestArtifact_Inspect(t *testing.T) {
333338
SchemaVersion: 1,
334339
Digest: "",
335340
DiffID: "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02",
341+
Size: 3056640,
336342
},
337343
},
338344
},
@@ -343,6 +349,7 @@ func TestArtifact_Inspect(t *testing.T) {
343349
SchemaVersion: 1,
344350
Digest: "",
345351
DiffID: "sha256:dffd9992ca398466a663c87c92cfea2a2db0ae0cf33fcb99da60eec52addbfc5",
352+
Size: 15433728,
346353
},
347354
},
348355
},
@@ -354,6 +361,7 @@ func TestArtifact_Inspect(t *testing.T) {
354361
Digest: "",
355362
DiffID: "sha256:24df0d4e20c0f42d3703bf1f1db2bdd77346c7956f74f423603d651e8e5ae8a7",
356363
OpaqueDirs: []string{"php-app/"},
364+
Size: 29696,
357365
},
358366
},
359367
},
@@ -365,6 +373,7 @@ func TestArtifact_Inspect(t *testing.T) {
365373
Digest: "",
366374
DiffID: "sha256:a4595c43a874856bf95f3bfc4fbf78bbaa04c92c726276d4f64193a47ced0566",
367375
OpaqueDirs: []string{"ruby-app/"},
376+
Size: 6656,
368377
},
369378
},
370379
},
@@ -440,6 +449,7 @@ func TestArtifact_Inspect(t *testing.T) {
440449
Applications: []types.Application(nil),
441450
OpaqueDirs: []string(nil),
442451
WhiteoutFiles: []string(nil),
452+
Size: 5861888,
443453
},
444454
},
445455
Returns: cache.ArtifactCachePutBlobReturns{
@@ -496,6 +506,7 @@ func TestArtifact_Inspect(t *testing.T) {
496506
Applications: []types.Application(nil),
497507
OpaqueDirs: []string(nil),
498508
WhiteoutFiles: []string(nil),
509+
Size: 5861888,
499510
},
500511
},
501512
Returns: cache.ArtifactCachePutBlobReturns{},

types/artifact.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ type BlobInfo struct {
9090
Misconfigurations []Misconfiguration `json:",omitempty"`
9191
OpaqueDirs []string `json:",omitempty"`
9292
WhiteoutFiles []string `json:",omitempty"`
93+
Size int `json:",omitempty"`
9394
}
9495

9596
// ArtifactDetail is generated by applying blobs
@@ -98,6 +99,7 @@ type ArtifactDetail struct {
9899
Packages []Package `json:",omitempty"`
99100
Applications []Application `json:",omitempty"`
100101
Misconfigurations []Misconfiguration `json:",omitempty"`
102+
Size int `json:",omitempty"`
101103

102104
// HistoryPackages are packages extracted from RUN instructions
103105
HistoryPackages []Package `json:",omitempty"`

0 commit comments

Comments
 (0)