167 lines
3.2 KiB
Go
167 lines
3.2 KiB
Go
package version
|
|
|
|
import (
|
|
"fmt"
|
|
"log/slog"
|
|
"runtime"
|
|
"runtime/debug"
|
|
"strings"
|
|
|
|
"github.com/prometheus/client_golang/prometheus"
|
|
"github.com/spf13/cobra"
|
|
"golang.org/x/mod/semver"
|
|
)
|
|
|
|
// VERSION has the current software version (set in the build process)
|
|
var VERSION string
|
|
var buildTime string
|
|
var gitVersion string
|
|
var gitModified bool
|
|
|
|
var info Info
|
|
|
|
type Info struct {
|
|
Version string `json:",omitempty"`
|
|
GitRev string `json:",omitempty"`
|
|
GitRevShort string `json:",omitempty"`
|
|
BuildTime string `json:",omitempty"`
|
|
}
|
|
|
|
func init() {
|
|
|
|
info.BuildTime = buildTime
|
|
info.GitRev = gitVersion
|
|
|
|
if len(VERSION) == 0 {
|
|
VERSION = "dev-snapshot"
|
|
} else {
|
|
if !strings.HasPrefix(VERSION, "v") {
|
|
VERSION = "v" + VERSION
|
|
}
|
|
if !semver.IsValid(VERSION) {
|
|
slog.Default().Warn("invalid version number", "version", VERSION)
|
|
}
|
|
}
|
|
if bi, ok := debug.ReadBuildInfo(); ok {
|
|
for _, h := range bi.Settings {
|
|
// logger.Setup().Info("build info", "k", h.Key, "v", h.Value)
|
|
switch h.Key {
|
|
case "vcs.time":
|
|
if len(buildTime) == 0 {
|
|
buildTime = h.Value
|
|
}
|
|
info.BuildTime = h.Value
|
|
case "vcs.revision":
|
|
// https://blog.carlmjohnson.net/post/2023/golang-git-hash-how-to/
|
|
// todo: use BuildInfo.Main.Version if revision is empty
|
|
info.GitRev = h.Value
|
|
// if gitVersion != h.Value {
|
|
// logger.Setup().Warn("gitVersion and info.GitRev differs", "gitVersion", gitVersion, "gitRev", info.GitRev)
|
|
// }
|
|
gitVersion = h.Value
|
|
case "vcs.modified":
|
|
if h.Value == "true" {
|
|
gitModified = true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
info.GitRevShort = info.GitRev
|
|
|
|
if len(info.GitRevShort) > 7 {
|
|
info.GitRevShort = info.GitRevShort[:7]
|
|
}
|
|
|
|
info.Version = VERSION
|
|
|
|
Version()
|
|
}
|
|
|
|
func VersionCmd(name string) *cobra.Command {
|
|
versionCmd := &cobra.Command{
|
|
Use: "version",
|
|
Short: "Print version and build information",
|
|
Run: func(cmd *cobra.Command, args []string) {
|
|
ver := Version()
|
|
fmt.Printf("%s %s\n", name, ver)
|
|
},
|
|
}
|
|
return versionCmd
|
|
}
|
|
|
|
func RegisterMetric(name string, registry prometheus.Registerer) {
|
|
if len(name) > 0 {
|
|
name = strings.ReplaceAll(name, "-", "_")
|
|
name = name + "_build_info"
|
|
} else {
|
|
name = "build_info"
|
|
}
|
|
buildInfo := prometheus.NewGaugeVec(
|
|
prometheus.GaugeOpts{
|
|
Name: name,
|
|
Help: "Build information",
|
|
},
|
|
[]string{
|
|
"version",
|
|
"buildtime",
|
|
"gittime",
|
|
"git",
|
|
},
|
|
)
|
|
registry.MustRegister(buildInfo)
|
|
info := VersionInfo()
|
|
buildInfo.WithLabelValues(
|
|
fmt.Sprintf("%s/%s",
|
|
info.Version, info.GitRevShort,
|
|
),
|
|
buildTime,
|
|
info.BuildTime,
|
|
info.GitRev,
|
|
).Set(1)
|
|
}
|
|
|
|
var v string
|
|
|
|
func VersionInfo() Info {
|
|
return info
|
|
}
|
|
|
|
func Version() string {
|
|
if len(v) > 0 {
|
|
return v
|
|
}
|
|
extra := []string{}
|
|
if len(buildTime) > 0 {
|
|
extra = append(extra, buildTime)
|
|
}
|
|
extra = append(extra, runtime.Version())
|
|
|
|
v := VERSION
|
|
if len(gitVersion) > 0 {
|
|
g := gitVersion
|
|
if len(g) > 7 {
|
|
g = g[0:7]
|
|
}
|
|
v += "/" + g
|
|
if gitModified {
|
|
v += "-M"
|
|
}
|
|
|
|
}
|
|
|
|
v = fmt.Sprintf("%s (%s)", v, strings.Join(extra, ", "))
|
|
return v
|
|
}
|
|
|
|
func CheckVersion(version, minimumVersion string) bool {
|
|
if version == "dev-snapshot" {
|
|
return true
|
|
}
|
|
if semver.Compare(version, minimumVersion) < 0 {
|
|
// log.Debug("version too old", "v", cl.Version.Version)
|
|
return false
|
|
}
|
|
return true
|
|
}
|