mirror of
https://github.com/moby/moby.git
synced 2026-01-11 18:51:37 +00:00
Merge pull request #51258 from thaJeztah/client_ping
api/types: move Ping and swarm.Status to client
This commit is contained in:
@@ -214,16 +214,6 @@ type Info struct {
|
||||
Warnings []string `json:",omitempty"`
|
||||
}
|
||||
|
||||
// Status provides information about the current swarm status and role,
|
||||
// obtained from the "Swarm" header in the API response.
|
||||
type Status struct {
|
||||
// NodeState represents the state of the node.
|
||||
NodeState LocalNodeState
|
||||
|
||||
// ControlAvailable indicates if the node is a swarm manager.
|
||||
ControlAvailable bool
|
||||
}
|
||||
|
||||
// Peer represents a peer.
|
||||
type Peer struct {
|
||||
NodeID string
|
||||
|
||||
@@ -1,10 +1,5 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"github.com/moby/moby/api/types/build"
|
||||
"github.com/moby/moby/api/types/swarm"
|
||||
)
|
||||
|
||||
const (
|
||||
// MediaTypeRawStream is vendor specific MIME-Type set for raw TTY streams
|
||||
MediaTypeRawStream = "application/vnd.docker.raw-stream"
|
||||
@@ -22,24 +17,6 @@ const (
|
||||
MediaTypeJSONSequence = "application/json-seq"
|
||||
)
|
||||
|
||||
// Ping contains response of Engine API:
|
||||
// GET "/_ping"
|
||||
type Ping struct {
|
||||
APIVersion string
|
||||
OSType string
|
||||
Experimental bool
|
||||
BuilderVersion build.BuilderVersion
|
||||
|
||||
// SwarmStatus provides information about the current swarm status of the
|
||||
// engine, obtained from the "Swarm" header in the API response.
|
||||
//
|
||||
// It can be a nil struct if the API version does not provide this header
|
||||
// in the ping response, or if an error occurred, in which case the client
|
||||
// should use other ways to get the current swarm status, such as the /swarm
|
||||
// endpoint.
|
||||
SwarmStatus *swarm.Status
|
||||
}
|
||||
|
||||
// ComponentVersion describes the version information for a specific component.
|
||||
type ComponentVersion struct {
|
||||
Name string
|
||||
|
||||
@@ -56,7 +56,6 @@ import (
|
||||
|
||||
cerrdefs "github.com/containerd/errdefs"
|
||||
"github.com/docker/go-connections/sockets"
|
||||
"github.com/moby/moby/api/types"
|
||||
"github.com/moby/moby/api/types/versions"
|
||||
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
|
||||
)
|
||||
@@ -270,7 +269,7 @@ func (cli *Client) checkVersion(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
ping, err := cli.Ping(ctx)
|
||||
ping, err := cli.Ping(ctx, PingOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -317,7 +316,7 @@ func (cli *Client) NegotiateAPIVersion(ctx context.Context) {
|
||||
cli.negotiateLock.Lock()
|
||||
defer cli.negotiateLock.Unlock()
|
||||
|
||||
ping, err := cli.Ping(ctx)
|
||||
ping, err := cli.Ping(ctx, PingOptions{})
|
||||
if err != nil {
|
||||
// FIXME(thaJeztah): Ping returns an error when failing to connect to the API; we should not swallow the error here, and instead returning it.
|
||||
return
|
||||
@@ -338,7 +337,8 @@ func (cli *Client) NegotiateAPIVersion(ctx context.Context) {
|
||||
//
|
||||
// If the API server's ping response does not contain an API version, it falls
|
||||
// back to the oldest API version supported.
|
||||
func (cli *Client) NegotiateAPIVersionPing(pingResponse types.Ping) {
|
||||
func (cli *Client) NegotiateAPIVersionPing(pingResponse PingResult) {
|
||||
// TODO(thaJeztah): should this take a "Ping" option? It only consumes the version. This method should be removed overall and not be exported.
|
||||
if !cli.manualOverride {
|
||||
// Avoid concurrent modification of version-related fields
|
||||
cli.negotiateLock.Lock()
|
||||
|
||||
@@ -35,7 +35,7 @@ type stableAPIClient interface {
|
||||
DaemonHost() string
|
||||
ServerVersion(ctx context.Context) (types.Version, error)
|
||||
NegotiateAPIVersion(ctx context.Context)
|
||||
NegotiateAPIVersionPing(types.Ping)
|
||||
NegotiateAPIVersionPing(PingResult)
|
||||
HijackDialer
|
||||
Dialer() func(context.Context) (net.Conn, error)
|
||||
Close() error
|
||||
@@ -187,7 +187,7 @@ type SystemAPIClient interface {
|
||||
Info(ctx context.Context) (system.Info, error)
|
||||
RegistryLogin(ctx context.Context, auth registry.AuthConfig) (registry.AuthenticateOKBody, error)
|
||||
DiskUsage(ctx context.Context, options DiskUsageOptions) (system.DiskUsage, error)
|
||||
Ping(ctx context.Context) (types.Ping, error)
|
||||
Ping(ctx context.Context, options PingOptions) (PingResult, error)
|
||||
}
|
||||
|
||||
// VolumeAPIClient defines API client methods for the volumes
|
||||
|
||||
@@ -11,7 +11,6 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/moby/moby/api/types"
|
||||
"gotest.tools/v3/assert"
|
||||
is "gotest.tools/v3/assert/cmp"
|
||||
"gotest.tools/v3/skip"
|
||||
@@ -267,7 +266,7 @@ func TestNegotiateAPIVersionEmpty(t *testing.T) {
|
||||
const expected = fallbackAPIVersion
|
||||
|
||||
// test downgrade
|
||||
client.NegotiateAPIVersionPing(types.Ping{})
|
||||
client.NegotiateAPIVersionPing(PingResult{})
|
||||
assert.Check(t, is.Equal(client.ClientVersion(), expected))
|
||||
}
|
||||
|
||||
@@ -330,7 +329,7 @@ func TestNegotiateAPIVersion(t *testing.T) {
|
||||
}
|
||||
client, err := NewClientWithOpts(opts...)
|
||||
assert.NilError(t, err)
|
||||
client.NegotiateAPIVersionPing(types.Ping{APIVersion: tc.pingVersion})
|
||||
client.NegotiateAPIVersionPing(PingResult{APIVersion: tc.pingVersion})
|
||||
assert.Check(t, is.Equal(tc.expectedVersion, client.ClientVersion()))
|
||||
})
|
||||
}
|
||||
@@ -346,7 +345,7 @@ func TestNegotiateAPIVersionOverride(t *testing.T) {
|
||||
assert.NilError(t, err)
|
||||
|
||||
// test that we honored the env var
|
||||
client.NegotiateAPIVersionPing(types.Ping{APIVersion: "1.24"})
|
||||
client.NegotiateAPIVersionPing(PingResult{APIVersion: "1.24"})
|
||||
assert.Check(t, is.Equal(client.ClientVersion(), expected))
|
||||
}
|
||||
|
||||
@@ -404,7 +403,7 @@ func TestNegotiateAPIVersionWithEmptyVersion(t *testing.T) {
|
||||
assert.NilError(t, err)
|
||||
|
||||
const expected = "1.50"
|
||||
client.NegotiateAPIVersionPing(types.Ping{APIVersion: expected})
|
||||
client.NegotiateAPIVersionPing(PingResult{APIVersion: expected})
|
||||
assert.Check(t, is.Equal(client.ClientVersion(), expected))
|
||||
}
|
||||
|
||||
@@ -415,7 +414,7 @@ func TestNegotiateAPIVersionWithFixedVersion(t *testing.T) {
|
||||
client, err := NewClientWithOpts(WithVersion(customVersion))
|
||||
assert.NilError(t, err)
|
||||
|
||||
client.NegotiateAPIVersionPing(types.Ping{APIVersion: "1.49"})
|
||||
client.NegotiateAPIVersionPing(PingResult{APIVersion: "1.49"})
|
||||
assert.Check(t, is.Equal(client.ClientVersion(), customVersion))
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"runtime"
|
||||
"testing"
|
||||
@@ -72,7 +71,7 @@ func TestWithUserAgent(t *testing.T) {
|
||||
}),
|
||||
)
|
||||
assert.NilError(t, err)
|
||||
_, err = c.Ping(context.Background())
|
||||
_, err = c.Ping(t.Context(), PingOptions{})
|
||||
assert.NilError(t, err)
|
||||
assert.NilError(t, c.Close())
|
||||
})
|
||||
@@ -87,7 +86,7 @@ func TestWithUserAgent(t *testing.T) {
|
||||
}),
|
||||
)
|
||||
assert.NilError(t, err)
|
||||
_, err = c.Ping(context.Background())
|
||||
_, err = c.Ping(t.Context(), PingOptions{})
|
||||
assert.NilError(t, err)
|
||||
assert.NilError(t, c.Close())
|
||||
})
|
||||
@@ -101,7 +100,7 @@ func TestWithUserAgent(t *testing.T) {
|
||||
}),
|
||||
)
|
||||
assert.NilError(t, err)
|
||||
_, err = c.Ping(context.Background())
|
||||
_, err = c.Ping(t.Context(), PingOptions{})
|
||||
assert.NilError(t, err)
|
||||
assert.NilError(t, c.Close())
|
||||
})
|
||||
@@ -115,7 +114,7 @@ func TestWithUserAgent(t *testing.T) {
|
||||
}),
|
||||
)
|
||||
assert.NilError(t, err)
|
||||
_, err = c.Ping(context.Background())
|
||||
_, err = c.Ping(t.Context(), PingOptions{})
|
||||
assert.NilError(t, err)
|
||||
assert.NilError(t, c.Close())
|
||||
})
|
||||
@@ -130,7 +129,7 @@ func TestWithUserAgent(t *testing.T) {
|
||||
}),
|
||||
)
|
||||
assert.NilError(t, err)
|
||||
_, err = c.Ping(context.Background())
|
||||
_, err = c.Ping(t.Context(), PingOptions{})
|
||||
assert.NilError(t, err)
|
||||
assert.NilError(t, c.Close())
|
||||
})
|
||||
|
||||
@@ -6,11 +6,42 @@ import (
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/moby/moby/api/types"
|
||||
"github.com/moby/moby/api/types/build"
|
||||
"github.com/moby/moby/api/types/swarm"
|
||||
)
|
||||
|
||||
// PingOptions holds options for [client.Ping].
|
||||
type PingOptions struct {
|
||||
// Add future optional parameters here
|
||||
}
|
||||
|
||||
// PingResult holds the result of a [Client.Ping] API call.
|
||||
type PingResult struct {
|
||||
APIVersion string
|
||||
OSType string
|
||||
Experimental bool
|
||||
BuilderVersion build.BuilderVersion
|
||||
|
||||
// SwarmStatus provides information about the current swarm status of the
|
||||
// engine, obtained from the "Swarm" header in the API response.
|
||||
//
|
||||
// It can be a nil struct if the API version does not provide this header
|
||||
// in the ping response, or if an error occurred, in which case the client
|
||||
// should use other ways to get the current swarm status, such as the /swarm
|
||||
// endpoint.
|
||||
SwarmStatus *SwarmStatus
|
||||
}
|
||||
|
||||
// SwarmStatus provides information about the current swarm status and role,
|
||||
// obtained from the "Swarm" header in the API response.
|
||||
type SwarmStatus struct {
|
||||
// NodeState represents the state of the node.
|
||||
NodeState swarm.LocalNodeState
|
||||
|
||||
// ControlAvailable indicates if the node is a swarm manager.
|
||||
ControlAvailable bool
|
||||
}
|
||||
|
||||
// Ping pings the server and returns the value of the "Docker-Experimental",
|
||||
// "Builder-Version", "OS-Type" & "API-Version" headers. It attempts to use
|
||||
// a HEAD request on the endpoint, but falls back to GET if HEAD is not supported
|
||||
@@ -18,13 +49,13 @@ import (
|
||||
// may be returned if the daemon is in an unhealthy state, but returns errors
|
||||
// for other non-success status codes, failing to connect to the API, or failing
|
||||
// to parse the API response.
|
||||
func (cli *Client) Ping(ctx context.Context) (types.Ping, error) {
|
||||
func (cli *Client) Ping(ctx context.Context, options PingOptions) (PingResult, error) {
|
||||
// Using cli.buildRequest() + cli.doRequest() instead of cli.sendRequest()
|
||||
// because ping requests are used during API version negotiation, so we want
|
||||
// to hit the non-versioned /_ping endpoint, not /v1.xx/_ping
|
||||
req, err := cli.buildRequest(ctx, http.MethodHead, path.Join(cli.basePath, "/_ping"), nil, nil)
|
||||
if err != nil {
|
||||
return types.Ping{}, err
|
||||
return PingResult{}, err
|
||||
}
|
||||
resp, err := cli.doRequest(req)
|
||||
defer ensureReaderClosed(resp)
|
||||
@@ -33,7 +64,7 @@ func (cli *Client) Ping(ctx context.Context) (types.Ping, error) {
|
||||
// we got a "OK" (200) status. For non-200 status-codes, we fall
|
||||
// back to doing a GET request, as a HEAD request won't have a
|
||||
// response-body to get error details from.
|
||||
return newPingResponse(resp), nil
|
||||
return newPingResult(resp), nil
|
||||
}
|
||||
|
||||
// HEAD failed or returned a non-OK status; fallback to GET.
|
||||
@@ -42,29 +73,29 @@ func (cli *Client) Ping(ctx context.Context) (types.Ping, error) {
|
||||
defer ensureReaderClosed(resp)
|
||||
if err != nil {
|
||||
// Failed to connect.
|
||||
return types.Ping{}, err
|
||||
return PingResult{}, err
|
||||
}
|
||||
|
||||
// GET request succeeded but may have returned a non-200 status.
|
||||
// Return a Ping response, together with any error returned by
|
||||
// the API server.
|
||||
return newPingResponse(resp), checkResponseErr(resp)
|
||||
return newPingResult(resp), checkResponseErr(resp)
|
||||
}
|
||||
|
||||
func newPingResponse(resp *http.Response) types.Ping {
|
||||
func newPingResult(resp *http.Response) PingResult {
|
||||
if resp == nil {
|
||||
return types.Ping{}
|
||||
return PingResult{}
|
||||
}
|
||||
var swarmStatus *swarm.Status
|
||||
var swarmStatus *SwarmStatus
|
||||
if si := resp.Header.Get("Swarm"); si != "" {
|
||||
state, role, _ := strings.Cut(si, "/")
|
||||
swarmStatus = &swarm.Status{
|
||||
swarmStatus = &SwarmStatus{
|
||||
NodeState: swarm.LocalNodeState(state),
|
||||
ControlAvailable: role == "manager",
|
||||
}
|
||||
}
|
||||
|
||||
return types.Ping{
|
||||
return PingResult{
|
||||
APIVersion: resp.Header.Get("Api-Version"),
|
||||
OSType: resp.Header.Get("Ostype"),
|
||||
Experimental: resp.Header.Get("Docker-Experimental") == "true",
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
@@ -10,7 +9,6 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/moby/moby/api/types/swarm"
|
||||
"gotest.tools/v3/assert"
|
||||
is "gotest.tools/v3/assert/cmp"
|
||||
)
|
||||
@@ -34,19 +32,19 @@ func TestPingFail(t *testing.T) {
|
||||
}))
|
||||
assert.NilError(t, err)
|
||||
|
||||
ping, err := client.Ping(context.Background())
|
||||
ping, err := client.Ping(t.Context(), PingOptions{})
|
||||
assert.Check(t, is.ErrorContains(err, "some error with the server"))
|
||||
assert.Check(t, is.Equal(false, ping.Experimental))
|
||||
assert.Check(t, is.Equal("", ping.APIVersion))
|
||||
var si *swarm.Status
|
||||
var si *SwarmStatus
|
||||
assert.Check(t, is.Equal(si, ping.SwarmStatus))
|
||||
|
||||
withHeader = true
|
||||
ping2, err := client.Ping(context.Background())
|
||||
ping2, err := client.Ping(t.Context(), PingOptions{})
|
||||
assert.Check(t, is.ErrorContains(err, "some error with the server"))
|
||||
assert.Check(t, is.Equal(true, ping2.Experimental))
|
||||
assert.Check(t, is.Equal("awesome", ping2.APIVersion))
|
||||
assert.Check(t, is.Equal(swarm.Status{NodeState: "inactive"}, *ping2.SwarmStatus))
|
||||
assert.Check(t, is.Equal(SwarmStatus{NodeState: "inactive"}, *ping2.SwarmStatus))
|
||||
}
|
||||
|
||||
// TestPingWithError tests the case where there is a protocol error in the ping.
|
||||
@@ -57,11 +55,11 @@ func TestPingWithError(t *testing.T) {
|
||||
}))
|
||||
assert.NilError(t, err)
|
||||
|
||||
ping, err := client.Ping(context.Background())
|
||||
ping, err := client.Ping(t.Context(), PingOptions{})
|
||||
assert.Check(t, is.ErrorContains(err, "some connection error"))
|
||||
assert.Check(t, is.Equal(false, ping.Experimental))
|
||||
assert.Check(t, is.Equal("", ping.APIVersion))
|
||||
var si *swarm.Status
|
||||
var si *SwarmStatus
|
||||
assert.Check(t, is.Equal(si, ping.SwarmStatus))
|
||||
}
|
||||
|
||||
@@ -78,11 +76,11 @@ func TestPingSuccess(t *testing.T) {
|
||||
return resp, nil
|
||||
}))
|
||||
assert.NilError(t, err)
|
||||
ping, err := client.Ping(context.Background())
|
||||
ping, err := client.Ping(t.Context(), PingOptions{})
|
||||
assert.NilError(t, err)
|
||||
assert.Check(t, is.Equal(true, ping.Experimental))
|
||||
assert.Check(t, is.Equal("awesome", ping.APIVersion))
|
||||
assert.Check(t, is.Equal(swarm.Status{NodeState: "active", ControlAvailable: true}, *ping.SwarmStatus))
|
||||
assert.Check(t, is.Equal(SwarmStatus{NodeState: "active", ControlAvailable: true}, *ping.SwarmStatus))
|
||||
}
|
||||
|
||||
// TestPingHeadFallback tests that the client falls back to GET if HEAD fails.
|
||||
@@ -131,7 +129,7 @@ func TestPingHeadFallback(t *testing.T) {
|
||||
return resp, nil
|
||||
}))
|
||||
assert.NilError(t, err)
|
||||
ping, _ := client.Ping(context.Background())
|
||||
ping, _ := client.Ping(t.Context(), PingOptions{})
|
||||
assert.Check(t, is.Equal(ping.APIVersion, "1.2.3"))
|
||||
assert.Check(t, is.DeepEqual(reqs, tc.expected))
|
||||
})
|
||||
|
||||
@@ -210,7 +210,7 @@ func TestResponseErrors(t *testing.T) {
|
||||
client, err = NewClientWithOpts(WithHTTPClient(client.client), WithVersion(tc.apiVersion))
|
||||
}
|
||||
assert.NilError(t, err)
|
||||
_, err = client.Ping(context.Background())
|
||||
_, err = client.Ping(t.Context(), PingOptions{})
|
||||
assert.Check(t, is.Error(err, tc.expected))
|
||||
assert.Check(t, is.ErrorType(err, cerrdefs.IsInvalidArgument))
|
||||
})
|
||||
@@ -229,7 +229,7 @@ func TestInfiniteError(t *testing.T) {
|
||||
}))
|
||||
assert.NilError(t, err)
|
||||
|
||||
_, err = client.Ping(context.Background())
|
||||
_, err = client.Ping(t.Context(), PingOptions{})
|
||||
assert.Check(t, is.ErrorType(err, cerrdefs.IsInternal))
|
||||
assert.Check(t, is.ErrorContains(err, "request returned Internal Server Error"))
|
||||
}
|
||||
|
||||
@@ -2235,7 +2235,7 @@ func (s *DockerDaemonSuite) TestFailedPluginRemove(c *testing.T) {
|
||||
d.Restart(c)
|
||||
ctx, cancel = context.WithTimeout(testutil.GetContext(c), 30*time.Second)
|
||||
defer cancel()
|
||||
_, err = apiClient.Ping(ctx)
|
||||
_, err = apiClient.Ping(ctx, client.PingOptions{})
|
||||
assert.NilError(c, err)
|
||||
|
||||
_, err = apiClient.PluginInspect(ctx, name, client.PluginInspectOptions{})
|
||||
|
||||
@@ -68,7 +68,7 @@ func TestPingSwarmHeader(t *testing.T) {
|
||||
|
||||
t.Run("before swarm init", func(t *testing.T) {
|
||||
ctx := testutil.StartSpan(ctx, t)
|
||||
p, err := apiClient.Ping(ctx)
|
||||
p, err := apiClient.Ping(ctx, client.PingOptions{})
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, p.SwarmStatus.NodeState, swarm.LocalNodeStateInactive)
|
||||
assert.Equal(t, p.SwarmStatus.ControlAvailable, false)
|
||||
@@ -79,7 +79,7 @@ func TestPingSwarmHeader(t *testing.T) {
|
||||
|
||||
t.Run("after swarm init", func(t *testing.T) {
|
||||
ctx := testutil.StartSpan(ctx, t)
|
||||
p, err := apiClient.Ping(ctx)
|
||||
p, err := apiClient.Ping(ctx, client.PingOptions{})
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, p.SwarmStatus.NodeState, swarm.LocalNodeStateActive)
|
||||
assert.Equal(t, p.SwarmStatus.ControlAvailable, true)
|
||||
@@ -90,7 +90,7 @@ func TestPingSwarmHeader(t *testing.T) {
|
||||
|
||||
t.Run("after swarm leave", func(t *testing.T) {
|
||||
ctx := testutil.StartSpan(ctx, t)
|
||||
p, err := apiClient.Ping(ctx)
|
||||
p, err := apiClient.Ping(ctx, client.PingOptions{})
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, p.SwarmStatus.NodeState, swarm.LocalNodeStateInactive)
|
||||
assert.Equal(t, p.SwarmStatus.ControlAvailable, false)
|
||||
@@ -116,7 +116,7 @@ func TestPingBuilderHeader(t *testing.T) {
|
||||
expected = build.BuilderV1
|
||||
}
|
||||
|
||||
p, err := apiClient.Ping(ctx)
|
||||
p, err := apiClient.Ping(ctx, client.PingOptions{})
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, p.BuilderVersion, expected)
|
||||
})
|
||||
@@ -130,7 +130,7 @@ func TestPingBuilderHeader(t *testing.T) {
|
||||
defer d.Stop(t)
|
||||
|
||||
expected := build.BuilderV1
|
||||
p, err := apiClient.Ping(ctx)
|
||||
p, err := apiClient.Ping(ctx, client.PingOptions{})
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, p.BuilderVersion, expected)
|
||||
})
|
||||
|
||||
10
vendor/github.com/moby/moby/api/types/swarm/swarm.go
generated
vendored
10
vendor/github.com/moby/moby/api/types/swarm/swarm.go
generated
vendored
@@ -214,16 +214,6 @@ type Info struct {
|
||||
Warnings []string `json:",omitempty"`
|
||||
}
|
||||
|
||||
// Status provides information about the current swarm status and role,
|
||||
// obtained from the "Swarm" header in the API response.
|
||||
type Status struct {
|
||||
// NodeState represents the state of the node.
|
||||
NodeState LocalNodeState
|
||||
|
||||
// ControlAvailable indicates if the node is a swarm manager.
|
||||
ControlAvailable bool
|
||||
}
|
||||
|
||||
// Peer represents a peer.
|
||||
type Peer struct {
|
||||
NodeID string
|
||||
|
||||
23
vendor/github.com/moby/moby/api/types/types.go
generated
vendored
23
vendor/github.com/moby/moby/api/types/types.go
generated
vendored
@@ -1,10 +1,5 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"github.com/moby/moby/api/types/build"
|
||||
"github.com/moby/moby/api/types/swarm"
|
||||
)
|
||||
|
||||
const (
|
||||
// MediaTypeRawStream is vendor specific MIME-Type set for raw TTY streams
|
||||
MediaTypeRawStream = "application/vnd.docker.raw-stream"
|
||||
@@ -22,24 +17,6 @@ const (
|
||||
MediaTypeJSONSequence = "application/json-seq"
|
||||
)
|
||||
|
||||
// Ping contains response of Engine API:
|
||||
// GET "/_ping"
|
||||
type Ping struct {
|
||||
APIVersion string
|
||||
OSType string
|
||||
Experimental bool
|
||||
BuilderVersion build.BuilderVersion
|
||||
|
||||
// SwarmStatus provides information about the current swarm status of the
|
||||
// engine, obtained from the "Swarm" header in the API response.
|
||||
//
|
||||
// It can be a nil struct if the API version does not provide this header
|
||||
// in the ping response, or if an error occurred, in which case the client
|
||||
// should use other ways to get the current swarm status, such as the /swarm
|
||||
// endpoint.
|
||||
SwarmStatus *swarm.Status
|
||||
}
|
||||
|
||||
// ComponentVersion describes the version information for a specific component.
|
||||
type ComponentVersion struct {
|
||||
Name string
|
||||
|
||||
8
vendor/github.com/moby/moby/client/client.go
generated
vendored
8
vendor/github.com/moby/moby/client/client.go
generated
vendored
@@ -56,7 +56,6 @@ import (
|
||||
|
||||
cerrdefs "github.com/containerd/errdefs"
|
||||
"github.com/docker/go-connections/sockets"
|
||||
"github.com/moby/moby/api/types"
|
||||
"github.com/moby/moby/api/types/versions"
|
||||
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
|
||||
)
|
||||
@@ -270,7 +269,7 @@ func (cli *Client) checkVersion(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
ping, err := cli.Ping(ctx)
|
||||
ping, err := cli.Ping(ctx, PingOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -317,7 +316,7 @@ func (cli *Client) NegotiateAPIVersion(ctx context.Context) {
|
||||
cli.negotiateLock.Lock()
|
||||
defer cli.negotiateLock.Unlock()
|
||||
|
||||
ping, err := cli.Ping(ctx)
|
||||
ping, err := cli.Ping(ctx, PingOptions{})
|
||||
if err != nil {
|
||||
// FIXME(thaJeztah): Ping returns an error when failing to connect to the API; we should not swallow the error here, and instead returning it.
|
||||
return
|
||||
@@ -338,7 +337,8 @@ func (cli *Client) NegotiateAPIVersion(ctx context.Context) {
|
||||
//
|
||||
// If the API server's ping response does not contain an API version, it falls
|
||||
// back to the oldest API version supported.
|
||||
func (cli *Client) NegotiateAPIVersionPing(pingResponse types.Ping) {
|
||||
func (cli *Client) NegotiateAPIVersionPing(pingResponse PingResult) {
|
||||
// TODO(thaJeztah): should this take a "Ping" option? It only consumes the version. This method should be removed overall and not be exported.
|
||||
if !cli.manualOverride {
|
||||
// Avoid concurrent modification of version-related fields
|
||||
cli.negotiateLock.Lock()
|
||||
|
||||
4
vendor/github.com/moby/moby/client/client_interfaces.go
generated
vendored
4
vendor/github.com/moby/moby/client/client_interfaces.go
generated
vendored
@@ -35,7 +35,7 @@ type stableAPIClient interface {
|
||||
DaemonHost() string
|
||||
ServerVersion(ctx context.Context) (types.Version, error)
|
||||
NegotiateAPIVersion(ctx context.Context)
|
||||
NegotiateAPIVersionPing(types.Ping)
|
||||
NegotiateAPIVersionPing(PingResult)
|
||||
HijackDialer
|
||||
Dialer() func(context.Context) (net.Conn, error)
|
||||
Close() error
|
||||
@@ -187,7 +187,7 @@ type SystemAPIClient interface {
|
||||
Info(ctx context.Context) (system.Info, error)
|
||||
RegistryLogin(ctx context.Context, auth registry.AuthConfig) (registry.AuthenticateOKBody, error)
|
||||
DiskUsage(ctx context.Context, options DiskUsageOptions) (system.DiskUsage, error)
|
||||
Ping(ctx context.Context) (types.Ping, error)
|
||||
Ping(ctx context.Context, options PingOptions) (PingResult, error)
|
||||
}
|
||||
|
||||
// VolumeAPIClient defines API client methods for the volumes
|
||||
|
||||
53
vendor/github.com/moby/moby/client/ping.go
generated
vendored
53
vendor/github.com/moby/moby/client/ping.go
generated
vendored
@@ -6,11 +6,42 @@ import (
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/moby/moby/api/types"
|
||||
"github.com/moby/moby/api/types/build"
|
||||
"github.com/moby/moby/api/types/swarm"
|
||||
)
|
||||
|
||||
// PingOptions holds options for [client.Ping].
|
||||
type PingOptions struct {
|
||||
// Add future optional parameters here
|
||||
}
|
||||
|
||||
// PingResult holds the result of a [Client.Ping] API call.
|
||||
type PingResult struct {
|
||||
APIVersion string
|
||||
OSType string
|
||||
Experimental bool
|
||||
BuilderVersion build.BuilderVersion
|
||||
|
||||
// SwarmStatus provides information about the current swarm status of the
|
||||
// engine, obtained from the "Swarm" header in the API response.
|
||||
//
|
||||
// It can be a nil struct if the API version does not provide this header
|
||||
// in the ping response, or if an error occurred, in which case the client
|
||||
// should use other ways to get the current swarm status, such as the /swarm
|
||||
// endpoint.
|
||||
SwarmStatus *SwarmStatus
|
||||
}
|
||||
|
||||
// SwarmStatus provides information about the current swarm status and role,
|
||||
// obtained from the "Swarm" header in the API response.
|
||||
type SwarmStatus struct {
|
||||
// NodeState represents the state of the node.
|
||||
NodeState swarm.LocalNodeState
|
||||
|
||||
// ControlAvailable indicates if the node is a swarm manager.
|
||||
ControlAvailable bool
|
||||
}
|
||||
|
||||
// Ping pings the server and returns the value of the "Docker-Experimental",
|
||||
// "Builder-Version", "OS-Type" & "API-Version" headers. It attempts to use
|
||||
// a HEAD request on the endpoint, but falls back to GET if HEAD is not supported
|
||||
@@ -18,13 +49,13 @@ import (
|
||||
// may be returned if the daemon is in an unhealthy state, but returns errors
|
||||
// for other non-success status codes, failing to connect to the API, or failing
|
||||
// to parse the API response.
|
||||
func (cli *Client) Ping(ctx context.Context) (types.Ping, error) {
|
||||
func (cli *Client) Ping(ctx context.Context, options PingOptions) (PingResult, error) {
|
||||
// Using cli.buildRequest() + cli.doRequest() instead of cli.sendRequest()
|
||||
// because ping requests are used during API version negotiation, so we want
|
||||
// to hit the non-versioned /_ping endpoint, not /v1.xx/_ping
|
||||
req, err := cli.buildRequest(ctx, http.MethodHead, path.Join(cli.basePath, "/_ping"), nil, nil)
|
||||
if err != nil {
|
||||
return types.Ping{}, err
|
||||
return PingResult{}, err
|
||||
}
|
||||
resp, err := cli.doRequest(req)
|
||||
defer ensureReaderClosed(resp)
|
||||
@@ -33,7 +64,7 @@ func (cli *Client) Ping(ctx context.Context) (types.Ping, error) {
|
||||
// we got a "OK" (200) status. For non-200 status-codes, we fall
|
||||
// back to doing a GET request, as a HEAD request won't have a
|
||||
// response-body to get error details from.
|
||||
return newPingResponse(resp), nil
|
||||
return newPingResult(resp), nil
|
||||
}
|
||||
|
||||
// HEAD failed or returned a non-OK status; fallback to GET.
|
||||
@@ -42,29 +73,29 @@ func (cli *Client) Ping(ctx context.Context) (types.Ping, error) {
|
||||
defer ensureReaderClosed(resp)
|
||||
if err != nil {
|
||||
// Failed to connect.
|
||||
return types.Ping{}, err
|
||||
return PingResult{}, err
|
||||
}
|
||||
|
||||
// GET request succeeded but may have returned a non-200 status.
|
||||
// Return a Ping response, together with any error returned by
|
||||
// the API server.
|
||||
return newPingResponse(resp), checkResponseErr(resp)
|
||||
return newPingResult(resp), checkResponseErr(resp)
|
||||
}
|
||||
|
||||
func newPingResponse(resp *http.Response) types.Ping {
|
||||
func newPingResult(resp *http.Response) PingResult {
|
||||
if resp == nil {
|
||||
return types.Ping{}
|
||||
return PingResult{}
|
||||
}
|
||||
var swarmStatus *swarm.Status
|
||||
var swarmStatus *SwarmStatus
|
||||
if si := resp.Header.Get("Swarm"); si != "" {
|
||||
state, role, _ := strings.Cut(si, "/")
|
||||
swarmStatus = &swarm.Status{
|
||||
swarmStatus = &SwarmStatus{
|
||||
NodeState: swarm.LocalNodeState(state),
|
||||
ControlAvailable: role == "manager",
|
||||
}
|
||||
}
|
||||
|
||||
return types.Ping{
|
||||
return PingResult{
|
||||
APIVersion: resp.Header.Get("Api-Version"),
|
||||
OSType: resp.Header.Get("Ostype"),
|
||||
Experimental: resp.Header.Get("Docker-Experimental") == "true",
|
||||
|
||||
Reference in New Issue
Block a user