mirror of
https://github.com/moby/moby.git
synced 2026-01-11 18:51:37 +00:00
client: define default (and maximum) API version
With the client and API migrating to separate modules, users of the Client module may upgrade the API module to higher versions. Currently, the Client uses the API's Default version. While the version of the API module is allowed to be updated (following SemVer), we should not allow the Client to support higher API versions than it was written for. This patch introduces a DefaultAPIVersion in the client package that is used as default version of the API for the client to use. Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
@@ -53,7 +53,6 @@ import (
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/api"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/versions"
|
||||
"github.com/docker/go-connections/sockets"
|
||||
@@ -91,6 +90,16 @@ import (
|
||||
// [Go stdlib]: https://github.com/golang/go/blob/6244b1946bc2101b01955468f1be502dbadd6807/src/net/http/transport.go#L558-L569
|
||||
const DummyHost = "api.moby.localhost"
|
||||
|
||||
// DefaultAPIVersion is the highest REST API version supported by the client.
|
||||
// If API-version negotiation is enabled (see [WithAPIVersionNegotiation],
|
||||
// [Client.NegotiateAPIVersion]), the client may downgrade its API version.
|
||||
// Similarly, the [WithVersion] and [WithVersionFromEnv] allow overriding
|
||||
// the version.
|
||||
//
|
||||
// This version may be lower than the [api.DefaultVersion], which is the default
|
||||
// (and highest supported) version of the api library module used.
|
||||
const DefaultAPIVersion = "1.52"
|
||||
|
||||
// fallbackAPIVersion is the version to fallback to if API-version negotiation
|
||||
// fails. This version is the highest version of the API before API-version
|
||||
// negotiation was introduced. If negotiation fails (or no API version was
|
||||
@@ -198,7 +207,7 @@ func NewClientWithOpts(ops ...Opt) (*Client, error) {
|
||||
}
|
||||
c := &Client{
|
||||
host: DefaultDockerHost,
|
||||
version: api.DefaultVersion,
|
||||
version: DefaultAPIVersion,
|
||||
client: client,
|
||||
proto: hostURL.Scheme,
|
||||
addr: hostURL.Host,
|
||||
@@ -381,7 +390,7 @@ func (cli *Client) negotiateAPIVersionPing(pingResponse types.Ping) {
|
||||
|
||||
// if the client is not initialized with a version, start with the latest supported version
|
||||
if cli.version == "" {
|
||||
cli.version = api.DefaultVersion
|
||||
cli.version = DefaultAPIVersion
|
||||
}
|
||||
|
||||
// if server version is lower than the client version, downgrade
|
||||
|
||||
@@ -11,7 +11,6 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/docker/api"
|
||||
"github.com/docker/docker/api/types"
|
||||
"gotest.tools/v3/assert"
|
||||
is "gotest.tools/v3/assert/cmp"
|
||||
@@ -30,7 +29,7 @@ func TestNewClientWithOpsFromEnv(t *testing.T) {
|
||||
{
|
||||
doc: "default api version",
|
||||
envs: map[string]string{},
|
||||
expectedVersion: api.DefaultVersion,
|
||||
expectedVersion: DefaultAPIVersion,
|
||||
},
|
||||
{
|
||||
doc: "invalid cert path",
|
||||
@@ -44,7 +43,7 @@ func TestNewClientWithOpsFromEnv(t *testing.T) {
|
||||
envs: map[string]string{
|
||||
"DOCKER_CERT_PATH": "testdata/",
|
||||
},
|
||||
expectedVersion: api.DefaultVersion,
|
||||
expectedVersion: DefaultAPIVersion,
|
||||
},
|
||||
{
|
||||
doc: "default api version with cert path and tls verify",
|
||||
@@ -52,7 +51,7 @@ func TestNewClientWithOpsFromEnv(t *testing.T) {
|
||||
"DOCKER_CERT_PATH": "testdata/",
|
||||
"DOCKER_TLS_VERIFY": "1",
|
||||
},
|
||||
expectedVersion: api.DefaultVersion,
|
||||
expectedVersion: DefaultAPIVersion,
|
||||
},
|
||||
{
|
||||
doc: "default api version with cert path and host",
|
||||
@@ -60,7 +59,7 @@ func TestNewClientWithOpsFromEnv(t *testing.T) {
|
||||
"DOCKER_CERT_PATH": "testdata/",
|
||||
"DOCKER_HOST": "https://notaunixsocket",
|
||||
},
|
||||
expectedVersion: api.DefaultVersion,
|
||||
expectedVersion: DefaultAPIVersion,
|
||||
},
|
||||
{
|
||||
doc: "invalid docker host",
|
||||
@@ -74,7 +73,7 @@ func TestNewClientWithOpsFromEnv(t *testing.T) {
|
||||
envs: map[string]string{
|
||||
"DOCKER_HOST": "invalid://url",
|
||||
},
|
||||
expectedVersion: api.DefaultVersion,
|
||||
expectedVersion: DefaultAPIVersion,
|
||||
},
|
||||
{
|
||||
doc: "override api version",
|
||||
@@ -117,17 +116,17 @@ func TestGetAPIPath(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
path: "/containers/json",
|
||||
expected: "/v" + api.DefaultVersion + "/containers/json",
|
||||
expected: "/v" + DefaultAPIVersion + "/containers/json",
|
||||
},
|
||||
{
|
||||
path: "/containers/json",
|
||||
query: url.Values{},
|
||||
expected: "/v" + api.DefaultVersion + "/containers/json",
|
||||
expected: "/v" + DefaultAPIVersion + "/containers/json",
|
||||
},
|
||||
{
|
||||
path: "/containers/json",
|
||||
query: url.Values{"s": []string{"c"}},
|
||||
expected: "/v" + api.DefaultVersion + "/containers/json?s=c",
|
||||
expected: "/v" + DefaultAPIVersion + "/containers/json?s=c",
|
||||
},
|
||||
{
|
||||
version: "1.22",
|
||||
@@ -235,7 +234,7 @@ func TestNewClientWithOpsFromEnvSetsDefaultVersion(t *testing.T) {
|
||||
|
||||
client, err := NewClientWithOpts(FromEnv)
|
||||
assert.NilError(t, err)
|
||||
assert.Check(t, is.Equal(client.ClientVersion(), api.DefaultVersion))
|
||||
assert.Check(t, is.Equal(client.ClientVersion(), DefaultAPIVersion))
|
||||
|
||||
const expected = "1.22"
|
||||
t.Setenv("DOCKER_API_VERSION", expected)
|
||||
@@ -375,8 +374,8 @@ func TestNegotiateAPIVersionAutomatic(t *testing.T) {
|
||||
)
|
||||
assert.NilError(t, err)
|
||||
|
||||
// Client defaults to use api.DefaultVersion before version-negotiation.
|
||||
expected := api.DefaultVersion
|
||||
// Client defaults to use DefaultAPIVersion before version-negotiation.
|
||||
expected := DefaultAPIVersion
|
||||
assert.Check(t, is.Equal(client.ClientVersion(), expected))
|
||||
|
||||
// First request should trigger negotiation
|
||||
@@ -423,7 +422,7 @@ func TestCustomAPIVersion(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
version: "",
|
||||
expected: api.DefaultVersion,
|
||||
expected: DefaultAPIVersion,
|
||||
},
|
||||
{
|
||||
version: "1.0",
|
||||
@@ -435,7 +434,7 @@ func TestCustomAPIVersion(t *testing.T) {
|
||||
},
|
||||
{
|
||||
version: "v",
|
||||
expected: api.DefaultVersion,
|
||||
expected: DefaultAPIVersion,
|
||||
},
|
||||
{
|
||||
version: "v1.0",
|
||||
|
||||
@@ -194,6 +194,10 @@ func WithTLSClientConfigFromEnv() Opt {
|
||||
// WithVersion overrides the client version with the specified one. If an empty
|
||||
// version is provided, the value is ignored to allow version negotiation
|
||||
// (see [WithAPIVersionNegotiation]).
|
||||
//
|
||||
// WithVersion does not validate if the client supports the given version,
|
||||
// and callers should verify if the version is in the correct format and
|
||||
// lower than the maximum supported version as defined by [DefaultAPIVersion].
|
||||
func WithVersion(version string) Opt {
|
||||
return func(c *Client) error {
|
||||
if v := strings.TrimPrefix(version, "v"); v != "" {
|
||||
@@ -208,6 +212,10 @@ func WithVersion(version string) Opt {
|
||||
// the DOCKER_API_VERSION ([EnvOverrideAPIVersion]) environment variable.
|
||||
// If DOCKER_API_VERSION is not set, or set to an empty value, the version
|
||||
// is not modified.
|
||||
//
|
||||
// WithVersion does not validate if the client supports the given version,
|
||||
// and callers should verify if the version is in the correct format and
|
||||
// lower than the maximum supported version as defined by [DefaultAPIVersion].
|
||||
func WithVersionFromEnv() Opt {
|
||||
return func(c *Client) error {
|
||||
return WithVersion(os.Getenv(EnvOverrideAPIVersion))(c)
|
||||
|
||||
@@ -7,7 +7,6 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/api"
|
||||
"gotest.tools/v3/assert"
|
||||
is "gotest.tools/v3/assert/cmp"
|
||||
)
|
||||
@@ -50,7 +49,7 @@ func TestOptionWithVersionFromEnv(t *testing.T) {
|
||||
c, err := NewClientWithOpts(WithVersionFromEnv())
|
||||
assert.NilError(t, err)
|
||||
assert.Check(t, c.client != nil)
|
||||
assert.Check(t, is.Equal(c.version, api.DefaultVersion))
|
||||
assert.Check(t, is.Equal(c.version, DefaultAPIVersion))
|
||||
assert.Check(t, is.Equal(c.manualOverride, false))
|
||||
|
||||
t.Setenv("DOCKER_API_VERSION", "2.9999")
|
||||
|
||||
Reference in New Issue
Block a user