Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[POC] Provisioner for SBOM #13171

Draft
wants to merge 27 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
10a107c
Add outer provisioner to download, validate and compress SBOM
devashish-patel Sep 18, 2024
e359898
Add and set up internal SBOM provisioner
devashish-patel Sep 25, 2024
8ab261e
Modify external provisioner
devashish-patel Sep 25, 2024
df8f3cf
Fix lint
devashish-patel Sep 25, 2024
54a0f9a
Fix tests
devashish-patel Sep 25, 2024
d17d0a7
Add PR suggestions
devashish-patel Sep 30, 2024
ed7a0d5
Remove unnecessary test
devashish-patel Sep 30, 2024
66daeb7
Run generate
devashish-patel Oct 4, 2024
b38d844
DRY download SBOM functions
devashish-patel Oct 9, 2024
2b3c440
Add support for SPDX
devashish-patel Oct 9, 2024
4139f75
Fix linting
devashish-patel Oct 9, 2024
4cf3811
Optimize code
devashish-patel Oct 14, 2024
768b9a0
Rename hcp_sbom to hcp-sbom
devashish-patel Oct 15, 2024
890b476
Typed error check in validation
devashish-patel Oct 21, 2024
fb3d15c
Use single buffer
devashish-patel Oct 21, 2024
03a7142
Lint
devashish-patel Oct 21, 2024
d35cafe
packer_test: add file checker
lbajolet-hashicorp Oct 1, 2024
8a996bb
simplify error typing for SBOM validation
lbajolet-hashicorp Oct 25, 2024
4e8affb
fixme: add path/home to commands for docker to run, should be general…
lbajolet-hashicorp Oct 25, 2024
127d625
packer_test: add intergation tests for hcp-sbom
lbajolet-hashicorp Oct 25, 2024
9dae54a
Add more acceptance tests
devashish-patel Oct 25, 2024
b697100
Refactor to filepath.Glob
devashish-patel Oct 28, 2024
eda9f4f
fix: file download logic when given destination does not exist
devashish-patel Oct 28, 2024
8505791
Fix error messages for FileGlob checker
devashish-patel Oct 31, 2024
cf02850
parity in error messages
devashish-patel Oct 31, 2024
b446bce
Add docs
devashish-patel Nov 1, 2024
bc70ae1
Fix verbiage in website
devashish-patel Nov 4, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions command/execute.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
shelllocalpostprocessor "github.com/hashicorp/packer/post-processor/shell-local"
breakpointprovisioner "github.com/hashicorp/packer/provisioner/breakpoint"
fileprovisioner "github.com/hashicorp/packer/provisioner/file"
hcpsbomprovisioner "github.com/hashicorp/packer/provisioner/hcp-sbom"
powershellprovisioner "github.com/hashicorp/packer/provisioner/powershell"
shellprovisioner "github.com/hashicorp/packer/provisioner/shell"
shelllocalprovisioner "github.com/hashicorp/packer/provisioner/shell-local"
Expand All @@ -48,6 +49,7 @@ var Builders = map[string]packersdk.Builder{
var Provisioners = map[string]packersdk.Provisioner{
"breakpoint": new(breakpointprovisioner.Provisioner),
"file": new(fileprovisioner.Provisioner),
"hcp-sbom": new(hcpsbomprovisioner.Provisioner),
"powershell": new(powershellprovisioner.Provisioner),
"shell": new(shellprovisioner.Provisioner),
"shell-local": new(shelllocalprovisioner.Provisioner),
Expand Down
7 changes: 5 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ require (
github.com/hashicorp/packer-plugin-amazon v1.2.1
github.com/hashicorp/packer-plugin-sdk v0.5.4
github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869
github.com/klauspost/compress v1.13.6 // indirect
github.com/klauspost/compress v1.13.6
github.com/klauspost/pgzip v1.2.5
github.com/masterzen/winrm v0.0.0-20210623064412-3b76017826b0
github.com/mattn/go-runewidth v0.0.13 // indirect
Expand All @@ -40,7 +40,7 @@ require (
github.com/packer-community/winrmcp v0.0.0-20180921211025-c76d91c1e7db // indirect
github.com/pkg/sftp v1.13.2 // indirect
github.com/posener/complete v1.2.3
github.com/stretchr/testify v1.8.4
github.com/stretchr/testify v1.9.0
github.com/ulikunitz/xz v0.5.10
github.com/zclconf/go-cty v1.13.3
github.com/zclconf/go-cty-yaml v1.0.1
Expand All @@ -58,10 +58,12 @@ require (
)

require (
github.com/CycloneDX/cyclonedx-go v0.9.1
github.com/go-openapi/strfmt v0.21.10
github.com/oklog/ulid v1.3.1
github.com/pierrec/lz4/v4 v4.1.18
github.com/shirou/gopsutil/v3 v3.23.4
github.com/spdx/tools-golang v0.5.5
)

require (
Expand All @@ -78,6 +80,7 @@ require (
github.com/Microsoft/go-winio v0.6.1 // indirect
github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 // indirect
github.com/agext/levenshtein v1.2.3 // indirect
github.com/anchore/go-struct-converter v0.0.0-20221118182256-c68fdcfa2092 // indirect
github.com/apparentlymart/go-cidr v1.0.1 // indirect
github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect
github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect
Expand Down
22 changes: 20 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym
github.com/ChrisTrenkamp/goxpath v0.0.0-20170922090931-c385f95c6022/go.mod h1:nuWgzSkT5PnyOd+272uUmV0dnAnAn42Mk7PiQC5VzN4=
github.com/ChrisTrenkamp/goxpath v0.0.0-20210404020558-97928f7e12b6 h1:w0E0fgc1YafGEh5cROhlROMWXiNoZqApk2PDN0M1+Ns=
github.com/ChrisTrenkamp/goxpath v0.0.0-20210404020558-97928f7e12b6/go.mod h1:nuWgzSkT5PnyOd+272uUmV0dnAnAn42Mk7PiQC5VzN4=
github.com/CycloneDX/cyclonedx-go v0.9.1 h1:yffaWOZsv77oTJa/SdVZYdgAgFioCeycBUKkqS2qzQM=
github.com/CycloneDX/cyclonedx-go v0.9.1/go.mod h1:NE/EWvzELOFlG6+ljX/QeMlVt9VKcTwu8u0ccsACEsw=
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
Expand All @@ -38,6 +40,8 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuy
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/anchore/go-struct-converter v0.0.0-20221118182256-c68fdcfa2092 h1:aM1rlcoLz8y5B2r4tTLMiVTrMtpfY0O8EScKJxaSaEc=
github.com/anchore/go-struct-converter v0.0.0-20221118182256-c68fdcfa2092/go.mod h1:rYqSE9HbjzpHTI74vwPvae4ZVYZd1lue2ta6xHPdblA=
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=
github.com/antchfx/xmlquery v1.3.5 h1:I7TuBRqsnfFuL11ruavGm911Awx9IqSdiU6W/ztSmVw=
Expand Down Expand Up @@ -78,6 +82,8 @@ github.com/biogo/hts v1.4.3 h1:vir2yUTiRkPvtp6ZTpzh9lWTKQJZXJKZ563rpAQAsRM=
github.com/biogo/hts v1.4.3/go.mod h1:eW40HJ1l2ExK9C+yvvoRSftInqWsf3ue+zAEjzCGWjA=
github.com/bmatcuk/doublestar v1.1.5 h1:2bNwBOmhyFEFcoB3tGvTD5xanq+4kyOZlB8wFYbMjkk=
github.com/bmatcuk/doublestar v1.1.5/go.mod h1:wiQtGV+rzVYxB7WIlirSN++5HPtPlXEo9MEoZQC/PmE=
github.com/bradleyjkemp/cupaloy/v2 v2.8.0 h1:any4BmKE+jGIaMpnU8YgH/I2LPiLBufr6oMMlVBbn9M=
github.com/bradleyjkemp/cupaloy/v2 v2.8.0/go.mod h1:bm7JXdkRd4BHJk9HpwqAI8BoAY1lps46Enkdqw6aRX0=
github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
github.com/cenkalti/backoff/v3 v3.2.2 h1:cfUAAO3yvKMYKPrvhDuHSwQnhZNk/RMHKdZqKTxfm6M=
github.com/cenkalti/backoff/v3 v3.2.2/go.mod h1:cIeZDE3IrqwwJl6VUwCN6trj1oXrTS4rc0ij+ULvLYs=
Expand Down Expand Up @@ -497,13 +503,17 @@ github.com/skeema/knownhosts v1.2.1 h1:SHWdIUa82uGZz+F+47k8SY4QhhI291cXCpopT1lK2
github.com/skeema/knownhosts v1.2.1/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo=
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 h1:JIAuq3EEf9cgbU6AtGPK4CTG3Zf6CKMNqf0MHTggAUA=
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog=
github.com/spdx/gordf v0.0.0-20201111095634-7098f93598fb/go.mod h1:uKWaldnbMnjsSAXRurWqqrdyZen1R7kxl8TkmWk2OyM=
github.com/spdx/tools-golang v0.5.5 h1:61c0KLfAcNqAjlg6UNMdkwpMernhw3zVRwDZ2x9XOmk=
github.com/spdx/tools-golang v0.5.5/go.mod h1:MVIsXx8ZZzaRWNQpUDhC4Dud34edUYJYecciXgrw5vE=
github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng=
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
Expand All @@ -515,8 +525,11 @@ github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1F
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/terminalstatic/go-xsd-validate v0.1.5 h1:RqpJnf6HGE2CB/lZB1A8BYguk8uRtcvYAPLCF15qguo=
github.com/terminalstatic/go-xsd-validate v0.1.5/go.mod h1:18lsvYFofBflqCrvo1umpABZ99+GneNTw2kEEc8UPJw=
github.com/tklauser/go-sysconf v0.3.11 h1:89WgdJhk5SNwJfu+GKyYveZ4IaJ7xAkecBo+KdJV0CM=
github.com/tklauser/go-sysconf v0.3.11/go.mod h1:GqXfhXY3kiPa0nAXPDIQIWzJbMCB7AmcWpGR8lSZfqI=
github.com/tklauser/numcpus v0.6.0 h1:kebhY2Qt+3U6RNK7UqpYNA+tJ23IBEGKkB7JQBfDYms=
Expand All @@ -537,6 +550,10 @@ github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3k
github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM=
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo=
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg=
Expand Down Expand Up @@ -758,3 +775,4 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
6 changes: 6 additions & 0 deletions hcl2template/types.packer_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,12 @@ func (cfg *PackerConfig) getCoreBuildProvisioner(source SourceUseBlock, pb *Prov
}
}

if pb.PType == "hcp-sbom" {
provisioner = &packer.SBOMInternalProvisioner{
Provisioner: provisioner,
}
}

return packer.CoreBuildProvisioner{
PType: pb.PType,
PName: pb.PName,
Expand Down
20 changes: 20 additions & 0 deletions packer/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,19 @@ type CoreBuild struct {
onError string
l sync.Mutex
prepareCalled bool

SBOMs []SBOM
}

type SBOM struct {
Format string
CompressedData []byte
}

type BuildMetadata struct {
PackerVersion string
Plugins map[string]PluginDetails
SBOMs []SBOM
}

func (b *CoreBuild) getPluginsMetadata() map[string]PluginDetails {
Expand Down Expand Up @@ -88,6 +96,7 @@ func (b *CoreBuild) GetMetadata() BuildMetadata {
metadata := BuildMetadata{
PackerVersion: version.FormattedVersion(),
Plugins: b.getPluginsMetadata(),
SBOMs: b.SBOMs,
}
return metadata
}
Expand Down Expand Up @@ -300,6 +309,17 @@ func (b *CoreBuild) Run(ctx context.Context, originalUi packersdk.Ui) ([]packers
return nil, err
}

for _, p := range b.Provisioners {
sbomInternalProvisioner, ok := p.Provisioner.(*SBOMInternalProvisioner)
if ok {
sbom := SBOM{
Format: sbomInternalProvisioner.SBOMFormat,
CompressedData: sbomInternalProvisioner.CompressedData,
}
b.SBOMs = append(b.SBOMs, sbom)
}
}

// If there was no result, don't worry about running post-processors
// because there is nothing they can do, just return.
if builderArtifact == nil {
Expand Down
7 changes: 7 additions & 0 deletions packer/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,13 @@ func (c *Core) generateCoreBuildProvisioner(rawP *template.Provisioner, rawName
Provisioner: provisioner,
}
}

if rawP.Type == "hcp-sbom" {
provisioner = &SBOMInternalProvisioner{
Provisioner: provisioner,
}
}

cbp = CoreBuildProvisioner{
PType: rawP.Type,
Provisioner: provisioner,
Expand Down
101 changes: 101 additions & 0 deletions packer/provisioner.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ import (
"context"
"fmt"
"log"
"os"

hcpSbomProvisioner "github.com/hashicorp/packer/provisioner/hcp-sbom"

"github.com/klauspost/compress/zstd"

"time"

"github.com/hashicorp/hcl/v2/hcldec"
Expand Down Expand Up @@ -234,3 +240,98 @@ func (p *DebuggedProvisioner) Provision(ctx context.Context, ui packersdk.Ui, co

return p.Provisioner.Provision(ctx, ui, comm, generatedData)
}

// SBOMInternalProvisioner is a wrapper provisioner for the `hcp-sbom` provisioner
// that sets the path for SBOM file download and, after the successful execution of
// the `hcp-sbom` provisioner, compresses the SBOM and prepares the data for API
// integration.
type SBOMInternalProvisioner struct {
Provisioner packersdk.Provisioner
CompressedData []byte
SBOMFormat string
}

func (p *SBOMInternalProvisioner) ConfigSpec() hcldec.ObjectSpec { return p.ConfigSpec() }
func (p *SBOMInternalProvisioner) FlatConfig() interface{} { return p.FlatConfig() }
func (p *SBOMInternalProvisioner) Prepare(raws ...interface{}) error {
return p.Provisioner.Prepare(raws...)
}

func (p *SBOMInternalProvisioner) Provision(
ctx context.Context, ui packersdk.Ui, comm packersdk.Communicator,
generatedData map[string]interface{},
) error {
cwd, err := os.Getwd()
if err != nil {
return fmt.Errorf("failed to get current working directory for Packer SBOM: %s", err)
}

tmpFile, err := os.CreateTemp(cwd, "packer-sbom-*.json")
if err != nil {
return fmt.Errorf("failed to create internal temporary file for Packer SBOM: %s", err)
}

tmpFileName := tmpFile.Name()
if err = tmpFile.Close(); err != nil {
return fmt.Errorf("failed to close temporary file for Packer SBOM %s: %s", tmpFileName, err)
}

defer func(name string) {
fileRemoveErr := os.Remove(name)
if fileRemoveErr != nil {
log.Printf("Error removing SBOM temporary file %s: %s", name, fileRemoveErr)
}
}(tmpFile.Name())

generatedData["dst"] = tmpFile.Name()

err = p.Provisioner.Provision(ctx, ui, comm, generatedData)
if err != nil {
return err
}

sbomFormat, err := p.getSBOMFormat(tmpFile.Name())
if err != nil {
return err
}

compressedData, err := p.compressFile(tmpFile.Name())
if err != nil {
return err
}
p.CompressedData = compressedData
p.SBOMFormat = sbomFormat
return nil
}

func (p *SBOMInternalProvisioner) compressFile(filePath string) ([]byte, error) {
data, err := os.ReadFile(filePath)
if err != nil {
return nil, fmt.Errorf("failed to read file %s: %w", filePath, err)
}

encoder, err := zstd.NewWriter(nil, zstd.WithEncoderLevel(zstd.SpeedBestCompression))
if err != nil {
return nil, fmt.Errorf("failed to create zstd encoder: %w", err)
}

compressedData := encoder.EncodeAll(data, nil)

log.Printf("SBOM file compressed successfully. Size: %d bytes\n", len(compressedData))
return compressedData, nil
}

func (p *SBOMInternalProvisioner) getSBOMFormat(filePath string) (string, error) {
file, err := os.Open(filePath)
if err != nil {
return "", fmt.Errorf("failed to open SBOM file %s: %w", filePath, err)
}
defer file.Close()

format, err := hcpSbomProvisioner.ValidateSBOM(file)
if err != nil {
return "", fmt.Errorf("failed to detect SBOM format: %w", err)
}

return format, nil
}
59 changes: 59 additions & 0 deletions packer_test/common/check/file_gadgets.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package check

import (
"fmt"
"os"
"path/filepath"
)

type fileExists struct {
filepath string
isDir bool
}

func (fe fileExists) Check(_, _ string, _ error) error {
st, err := os.Stat(fe.filepath)
if err != nil {
return fmt.Errorf("failed to stat %q: %s", fe.filepath, err)
}

if st.IsDir() && !fe.isDir {
return fmt.Errorf("file %q is a directory, wasn't supposed to be", fe.filepath)
}

if !st.IsDir() && fe.isDir {
return fmt.Errorf("file %q is not a directory, was supposed to be", fe.filepath)
}

return nil
}

func FileExists(filePath string, isDir bool) Checker {
return fileExists{
filepath: filePath,
isDir: isDir,
}
}

type fileGlob struct {
filepath string
}

func (fe fileGlob) Check(_, _ string, _ error) error {
matches, err := filepath.Glob(fe.filepath)
if err != nil {
return fmt.Errorf("error evaluating file glob pattern %q: %v", fe.filepath, err)
}

if len(matches) == 0 {
return fmt.Errorf("no matches found for file glob pattern %q", fe.filepath)
}

return nil
}

func FileGlob(filename string) Checker {
return fileGlob{
filepath: filename,
}
}
2 changes: 2 additions & 0 deletions packer_test/common/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ func (ts *PackerTestSuite) PackerCommand() *packerCommand {
// make them as self-contained and quick as possible.
// Removing telemetry here is probably for the best.
"CHECKPOINT_DISABLE": "1",
"HOME": os.Getenv("HOME"),
"PATH": os.Getenv("PATH"),
},
t: ts.T(),
}
Expand Down
Loading