summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--caddy.go115
-rw-r--r--cmd/commandfuncs.go21
-rw-r--r--cmd/main.go26
-rw-r--r--modules/caddyhttp/reverseproxy/fastcgi/fastcgi.go6
-rw-r--r--modules/caddyhttp/tracing/tracer.go4
5 files changed, 103 insertions, 69 deletions
diff --git a/caddy.go b/caddy.go
index 54c890b..6964f77 100644
--- a/caddy.go
+++ b/caddy.go
@@ -127,7 +127,9 @@ func Load(cfgJSON []byte, forceReload bool) error {
// forcefully reloaded, then errConfigUnchanged This function is safe for
// concurrent use.
// 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
// 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.
@@ -791,38 +793,102 @@ func InstanceID() (uuid.UUID, error) {
return uuid.ParseBytes(uuidFileBytes)
}
-// GoModule returns the build info of this Caddy
-// build from debug.BuildInfo (requires Go modules).
-// If no version information is available, a non-nil
-// value will still be returned, but with an
-// unknown version.
-func GoModule() *debug.Module {
- var mod debug.Module
- return goModule(&mod)
-}
-
-// goModule holds the actual implementation of GoModule.
-// Allocating debug.Module in GoModule() and passing a
-// reference to goModule enables mid-stack inlining.
-func goModule(mod *debug.Module) *debug.Module {
- mod.Version = "unknown"
+// Version returns the Caddy version in a simple/short form, and
+// a full version string. The short form will not have spaces and
+// is intended for User-Agent strings and similar, but may be
+// omitting valuable information. Note that Caddy must be compiled
+// in a special way to properly embed complete version information.
+// First this function tries to get the version from the embedded
+// build info provided by go.mod dependencies; then it tries to
+// 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
+// the simple form we change it to "unknown".
+//
+// See relevant Go issues: https://github.com/golang/go/issues/29228
+// and https://github.com/golang/go/issues/50603.
+//
+// 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()
if ok {
- mod.Path = bi.Main.Path
- // 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.
+ // find the Caddy module in the dependency list
for _, dep := range bi.Deps {
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 {
currentCtxMu.RLock()
defer currentCtxMu.RUnlock()
@@ -867,4 +933,5 @@ var (
var errSameConfig = errors.New("config is unchanged")
// ImportPath is the package import path for Caddy core.
+// This identifier may be removed in the future.
const ImportPath = "github.com/caddyserver/caddy/v2"
diff --git a/cmd/commandfuncs.go b/cmd/commandfuncs.go
index a4b7bdf..67015f7 100644
--- a/cmd/commandfuncs.go
+++ b/cmd/commandfuncs.go
@@ -331,30 +331,17 @@ func cmdReload(fl Flags) (int, error) {
}
func cmdVersion(_ Flags) (int, error) {
- fmt.Println(CaddyVersion())
+ _, full := caddy.Version()
+ fmt.Println(full)
return caddy.ExitCodeSuccess, nil
}
-func cmdBuildInfo(fl Flags) (int, error) {
+func cmdBuildInfo(_ Flags) (int, error) {
bi, ok := debug.ReadBuildInfo()
if !ok {
return caddy.ExitCodeFailedStartup, fmt.Errorf("no build information")
}
-
- 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()
- }
+ fmt.Println(bi)
return caddy.ExitCodeSuccess, nil
}
diff --git a/cmd/main.go b/cmd/main.go
index e5a4edf..e932b6b 100644
--- a/cmd/main.go
+++ b/cmd/main.go
@@ -38,8 +38,8 @@ import (
func init() {
// set a fitting User-Agent for ACME requests
- goModule := caddy.GoModule()
- cleanModVersion := strings.TrimPrefix(goModule.Version, "v")
+ version, _ := caddy.Version()
+ cleanModVersion := strings.TrimPrefix(version, "v")
certmagic.UserAgent = "Caddy/" + cleanModVersion
// by using Caddy, user indicates agreement to CA terms
@@ -441,11 +441,12 @@ func parseEnvFile(envInput io.Reader) (map[string]string, error) {
}
func printEnvironment() {
+ _, version := caddy.Version()
fmt.Printf("caddy.HomeDir=%s\n", caddy.HomeDir())
fmt.Printf("caddy.AppDataDir=%s\n", caddy.AppDataDir())
fmt.Printf("caddy.AppConfigDir=%s\n", caddy.AppConfigDir())
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.GOARCH=%s\n", runtime.GOARCH)
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.
type StringSlice []string
diff --git a/modules/caddyhttp/reverseproxy/fastcgi/fastcgi.go b/modules/caddyhttp/reverseproxy/fastcgi/fastcgi.go
index 2848133..313f4eb 100644
--- a/modules/caddyhttp/reverseproxy/fastcgi/fastcgi.go
+++ b/modules/caddyhttp/reverseproxy/fastcgi/fastcgi.go
@@ -94,10 +94,8 @@ func (t *Transport) Provision(ctx caddy.Context) error {
t.Root = "{http.vars.root}"
}
- t.serverSoftware = "Caddy"
- if mod := caddy.GoModule(); mod.Version != "" {
- t.serverSoftware += "/" + mod.Version
- }
+ version, _ := caddy.Version()
+ t.serverSoftware = "Caddy/" + version
// Set a relatively short default dial timeout.
// This is helpful to make load-balancer retries more speedy.
diff --git a/modules/caddyhttp/tracing/tracer.go b/modules/caddyhttp/tracing/tracer.go
index ce23944..ddb01e8 100644
--- a/modules/caddyhttp/tracing/tracer.go
+++ b/modules/caddyhttp/tracing/tracer.go
@@ -7,7 +7,6 @@ import (
"github.com/caddyserver/caddy/v2"
- caddycmd "github.com/caddyserver/caddy/v2/cmd"
"github.com/caddyserver/caddy/v2/modules/caddyhttp"
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc"
@@ -52,7 +51,8 @@ func newOpenTelemetryWrapper(
spanName: spanName,
}
- res, err := ot.newResource(webEngineName, caddycmd.CaddyVersion())
+ version, _ := caddy.Version()
+ res, err := ot.newResource(webEngineName, version)
if err != nil {
return ot, fmt.Errorf("creating resource error: %w", err)
}