瀏覽代碼

Merge pull request #45670 from thaJeztah/c8d_useragent_more_details

containerd: add c8d version and storage-driver to User-Agent
Sebastiaan van Stijn 2 年之前
父節點
當前提交
79c7d26495
共有 3 個文件被更改,包括 61 次插入22 次删除
  1. 3 1
      daemon/containerd/resolver.go
  2. 20 21
      dockerversion/useragent.go
  3. 38 0
      dockerversion/useragent_test.go

+ 3 - 1
daemon/containerd/resolver.go

@@ -8,8 +8,10 @@ import (
 
 
 	"github.com/containerd/containerd/remotes"
 	"github.com/containerd/containerd/remotes"
 	"github.com/containerd/containerd/remotes/docker"
 	"github.com/containerd/containerd/remotes/docker"
+	"github.com/containerd/containerd/version"
 	registrytypes "github.com/docker/docker/api/types/registry"
 	registrytypes "github.com/docker/docker/api/types/registry"
 	"github.com/docker/docker/dockerversion"
 	"github.com/docker/docker/dockerversion"
+	"github.com/docker/docker/pkg/useragent"
 	"github.com/docker/docker/registry"
 	"github.com/docker/docker/registry"
 	"github.com/sirupsen/logrus"
 	"github.com/sirupsen/logrus"
 )
 )
@@ -19,7 +21,7 @@ func (i *ImageService) newResolverFromAuthConfig(ctx context.Context, authConfig
 
 
 	hosts := hostsWrapper(i.registryHosts, authConfig, i.registryService)
 	hosts := hostsWrapper(i.registryHosts, authConfig, i.registryService)
 	headers := http.Header{}
 	headers := http.Header{}
-	headers.Set("User-Agent", dockerversion.DockerUserAgent(ctx))
+	headers.Set("User-Agent", dockerversion.DockerUserAgent(ctx, useragent.VersionInfo{Name: "containerd-client", Version: version.Version}, useragent.VersionInfo{Name: "storage-driver", Version: i.snapshotter}))
 
 
 	return docker.NewResolver(docker.ResolverOptions{
 	return docker.NewResolver(docker.ResolverOptions{
 		Hosts:   hosts,
 		Hosts:   hosts,

+ 20 - 21
dockerversion/useragent.go

@@ -17,12 +17,12 @@ type UAStringKey struct{}
 // In accordance with RFC 7231 (5.5.3) is of the form:
 // In accordance with RFC 7231 (5.5.3) is of the form:
 //
 //
 //	[docker client's UA] UpstreamClient([upstream client's UA])
 //	[docker client's UA] UpstreamClient([upstream client's UA])
-func DockerUserAgent(ctx context.Context) string {
-	daemonUA := getDaemonUserAgent()
-	if upstreamUA := getUserAgentFromContext(ctx); len(upstreamUA) > 0 {
-		return insertUpstreamUserAgent(upstreamUA, daemonUA)
+func DockerUserAgent(ctx context.Context, extraVersions ...useragent.VersionInfo) string {
+	ua := useragent.AppendVersions(getDaemonUserAgent(), extraVersions...)
+	if upstreamUA := getUpstreamUserAgent(ctx); upstreamUA != "" {
+		ua += " " + upstreamUA
 	}
 	}
-	return daemonUA
+	return ua
 }
 }
 
 
 var (
 var (
@@ -57,20 +57,29 @@ func getDaemonUserAgent() string {
 	return daemonUA
 	return daemonUA
 }
 }
 
 
-// getUserAgentFromContext returns the previously saved user-agent context stored in ctx, if one exists
-func getUserAgentFromContext(ctx context.Context) string {
+// 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 {
 	var upstreamUA string
 	var upstreamUA string
 	if ctx != nil {
 	if ctx != nil {
-		var ki interface{} = ctx.Value(UAStringKey{})
-		if ki != nil {
+		if ki := ctx.Value(UAStringKey{}); ki != nil {
 			upstreamUA = ctx.Value(UAStringKey{}).(string)
 			upstreamUA = ctx.Value(UAStringKey{}).(string)
 		}
 		}
 	}
 	}
-	return upstreamUA
+	if upstreamUA == "" {
+		return ""
+	}
+	return fmt.Sprintf("UpstreamClient(%s)", escapeStr(upstreamUA))
 }
 }
 
 
+const charsToEscape = `();\`
+
 // escapeStr returns s with every rune in charsToEscape escaped by a backslash
 // escapeStr returns s with every rune in charsToEscape escaped by a backslash
-func escapeStr(s string, charsToEscape string) string {
+func escapeStr(s string) string {
 	var ret string
 	var ret string
 	for _, currRune := range s {
 	for _, currRune := range s {
 		appended := false
 		appended := false
@@ -87,13 +96,3 @@ func escapeStr(s string, charsToEscape string) string {
 	}
 	}
 	return ret
 	return ret
 }
 }
-
-// insertUpstreamUserAgent adds the upstream client useragent to create a user-agent
-// string of the form:
-//
-//	$dockerUA UpstreamClient($upstreamUA)
-func insertUpstreamUserAgent(upstreamUA string, dockerUA string) string {
-	charsToEscape := `();\`
-	upstreamUAEscaped := escapeStr(upstreamUA, charsToEscape)
-	return fmt.Sprintf("%s UpstreamClient(%s)", dockerUA, upstreamUAEscaped)
-}

+ 38 - 0
dockerversion/useragent_test.go

@@ -0,0 +1,38 @@
+package dockerversion
+
+import (
+	"context"
+	"testing"
+
+	"github.com/docker/docker/pkg/useragent"
+	"gotest.tools/v3/assert"
+	is "gotest.tools/v3/assert/cmp"
+)
+
+func TestDockerUserAgent(t *testing.T) {
+	t.Run("daemon user-agent", func(t *testing.T) {
+		ua := DockerUserAgent(context.TODO())
+		expected := getDaemonUserAgent()
+		assert.Check(t, is.Equal(ua, expected))
+	})
+
+	t.Run("daemon user-agent custom metadata", func(t *testing.T) {
+		ua := DockerUserAgent(context.TODO(), useragent.VersionInfo{Name: "hello", Version: "world"}, useragent.VersionInfo{Name: "foo", Version: "bar"})
+		expected := getDaemonUserAgent() + ` hello/world foo/bar`
+		assert.Check(t, is.Equal(ua, expected))
+	})
+
+	t.Run("daemon user-agent with upstream", func(t *testing.T) {
+		ctx := context.WithValue(context.TODO(), UAStringKey{}, "Magic-Client/1.2.3 (linux)")
+		ua := DockerUserAgent(ctx)
+		expected := getDaemonUserAgent() + ` UpstreamClient(Magic-Client/1.2.3 \(linux\))`
+		assert.Check(t, is.Equal(ua, expected))
+	})
+
+	t.Run("daemon user-agent with upstream and custom metadata", func(t *testing.T) {
+		ctx := context.WithValue(context.TODO(), UAStringKey{}, "Magic-Client/1.2.3 (linux)")
+		ua := DockerUserAgent(ctx, useragent.VersionInfo{Name: "hello", Version: "world"}, useragent.VersionInfo{Name: "foo", Version: "bar"})
+		expected := getDaemonUserAgent() + ` hello/world foo/bar UpstreamClient(Magic-Client/1.2.3 \(linux\))`
+		assert.Check(t, is.Equal(ua, expected))
+	})
+}