-
Notifications
You must be signed in to change notification settings - Fork 18.9k
Description
Description
related;
deconstruct the dockerversion package and move internal
The dockerversion package is for internal use by the daemon. It has a couple of responsibilities / functionalities;
Handling of user-agent
It defines the UAtringKey{} type, which is used to attach the "upstream" (API client's) user-agent (if any) to the context and to include in OTel;
moby/dockerversion/useragent.go
Lines 13 to 14 in 606519a
| // UAStringKey is used as key type for user-agent string in net/context struct | |
| type UAStringKey struct{} |
Lines 36 to 51 in 606519a
| func (s *Server) makeHTTPHandler(handler httputils.APIFunc, operation string) http.HandlerFunc { | |
| return otelhttp.NewHandler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | |
| // Define the context that we'll pass around to share info | |
| // like the docker-request-id. | |
| // | |
| // The 'context' will be used for global data that should | |
| // apply to all requests. Data that is specific to the | |
| // immediate function being called should still be passed | |
| // as 'args' on the function call. | |
| // use intermediate variable to prevent "should not use basic type | |
| // string as key in context.WithValue" golint errors | |
| ua := r.Header.Get("User-Agent") | |
| ctx := baggage.ContextWithBaggage(context.WithValue(r.Context(), dockerversion.UAStringKey{}, ua), otelutil.MustNewBaggage( | |
| otelutil.MustNewMemberRaw(otelutil.TriggerKey, "api"), | |
| )) |
It has a getUpstreamUserAgent utility to get that user-agent from the context;
moby/dockerversion/useragent.go
Lines 60 to 66 in 606519a
| // getUpstreamUserAgent returns the previously saved user-agent context stored | |
| // in ctx, if one exists, and formats it as: | |
| // | |
| // UpstreamClient(<upstream user agent string>) | |
| // | |
| // It returns an empty string if no user-agent is present in the context. | |
| func getUpstreamUserAgent(ctx context.Context) string { |
It has a DockerUserAgent utility, which is used to construct the User-Agent that's used by the daemon itself for network requests (to registries); this user-agent is contructed of;
- The "upstream" user-agent (if any); see above
- The daemon's useer-agent (which includes the daemon's binary version, go version, git-commit, the host's kernel version, os, and architecture)
moby/dockerversion/useragent.go
Lines 16 to 20 in 606519a
| // DockerUserAgent is the User-Agent the Docker client uses to identify itself. | |
| // In accordance with RFC 7231 (5.5.3) is of the form: | |
| // | |
| // [docker client's UA] UpstreamClient([upstream client's UA]) | |
| func DockerUserAgent(ctx context.Context, extraVersions ...useragent.VersionInfo) string { |
To construct the user-agent, it makes use of;
pkg/useragent, which is a "generic" package to handle user-agents (and to handle escaping to make it well-formed)pkg/parsers/kernel, which is a "somewhat" generic package to get the kernel version; it's a bit too broad for our own use (as it also handles macOS)
Version Metadata (set at compile time)
In addition to handling user-agents, it contains a number of variables that are set at compile-time;
moby/dockerversion/version_lib.go
Lines 3 to 12 in 606519a
| // Default build-time variable for library-import. | |
| // These variables are overridden on build with build-time information. | |
| var ( | |
| GitCommit = "library-import" | |
| Version = "library-import" | |
| BuildTime = "library-import" | |
| PlatformName = "" | |
| ProductName = "" | |
| DefaultProductLicense = "" | |
| ) |
Suggested changes
User-Agent utilities
These utilities are really for internal use by the daemon and API server;
- We should move them internal to the daemon, which can be either
daemon/internal. - TBD: constructing the user-agent of the daemon is rather involved; do we want a
WithUserAgent(e.g.) option when constructing the daemon? - TBD: the
daemonUserAgenthasdockerhard-coded; should this be taken from themetapackage (see below) and configurable at compile-time?
Version metadata
The compile-time variables are currently consumed directly in many places, but likely make most sense in the cmd/ or cmd/dockerd package, as they are directly related to the binary being compiled.
- We can move the vars to a
meta(e.g.) package undercmd/orcmd/dockerd - Perhaps it's cleanest to pass such metadata as argument when constructing the daemon, instead of depending directly on the meta package. The daemon can hold this information?
- ☝️ but there's some places in (e.g.) integration tests that use it, so to be looked at more closely.