@@ -77,17 +77,27 @@ func writeSBOM(p *Package, buildctx *buildContext, builddir string) (err error)
77
77
return nil
78
78
}
79
79
80
- // Get the source for SBOM generation
81
- src , err := syft .GetSource (context .Background (), builddir , nil )
82
- if err != nil {
83
- return xerrors .Errorf ("failed to get source for SBOM generation: %w" , err )
84
- }
85
-
86
80
// Create SBOM configuration
87
81
cfg := syft .DefaultCreateSBOMConfig ()
88
82
89
- // Generate the SBOM
90
- s , err := syft .CreateSBOM (context .Background (), src , cfg )
83
+ // Get the source for SBOM generation based on package type
84
+ var s * sbom.SBOM
85
+ if p .Type == DockerPackage {
86
+ s , err = generateDockerSBOM (p , buildctx , builddir , cfg )
87
+ } else {
88
+ // For non-Docker packages, use the standard approach
89
+ src , err := syft .GetSource (context .Background (), builddir , nil )
90
+ if err != nil {
91
+ return xerrors .Errorf ("failed to get source for SBOM generation: %w" , err )
92
+ }
93
+
94
+ // Generate the SBOM
95
+ s , err = syft .CreateSBOM (context .Background (), src , cfg )
96
+ if err != nil {
97
+ return xerrors .Errorf ("failed to create SBOM: %w" , err )
98
+ }
99
+ }
100
+
91
101
if err != nil {
92
102
return xerrors .Errorf ("failed to create SBOM: %w" , err )
93
103
}
@@ -123,6 +133,61 @@ func writeSBOM(p *Package, buildctx *buildContext, builddir string) (err error)
123
133
return nil
124
134
}
125
135
136
+ // generateDockerSBOM generates an SBOM specifically for Docker packages
137
+ func generateDockerSBOM (p * Package , buildctx * buildContext , builddir string , cfg interface {}) (* sbom.SBOM , error ) {
138
+ // We need to use the same configuration type as returned by syft.DefaultCreateSBOMConfig()
139
+ // Based on the error message, we need to use *syft.CreateSBOMConfig
140
+ sbomConfig , ok := cfg .(* syft.CreateSBOMConfig )
141
+ if ! ok {
142
+ return nil , xerrors .Errorf ("invalid SBOM configuration type" )
143
+ }
144
+
145
+ // Check if this is a Docker package with specified image names (pushed to registry)
146
+ dockerCfg , ok := p .Config .(DockerPkgConfig )
147
+ if ! ok {
148
+ return nil , xerrors .Errorf ("package should have Docker config" )
149
+ }
150
+
151
+ // Get the version which is used as the image tag during build
152
+ version , err := p .Version ()
153
+ if err != nil {
154
+ return nil , xerrors .Errorf ("failed to get package version: %w" , err )
155
+ }
156
+
157
+ if len (dockerCfg .Image ) > 0 {
158
+ // For pushed Docker images, analyze the image directly before it's pushed
159
+ buildctx .Reporter .PackageBuildLog (p , false , []byte ("Generating SBOM from Docker image\n " ))
160
+
161
+ // Use the daemon source to analyze the Docker image directly
162
+ src , err := syft .GetSource (context .Background (), "docker:" + version , nil )
163
+ if err != nil {
164
+ return nil , xerrors .Errorf ("failed to get Docker image source for SBOM generation: %w" , err )
165
+ }
166
+
167
+ // Generate the SBOM from the Docker image
168
+ return syft .CreateSBOM (context .Background (), src , sbomConfig )
169
+ } else {
170
+ // For non-pushed Docker images, use the extracted container filesystem
171
+ containerDir := filepath .Join (builddir , "container" , "content" )
172
+
173
+ // Check if the container directory exists
174
+ if _ , err := os .Stat (containerDir ); os .IsNotExist (err ) {
175
+ return nil , xerrors .Errorf ("container directory not found at %s: %w" , containerDir , err )
176
+ }
177
+
178
+ buildctx .Reporter .PackageBuildLog (p , false , []byte (fmt .Sprintf ("Generating SBOM from extracted container filesystem at %s\n " , containerDir )))
179
+
180
+ // Use the directory source to analyze the extracted container filesystem
181
+ src , err := syft .GetSource (context .Background (), containerDir , nil )
182
+ if err != nil {
183
+ return nil , xerrors .Errorf ("failed to get container filesystem source for SBOM generation: %w" , err )
184
+ }
185
+
186
+ // Generate the SBOM from the extracted container filesystem
187
+ return syft .CreateSBOM (context .Background (), src , sbomConfig )
188
+ }
189
+ }
190
+
126
191
// getSBOMEncoder returns the appropriate encoder and file extension for the given SBOM format
127
192
func getSBOMEncoder (format string ) (encoder sbom.FormatEncoder , fileExtension string , err error ) {
128
193
switch format {
0 commit comments