Skip to content

Commit

Permalink
cmd: better version information
Browse files Browse the repository at this point in the history
Don't ever bother exec'ing git (was very often wrong) and just read out
the metadata the go toolchain is nice enough to record for us.

Signed-off-by: Hank Donnay <hdonnay@redhat.com>
  • Loading branch information
hdonnay committed Feb 8, 2023
1 parent 670376a commit d3e8877
Showing 1 changed file with 66 additions and 34 deletions.
100 changes: 66 additions & 34 deletions cmd/build.go
Expand Up @@ -2,11 +2,12 @@
package cmd // import "github.com/quay/clair/v4/cmd"

import (
"bytes"
"context"
"os/exec"
"runtime"
"runtime/debug"
"time"
"strings"

"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
)

// Injected via git-export(1). See that man page and gitattributes(5).
Expand All @@ -17,50 +18,81 @@ const (
revision = `$Format:%h (%cI)$`
)

var versionInfo = promauto.NewGaugeVec(
prometheus.GaugeOpts{
Namespace: "clair",
Subsystem: "cmd",
Name: "version_info",
Help: "Version information.",
},
[]string{
"claircore_version",
"goversion",
"modified",
"revision",
"version",
},
)

func init() {
meta := prometheus.Labels{
"claircore_version": "",
"goversion": runtime.Version(),
"modified": "",
"revision": "",
"version": "",
}
info, infoOK := debug.ReadBuildInfo()
var vcs []string
var core string
if infoOK {
// If not OK, built without modules? Weird.
for _, s := range info.Settings {
switch s.Key {
case `vcs.revision`:
meta["revision"] = s.Value
vcs = append(vcs, `rev`, s.Value)
case `vcs.modified`:
meta["modified"] = s.Value
if s.Value == `true` {
vcs = append(vcs, `(dirty)`)
}
}
}
// If we can read out the current binary's debug info, find the
// claircore version.
for _, m := range info.Deps {
if m.Path != "github.com/quay/claircore" {
continue
}
core = m.Version
if m.Replace != nil && m.Replace.Version != m.Version {
core = m.Replace.Version
}
}
meta["claircore_version"] = core
}

switch {
case Version != "":
// Had our version injected at build: do nothing.
case len(describe) > 0 && describe[0] != '$':
Version = describe
case revision[0] == '$':
// This is a helper for development. In production, we shouldn't assume
// that the process is running in a git repository or that git is
// installed. This is quite possibly wrong if run from the wrong working
// directory.
Version = `(random source build)`
ctx, done := context.WithTimeout(context.Background(), 5*time.Second)
defer done()
if _, err := exec.LookPath("git"); err != nil {
// Couldn't find a git binary: do nothing.
break
}
if err := exec.CommandContext(ctx, "git", "rev-parse", "--show-toplevel").Run(); err != nil {
// Couldn't find a git repository: do nothing.
if len(vcs) == 0 {
// A `go run` invocation, perhaps.
break
}
out, err := exec.CommandContext(ctx, "git", "describe").Output()
if err != nil {
// Couldn't describe the current commit: do nothing.
break
}
Version = string(bytes.TrimSpace(out))
Version = strings.Join(vcs, " ")
default:
Version = revision
}

// If we can read out the current binary's debug info, append the claircore
// version if there was a replacement.
if info, ok := debug.ReadBuildInfo(); ok {
for _, m := range info.Deps {
if m.Path != "github.com/quay/claircore" {
continue
}
if m.Replace != nil && m.Replace.Version != m.Version {
Version += " (claircore " + m.Replace.Version + ")"
}
}
meta["version"] = Version
if core != "" {
Version += " (claircore " + core + ")"
}
versionInfo.With(meta).Set(1)
}

// Version is a version string, injected at release time for release builds.
Expand Down

0 comments on commit d3e8877

Please sign in to comment.