mirror of
https://github.com/anchore/syft.git
synced 2025-11-18 08:53:15 +01:00
Extract go module versions from ldflags for binaries built by go (#1832)
* wip Signed-off-by: Weston Steimel <weston.steimel@anchore.com> * with golang bin ldflags refactor Signed-off-by: Alex Goodman <alex.goodman@anchore.com> * add test for golang binary cataloger for ldflag extraction Signed-off-by: Alex Goodman <alex.goodman@anchore.com> * remove binary classfiers that overlap with new go ldflags detection Signed-off-by: Alex Goodman <alex.goodman@anchore.com> --------- Signed-off-by: Weston Steimel <weston.steimel@anchore.com> Signed-off-by: Alex Goodman <alex.goodman@anchore.com> Co-authored-by: Weston Steimel <weston.steimel@anchore.com>
This commit is contained in:
parent
a3c5550217
commit
26c201f7f7
@ -239,30 +239,6 @@ func Test_Cataloger_DefaultClassifiers_PositiveCases(t *testing.T) {
|
||||
Metadata: metadata("redis-binary"),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "positive-argocd-2.5.11",
|
||||
fixtureDir: "test-fixtures/classifiers/dynamic/argocd-2.5.11",
|
||||
expected: pkg.Package{
|
||||
Name: "argocd",
|
||||
Version: "2.5.11",
|
||||
Type: "binary",
|
||||
PURL: "pkg:golang/github.com/argoproj/argo-cd@2.5.11",
|
||||
Locations: locations("argocd"),
|
||||
Metadata: metadata("argocd"),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "positive-argocd-2.6.4",
|
||||
fixtureDir: "test-fixtures/classifiers/dynamic/argocd-2.6.4",
|
||||
expected: pkg.Package{
|
||||
Name: "argocd",
|
||||
Version: "2.6.4",
|
||||
Type: "binary",
|
||||
PURL: "pkg:golang/github.com/argoproj/argo-cd@2.6.4",
|
||||
Locations: locations("argocd"),
|
||||
Metadata: metadata("argocd"),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "positive-helm-3.11.1",
|
||||
fixtureDir: "test-fixtures/classifiers/dynamic/helm-3.11.1",
|
||||
@ -287,66 +263,6 @@ func Test_Cataloger_DefaultClassifiers_PositiveCases(t *testing.T) {
|
||||
Metadata: metadata("helm"),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "positive-kubectl-1.24.11",
|
||||
fixtureDir: "test-fixtures/classifiers/dynamic/kubectl-1.24.11",
|
||||
expected: pkg.Package{
|
||||
Name: "kubectl",
|
||||
Version: "1.24.11",
|
||||
Type: "binary",
|
||||
PURL: "pkg:golang/k8s.io/kubectl@1.24.11",
|
||||
Locations: locations("kubectl"),
|
||||
Metadata: metadata("kubectl"),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "positive-kubectl-1.25.7",
|
||||
fixtureDir: "test-fixtures/classifiers/dynamic/kubectl-1.25.7",
|
||||
expected: pkg.Package{
|
||||
Name: "kubectl",
|
||||
Version: "1.25.7",
|
||||
Type: "binary",
|
||||
PURL: "pkg:golang/k8s.io/kubectl@1.25.7",
|
||||
Locations: locations("kubectl"),
|
||||
Metadata: metadata("kubectl"),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "positive-kubectl-1.26.2",
|
||||
fixtureDir: "test-fixtures/classifiers/dynamic/kubectl-1.26.2",
|
||||
expected: pkg.Package{
|
||||
Name: "kubectl",
|
||||
Version: "1.26.2",
|
||||
Type: "binary",
|
||||
PURL: "pkg:golang/k8s.io/kubectl@1.26.2",
|
||||
Locations: locations("kubectl"),
|
||||
Metadata: metadata("kubectl"),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "positive-kustomize-4.5.7",
|
||||
fixtureDir: "test-fixtures/classifiers/dynamic/kustomize-4.5.7",
|
||||
expected: pkg.Package{
|
||||
Name: "kustomize",
|
||||
Version: "4.5.7",
|
||||
Type: "binary",
|
||||
PURL: "pkg:golang/sigs.k8s.io/kustomize@4.5.7",
|
||||
Locations: locations("kustomize"),
|
||||
Metadata: metadata("kustomize"),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "positive-kustomize-5.0.0",
|
||||
fixtureDir: "test-fixtures/classifiers/dynamic/kustomize-5.0.0",
|
||||
expected: pkg.Package{
|
||||
Name: "kustomize",
|
||||
Version: "5.0.0",
|
||||
Type: "binary",
|
||||
PURL: "pkg:golang/sigs.k8s.io/kustomize@5.0.0",
|
||||
Locations: locations("kustomize"),
|
||||
Metadata: metadata("kustomize"),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "positive-redis-4.0.11",
|
||||
fixtureDir: "test-fixtures/classifiers/positive/redis-server-4.0.11",
|
||||
|
||||
@ -46,15 +46,6 @@ var defaultClassifiers = []classifier{
|
||||
PURL: mustPURL("pkg:generic/go@version"),
|
||||
CPEs: singleCPE("cpe:2.3:a:golang:go:*:*:*:*:*:*:*:*"),
|
||||
},
|
||||
{
|
||||
Class: "argocd",
|
||||
FileGlob: "**/argocd",
|
||||
EvidenceMatcher: fileContentsVersionMatcher(
|
||||
`(?m)common\.version=(?P<version>[0-9]+\.[0-9]+\.[0-9]+)`),
|
||||
Package: "argocd",
|
||||
PURL: mustPURL("pkg:golang/github.com/argoproj/argo-cd@version"),
|
||||
CPEs: singleCPE("cpe:2.3:a:argoproj:argocd:*:*:*:*:*:*:*"),
|
||||
},
|
||||
{
|
||||
Class: "helm",
|
||||
FileGlob: "**/helm",
|
||||
@ -64,24 +55,6 @@ var defaultClassifiers = []classifier{
|
||||
PURL: mustPURL("pkg:golang/helm.sh/helm@version"),
|
||||
CPEs: singleCPE("cpe:2.3:a:helm:helm:*:*:*:*:*:*:*"),
|
||||
},
|
||||
{
|
||||
Class: "kustomize",
|
||||
FileGlob: "**/kustomize",
|
||||
EvidenceMatcher: fileContentsVersionMatcher(
|
||||
`(?m)version=kustomize/v(?P<version>[0-9]+\.[0-9]+\.[0-9]+)`),
|
||||
Package: "kustomize",
|
||||
PURL: mustPURL("pkg:golang/sigs.k8s.io/kustomize@version"),
|
||||
CPEs: singleCPE("cpe:2.3:a:kustomize:kustomize:*:*:*:*:*:*:*"),
|
||||
},
|
||||
{
|
||||
Class: "kubectl",
|
||||
FileGlob: "**/kubectl",
|
||||
EvidenceMatcher: fileContentsVersionMatcher(
|
||||
`(?m)\x00v(?P<version>[0-9]+\.[0-9]+\.[0-9]+)\x00`),
|
||||
Package: "kubectl",
|
||||
PURL: mustPURL("pkg:golang/k8s.io/kubectl@version"),
|
||||
CPEs: singleCPE("cpe:2.3:a:kubectl:kubectl:*:*:*:*:*:*:*"),
|
||||
},
|
||||
{
|
||||
Class: "redis-binary",
|
||||
FileGlob: "**/redis-server",
|
||||
|
||||
@ -7,15 +7,8 @@ all: \
|
||||
classifiers/dynamic/ruby-library-3.2.1 \
|
||||
classifiers/dynamic/ruby-library-2.7.7 \
|
||||
classifiers/dynamic/ruby-library-2.6.10 \
|
||||
classifiers/dynamic/argocd-2.5.11 \
|
||||
classifiers/dynamic/argocd-2.6.4 \
|
||||
classifiers/dynamic/helm-3.11.1 \
|
||||
classifiers/dynamic/helm-3.10.3 \
|
||||
classifiers/dynamic/kubectl-1.24.11 \
|
||||
classifiers/dynamic/kubectl-1.25.7 \
|
||||
classifiers/dynamic/kubectl-1.26.2 \
|
||||
classifiers/dynamic/kustomize-4.5.7 \
|
||||
classifiers/dynamic/kustomize-5.0.0 \
|
||||
classifiers/dynamic/consul-1.15.2
|
||||
|
||||
|
||||
@ -89,18 +82,6 @@ classifiers/dynamic/ruby-library-2.6.10:
|
||||
/usr/local/lib/libruby.so.2.6 \
|
||||
$@/libruby.so.2.6
|
||||
|
||||
classifiers/dynamic/argocd-2.5.11:
|
||||
$(eval $@_image := "argoproj/argocd:v2.5.11@sha256:d1062935b3256ec69422843ebcb50debb54fd389436961586000c8ce6ee7f249")
|
||||
./get-image-file.sh $($@_image) \
|
||||
/usr/local/bin/argocd \
|
||||
$@/argocd
|
||||
|
||||
classifiers/dynamic/argocd-2.6.4:
|
||||
$(eval $@_image := "argoproj/argocd:v2.6.4@sha256:61fcbba187ff53c00696cb580edf70cada59c45cf399d8477631acf43cf522ee")
|
||||
./get-image-file.sh $($@_image) \
|
||||
/usr/local/bin/argocd \
|
||||
$@/argocd
|
||||
|
||||
classifiers/dynamic/helm-3.11.1:
|
||||
$(eval $@_image := "alpine/helm:3.11.1@sha256:8628e3695fb743a8b9de89626f1b7a221280c2152c0e288c2504e59b68233e8b")
|
||||
./get-image-file.sh $($@_image) \
|
||||
@ -113,36 +94,6 @@ classifiers/dynamic/helm-3.10.3:
|
||||
/usr/local/bin/helm \
|
||||
$@/helm
|
||||
|
||||
classifiers/dynamic/kubectl-1.24.11:
|
||||
$(eval $@_image := "bitnami/kubectl:1.24.11@sha256:79d60c5ac8a1dc84e2c39f56d8e8cc0053159b5ed88f283bdf8fbda1ee86c8bc")
|
||||
./get-image-file.sh $($@_image) \
|
||||
/opt/bitnami/kubectl/bin/kubectl \
|
||||
$@/kubectl
|
||||
|
||||
classifiers/dynamic/kubectl-1.25.7:
|
||||
$(eval $@_image := "bitnami/kubectl:1.25.7@sha256:d7b00dbfdc6d8890aefe40edfb6c1d4c90cbb6c978794bb51a21744edc34ba7a")
|
||||
./get-image-file.sh $($@_image) \
|
||||
/opt/bitnami/kubectl/bin/kubectl \
|
||||
$@/kubectl
|
||||
|
||||
classifiers/dynamic/kubectl-1.26.2:
|
||||
$(eval $@_image := "line/kubectl-kustomize:1.26.2-5.0.0@sha256:9ee3b4a9a21f0777fc1d8c64208290f818a2e68c5e9e892e931621bda089bf06")
|
||||
./get-image-file.sh $($@_image) \
|
||||
/usr/local/bin/kubectl \
|
||||
$@/kubectl
|
||||
|
||||
classifiers/dynamic/kustomize-4.5.7:
|
||||
$(eval $@_image := "argoproj/argocd:v2.6.4@sha256:61fcbba187ff53c00696cb580edf70cada59c45cf399d8477631acf43cf522ee")
|
||||
./get-image-file.sh $($@_image) \
|
||||
/usr/local/bin/kustomize \
|
||||
$@/kustomize
|
||||
|
||||
classifiers/dynamic/kustomize-5.0.0:
|
||||
$(eval $@_image := "line/kubectl-kustomize:1.26.2-5.0.0@sha256:9ee3b4a9a21f0777fc1d8c64208290f818a2e68c5e9e892e931621bda089bf06")
|
||||
./get-image-file.sh $($@_image) \
|
||||
/usr/local/bin/kustomize \
|
||||
$@/kustomize
|
||||
|
||||
classifiers/dynamic/consul-1.15.2:
|
||||
$(eval $@_image := "hashicorp/consul:1.15.2@sha256:c2169f3bb18dd947ae8eb5f6766896695c71fb439f050a3343e0007d895615b8")
|
||||
./get-image-file.sh $($@_image) \
|
||||
|
||||
@ -18,7 +18,7 @@ func (c *goBinaryCataloger) newGoBinaryPackage(resolver source.FileResolver, dep
|
||||
|
||||
licenses, err := c.licenses.getLicenses(resolver, dep.Path, dep.Version)
|
||||
if err != nil {
|
||||
log.Tracef("error getting licenses for package: %s %v", dep.Path, err)
|
||||
log.Tracef("error getting licenses for golang package: %s %v", dep.Path, err)
|
||||
}
|
||||
|
||||
p := pkg.Package{
|
||||
|
||||
@ -8,6 +8,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"regexp"
|
||||
"runtime/debug"
|
||||
"strings"
|
||||
"time"
|
||||
@ -34,6 +35,11 @@ var (
|
||||
// devel is used to recognize the current default version when a golang main distribution is built
|
||||
// https://github.com/golang/go/issues/29228 this issue has more details on the progress of being able to
|
||||
// inject the correct version into the main module of the build process
|
||||
|
||||
knownBuildFlagPatterns = []*regexp.Regexp{
|
||||
regexp.MustCompile(`(?m)\.([gG]it)?([bB]uild)?[vV]ersion=(\S+/)*(?P<version>v?\d+.\d+.\d+[-\w]*)`),
|
||||
regexp.MustCompile(`(?m)\.([tT]ag)=(\S+/)*(?P<version>v?\d+.\d+.\d+[-\w]*)`),
|
||||
}
|
||||
)
|
||||
|
||||
const devel = "(devel)"
|
||||
@ -71,9 +77,16 @@ func (c *goBinaryCataloger) makeGoMainPackage(resolver source.FileResolver, mod
|
||||
gbs,
|
||||
location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
|
||||
)
|
||||
if main.Version == devel {
|
||||
if version, ok := gbs["vcs.revision"]; ok {
|
||||
if timestamp, ok := gbs["vcs.time"]; ok {
|
||||
|
||||
if main.Version != devel {
|
||||
return main
|
||||
}
|
||||
|
||||
version, hasVersion := gbs["vcs.revision"]
|
||||
timestamp, hasTimestamp := gbs["vcs.time"]
|
||||
|
||||
if hasVersion {
|
||||
if hasTimestamp {
|
||||
//NOTE: err is ignored, because if parsing fails
|
||||
// we still use the empty Time{} struct to generate an empty date, like 00010101000000
|
||||
// for consistency with the pseudo-version format: https://go.dev/ref/mod#pseudo-versions
|
||||
@ -81,17 +94,65 @@ func (c *goBinaryCataloger) makeGoMainPackage(resolver source.FileResolver, mod
|
||||
if len(version) >= 12 {
|
||||
version = version[:12]
|
||||
}
|
||||
version = module.PseudoVersion("", "", ts, version)
|
||||
|
||||
var ldflags string
|
||||
if metadata, ok := main.Metadata.(pkg.GolangBinMetadata); ok {
|
||||
ldflags = metadata.BuildSettings["-ldflags"]
|
||||
}
|
||||
main.Version = version
|
||||
main.PURL = packageURL(main.Name, main.Version)
|
||||
main.SetID()
|
||||
|
||||
majorVersion, fullVersion := extractVersionFromLDFlags(ldflags)
|
||||
if fullVersion != "" {
|
||||
// we've found a specific version from the ldflags! use it as the version.
|
||||
// why not combine that with the pseudo version (e.g. v1.2.3-0.20210101000000-abcdef123456)?
|
||||
// short answer: we're assuming that if a specific semver was provided in the ldflags that
|
||||
// there is a matching vcs tag to match that could be referenced. This assumption could
|
||||
// be incorrect in terms of the go.mod contents, but is not incorrect in terms of the logical
|
||||
// version of the package.
|
||||
version = fullVersion
|
||||
} else {
|
||||
version = module.PseudoVersion(majorVersion, fullVersion, ts, version)
|
||||
}
|
||||
}
|
||||
|
||||
main.Version = version
|
||||
main.PURL = packageURL(main.Name, main.Version)
|
||||
|
||||
main.SetID()
|
||||
}
|
||||
|
||||
return main
|
||||
}
|
||||
|
||||
func extractVersionFromLDFlags(ldflags string) (majorVersion string, fullVersion string) {
|
||||
if ldflags == "" {
|
||||
return "", ""
|
||||
}
|
||||
|
||||
for _, pattern := range knownBuildFlagPatterns {
|
||||
groups := internal.MatchNamedCaptureGroups(pattern, ldflags)
|
||||
v, ok := groups["version"]
|
||||
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
fullVersion = v
|
||||
if !strings.HasPrefix(v, "v") {
|
||||
fullVersion = fmt.Sprintf("v%s", v)
|
||||
}
|
||||
components := strings.Split(v, ".")
|
||||
|
||||
if len(components) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
majorVersion = strings.TrimPrefix(components[0], "v")
|
||||
return majorVersion, fullVersion
|
||||
}
|
||||
|
||||
return "", ""
|
||||
}
|
||||
|
||||
// getArchs finds a binary architecture by two ways:
|
||||
// 1) reading build info from binaries compiled by go1.18+
|
||||
// 2) reading file headers from binaries compiled by < go1.18
|
||||
|
||||
@ -299,7 +299,101 @@ func TestBuildGoPkgInfo(t *testing.T) {
|
||||
expected: []pkg.Package{unmodifiedMain},
|
||||
},
|
||||
{
|
||||
name: "parse main mod and replace devel version",
|
||||
name: "parse main mod and replace devel pseudo version and ldflags exists (but contains no version)",
|
||||
arch: archDetails,
|
||||
mod: &debug.BuildInfo{
|
||||
GoVersion: goCompiledVersion,
|
||||
Main: debug.Module{Path: "github.com/anchore/syft", Version: "(devel)"},
|
||||
Settings: []debug.BuildSetting{
|
||||
{Key: "GOARCH", Value: archDetails},
|
||||
{Key: "GOOS", Value: "darwin"},
|
||||
{Key: "GOAMD64", Value: "v1"},
|
||||
{Key: "vcs.revision", Value: "41bc6bb410352845f22766e27dd48ba93aa825a4"},
|
||||
{Key: "vcs.time", Value: "2022-10-14T19:54:57Z"},
|
||||
{Key: "-ldflags", Value: `build -ldflags="-w -s -extldflags '-static' -X blah=foobar`},
|
||||
},
|
||||
},
|
||||
expected: []pkg.Package{
|
||||
{
|
||||
Name: "github.com/anchore/syft",
|
||||
Language: pkg.Go,
|
||||
Type: pkg.GoModulePkg,
|
||||
Version: "v0.0.0-20221014195457-41bc6bb41035",
|
||||
PURL: "pkg:golang/github.com/anchore/syft@v0.0.0-20221014195457-41bc6bb41035",
|
||||
Locations: source.NewLocationSet(
|
||||
source.NewLocationFromCoordinates(
|
||||
source.Coordinates{
|
||||
RealPath: "/a-path",
|
||||
FileSystemID: "layer-id",
|
||||
},
|
||||
).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
|
||||
),
|
||||
MetadataType: pkg.GolangBinMetadataType,
|
||||
Metadata: pkg.GolangBinMetadata{
|
||||
GoCompiledVersion: goCompiledVersion,
|
||||
Architecture: archDetails,
|
||||
BuildSettings: map[string]string{
|
||||
"GOARCH": archDetails,
|
||||
"GOOS": "darwin",
|
||||
"GOAMD64": "v1",
|
||||
"vcs.revision": "41bc6bb410352845f22766e27dd48ba93aa825a4",
|
||||
"vcs.time": "2022-10-14T19:54:57Z",
|
||||
"-ldflags": `build -ldflags="-w -s -extldflags '-static' -X blah=foobar`,
|
||||
},
|
||||
MainModule: "github.com/anchore/syft",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "parse main mod and replace devel version with one from ldflags",
|
||||
arch: archDetails,
|
||||
mod: &debug.BuildInfo{
|
||||
GoVersion: goCompiledVersion,
|
||||
Main: debug.Module{Path: "github.com/anchore/syft", Version: "(devel)"},
|
||||
Settings: []debug.BuildSetting{
|
||||
{Key: "GOARCH", Value: archDetails},
|
||||
{Key: "GOOS", Value: "darwin"},
|
||||
{Key: "GOAMD64", Value: "v1"},
|
||||
{Key: "vcs.revision", Value: "41bc6bb410352845f22766e27dd48ba93aa825a4"},
|
||||
{Key: "vcs.time", Value: "2022-10-14T19:54:57Z"},
|
||||
{Key: "-ldflags", Value: `build -ldflags="-w -s -extldflags '-static' -X github.com/anchore/syft/internal/version.version=0.79.0`},
|
||||
},
|
||||
},
|
||||
expected: []pkg.Package{
|
||||
{
|
||||
Name: "github.com/anchore/syft",
|
||||
Language: pkg.Go,
|
||||
Type: pkg.GoModulePkg,
|
||||
Version: "v0.79.0",
|
||||
PURL: "pkg:golang/github.com/anchore/syft@v0.79.0",
|
||||
Locations: source.NewLocationSet(
|
||||
source.NewLocationFromCoordinates(
|
||||
source.Coordinates{
|
||||
RealPath: "/a-path",
|
||||
FileSystemID: "layer-id",
|
||||
},
|
||||
).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
|
||||
),
|
||||
MetadataType: pkg.GolangBinMetadataType,
|
||||
Metadata: pkg.GolangBinMetadata{
|
||||
GoCompiledVersion: goCompiledVersion,
|
||||
Architecture: archDetails,
|
||||
BuildSettings: map[string]string{
|
||||
"GOARCH": archDetails,
|
||||
"GOOS": "darwin",
|
||||
"GOAMD64": "v1",
|
||||
"vcs.revision": "41bc6bb410352845f22766e27dd48ba93aa825a4",
|
||||
"vcs.time": "2022-10-14T19:54:57Z",
|
||||
"-ldflags": `build -ldflags="-w -s -extldflags '-static' -X github.com/anchore/syft/internal/version.version=0.79.0`,
|
||||
},
|
||||
MainModule: "github.com/anchore/syft",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "parse main mod and replace devel version with a pseudo version",
|
||||
arch: archDetails,
|
||||
mod: &debug.BuildInfo{
|
||||
GoVersion: goCompiledVersion,
|
||||
@ -512,3 +606,161 @@ func TestBuildGoPkgInfo(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_extractVersionFromLDFlags(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
ldflags string
|
||||
wantMajorVersion string
|
||||
wantFullVersion string
|
||||
}{
|
||||
{
|
||||
name: "empty ldflags",
|
||||
ldflags: "",
|
||||
},
|
||||
{
|
||||
name: "syft ldflags",
|
||||
ldflags: ` build -ldflags="-w -s -extldflags '-static' -X github.com/anchore/syft/internal/version.version=0.79.0 -X github.com/anchore/syft/internal/version.gitCommit=b2b332e8b2b66af0905e98b54ebd713a922be1a8 -X github.com/anchore/syft/internal/version.buildDate=2023-04-21T16:20:25Z -X github.com/anchore/syft/internal/version.gitDescription=v0.79.0 "`,
|
||||
wantMajorVersion: "0",
|
||||
wantFullVersion: "v0.79.0",
|
||||
},
|
||||
{
|
||||
name: "kubectl ldflags",
|
||||
ldflags: ` build -asmflags=all=-trimpath=/workspace/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes
|
||||
build -compiler=gc
|
||||
build -gcflags="all=-trimpath=/workspace/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes "
|
||||
build -ldflags="all=-X 'k8s.io/kubernetes/vendor/k8s.io/client-go/pkg/version.buildDate=2023-04-12T12:16:51Z' -X 'k8s.io/kubernetes/vendor/k8s.io/component-base/version.buildDate=2023-04-12T12:16:51Z' -X 'k8s.io/client-go/pkg/version.buildDate=2023-04-12T12:16:51Z' -X 'k8s.io/component-base/version.buildDate=2023-04-12T12:16:51Z' -X 'k8s.io/kubernetes/vendor/k8s.io/client-go/pkg/version.gitCommit=a1a87a0a2bcd605820920c6b0e618a8ab7d117d4' -X 'k8s.io/kubernetes/vendor/k8s.io/component-base/version.gitCommit=a1a87a0a2bcd605820920c6b0e618a8ab7d117d4' -X 'k8s.io/client-go/pkg/version.gitCommit=a1a87a0a2bcd605820920c6b0e618a8ab7d117d4' -X 'k8s.io/component-base/version.gitCommit=a1a87a0a2bcd605820920c6b0e618a8ab7d117d4' -X 'k8s.io/kubernetes/vendor/k8s.io/client-go/pkg/version.gitTreeState=clean' -X 'k8s.io/kubernetes/vendor/k8s.io/component-base/version.gitTreeState=clean' -X 'k8s.io/client-go/pkg/version.gitTreeState=clean' -X 'k8s.io/component-base/version.gitTreeState=clean' -X 'k8s.io/kubernetes/vendor/k8s.io/client-go/pkg/version.gitVersion=v1.25.9' -X 'k8s.io/kubernetes/vendor/k8s.io/component-base/version.gitVersion=v1.25.9' -X 'k8s.io/client-go/pkg/version.gitVersion=v1.25.9' -X 'k8s.io/component-base/version.gitVersion=v1.25.9' -X 'k8s.io/kubernetes/vendor/k8s.io/client-go/pkg/version.gitMajor=1' -X 'k8s.io/kubernetes/vendor/k8s.io/component-base/version.gitMajor=1' -X 'k8s.io/client-go/pkg/version.gitMajor=1' -X 'k8s.io/component-base/version.gitMajor=1' -X 'k8s.io/kubernetes/vendor/k8s.io/client-go/pkg/version.gitMinor=25' -X 'k8s.io/kubernetes/vendor/k8s.io/component-base/version.gitMinor=25' -X 'k8s.io/client-go/pkg/version.gitMinor=25' -X 'k8s.io/component-base/version.gitMinor=25' -s -w"`,
|
||||
wantMajorVersion: "1",
|
||||
wantFullVersion: "v1.25.9",
|
||||
},
|
||||
{
|
||||
name: "nerdctl ldflags",
|
||||
ldflags: ` build -ldflags="-s -w -X github.com/containerd/nerdctl/pkg/version.Version=v1.3.1 -X github.com/containerd/nerdctl/pkg/version.Revision=b224b280ff3086516763c7335fc0e0997aca617a"`,
|
||||
wantMajorVersion: "1",
|
||||
wantFullVersion: "v1.3.1",
|
||||
},
|
||||
{
|
||||
name: "limactl ldflags",
|
||||
ldflags: ` build -ldflags="-s -w -X github.com/lima-vm/lima/pkg/version.Version=v0.15.1"`,
|
||||
wantMajorVersion: "0",
|
||||
wantFullVersion: "v0.15.1",
|
||||
},
|
||||
{
|
||||
name: "terraform ldflags",
|
||||
ldflags: ` build -ldflags="-w -s -X 'github.com/hashicorp/terraform/version.Version=1.4.6' -X 'github.com/hashicorp/terraform/version.Prerelease='"`,
|
||||
wantMajorVersion: "1",
|
||||
wantFullVersion: "v1.4.6",
|
||||
},
|
||||
{
|
||||
name: "kube-apiserver ldflags",
|
||||
ldflags: ` build -asmflags=all=-trimpath=/workspace/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes
|
||||
build -buildmode=exe
|
||||
build -compiler=gc
|
||||
build -gcflags="all=-trimpath=/workspace/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes "
|
||||
build -ldflags="all=-X 'k8s.io/kubernetes/vendor/k8s.io/client-go/pkg/version.buildDate=2023-04-14T13:14:42Z' -X 'k8s.io/kubernetes/vendor/k8s.io/component-base/version.buildDate=2023-04-14T13:14:42Z' -X 'k8s.io/client-go/pkg/version.buildDate=2023-04-14T13:14:42Z' -X 'k8s.io/component-base/version.buildDate=2023-04-14T13:14:42Z' -X 'k8s.io/kubernetes/vendor/k8s.io/client-go/pkg/version.gitCommit=4c9411232e10168d7b050c49a1b59f6df9d7ea4b' -X 'k8s.io/kubernetes/vendor/k8s.io/component-base/version.gitCommit=4c9411232e10168d7b050c49a1b59f6df9d7ea4b' -X 'k8s.io/client-go/pkg/version.gitCommit=4c9411232e10168d7b050c49a1b59f6df9d7ea4b' -X 'k8s.io/component-base/version.gitCommit=4c9411232e10168d7b050c49a1b59f6df9d7ea4b' -X 'k8s.io/kubernetes/vendor/k8s.io/client-go/pkg/version.gitTreeState=clean' -X 'k8s.io/kubernetes/vendor/k8s.io/component-base/version.gitTreeState=clean' -X 'k8s.io/client-go/pkg/version.gitTreeState=clean' -X 'k8s.io/component-base/version.gitTreeState=clean' -X 'k8s.io/kubernetes/vendor/k8s.io/client-go/pkg/version.gitVersion=v1.27.1' -X 'k8s.io/kubernetes/vendor/k8s.io/component-base/version.gitVersion=v1.27.1' -X 'k8s.io/client-go/pkg/version.gitVersion=v1.27.1' -X 'k8s.io/component-base/version.gitVersion=v1.27.1' -X 'k8s.io/kubernetes/vendor/k8s.io/client-go/pkg/version.gitMajor=1' -X 'k8s.io/kubernetes/vendor/k8s.io/component-base/version.gitMajor=1' -X 'k8s.io/client-go/pkg/version.gitMajor=1' -X 'k8s.io/component-base/version.gitMajor=1' -X 'k8s.io/kubernetes/vendor/k8s.io/client-go/pkg/version.gitMinor=27' -X 'k8s.io/kubernetes/vendor/k8s.io/component-base/version.gitMinor=27' -X 'k8s.io/client-go/pkg/version.gitMinor=27' -X 'k8s.io/component-base/version.gitMinor=27' -s -w"`,
|
||||
wantMajorVersion: "1",
|
||||
wantFullVersion: "v1.27.1",
|
||||
},
|
||||
{
|
||||
name: "prometheus ldflags",
|
||||
ldflags: ` build -ldflags="-X github.com/prometheus/common/version.Version=2.44.0 -X github.com/prometheus/common/version.Revision=1ac5131f698ebc60f13fe2727f89b115a41f6558 -X github.com/prometheus/common/version.Branch=HEAD -X github.com/prometheus/common/version.BuildUser=root@739e8181c5db -X github.com/prometheus/common/version.BuildDate=20230514-06:18:11 -extldflags '-static'"
|
||||
build -tags=netgo,builtinassets,stringlabels`,
|
||||
wantMajorVersion: "2",
|
||||
wantFullVersion: "v2.44.0",
|
||||
},
|
||||
{
|
||||
name: "influxdb ldflags",
|
||||
ldflags: ` build -ldflags="-s -w -X main.version=v2.7.1 -X main.commit=407fa622e9 -X main.date=2023-04-28T13:24:27Z -linkmode=external -extld=/musl/x86_64/bin/musl-gcc -extldflags '-fno-PIC -static-pie -Wl,-z,stack-size=8388608'"
|
||||
build -tags=assets,sqlite_foreign_keys,sqlite_json,static_build,noasm`,
|
||||
wantMajorVersion: "2",
|
||||
wantFullVersion: "v2.7.1",
|
||||
},
|
||||
{
|
||||
name: "gitea ldflags",
|
||||
ldflags: ` build -ldflags=" -X \"main.MakeVersion=GNU Make 4.1\" -X \"main.Version=1.19.3\" -X \"main.Tags=bindata sqlite sqlite_unlock_notify\" "`,
|
||||
wantMajorVersion: "1",
|
||||
wantFullVersion: "v1.19.3",
|
||||
},
|
||||
{
|
||||
name: "docker sbom cli ldflags",
|
||||
ldflags: ` build -ldflags="-w -s -extldflags '-static' -X github.com/docker/sbom-cli-plugin/internal/version.version=0.6.1-SNAPSHOT-02cf1c8 -X github.com/docker/sbom-cli-plugin/internal/version.gitCommit=02cf1c888ad6662109ac6e3be618392514a56316 -X github.com/docker/sbom-cli-plugin/internal/version.gitDescription=v0.6.1-dirty "`,
|
||||
wantMajorVersion: "0",
|
||||
wantFullVersion: "v0.6.1-SNAPSHOT-02cf1c8",
|
||||
},
|
||||
{
|
||||
name: "docker scout ldflags",
|
||||
ldflags: ` build -ldflags="-w -s -extldflags '-static' -X github.com/docker/scout-cli-plugin/internal.version=0.10.0 "`,
|
||||
wantMajorVersion: "0",
|
||||
wantFullVersion: "v0.10.0",
|
||||
},
|
||||
{
|
||||
name: "influx telegraf ldflags",
|
||||
ldflags: ` build -ldflags="-w -s -X github.com/influxdata/telegraf/internal.Commit=a3a884a1 -X github.com/influxdata/telegraf/internal.Branch=HEAD -X github.com/influxdata/telegraf/internal.Version=1.26.2"`,
|
||||
wantMajorVersion: "1",
|
||||
wantFullVersion: "v1.26.2",
|
||||
},
|
||||
{
|
||||
name: "argocd ldflags",
|
||||
ldflags: ` build -ldflags="-X github.com/argoproj/argo-cd/v2/common.version=2.7.2 -X github.com/argoproj/argo-cd/v2/common.buildDate=2023-05-12T14:06:49Z -X github.com/argoproj/argo-cd/v2/common.gitCommit=cbee7e6011407ed2d1066c482db74e97e0cc6bdb -X github.com/argoproj/argo-cd/v2/common.gitTreeState=clean -X github.com/argoproj/argo-cd/v2/common.kubectlVersion=v0.24.2 -extldflags=\"-static\""`,
|
||||
wantMajorVersion: "2",
|
||||
wantFullVersion: "v2.7.2",
|
||||
},
|
||||
{
|
||||
name: "kustomize ldflags",
|
||||
ldflags: ` build -ldflags="-s -X sigs.k8s.io/kustomize/api/provenance.version=kustomize/v4.5.7 -X sigs.k8s.io/kustomize/api/provenance.gitCommit=56d82a8378dfc8dc3b3b1085e5a6e67b82966bd7 -X sigs.k8s.io/kustomize/api/provenance.buildDate=2022-08-02T16:35:54Z "`,
|
||||
wantMajorVersion: "4",
|
||||
wantFullVersion: "v4.5.7",
|
||||
},
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// negative cases
|
||||
{
|
||||
name: "hugo ldflags",
|
||||
ldflags: ` build -ldflags="-s -w -X github.com/gohugoio/hugo/common/hugo.vendorInfo=gohugoio"`,
|
||||
},
|
||||
{
|
||||
name: "ghostunnel ldflags",
|
||||
ldflags: ` build -ldflags="-X main.version=77d9aaa"`,
|
||||
},
|
||||
{
|
||||
name: "opa ldflags",
|
||||
ldflags: `build -ldflags=" -X github.com/open-policy-agent/opa/version.Hostname=9549178459bc"`,
|
||||
},
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// trickier cases
|
||||
{
|
||||
name: "macvlan plugin for cri-o ldflags",
|
||||
ldflags: ` build -ldflags="-extldflags -static -X github.com/containernetworking/plugins/pkg/utils/buildversion.BuildVersion=v1.2.0"`,
|
||||
wantMajorVersion: "1",
|
||||
wantFullVersion: "v1.2.0",
|
||||
},
|
||||
{
|
||||
name: "coder ldflags",
|
||||
ldflags: ` build -ldflags="-s -w -X 'github.com/coder/coder/buildinfo.tag=0.23.4'"`,
|
||||
wantMajorVersion: "0",
|
||||
wantFullVersion: "v0.23.4",
|
||||
},
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// don't know how to handle these... yet
|
||||
//{
|
||||
// // package name: pkgName: "github.com/krakendio/krakend-ce/v2",
|
||||
// name: "krakenD ldflags",
|
||||
// ldflags: ` build -ldflags="-X github.com/luraproject/lura/v2/core.KrakendVersion=2.3.2 -X github.com/luraproject/lura/v2/core.GoVersion=1.20.4 -X github.com/luraproject/lura/v2/core.GlibcVersion=GLIBC-2.31_(debian-11) "`,
|
||||
// wantMajorVersion: "2.3.2",
|
||||
// wantFullVersion: "v2.3.2",
|
||||
//},
|
||||
//{
|
||||
// // package name: pkgName: "github.com/krakendio/krakend-ce/v2",
|
||||
// name: "krakenD ldflags -- answer embedded in the middle",
|
||||
// ldflags: ` build -ldflags=" -X github.com/luraproject/lura/v2/core.GoVersion=1.20.4 -X github.com/luraproject/lura/v2/core.KrakendVersion=2.3.2 -X github.com/luraproject/lura/v2/core.GlibcVersion=GLIBC-2.31_(debian-11) "`,
|
||||
// wantMajorVersion: "2.3.2",
|
||||
// wantFullVersion: "v2.3.2",
|
||||
//},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
gotMajorVersion, gotFullVersion := extractVersionFromLDFlags(tt.ldflags)
|
||||
assert.Equal(t, tt.wantMajorVersion, gotMajorVersion, "unexpected major version")
|
||||
assert.Equal(t, tt.wantFullVersion, gotFullVersion, "unexpected full version")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user