anchore / syft

CLI tool and library for generating a Software Bill of Materials from container images and filesystems
Apache License 2.0
5.98k stars 551 forks source link

Detect go main module from partial package builds #3060

Closed wagoodman closed 1 month ago

wagoodman commented 1 month ago

Today syft has the capability of detecting the go main module from the buildinfo section within binaries. One case not handled is when you are building from a set of source files instead of a package:

CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo \
    -ldflags="-w -s \
    -X ${GITHUB_REPO}/config.Version=${VERSION} \
    -X ${GITHUB_REPO}/config.GitCommit=${GIT_COMMIT} \
    -X ${GITHUB_REPO}/config.BuildDate=$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
    -o main cmd/exporter/main.go

(Note: the -o is a list of source files, not a directory)

Something like this has the correct LD flags, thus, we should be able to pick up on the version for the main module. However, in this circumstance, there is no module information:

go version -m ./app
./app: go1.22.5
    path    command-line-arguments
    dep github.com/beorn7/perks v1.0.1  h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
    dep github.com/cespare/xxhash/v2    v2.3.0  h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
    dep github.com/joho/godotenv    v1.5.1  h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
    dep github.com/kuskoman/logstash-exporter   (devel)
    dep github.com/munnerz/goautoneg    v0.0.0-20191010083416-a7dc8b61c822  h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
    dep github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE=
    dep github.com/prometheus/client_model  v0.6.1  h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
    dep github.com/prometheus/common    v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc=
    dep github.com/prometheus/procfs    v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
    dep golang.org/x/sys    v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
    dep google.golang.org/protobuf  v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
    build   -buildmode=exe
    build   -compiler=gc
    build   -ldflags="-w -s     -X github.com/kuskoman/logstash-exporter/config.Version=v1.7.0     -X github.com/kuskoman/logstash-exporter/config.GitCommit=db696dbcfe5a91d288d5ad44ce8ccbea97e65978     -X github.com/kuskoman/logstash-exporter/config.BuildDate=2024-07-17T08:12:17Z"
    build   CGO_ENABLED=0
    build   GOARCH=arm64
    build   GOOS=linux

Where the important bits are:

path    command-line-arguments
...
dep github.com/kuskoman/logstash-exporter   (devel)

In this case the real main module is a dependency of a fictitious main module called command-line-arguments. This PR adjusts the behavior to correctly identify the main module, thus, be able to identify the version information.

Before (with syft kuskoman/logstash-exporter:v1.7.0 -v | grep logstash-exporter) :

github.com/kuskoman/logstash-exporter  (devel)                             go-module    

With the current change:

github.com/kuskoman/logstash-exporter  v1.7.0                              go-module