Skip to content

Commit

Permalink
Merge pull request #34767 from dnephin/deprecate-some-client
Browse files Browse the repository at this point in the history
Cleanup client/ interface
  • Loading branch information
dnephin authored Sep 8, 2017
2 parents 8ec484f + 54242cd commit 96255ba
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 113 deletions.
68 changes: 35 additions & 33 deletions client/client.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
/*
Package client is a Go client for the Docker Engine API.
The "docker" command uses this package to communicate with the daemon. It can also
be used by your own Go applications to do anything the command-line interface does
- running containers, pulling images, managing swarms, etc.
For more information about the Engine API, see the documentation:
https://docs.docker.com/engine/reference/api/
Expand Down Expand Up @@ -160,7 +156,7 @@ func NewEnvClient() (*Client, error) {
// highly recommended that you set a version or your client may break if the
// server is upgraded.
func NewClient(host string, version string, client *http.Client, httpHeaders map[string]string) (*Client, error) {
proto, addr, basePath, err := ParseHost(host)
hostURL, err := ParseHostURL(host)
if err != nil {
return nil, err
}
Expand All @@ -171,7 +167,7 @@ func NewClient(host string, version string, client *http.Client, httpHeaders map
}
} else {
transport := new(http.Transport)
sockets.ConfigureTransport(transport, proto, addr)
sockets.ConfigureTransport(transport, hostURL.Scheme, hostURL.Host)
client = &http.Client{
Transport: transport,
CheckRedirect: CheckRedirect,
Expand All @@ -189,28 +185,24 @@ func NewClient(host string, version string, client *http.Client, httpHeaders map
scheme = "https"
}

// TODO: store URL instead of proto/addr/basePath
return &Client{
scheme: scheme,
host: host,
proto: proto,
addr: addr,
basePath: basePath,
proto: hostURL.Scheme,
addr: hostURL.Host,
basePath: hostURL.Path,
client: client,
version: version,
customHTTPHeaders: httpHeaders,
}, nil
}

// Close ensures that transport.Client is closed
// especially needed while using NewClient with *http.Client = nil
// for example
// client.NewClient("unix:///var/run/docker.sock", nil, "v1.18", map[string]string{"User-Agent": "engine-api-cli-1.0"})
// Close the transport used by the client
func (cli *Client) Close() error {

if t, ok := cli.client.Transport.(*http.Transport); ok {
t.CloseIdleConnections()
}

return nil
}

Expand All @@ -234,23 +226,20 @@ func (cli *Client) getAPIPath(p string, query url.Values) string {
return u.String()
}

// ClientVersion returns the version string associated with this
// instance of the Client. Note that this value can be changed
// via the DOCKER_API_VERSION env var.
// This operation doesn't acquire a mutex.
// ClientVersion returns the API version used by this client.
func (cli *Client) ClientVersion() string {
return cli.version
}

// NegotiateAPIVersion updates the version string associated with this
// instance of the Client to match the latest version the server supports
// NegotiateAPIVersion queries the API and updates the version to match the
// API version. Any errors are silently ignored.
func (cli *Client) NegotiateAPIVersion(ctx context.Context) {
ping, _ := cli.Ping(ctx)
cli.NegotiateAPIVersionPing(ping)
}

// NegotiateAPIVersionPing updates the version string associated with this
// instance of the Client to match the latest version the server supports
// NegotiateAPIVersionPing updates the client version to match the Ping.APIVersion
// if the ping version is less than the default version.
func (cli *Client) NegotiateAPIVersionPing(p types.Ping) {
if cli.manualOverride {
return
Expand All @@ -272,34 +261,48 @@ func (cli *Client) NegotiateAPIVersionPing(p types.Ping) {
}
}

// DaemonHost returns the host associated with this instance of the Client.
// This operation doesn't acquire a mutex.
// DaemonHost returns the host address used by the client
func (cli *Client) DaemonHost() string {
return cli.host
}

// ParseHost verifies that the given host strings is valid.
// ParseHost parses a url string, validates the strings is a host url, and returns
// the parsed host as: protocol, address, and base path
// Deprecated: use ParseHostURL
func ParseHost(host string) (string, string, string, error) {
hostURL, err := ParseHostURL(host)
if err != nil {
return "", "", "", err
}
return hostURL.Scheme, hostURL.Host, hostURL.Path, nil
}

// ParseHostURL parses a url string, validates the string is a host url, and
// returns the parsed URL
func ParseHostURL(host string) (*url.URL, error) {
protoAddrParts := strings.SplitN(host, "://", 2)
if len(protoAddrParts) == 1 {
return "", "", "", fmt.Errorf("unable to parse docker host `%s`", host)
return nil, fmt.Errorf("unable to parse docker host `%s`", host)
}

var basePath string
proto, addr := protoAddrParts[0], protoAddrParts[1]
if proto == "tcp" {
parsed, err := url.Parse("tcp://" + addr)
if err != nil {
return "", "", "", err
return nil, err
}
addr = parsed.Host
basePath = parsed.Path
}
return proto, addr, basePath, nil
return &url.URL{
Scheme: proto,
Host: addr,
Path: basePath,
}, nil
}

// CustomHTTPHeaders returns the custom http headers associated with this
// instance of the Client. This operation doesn't acquire a mutex.
// CustomHTTPHeaders returns the custom http headers stored by the client.
func (cli *Client) CustomHTTPHeaders() map[string]string {
m := make(map[string]string)
for k, v := range cli.customHTTPHeaders {
Expand All @@ -308,8 +311,7 @@ func (cli *Client) CustomHTTPHeaders() map[string]string {
return m
}

// SetCustomHTTPHeaders updates the custom http headers associated with this
// instance of the Client. This operation doesn't acquire a mutex.
// SetCustomHTTPHeaders that will be set on every HTTP request made by the client.
func (cli *Client) SetCustomHTTPHeaders(headers map[string]string) {
cli.customHTTPHeaders = headers
}
39 changes: 38 additions & 1 deletion client/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (

"github.com/docker/docker/api"
"github.com/docker/docker/api/types"
"github.com/docker/docker/internal/testutil"
"github.com/stretchr/testify/assert"
)

Expand Down Expand Up @@ -152,7 +153,6 @@ func TestParseHost(t *testing.T) {

for _, cs := range cases {
p, a, b, e := ParseHost(cs.host)
// if we expected an error to be returned...
if cs.err {
assert.Error(t, e)
}
Expand All @@ -162,6 +162,43 @@ func TestParseHost(t *testing.T) {
}
}

func TestParseHostURL(t *testing.T) {
testcases := []struct {
host string
expected *url.URL
expectedErr string
}{
{
host: "",
expectedErr: "unable to parse docker host",
},
{
host: "foobar",
expectedErr: "unable to parse docker host",
},
{
host: "foo://bar",
expected: &url.URL{Scheme: "foo", Host: "bar"},
},
{
host: "tcp://localhost:2476",
expected: &url.URL{Scheme: "tcp", Host: "localhost:2476"},
},
{
host: "tcp://localhost:2476/path",
expected: &url.URL{Scheme: "tcp", Host: "localhost:2476", Path: "/path"},
},
}

for _, testcase := range testcases {
actual, err := ParseHostURL(testcase.host)
if testcase.expectedErr != "" {
testutil.ErrorContains(t, err, testcase.expectedErr)
}
assert.Equal(t, testcase.expected, actual)
}
}

func TestNewEnvClientSetsDefaultVersion(t *testing.T) {
env := envToMap()
defer mapToEnv(env)
Expand Down
24 changes: 22 additions & 2 deletions client/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ type notFound interface {
NotFound() bool // Is the error a NotFound error
}

// IsErrNotFound returns true if the error is caused with an
// object (image, container, network, volume, …) is not found in the docker host.
// IsErrNotFound returns true if the error is a NotFound error, which is returned
// by the API when some object is not found.
func IsErrNotFound(err error) bool {
te, ok := err.(notFound)
return ok && te.NotFound()
Expand All @@ -60,6 +60,8 @@ func (e imageNotFoundError) Error() string {

// IsErrImageNotFound returns true if the error is caused
// when an image is not found in the docker host.
//
// Deprecated: Use IsErrNotFound
func IsErrImageNotFound(err error) bool {
return IsErrNotFound(err)
}
Expand All @@ -81,6 +83,8 @@ func (e containerNotFoundError) Error() string {

// IsErrContainerNotFound returns true if the error is caused
// when a container is not found in the docker host.
//
// Deprecated: Use IsErrNotFound
func IsErrContainerNotFound(err error) bool {
return IsErrNotFound(err)
}
Expand All @@ -102,6 +106,8 @@ func (e networkNotFoundError) Error() string {

// IsErrNetworkNotFound returns true if the error is caused
// when a network is not found in the docker host.
//
// Deprecated: Use IsErrNotFound
func IsErrNetworkNotFound(err error) bool {
return IsErrNotFound(err)
}
Expand All @@ -123,6 +129,8 @@ func (e volumeNotFoundError) Error() string {

// IsErrVolumeNotFound returns true if the error is caused
// when a volume is not found in the docker host.
//
// Deprecated: Use IsErrNotFound
func IsErrVolumeNotFound(err error) bool {
return IsErrNotFound(err)
}
Expand Down Expand Up @@ -161,6 +169,8 @@ func (e nodeNotFoundError) NotFound() bool {

// IsErrNodeNotFound returns true if the error is caused
// when a node is not found.
//
// Deprecated: Use IsErrNotFound
func IsErrNodeNotFound(err error) bool {
_, ok := err.(nodeNotFoundError)
return ok
Expand All @@ -183,6 +193,8 @@ func (e serviceNotFoundError) NotFound() bool {

// IsErrServiceNotFound returns true if the error is caused
// when a service is not found.
//
// Deprecated: Use IsErrNotFound
func IsErrServiceNotFound(err error) bool {
_, ok := err.(serviceNotFoundError)
return ok
Expand All @@ -205,6 +217,8 @@ func (e taskNotFoundError) NotFound() bool {

// IsErrTaskNotFound returns true if the error is caused
// when a task is not found.
//
// Deprecated: Use IsErrNotFound
func IsErrTaskNotFound(err error) bool {
_, ok := err.(taskNotFoundError)
return ok
Expand Down Expand Up @@ -251,6 +265,8 @@ func (e secretNotFoundError) NotFound() bool {

// IsErrSecretNotFound returns true if the error is caused
// when a secret is not found.
//
// Deprecated: Use IsErrNotFound
func IsErrSecretNotFound(err error) bool {
_, ok := err.(secretNotFoundError)
return ok
Expand All @@ -273,6 +289,8 @@ func (e configNotFoundError) NotFound() bool {

// IsErrConfigNotFound returns true if the error is caused
// when a config is not found.
//
// Deprecated: Use IsErrNotFound
func IsErrConfigNotFound(err error) bool {
_, ok := err.(configNotFoundError)
return ok
Expand All @@ -295,6 +313,8 @@ func (e pluginNotFoundError) Error() string {

// IsErrPluginNotFound returns true if the error is caused
// when a plugin is not found in the docker host.
//
// Deprecated: Use IsErrNotFound
func IsErrPluginNotFound(err error) bool {
return IsErrNotFound(err)
}
41 changes: 0 additions & 41 deletions client/parse_logs.go

This file was deleted.

36 changes: 0 additions & 36 deletions client/parse_logs_test.go

This file was deleted.

0 comments on commit 96255ba

Please sign in to comment.