cmd: Use newly-available version information (#4931)

This commit is contained in:
Matt Holt 2022-08-04 11:16:59 -06:00 committed by GitHub
parent 1960a0dc11
commit 17ae5acaba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 103 additions and 69 deletions

115
caddy.go
View File

@ -127,7 +127,9 @@ func Load(cfgJSON []byte, forceReload bool) error {
// forcefully reloaded, then errConfigUnchanged This function is safe for // forcefully reloaded, then errConfigUnchanged This function is safe for
// concurrent use. // concurrent use.
// The ifMatchHeader can optionally be given a string of the format: // The ifMatchHeader can optionally be given a string of the format:
// "<path> <hash>" //
// "<path> <hash>"
//
// where <path> is the absolute path in the config and <hash> is the expected hash of // where <path> is the absolute path in the config and <hash> is the expected hash of
// the config at that path. If the hash in the ifMatchHeader doesn't match // the config at that path. If the hash in the ifMatchHeader doesn't match
// the hash of the config, then an APIError with status 412 will be returned. // the hash of the config, then an APIError with status 412 will be returned.
@ -791,38 +793,102 @@ func InstanceID() (uuid.UUID, error) {
return uuid.ParseBytes(uuidFileBytes) return uuid.ParseBytes(uuidFileBytes)
} }
// GoModule returns the build info of this Caddy // Version returns the Caddy version in a simple/short form, and
// build from debug.BuildInfo (requires Go modules). // a full version string. The short form will not have spaces and
// If no version information is available, a non-nil // is intended for User-Agent strings and similar, but may be
// value will still be returned, but with an // omitting valuable information. Note that Caddy must be compiled
// unknown version. // in a special way to properly embed complete version information.
func GoModule() *debug.Module { // First this function tries to get the version from the embedded
var mod debug.Module // build info provided by go.mod dependencies; then it tries to
return goModule(&mod) // get info from embedded VCS information, which requires having
} // built Caddy from a git repository. If no version is available,
// this function returns "(devel)" becaise Go uses that, but for
// goModule holds the actual implementation of GoModule. // the simple form we change it to "unknown".
// Allocating debug.Module in GoModule() and passing a //
// reference to goModule enables mid-stack inlining. // See relevant Go issues: https://github.com/golang/go/issues/29228
func goModule(mod *debug.Module) *debug.Module { // and https://github.com/golang/go/issues/50603.
mod.Version = "unknown" //
// This function is experimental and subject to change or removal.
func Version() (simple, full string) {
// the currently-recommended way to build Caddy involves
// building it as a dependency so we can extract version
// information from go.mod tooling; once the upstream
// Go issues are fixed, we should just be able to use
// bi.Main... hopefully.
var module *debug.Module
bi, ok := debug.ReadBuildInfo() bi, ok := debug.ReadBuildInfo()
if ok { if ok {
mod.Path = bi.Main.Path // find the Caddy module in the dependency list
// The recommended way to build Caddy involves
// creating a separate main module, which
// TODO: track related Go issue: https://github.com/golang/go/issues/29228
// once that issue is fixed, we should just be able to use bi.Main... hopefully.
for _, dep := range bi.Deps { for _, dep := range bi.Deps {
if dep.Path == ImportPath { if dep.Path == ImportPath {
return dep module = dep
break
} }
} }
return &bi.Main
} }
return mod if module != nil {
simple, full = module.Version, module.Version
if module.Sum != "" {
full += " " + module.Sum
}
if module.Replace != nil {
full += " => " + module.Replace.Path
if module.Replace.Version != "" {
simple = module.Replace.Version + "_custom"
full += "@" + module.Replace.Version
}
if module.Replace.Sum != "" {
full += " " + module.Replace.Sum
}
}
}
if full == "" {
var vcsRevision string
var vcsTime time.Time
var vcsModified bool
for _, setting := range bi.Settings {
switch setting.Key {
case "vcs.revision":
vcsRevision = setting.Value
case "vcs.time":
vcsTime, _ = time.Parse(time.RFC3339, setting.Value)
case "vcs.modified":
vcsModified, _ = strconv.ParseBool(setting.Value)
}
}
if vcsRevision != "" {
var modified string
if vcsModified {
modified = "+modified"
}
full = fmt.Sprintf("%s%s (%s)", vcsRevision, modified, vcsTime.Format(time.RFC822))
simple = vcsRevision
// use short checksum for simple, if hex-only
if _, err := hex.DecodeString(simple); err == nil {
simple = simple[:8]
}
// append date to simple since it can be convenient
// to know the commit date as part of the version
if !vcsTime.IsZero() {
simple += "-" + vcsTime.Format("20060102")
}
}
}
if simple == "" || simple == "(devel)" {
simple = "unknown"
}
return
} }
// ActiveContext returns the currently-active context.
// This function is experimental and might be changed
// or removed in the future.
func ActiveContext() Context { func ActiveContext() Context {
currentCtxMu.RLock() currentCtxMu.RLock()
defer currentCtxMu.RUnlock() defer currentCtxMu.RUnlock()
@ -867,4 +933,5 @@ var (
var errSameConfig = errors.New("config is unchanged") var errSameConfig = errors.New("config is unchanged")
// ImportPath is the package import path for Caddy core. // ImportPath is the package import path for Caddy core.
// This identifier may be removed in the future.
const ImportPath = "github.com/caddyserver/caddy/v2" const ImportPath = "github.com/caddyserver/caddy/v2"

View File

@ -331,30 +331,17 @@ func cmdReload(fl Flags) (int, error) {
} }
func cmdVersion(_ Flags) (int, error) { func cmdVersion(_ Flags) (int, error) {
fmt.Println(CaddyVersion()) _, full := caddy.Version()
fmt.Println(full)
return caddy.ExitCodeSuccess, nil return caddy.ExitCodeSuccess, nil
} }
func cmdBuildInfo(fl Flags) (int, error) { func cmdBuildInfo(_ Flags) (int, error) {
bi, ok := debug.ReadBuildInfo() bi, ok := debug.ReadBuildInfo()
if !ok { if !ok {
return caddy.ExitCodeFailedStartup, fmt.Errorf("no build information") return caddy.ExitCodeFailedStartup, fmt.Errorf("no build information")
} }
fmt.Println(bi)
fmt.Printf("go_version: %s\n", runtime.Version())
fmt.Printf("go_os: %s\n", runtime.GOOS)
fmt.Printf("go_arch: %s\n", runtime.GOARCH)
fmt.Printf("path: %s\n", bi.Path)
fmt.Printf("main: %s %s %s\n", bi.Main.Path, bi.Main.Version, bi.Main.Sum)
fmt.Println("dependencies:")
for _, goMod := range bi.Deps {
fmt.Printf("%s %s %s", goMod.Path, goMod.Version, goMod.Sum)
if goMod.Replace != nil {
fmt.Printf(" => %s %s %s", goMod.Replace.Path, goMod.Replace.Version, goMod.Replace.Sum)
}
fmt.Println()
}
return caddy.ExitCodeSuccess, nil return caddy.ExitCodeSuccess, nil
} }

View File

@ -38,8 +38,8 @@ import (
func init() { func init() {
// set a fitting User-Agent for ACME requests // set a fitting User-Agent for ACME requests
goModule := caddy.GoModule() version, _ := caddy.Version()
cleanModVersion := strings.TrimPrefix(goModule.Version, "v") cleanModVersion := strings.TrimPrefix(version, "v")
certmagic.UserAgent = "Caddy/" + cleanModVersion certmagic.UserAgent = "Caddy/" + cleanModVersion
// by using Caddy, user indicates agreement to CA terms // by using Caddy, user indicates agreement to CA terms
@ -441,11 +441,12 @@ func parseEnvFile(envInput io.Reader) (map[string]string, error) {
} }
func printEnvironment() { func printEnvironment() {
_, version := caddy.Version()
fmt.Printf("caddy.HomeDir=%s\n", caddy.HomeDir()) fmt.Printf("caddy.HomeDir=%s\n", caddy.HomeDir())
fmt.Printf("caddy.AppDataDir=%s\n", caddy.AppDataDir()) fmt.Printf("caddy.AppDataDir=%s\n", caddy.AppDataDir())
fmt.Printf("caddy.AppConfigDir=%s\n", caddy.AppConfigDir()) fmt.Printf("caddy.AppConfigDir=%s\n", caddy.AppConfigDir())
fmt.Printf("caddy.ConfigAutosavePath=%s\n", caddy.ConfigAutosavePath) fmt.Printf("caddy.ConfigAutosavePath=%s\n", caddy.ConfigAutosavePath)
fmt.Printf("caddy.Version=%s\n", CaddyVersion()) fmt.Printf("caddy.Version=%s\n", version)
fmt.Printf("runtime.GOOS=%s\n", runtime.GOOS) fmt.Printf("runtime.GOOS=%s\n", runtime.GOOS)
fmt.Printf("runtime.GOARCH=%s\n", runtime.GOARCH) fmt.Printf("runtime.GOARCH=%s\n", runtime.GOARCH)
fmt.Printf("runtime.Compiler=%s\n", runtime.Compiler) fmt.Printf("runtime.Compiler=%s\n", runtime.Compiler)
@ -462,25 +463,6 @@ func printEnvironment() {
} }
} }
// CaddyVersion returns a detailed version string, if available.
func CaddyVersion() string {
goModule := caddy.GoModule()
ver := goModule.Version
if goModule.Sum != "" {
ver += " " + goModule.Sum
}
if goModule.Replace != nil {
ver += " => " + goModule.Replace.Path
if goModule.Replace.Version != "" {
ver += "@" + goModule.Replace.Version
}
if goModule.Replace.Sum != "" {
ver += " " + goModule.Replace.Sum
}
}
return ver
}
// StringSlice is a flag.Value that enables repeated use of a string flag. // StringSlice is a flag.Value that enables repeated use of a string flag.
type StringSlice []string type StringSlice []string

View File

@ -94,10 +94,8 @@ func (t *Transport) Provision(ctx caddy.Context) error {
t.Root = "{http.vars.root}" t.Root = "{http.vars.root}"
} }
t.serverSoftware = "Caddy" version, _ := caddy.Version()
if mod := caddy.GoModule(); mod.Version != "" { t.serverSoftware = "Caddy/" + version
t.serverSoftware += "/" + mod.Version
}
// Set a relatively short default dial timeout. // Set a relatively short default dial timeout.
// This is helpful to make load-balancer retries more speedy. // This is helpful to make load-balancer retries more speedy.

View File

@ -7,7 +7,6 @@ import (
"github.com/caddyserver/caddy/v2" "github.com/caddyserver/caddy/v2"
caddycmd "github.com/caddyserver/caddy/v2/cmd"
"github.com/caddyserver/caddy/v2/modules/caddyhttp" "github.com/caddyserver/caddy/v2/modules/caddyhttp"
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc" "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc"
@ -52,7 +51,8 @@ func newOpenTelemetryWrapper(
spanName: spanName, spanName: spanName,
} }
res, err := ot.newResource(webEngineName, caddycmd.CaddyVersion()) version, _ := caddy.Version()
res, err := ot.newResource(webEngineName, version)
if err != nil { if err != nil {
return ot, fmt.Errorf("creating resource error: %w", err) return ot, fmt.Errorf("creating resource error: %w", err)
} }