1717package sbom
1818
1919import (
20+ "crypto/sha256"
21+ "fmt"
22+ "io"
23+
24+ "github.com/anchore/syft/syft/source"
2025 "github.com/docker/cli/cli/command"
2126 cliflags "github.com/docker/cli/cli/flags"
27+ "github.com/docker/index-cli-plugin/registry"
28+ "github.com/docker/index-cli-plugin/sbom/util"
2229 "github.com/pkg/errors"
2330)
2431
@@ -41,3 +48,39 @@ func Send(image string, tx chan<- string) error {
4148 close (tx )
4249 return nil
4350}
51+
52+ func SendFileHashes (image string , tx chan <- string ) error {
53+ cmd , err := command .NewDockerCli ()
54+ if err != nil {
55+ return errors .Wrap (err , "failed to create docker cli" )
56+ }
57+ if err := cmd .Initialize (cliflags .NewClientOptions ()); err != nil {
58+ return errors .Wrap (err , "failed to initialize docker cli" )
59+ }
60+ cache , err := registry .SaveImage (image , cmd )
61+ if err != nil {
62+ return errors .Wrap (err , "failed to copy image" )
63+ }
64+ err = cache .StoreImage ()
65+ if err != nil {
66+ return errors .Wrap (err , "failed to save image" )
67+ }
68+ for _ , layer := range cache .Source .Image .Layers {
69+ res := util .NewSingleLayerResolver (layer )
70+ refs := layer .Tree .AllFiles ()
71+ for _ , ref := range refs {
72+ content , err := res .FileContentsByLocation (source .NewLocation (string (ref .RealPath )))
73+ if err == nil {
74+ b , _ := io .ReadAll (content )
75+ content .Close ()
76+ h := sha256 .New ()
77+ h .Write (b )
78+ hash := fmt .Sprintf ("sha256:%x" , h .Sum (nil ))
79+ msg := fmt .Sprintf (`{:path "%s" :hash "%s"}` , ref .RealPath , hash )
80+ tx <- msg
81+ }
82+ }
83+ }
84+ close (tx )
85+ return nil
86+ }
0 commit comments