mirror of
https://github.com/moby/moby.git
synced 2026-01-11 10:41:43 +00:00
Merge pull request #51233 from austinvazquez/refactor-client-version
client: refactor ServerVersion to return ServerVersionResult
This commit is contained in:
@@ -5,7 +5,6 @@ import (
|
||||
"io"
|
||||
"net"
|
||||
|
||||
"github.com/moby/moby/api/types"
|
||||
"github.com/moby/moby/api/types/network"
|
||||
"github.com/moby/moby/api/types/system"
|
||||
)
|
||||
@@ -27,7 +26,7 @@ type stableAPIClient interface {
|
||||
VolumeAPIClient
|
||||
ClientVersion() string
|
||||
DaemonHost() string
|
||||
ServerVersion(ctx context.Context) (types.Version, error)
|
||||
ServerVersion(ctx context.Context, options ServerVersionOptions) (ServerVersionResult, error)
|
||||
HijackDialer
|
||||
Dialer() func(context.Context) (net.Conn, error)
|
||||
Close() error
|
||||
|
||||
@@ -7,15 +7,56 @@ import (
|
||||
"github.com/moby/moby/api/types"
|
||||
)
|
||||
|
||||
// ServerVersion returns information of the docker client and server host.
|
||||
func (cli *Client) ServerVersion(ctx context.Context) (types.Version, error) {
|
||||
// ServerVersionOptions specifies options for the server version request.
|
||||
type ServerVersionOptions struct {
|
||||
// Currently no options are supported.
|
||||
}
|
||||
|
||||
// ServerVersionResult contains information about the Docker server host.
|
||||
type ServerVersionResult struct {
|
||||
// Platform is the platform (product name) the server is running on.
|
||||
Platform PlatformInfo
|
||||
|
||||
// APIVersion is the highest API version supported by the server.
|
||||
APIVersion string
|
||||
|
||||
// MinAPIVersion is the minimum API version the server supports.
|
||||
MinAPIVersion string
|
||||
|
||||
// Components contains version information for the components making
|
||||
// up the server. Information in this field is for informational
|
||||
// purposes, and not part of the API contract.
|
||||
Components []types.ComponentVersion
|
||||
}
|
||||
|
||||
// PlatformInfo holds information about the platform (product name) the
|
||||
// server is running on.
|
||||
type PlatformInfo struct {
|
||||
// Name is the name of the platform (for example, "Docker Engine - Community",
|
||||
// or "Docker Desktop 4.49.0 (208003)")
|
||||
Name string
|
||||
}
|
||||
|
||||
// ServerVersion returns information of the Docker server host.
|
||||
func (cli *Client) ServerVersion(ctx context.Context, _ ServerVersionOptions) (ServerVersionResult, error) {
|
||||
resp, err := cli.get(ctx, "/version", nil, nil)
|
||||
defer ensureReaderClosed(resp)
|
||||
if err != nil {
|
||||
return types.Version{}, err
|
||||
return ServerVersionResult{}, err
|
||||
}
|
||||
|
||||
var server types.Version
|
||||
err = json.NewDecoder(resp.Body).Decode(&server)
|
||||
return server, err
|
||||
var v types.Version
|
||||
err = json.NewDecoder(resp.Body).Decode(&v)
|
||||
if err != nil {
|
||||
return ServerVersionResult{}, err
|
||||
}
|
||||
|
||||
return ServerVersionResult{
|
||||
Platform: PlatformInfo{
|
||||
Name: v.Platform.Name,
|
||||
},
|
||||
APIVersion: v.APIVersion,
|
||||
MinAPIVersion: v.MinAPIVersion,
|
||||
Components: v.Components,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -43,11 +43,11 @@ func OnlyDefaultNetworks(ctx context.Context) bool {
|
||||
}
|
||||
|
||||
func IsAmd64() bool {
|
||||
return testEnv.DaemonVersion.Arch == "amd64"
|
||||
return testEnv.DaemonInfo.Architecture == "amd64"
|
||||
}
|
||||
|
||||
func NotPpc64le() bool {
|
||||
return testEnv.DaemonVersion.Arch != "ppc64le"
|
||||
return testEnv.DaemonInfo.Architecture != "ppc64le"
|
||||
}
|
||||
|
||||
func UnixCli() bool {
|
||||
|
||||
@@ -953,7 +953,7 @@ func TestEmptyPortBindingsBC(t *testing.T) {
|
||||
|
||||
// Skip this subtest if the daemon doesn't support the client version.
|
||||
// TODO(aker): drop this once the Engine supports API version >= 1.53
|
||||
_, err := apiClient.ServerVersion(ctx)
|
||||
_, err := apiClient.ServerVersion(ctx, client.ServerVersionOptions{})
|
||||
if err != nil && strings.Contains(err.Error(), fmt.Sprintf("client version %s is too new", version)) {
|
||||
t.Skipf("requires API %s", version)
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ func TestAuthZPluginAllowRequest(t *testing.T) {
|
||||
assertURIRecorded(t, ctrl.requestsURIs, "/containers/create")
|
||||
assertURIRecorded(t, ctrl.requestsURIs, fmt.Sprintf("/containers/%s/start", cID))
|
||||
|
||||
_, err := c.ServerVersion(ctx)
|
||||
_, err := c.ServerVersion(ctx, client.ServerVersionOptions{})
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, 1, ctrl.versionReqCount)
|
||||
assert.Equal(t, 1, ctrl.versionResCount)
|
||||
@@ -137,7 +137,7 @@ func TestAuthZPluginTLS(t *testing.T) {
|
||||
c, err := newTLSAPIClient(testDaemonHTTPSAddr, cacertPath, clientCertPath, clientKeyPath)
|
||||
assert.NilError(t, err)
|
||||
|
||||
_, err = c.ServerVersion(ctx)
|
||||
_, err = c.ServerVersion(ctx, client.ServerVersionOptions{})
|
||||
assert.NilError(t, err)
|
||||
|
||||
assert.Equal(t, "client", ctrl.reqUser)
|
||||
@@ -165,7 +165,7 @@ func TestAuthZPluginDenyRequest(t *testing.T) {
|
||||
c := d.NewClientT(t)
|
||||
|
||||
// Ensure command is blocked
|
||||
_, err := c.ServerVersion(ctx)
|
||||
_, err := c.ServerVersion(ctx, client.ServerVersionOptions{})
|
||||
assert.Assert(t, err != nil)
|
||||
assert.Equal(t, 1, ctrl.versionReqCount)
|
||||
assert.Equal(t, 0, ctrl.versionResCount)
|
||||
@@ -211,7 +211,7 @@ func TestAuthZPluginDenyResponse(t *testing.T) {
|
||||
c := d.NewClientT(t)
|
||||
|
||||
// Ensure command is blocked
|
||||
_, err := c.ServerVersion(ctx)
|
||||
_, err := c.ServerVersion(ctx, client.ServerVersionOptions{})
|
||||
assert.Assert(t, err != nil)
|
||||
assert.Equal(t, 1, ctrl.versionReqCount)
|
||||
assert.Equal(t, 1, ctrl.versionResCount)
|
||||
@@ -304,7 +304,7 @@ func TestAuthZPluginErrorResponse(t *testing.T) {
|
||||
c := d.NewClientT(t)
|
||||
|
||||
// Ensure command is blocked
|
||||
_, err := c.ServerVersion(ctx)
|
||||
_, err := c.ServerVersion(ctx, client.ServerVersionOptions{})
|
||||
assert.Assert(t, err != nil)
|
||||
assert.Equal(t, fmt.Sprintf("Error response from daemon: plugin %s failed with error: %s: %s", testAuthZPlugin, authorization.AuthZApiResponse, errorMessage), err.Error())
|
||||
}
|
||||
@@ -317,7 +317,7 @@ func TestAuthZPluginErrorRequest(t *testing.T) {
|
||||
c := d.NewClientT(t)
|
||||
|
||||
// Ensure command is blocked
|
||||
_, err := c.ServerVersion(ctx)
|
||||
_, err := c.ServerVersion(ctx, client.ServerVersionOptions{})
|
||||
assert.Assert(t, err != nil)
|
||||
assert.Equal(t, fmt.Sprintf("Error response from daemon: plugin %s failed with error: %s: %s", testAuthZPlugin, authorization.AuthZApiRequest, errorMessage), err.Error())
|
||||
}
|
||||
@@ -331,7 +331,7 @@ func TestAuthZPluginEnsureNoDuplicatePluginRegistration(t *testing.T) {
|
||||
|
||||
c := d.NewClientT(t)
|
||||
|
||||
_, err := c.ServerVersion(ctx)
|
||||
_, err := c.ServerVersion(ctx, client.ServerVersionOptions{})
|
||||
assert.NilError(t, err)
|
||||
|
||||
// assert plugin is only called once..
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/moby/moby/api/types"
|
||||
"github.com/moby/moby/client"
|
||||
"github.com/moby/moby/v2/internal/testutil/request"
|
||||
"gotest.tools/v3/assert"
|
||||
@@ -16,26 +17,45 @@ func TestVersion(t *testing.T) {
|
||||
ctx := setupTest(t)
|
||||
apiClient := testEnv.APIClient()
|
||||
|
||||
version, err := apiClient.ServerVersion(ctx)
|
||||
version, err := apiClient.ServerVersion(ctx, client.ServerVersionOptions{})
|
||||
assert.NilError(t, err)
|
||||
assert.Check(t, len(version.Components) > 0, "expected at least one component in version.Components")
|
||||
|
||||
assert.Check(t, version.APIVersion != "")
|
||||
assert.Check(t, version.Version != "")
|
||||
assert.Check(t, version.MinAPIVersion != "")
|
||||
assert.Check(t, is.Equal(testEnv.DaemonInfo.ExperimentalBuild, version.Experimental))
|
||||
assert.Check(t, is.Equal(testEnv.DaemonInfo.OSType, version.Os))
|
||||
var engine types.ComponentVersion
|
||||
var found bool
|
||||
|
||||
for _, comp := range version.Components {
|
||||
if comp.Name == "Engine" {
|
||||
engine = comp
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
assert.Check(t, found, "Engine component not found in version.Components")
|
||||
assert.Equal(t, engine.Name, "Engine")
|
||||
assert.Check(t, engine.Version != "")
|
||||
assert.Equal(t, engine.Details["ApiVersion"], version.APIVersion)
|
||||
assert.Equal(t, engine.Details["MinAPIVersion"], version.MinAPIVersion)
|
||||
assert.Check(t, is.Equal(testEnv.DaemonInfo.OSType, engine.Details["Os"]))
|
||||
|
||||
experimentalStr := engine.Details["Experimental"]
|
||||
experimentalBool, err := strconv.ParseBool(experimentalStr)
|
||||
assert.NilError(t, err, "Experimental field in Engine details is not a valid boolean string")
|
||||
assert.Equal(t, testEnv.DaemonInfo.ExperimentalBuild, experimentalBool)
|
||||
}
|
||||
|
||||
func TestAPIClientVersionOldNotSupported(t *testing.T) {
|
||||
ctx := setupTest(t)
|
||||
major, minor, _ := strings.Cut(testEnv.DaemonVersion.MinAPIVersion, ".")
|
||||
minApiVersion := testEnv.DaemonMinAPIVersion
|
||||
major, minor, _ := strings.Cut(minApiVersion, ".")
|
||||
vMinInt, err := strconv.Atoi(minor)
|
||||
assert.NilError(t, err)
|
||||
vMinInt--
|
||||
version := fmt.Sprintf("%s.%d", major, vMinInt)
|
||||
apiClient := request.NewAPIClient(t, client.WithVersion(version))
|
||||
|
||||
expectedErrorMessage := fmt.Sprintf("Error response from daemon: client version %s is too old. Minimum supported API version is %s, please upgrade your client to a newer version", version, testEnv.DaemonVersion.MinAPIVersion)
|
||||
_, err = apiClient.ServerVersion(ctx)
|
||||
expectedErrorMessage := fmt.Sprintf("Error response from daemon: client version %s is too old. Minimum supported API version is %s, please upgrade your client to a newer version", version, minApiVersion)
|
||||
_, err = apiClient.ServerVersion(ctx, client.ServerVersionOptions{})
|
||||
assert.Error(t, err, expectedErrorMessage)
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/moby/moby/api/types"
|
||||
"github.com/moby/moby/api/types/system"
|
||||
"github.com/moby/moby/client"
|
||||
"github.com/moby/moby/v2/internal/testutil/fixtures/load"
|
||||
@@ -20,11 +19,11 @@ import (
|
||||
// Execution contains information about the current test execution and daemon
|
||||
// under test
|
||||
type Execution struct {
|
||||
client client.APIClient
|
||||
DaemonInfo system.Info
|
||||
DaemonVersion types.Version
|
||||
PlatformDefaults PlatformDefaults
|
||||
protectedElements protectedElements
|
||||
client client.APIClient
|
||||
DaemonInfo system.Info
|
||||
DaemonMinAPIVersion string
|
||||
PlatformDefaults PlatformDefaults
|
||||
protectedElements protectedElements
|
||||
}
|
||||
|
||||
// PlatformDefaults are defaults values for the platform of the daemon under test
|
||||
@@ -46,22 +45,27 @@ func New(ctx context.Context) (*Execution, error) {
|
||||
|
||||
// FromClient creates a new Execution environment from the passed in client
|
||||
func FromClient(ctx context.Context, c *client.Client) (*Execution, error) {
|
||||
_, err := c.Ping(ctx, client.PingOptions{NegotiateAPIVersion: true})
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to ping daemon to negotiate api version")
|
||||
}
|
||||
|
||||
result, err := c.Info(ctx, client.InfoOptions{})
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to get info from daemon")
|
||||
}
|
||||
info := result.Info
|
||||
v, err := c.ServerVersion(context.Background())
|
||||
|
||||
version, err := c.ServerVersion(ctx, client.ServerVersionOptions{})
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to get version info from daemon")
|
||||
return nil, errors.Wrapf(err, "failed to get version from daemon")
|
||||
}
|
||||
|
||||
return &Execution{
|
||||
client: c,
|
||||
DaemonInfo: info,
|
||||
DaemonVersion: v,
|
||||
PlatformDefaults: getPlatformDefaults(info),
|
||||
protectedElements: newProtectedElements(),
|
||||
client: c,
|
||||
DaemonInfo: result.Info,
|
||||
DaemonMinAPIVersion: version.MinAPIVersion,
|
||||
PlatformDefaults: getPlatformDefaults(result.Info),
|
||||
protectedElements: newProtectedElements(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -129,11 +133,7 @@ func (e *Execution) IsRemoteDaemon() bool {
|
||||
|
||||
// DaemonAPIVersion returns the negotiated daemon api version
|
||||
func (e *Execution) DaemonAPIVersion() string {
|
||||
version, err := e.APIClient().ServerVersion(context.TODO())
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return version.APIVersion
|
||||
return e.APIClient().ClientVersion()
|
||||
}
|
||||
|
||||
// Print the execution details to stdout
|
||||
@@ -228,7 +228,7 @@ func (e *Execution) GitHubActions() bool {
|
||||
|
||||
// NotAmd64 returns true if the daemon's architecture is not amd64
|
||||
func (e *Execution) NotAmd64() bool {
|
||||
return e.DaemonVersion.Arch != "amd64"
|
||||
return e.DaemonInfo.Architecture != "amd64"
|
||||
}
|
||||
|
||||
// FirewallBackendDriver returns the value of FirewallBackend.Driver from
|
||||
|
||||
@@ -31,7 +31,7 @@ func ensureHTTPServerImage(t testing.TB) {
|
||||
if goos == "" {
|
||||
goos = "linux"
|
||||
}
|
||||
goarch := testEnv.DaemonVersion.Arch
|
||||
goarch := testEnv.DaemonInfo.Architecture
|
||||
if goarch == "" {
|
||||
goarch = "amd64"
|
||||
}
|
||||
|
||||
3
vendor/github.com/moby/moby/client/client_interfaces.go
generated
vendored
3
vendor/github.com/moby/moby/client/client_interfaces.go
generated
vendored
@@ -5,7 +5,6 @@ import (
|
||||
"io"
|
||||
"net"
|
||||
|
||||
"github.com/moby/moby/api/types"
|
||||
"github.com/moby/moby/api/types/network"
|
||||
"github.com/moby/moby/api/types/system"
|
||||
)
|
||||
@@ -27,7 +26,7 @@ type stableAPIClient interface {
|
||||
VolumeAPIClient
|
||||
ClientVersion() string
|
||||
DaemonHost() string
|
||||
ServerVersion(ctx context.Context) (types.Version, error)
|
||||
ServerVersion(ctx context.Context, options ServerVersionOptions) (ServerVersionResult, error)
|
||||
HijackDialer
|
||||
Dialer() func(context.Context) (net.Conn, error)
|
||||
Close() error
|
||||
|
||||
53
vendor/github.com/moby/moby/client/version.go
generated
vendored
53
vendor/github.com/moby/moby/client/version.go
generated
vendored
@@ -7,15 +7,56 @@ import (
|
||||
"github.com/moby/moby/api/types"
|
||||
)
|
||||
|
||||
// ServerVersion returns information of the docker client and server host.
|
||||
func (cli *Client) ServerVersion(ctx context.Context) (types.Version, error) {
|
||||
// ServerVersionOptions specifies options for the server version request.
|
||||
type ServerVersionOptions struct {
|
||||
// Currently no options are supported.
|
||||
}
|
||||
|
||||
// ServerVersionResult contains information about the Docker server host.
|
||||
type ServerVersionResult struct {
|
||||
// Platform is the platform (product name) the server is running on.
|
||||
Platform PlatformInfo
|
||||
|
||||
// APIVersion is the highest API version supported by the server.
|
||||
APIVersion string
|
||||
|
||||
// MinAPIVersion is the minimum API version the server supports.
|
||||
MinAPIVersion string
|
||||
|
||||
// Components contains version information for the components making
|
||||
// up the server. Information in this field is for informational
|
||||
// purposes, and not part of the API contract.
|
||||
Components []types.ComponentVersion
|
||||
}
|
||||
|
||||
// PlatformInfo holds information about the platform (product name) the
|
||||
// server is running on.
|
||||
type PlatformInfo struct {
|
||||
// Name is the name of the platform (for example, "Docker Engine - Community",
|
||||
// or "Docker Desktop 4.49.0 (208003)")
|
||||
Name string
|
||||
}
|
||||
|
||||
// ServerVersion returns information of the Docker server host.
|
||||
func (cli *Client) ServerVersion(ctx context.Context, _ ServerVersionOptions) (ServerVersionResult, error) {
|
||||
resp, err := cli.get(ctx, "/version", nil, nil)
|
||||
defer ensureReaderClosed(resp)
|
||||
if err != nil {
|
||||
return types.Version{}, err
|
||||
return ServerVersionResult{}, err
|
||||
}
|
||||
|
||||
var server types.Version
|
||||
err = json.NewDecoder(resp.Body).Decode(&server)
|
||||
return server, err
|
||||
var v types.Version
|
||||
err = json.NewDecoder(resp.Body).Decode(&v)
|
||||
if err != nil {
|
||||
return ServerVersionResult{}, err
|
||||
}
|
||||
|
||||
return ServerVersionResult{
|
||||
Platform: PlatformInfo{
|
||||
Name: v.Platform.Name,
|
||||
},
|
||||
APIVersion: v.APIVersion,
|
||||
MinAPIVersion: v.MinAPIVersion,
|
||||
Components: v.Components,
|
||||
}, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user