Remove duplicate calls for getting an APIClient

Remove request.SockRequest
Remove request.SockRequestHijack
Remove request.SockRequestRaw()
Remove deprecated ParseHost
Deprecate and unexport more helpers

Signed-off-by: Daniel Nephin <dnephin@docker.com>
This commit is contained in:
Daniel Nephin 2017-09-19 16:12:29 -04:00
parent a68ae4a2d9
commit 0a91ba2d8c
17 changed files with 158 additions and 311 deletions

View File

@ -356,17 +356,6 @@ func (cli *Client) DaemonHost() string {
return cli.host
}
// 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) {

View File

@ -132,32 +132,6 @@ func TestGetAPIPath(t *testing.T) {
}
}
func TestParseHost(t *testing.T) {
cases := []struct {
host string
proto string
addr string
base string
err bool
}{
{"", "", "", "", true},
{"foobar", "", "", "", true},
{"foo://bar", "foo", "bar", "", false},
{"tcp://localhost:2476", "tcp", "localhost:2476", "", false},
{"tcp://localhost:2476/path", "tcp", "localhost:2476", "/path", false},
}
for _, cs := range cases {
p, a, b, e := ParseHost(cs.host)
if cs.err {
assert.Error(t, e)
}
assert.Equal(t, cs.proto, p)
assert.Equal(t, cs.addr, a)
assert.Equal(t, cs.base, b)
}
}
func TestParseHostURL(t *testing.T) {
testcases := []struct {
host string

View File

@ -37,6 +37,7 @@ type CommonAPIClient interface {
NegotiateAPIVersion(ctx context.Context)
NegotiateAPIVersionPing(types.Ping)
DialSession(ctx context.Context, proto string, meta map[string][]string) (net.Conn, error)
Close() error
}
// ContainerAPIClient defines API client methods for the containers

View File

@ -123,10 +123,7 @@ func (cli *Client) sendRequest(ctx context.Context, method, path string, query u
if err != nil {
return resp, err
}
if err := cli.checkResponseErr(resp); err != nil {
return resp, err
}
return resp, nil
return resp, cli.checkResponseErr(resp)
}
func (cli *Client) doRequest(ctx context.Context, req *http.Request) (serverResponse, error) {

View File

@ -9,6 +9,7 @@ import (
"testing"
"github.com/docker/docker/api/types"
"github.com/stretchr/testify/require"
"golang.org/x/net/context"
)
@ -44,10 +45,8 @@ func TestSetHostHeader(t *testing.T) {
}
for c, test := range testCases {
proto, addr, basePath, err := ParseHost(test.host)
if err != nil {
t.Fatal(err)
}
hostURL, err := ParseHostURL(test.host)
require.NoError(t, err)
client := &Client{
client: newMockClient(func(req *http.Request) (*http.Response, error) {
@ -66,15 +65,13 @@ func TestSetHostHeader(t *testing.T) {
}, nil
}),
proto: proto,
addr: addr,
basePath: basePath,
proto: hostURL.Scheme,
addr: hostURL.Host,
basePath: hostURL.Path,
}
_, err = client.sendRequest(context.Background(), "GET", testURL, nil, nil, nil)
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)
}
}

View File

@ -1,7 +1,6 @@
package daemon // import "github.com/docker/docker/integration-cli/daemon"
import (
"bytes"
"encoding/json"
"fmt"
"io"
@ -14,7 +13,6 @@ import (
"strings"
"time"
"github.com/docker/docker/api"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/events"
"github.com/docker/docker/client"
@ -596,28 +594,6 @@ func (d *Daemon) PrependHostArg(args []string) []string {
return append([]string{"--host", d.Sock()}, args...)
}
// SockRequest executes a socket request on a daemon and returns statuscode and output.
func (d *Daemon) SockRequest(method, endpoint string, data interface{}) (int, []byte, error) {
jsonData := bytes.NewBuffer(nil)
if err := json.NewEncoder(jsonData).Encode(data); err != nil {
return -1, nil, err
}
res, body, err := d.SockRequestRaw(method, endpoint, jsonData, "application/json")
if err != nil {
return -1, nil, err
}
b, err := request.ReadBody(body)
return res.StatusCode, b, err
}
// SockRequestRaw executes a socket request on a daemon and returns an http
// response and a reader for the output data.
// Deprecated: use request package instead
func (d *Daemon) SockRequestRaw(method, endpoint string, data io.Reader, ct string) (*http.Response, io.ReadCloser, error) {
return request.SockRequestRaw(method, endpoint, data, ct, d.Sock())
}
// LogFileName returns the path the daemon's log file
func (d *Daemon) LogFileName() string {
return d.logFile.Name()
@ -746,12 +722,9 @@ func (d *Daemon) ReloadConfig() error {
// NewClient creates new client based on daemon's socket path
func (d *Daemon) NewClient() (*client.Client, error) {
httpClient, err := request.NewHTTPClient(d.Sock())
if err != nil {
return nil, err
}
return client.NewClient(d.Sock(), api.DefaultVersion, httpClient, nil)
return client.NewClientWithOpts(
client.FromEnv,
client.WithHost(d.Sock()))
}
// WaitInspectWithArgs waits for the specified expression to be equals to the specified expected string in the given time.

View File

@ -1,18 +1,18 @@
package daemon // import "github.com/docker/docker/integration-cli/daemon"
import (
"encoding/json"
"fmt"
"net/http"
"strings"
"time"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/client"
"github.com/docker/docker/integration-cli/checker"
"github.com/go-check/check"
"github.com/pkg/errors"
"github.com/stretchr/testify/require"
"golang.org/x/net/context"
)
@ -234,31 +234,28 @@ func (d *Swarm) CheckServiceUpdateState(service string) func(*check.C) (interfac
// CheckPluginRunning returns the runtime state of the plugin
func (d *Swarm) CheckPluginRunning(plugin string) func(c *check.C) (interface{}, check.CommentInterface) {
return func(c *check.C) (interface{}, check.CommentInterface) {
status, out, err := d.SockRequest("GET", "/plugins/"+plugin+"/json", nil)
c.Assert(err, checker.IsNil, check.Commentf(string(out)))
if status != http.StatusOK {
return false, nil
apiclient, err := d.NewClient()
require.NoError(c, err)
resp, _, err := apiclient.PluginInspectWithRaw(context.Background(), plugin)
if client.IsErrNotFound(err) {
return false, check.Commentf("%v", err)
}
var p types.Plugin
c.Assert(json.Unmarshal(out, &p), checker.IsNil, check.Commentf(string(out)))
return p.Enabled, check.Commentf("%+v", p)
require.NoError(c, err)
return resp.Enabled, check.Commentf("%+v", resp)
}
}
// CheckPluginImage returns the runtime state of the plugin
func (d *Swarm) CheckPluginImage(plugin string) func(c *check.C) (interface{}, check.CommentInterface) {
return func(c *check.C) (interface{}, check.CommentInterface) {
status, out, err := d.SockRequest("GET", "/plugins/"+plugin+"/json", nil)
c.Assert(err, checker.IsNil, check.Commentf(string(out)))
if status != http.StatusOK {
return false, nil
apiclient, err := d.NewClient()
require.NoError(c, err)
resp, _, err := apiclient.PluginInspectWithRaw(context.Background(), plugin)
if client.IsErrNotFound(err) {
return false, check.Commentf("%v", err)
}
var p types.Plugin
c.Assert(json.Unmarshal(out, &p), checker.IsNil, check.Commentf(string(out)))
return p.PluginReference, check.Commentf("%+v", p)
require.NoError(c, err)
return resp.PluginReference, check.Commentf("%+v", resp)
}
}

View File

@ -4,9 +4,11 @@ import (
"bufio"
"bytes"
"context"
"fmt"
"io"
"net"
"net/http"
"net/http/httputil"
"strings"
"time"
@ -73,10 +75,8 @@ func (s *DockerSuite) TestGetContainersAttachWebsocket(c *check.C) {
// regression gh14320
func (s *DockerSuite) TestPostContainersAttachContainerNotFound(c *check.C) {
client, err := request.NewHTTPClient(daemonHost())
resp, _, err := request.Post("/containers/doesnotexist/attach")
c.Assert(err, checker.IsNil)
req, err := request.New(daemonHost(), "/containers/doesnotexist/attach", request.Method(http.MethodPost))
resp, err := client.Do(req)
// connection will shutdown, err should be "persistent connection closed"
c.Assert(resp.StatusCode, checker.Equals, http.StatusNotFound)
content, err := request.ReadBody(resp.Body)
@ -140,12 +140,12 @@ func (s *DockerSuite) TestPostContainersAttach(c *check.C) {
cid, _ := dockerCmd(c, "run", "-di", "busybox", "cat")
cid = strings.TrimSpace(cid)
// Attach to the container's stdout stream.
conn, br, err := request.SockRequestHijack("POST", "/containers/"+cid+"/attach?stream=1&stdin=1&stdout=1", nil, "text/plain", daemonHost())
conn, br, err := sockRequestHijack("POST", "/containers/"+cid+"/attach?stream=1&stdin=1&stdout=1", nil, "text/plain", daemonHost())
c.Assert(err, checker.IsNil)
// Check if the data from stdout can be received.
expectSuccess(conn, br, "stdout", false)
// Attach to the container's stderr stream.
conn, br, err = request.SockRequestHijack("POST", "/containers/"+cid+"/attach?stream=1&stdin=1&stderr=1", nil, "text/plain", daemonHost())
conn, br, err = sockRequestHijack("POST", "/containers/"+cid+"/attach?stream=1&stdin=1&stderr=1", nil, "text/plain", daemonHost())
c.Assert(err, checker.IsNil)
// Since the container only emits stdout, attaching to stderr should return nothing.
expectTimeout(conn, br, "stdout")
@ -153,10 +153,10 @@ func (s *DockerSuite) TestPostContainersAttach(c *check.C) {
// Test the similar functions of the stderr stream.
cid, _ = dockerCmd(c, "run", "-di", "busybox", "/bin/sh", "-c", "cat >&2")
cid = strings.TrimSpace(cid)
conn, br, err = request.SockRequestHijack("POST", "/containers/"+cid+"/attach?stream=1&stdin=1&stderr=1", nil, "text/plain", daemonHost())
conn, br, err = sockRequestHijack("POST", "/containers/"+cid+"/attach?stream=1&stdin=1&stderr=1", nil, "text/plain", daemonHost())
c.Assert(err, checker.IsNil)
expectSuccess(conn, br, "stderr", false)
conn, br, err = request.SockRequestHijack("POST", "/containers/"+cid+"/attach?stream=1&stdin=1&stdout=1", nil, "text/plain", daemonHost())
conn, br, err = sockRequestHijack("POST", "/containers/"+cid+"/attach?stream=1&stdin=1&stdout=1", nil, "text/plain", daemonHost())
c.Assert(err, checker.IsNil)
expectTimeout(conn, br, "stderr")
@ -164,12 +164,12 @@ func (s *DockerSuite) TestPostContainersAttach(c *check.C) {
cid, _ = dockerCmd(c, "run", "-dit", "busybox", "/bin/sh", "-c", "cat >&2")
cid = strings.TrimSpace(cid)
// Attach to stdout only.
conn, br, err = request.SockRequestHijack("POST", "/containers/"+cid+"/attach?stream=1&stdin=1&stdout=1", nil, "text/plain", daemonHost())
conn, br, err = sockRequestHijack("POST", "/containers/"+cid+"/attach?stream=1&stdin=1&stdout=1", nil, "text/plain", daemonHost())
c.Assert(err, checker.IsNil)
expectSuccess(conn, br, "stdout", true)
// Attach without stdout stream.
conn, br, err = request.SockRequestHijack("POST", "/containers/"+cid+"/attach?stream=1&stdin=1&stderr=1", nil, "text/plain", daemonHost())
conn, br, err = sockRequestHijack("POST", "/containers/"+cid+"/attach?stream=1&stdin=1&stderr=1", nil, "text/plain", daemonHost())
c.Assert(err, checker.IsNil)
// Nothing should be received because both the stdout and stderr of the container will be
// sent to the client as stdout when tty is enabled.
@ -210,3 +210,43 @@ func (s *DockerSuite) TestPostContainersAttach(c *check.C) {
stdcopy.StdCopy(actualStdout, actualStderr, resp.Reader)
c.Assert(actualStdout.Bytes(), checker.DeepEquals, []byte("hello\nsuccess"), check.Commentf("Attach didn't return the expected data from stdout"))
}
// SockRequestHijack creates a connection to specified host (with method, contenttype, …) and returns a hijacked connection
// and the output as a `bufio.Reader`
func sockRequestHijack(method, endpoint string, data io.Reader, ct string, daemon string, modifiers ...func(*http.Request)) (net.Conn, *bufio.Reader, error) {
req, client, err := newRequestClient(method, endpoint, data, ct, daemon, modifiers...)
if err != nil {
return nil, nil, err
}
client.Do(req)
conn, br := client.Hijack()
return conn, br, nil
}
// FIXME(vdemeester) httputil.ClientConn is deprecated, use http.Client instead (closer to actual client)
// Deprecated: Use New instead of NewRequestClient
// Deprecated: use request.Do (or Get, Delete, Post) instead
func newRequestClient(method, endpoint string, data io.Reader, ct, daemon string, modifiers ...func(*http.Request)) (*http.Request, *httputil.ClientConn, error) {
c, err := request.SockConn(time.Duration(10*time.Second), daemon)
if err != nil {
return nil, nil, fmt.Errorf("could not dial docker daemon: %v", err)
}
client := httputil.NewClientConn(c, nil)
req, err := http.NewRequest(method, endpoint, data)
if err != nil {
client.Close()
return nil, nil, fmt.Errorf("could not create new request: %v", err)
}
for _, opt := range modifiers {
opt(req)
}
if ct != "" {
req.Header.Set("Content-Type", ct)
}
return req, client, nil
}

View File

@ -319,8 +319,7 @@ func (s *DockerSuite) TestBuildOnBuildCache(c *check.C) {
assert.Len(c, imageIDs, 2)
parentID, childID := imageIDs[0], imageIDs[1]
client, err := request.NewClient()
require.NoError(c, err)
client := testEnv.APIClient()
// check parentID is correct
image, _, err := client.ImageInspectWithRaw(context.Background(), childID)
@ -329,12 +328,11 @@ func (s *DockerSuite) TestBuildOnBuildCache(c *check.C) {
}
func (s *DockerRegistrySuite) TestBuildCopyFromForcePull(c *check.C) {
client, err := request.NewClient()
require.NoError(c, err)
client := testEnv.APIClient()
repoName := fmt.Sprintf("%v/dockercli/busybox", privateRegistryURL)
// tag the image to upload it to the private registry
err = client.ImageTag(context.TODO(), "busybox", repoName)
err := client.ImageTag(context.TODO(), "busybox", repoName)
assert.Nil(c, err)
// push the image to the registry
rc, err := client.ImagePush(context.TODO(), repoName, types.ImagePushOptions{RegistryAuth: "{}"})
@ -545,9 +543,7 @@ func (s *DockerSuite) TestBuildWithSession(c *check.C) {
assert.Equal(c, strings.Count(out, "Using cache"), 2)
assert.Contains(c, out, "contentcontent")
client, err := request.NewClient()
require.NoError(c, err)
client := testEnv.APIClient()
du, err := client.DiskUsage(context.TODO())
assert.Nil(c, err)
assert.True(c, du.BuilderSize > 10)
@ -582,9 +578,7 @@ func (s *DockerSuite) TestBuildWithSession(c *check.C) {
}
func testBuildWithSession(c *check.C, dir, dockerfile string) (outStr string) {
client, err := request.NewClient()
require.NoError(c, err)
client := testEnv.APIClient()
sess, err := session.NewSession("foo1", "foo")
assert.Nil(c, err)

View File

@ -6,13 +6,16 @@ import (
"fmt"
"io/ioutil"
"math/rand"
"net/http"
"strings"
winio "github.com/Microsoft/go-winio"
"github.com/docker/docker/integration-cli/checker"
"github.com/docker/docker/integration-cli/request"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/mount"
"github.com/go-check/check"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"golang.org/x/net/context"
)
func (s *DockerSuite) TestContainersAPICreateMountsBindNamedPipe(c *check.C) {
@ -44,28 +47,30 @@ func (s *DockerSuite) TestContainersAPICreateMountsBindNamedPipe(c *check.C) {
containerPipeName := `\\.\pipe\docker-cli-test-pipe`
text := "hello from a pipe"
cmd := fmt.Sprintf("echo %s > %s", text, containerPipeName)
name := "test-bind-npipe"
data := map[string]interface{}{
"Image": testEnv.PlatformDefaults.BaseImage,
"Cmd": []string{"cmd", "/c", cmd},
"HostConfig": map[string]interface{}{"Mounts": []map[string]interface{}{{"Type": "npipe", "Source": hostPipeName, "Target": containerPipeName}}},
}
status, resp, err := request.SockRequest("POST", "/containers/create?name="+name, data, daemonHost())
c.Assert(err, checker.IsNil, check.Commentf(string(resp)))
c.Assert(status, checker.Equals, http.StatusCreated, check.Commentf(string(resp)))
ctx := context.Background()
client := testEnv.APIClient()
_, err = client.ContainerCreate(ctx,
&container.Config{
Image: testEnv.PlatformDefaults.BaseImage,
Cmd: []string{"cmd", "/c", cmd},
}, &container.HostConfig{
Mounts: []mount.Mount{
{
Type: "npipe",
Source: hostPipeName,
Target: containerPipeName,
},
},
},
nil, name)
require.NoError(c, err)
status, _, err = request.SockRequest("POST", "/containers/"+name+"/start", nil, daemonHost())
c.Assert(err, checker.IsNil)
c.Assert(status, checker.Equals, http.StatusNoContent)
err = client.ContainerStart(ctx, name, types.ContainerStartOptions{})
require.NoError(c, err)
err = <-ch
if err != nil {
c.Fatal(err)
}
result := strings.TrimSpace(string(b))
if result != text {
c.Errorf("expected pipe to contain %s, got %s", text, result)
}
require.NoError(c, err)
assert.Equal(c, text, strings.TrimSpace(string(b)))
}

View File

@ -59,7 +59,7 @@ func (s *DockerSuite) TestExecResizeImmediatelyAfterExecStart(c *check.C) {
}
payload := bytes.NewBufferString(`{"Tty":true}`)
conn, _, err := request.SockRequestHijack("POST", fmt.Sprintf("/exec/%s/start", execID), payload, "application/json", daemonHost())
conn, _, err := sockRequestHijack("POST", fmt.Sprintf("/exec/%s/start", execID), payload, "application/json", daemonHost())
if err != nil {
return fmt.Errorf("Failed to start the exec: %q", err.Error())
}

View File

@ -157,33 +157,21 @@ func (s *DockerSuite) TestAPIImagesSearchJSONContentType(c *check.C) {
// Test case for 30027: image size reported as -1 in v1.12 client against v1.13 daemon.
// This test checks to make sure both v1.12 and v1.13 client against v1.13 daemon get correct `Size` after the fix.
func (s *DockerSuite) TestAPIImagesSizeCompatibility(c *check.C) {
cli, err := client.NewEnvClient()
c.Assert(err, checker.IsNil)
defer cli.Close()
apiclient := testEnv.APIClient()
defer apiclient.Close()
images, err := cli.ImageList(context.Background(), types.ImageListOptions{})
images, err := apiclient.ImageList(context.Background(), types.ImageListOptions{})
c.Assert(err, checker.IsNil)
c.Assert(len(images), checker.Not(checker.Equals), 0)
for _, image := range images {
c.Assert(image.Size, checker.Not(checker.Equals), int64(-1))
}
type v124Image struct {
ID string `json:"Id"`
ParentID string `json:"ParentId"`
RepoTags []string
RepoDigests []string
Created int64
Size int64
VirtualSize int64
Labels map[string]string
}
cli, err = client.NewClientWithOpts(client.FromEnv, client.WithVersion("v1.24"))
apiclient, err = client.NewClientWithOpts(client.FromEnv, client.WithVersion("v1.24"))
c.Assert(err, checker.IsNil)
defer cli.Close()
defer apiclient.Close()
v124Images, err := cli.ImageList(context.Background(), types.ImageListOptions{})
v124Images, err := apiclient.ImageList(context.Background(), types.ImageListOptions{})
c.Assert(err, checker.IsNil)
c.Assert(len(v124Images), checker.Not(checker.Equals), 0)
for _, image := range v124Images {

View File

@ -12,7 +12,6 @@ import (
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/integration-cli/checker"
"github.com/docker/docker/integration-cli/cli"
"github.com/docker/docker/integration-cli/request"
"github.com/go-check/check"
"golang.org/x/net/context"
)
@ -59,8 +58,7 @@ func testIpcNonePrivateShareable(c *check.C, mode string, mustBeMounted bool, mu
}
ctx := context.Background()
client, err := request.NewClient()
c.Assert(err, checker.IsNil)
client := testEnv.APIClient()
resp, err := client.ContainerCreate(ctx, &cfg, &hostCfg, nil, "")
c.Assert(err, checker.IsNil)
@ -125,8 +123,7 @@ func testIpcContainer(s *DockerSuite, c *check.C, donorMode string, mustWork boo
}
ctx := context.Background()
client, err := request.NewClient()
c.Assert(err, checker.IsNil)
client := testEnv.APIClient()
// create and start the "donor" container
resp, err := client.ContainerCreate(ctx, &cfg, &hostCfg, nil, "")
@ -195,9 +192,7 @@ func (s *DockerSuite) TestAPIIpcModeHost(c *check.C) {
}
ctx := context.Background()
client, err := request.NewClient()
c.Assert(err, checker.IsNil)
client := testEnv.APIClient()
resp, err := client.ContainerCreate(ctx, &cfg, &hostCfg, nil, "")
c.Assert(err, checker.IsNil)
c.Assert(len(resp.Warnings), checker.Equals, 0)

View File

@ -3,12 +3,10 @@
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"net"
"net/http"
"net/url"
"os"
"path/filepath"
"strings"
@ -21,11 +19,14 @@ import (
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/client"
"github.com/docker/docker/integration-cli/checker"
"github.com/docker/docker/integration-cli/daemon"
"github.com/docker/docker/integration-cli/request"
"github.com/docker/swarmkit/ca"
"github.com/go-check/check"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"golang.org/x/net/context"
)
@ -1006,32 +1007,19 @@ func (s *DockerSwarmSuite) TestSwarmRepeatedRootRotation(c *check.C) {
func (s *DockerSwarmSuite) TestAPINetworkInspectWithScope(c *check.C) {
d := s.AddDaemon(c, true, true)
name := "foo"
networkCreateRequest := types.NetworkCreateRequest{
Name: name,
}
name := "test-scoped-network"
ctx := context.Background()
apiclient, err := d.NewClient()
require.NoError(c, err)
var n types.NetworkCreateResponse
networkCreateRequest.NetworkCreate.Driver = "overlay"
resp, err := apiclient.NetworkCreate(ctx, name, types.NetworkCreate{Driver: "overlay"})
require.NoError(c, err)
status, out, err := d.SockRequest("POST", "/networks/create", networkCreateRequest)
c.Assert(err, checker.IsNil, check.Commentf(string(out)))
c.Assert(status, checker.Equals, http.StatusCreated, check.Commentf(string(out)))
c.Assert(json.Unmarshal(out, &n), checker.IsNil)
network, err := apiclient.NetworkInspect(ctx, name, types.NetworkInspectOptions{})
require.NoError(c, err)
assert.Equal(c, "swarm", network.Scope)
assert.Equal(c, resp.ID, network.ID)
var r types.NetworkResource
status, body, err := d.SockRequest("GET", "/networks/"+name, nil)
c.Assert(err, checker.IsNil, check.Commentf(string(out)))
c.Assert(status, checker.Equals, http.StatusOK, check.Commentf(string(out)))
c.Assert(json.Unmarshal(body, &r), checker.IsNil)
c.Assert(r.Scope, checker.Equals, "swarm")
c.Assert(r.ID, checker.Equals, n.ID)
v := url.Values{}
v.Set("scope", "local")
status, _, err = d.SockRequest("GET", "/networks/"+name+"?"+v.Encode(), nil)
c.Assert(err, checker.IsNil, check.Commentf(string(out)))
c.Assert(status, checker.Equals, http.StatusNotFound, check.Commentf(string(out)))
_, err = apiclient.NetworkInspect(ctx, name, types.NetworkInspectOptions{Scope: "local"})
assert.True(c, client.IsErrNotFound(err))
}

View File

@ -15,7 +15,6 @@ import (
"github.com/docker/docker/integration-cli/cli"
"github.com/docker/docker/integration-cli/daemon"
"github.com/docker/docker/integration-cli/fixtures/plugin"
"github.com/docker/docker/integration-cli/request"
"github.com/go-check/check"
"github.com/gotestyourself/gotestyourself/icmd"
"golang.org/x/net/context"
@ -159,9 +158,7 @@ func (s *DockerSuite) TestPluginInstallDisableVolumeLs(c *check.C) {
}
func (ps *DockerPluginSuite) TestPluginSet(c *check.C) {
// Create a new plugin with extra settings
client, err := request.NewClient()
c.Assert(err, checker.IsNil, check.Commentf("failed to create test client"))
client := testEnv.APIClient()
name := "test"
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
@ -171,7 +168,8 @@ func (ps *DockerPluginSuite) TestPluginSet(c *check.C) {
mntSrc := "foo"
devPath := "/dev/bar"
err = plugin.Create(ctx, client, name, func(cfg *plugin.Config) {
// Create a new plugin with extra settings
err := plugin.Create(ctx, client, name, func(cfg *plugin.Config) {
cfg.Env = []types.PluginEnv{{Name: "DEBUG", Value: &initialValue, Settable: []string{"value"}}}
cfg.Mounts = []types.PluginMount{
{Name: "pmount1", Settable: []string{"source"}, Type: "none", Source: &mntSrc},
@ -401,12 +399,11 @@ func (s *DockerTrustSuite) TestPluginUntrustedInstall(c *check.C) {
func (ps *DockerPluginSuite) TestPluginIDPrefix(c *check.C) {
name := "test"
client, err := request.NewClient()
c.Assert(err, checker.IsNil, check.Commentf("error creating test client"))
client := testEnv.APIClient()
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
initialValue := "0"
err = plugin.Create(ctx, client, name, func(cfg *plugin.Config) {
err := plugin.Create(ctx, client, name, func(cfg *plugin.Config) {
cfg.Env = []types.PluginEnv{{Name: "DEBUG", Value: &initialValue, Settable: []string{"value"}}}
})
cancel()
@ -466,8 +463,7 @@ func (ps *DockerPluginSuite) TestPluginListDefaultFormat(c *check.C) {
c.Assert(err, check.IsNil)
name := "test:latest"
client, err := request.NewClient()
c.Assert(err, checker.IsNil, check.Commentf("error creating test client"))
client := testEnv.APIClient()
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
defer cancel()

View File

@ -1,16 +1,13 @@
package request // import "github.com/docker/docker/integration-cli/request"
import (
"bufio"
"bytes"
"crypto/tls"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"net"
"net/http"
"net/http/httputil"
"net/url"
"os"
"path/filepath"
@ -95,11 +92,11 @@ func Do(endpoint string, modifiers ...func(*http.Request) error) (*http.Response
// DoOnHost creates and execute a request on the specified host and endpoint, with the specified request modifiers
func DoOnHost(host, endpoint string, modifiers ...func(*http.Request) error) (*http.Response, io.ReadCloser, error) {
req, err := New(host, endpoint, modifiers...)
req, err := newRequest(host, endpoint, modifiers...)
if err != nil {
return nil, nil, err
}
client, err := NewHTTPClient(host)
client, err := newHTTPClient(host)
if err != nil {
return nil, nil, err
}
@ -114,18 +111,15 @@ func DoOnHost(host, endpoint string, modifiers ...func(*http.Request) error) (*h
return resp, body, err
}
// New creates a new http Request to the specified host and endpoint, with the specified request modifiers
func New(host, endpoint string, modifiers ...func(*http.Request) error) (*http.Request, error) {
_, addr, _, err := dclient.ParseHost(host)
// newRequest creates a new http Request to the specified host and endpoint, with the specified request modifiers
func newRequest(host, endpoint string, modifiers ...func(*http.Request) error) (*http.Request, error) {
hostUrl, err := dclient.ParseHostURL(host)
if err != nil {
return nil, err
}
if err != nil {
return nil, errors.Wrapf(err, "could not parse url %q", host)
return nil, errors.Wrapf(err, "failed parsing url %q", host)
}
req, err := http.NewRequest("GET", endpoint, nil)
if err != nil {
return nil, fmt.Errorf("could not create new request: %v", err)
return nil, errors.Wrap(err, "failed to create request")
}
if os.Getenv("DOCKER_TLS_VERIFY") != "" {
@ -133,7 +127,7 @@ func New(host, endpoint string, modifiers ...func(*http.Request) error) (*http.R
} else {
req.URL.Scheme = "http"
}
req.URL.Host = addr
req.URL.Host = hostUrl.Host
for _, config := range modifiers {
if err := config(req); err != nil {
@ -143,15 +137,16 @@ func New(host, endpoint string, modifiers ...func(*http.Request) error) (*http.R
return req, nil
}
// NewHTTPClient creates an http client for the specific host
func NewHTTPClient(host string) (*http.Client, error) {
// newHTTPClient creates an http client for the specific host
// TODO: Share more code with client.defaultHTTPClient
func newHTTPClient(host string) (*http.Client, error) {
// FIXME(vdemeester) 10*time.Second timeout of SockRequest… ?
proto, addr, _, err := dclient.ParseHost(host)
hostUrl, err := dclient.ParseHostURL(host)
if err != nil {
return nil, err
}
transport := new(http.Transport)
if proto == "tcp" && os.Getenv("DOCKER_TLS_VERIFY") != "" {
if hostUrl.Scheme == "tcp" && os.Getenv("DOCKER_TLS_VERIFY") != "" {
// Setup the socket TLS configuration.
tlsConfig, err := getTLSConfig()
if err != nil {
@ -160,102 +155,22 @@ func NewHTTPClient(host string) (*http.Client, error) {
transport = &http.Transport{TLSClientConfig: tlsConfig}
}
transport.DisableKeepAlives = true
err = sockets.ConfigureTransport(transport, proto, addr)
return &http.Client{
Transport: transport,
}, err
err = sockets.ConfigureTransport(transport, hostUrl.Scheme, hostUrl.Host)
return &http.Client{Transport: transport}, err
}
// NewClient returns a new Docker API client
// Deprecated: Use Execution.APIClient()
func NewClient() (dclient.APIClient, error) {
return dclient.NewClientWithOpts(dclient.WithHost(DaemonHost()))
}
// FIXME(vdemeester) httputil.ClientConn is deprecated, use http.Client instead (closer to actual client)
// Deprecated: Use New instead of NewRequestClient
// Deprecated: use request.Do (or Get, Delete, Post) instead
func newRequestClient(method, endpoint string, data io.Reader, ct, daemon string, modifiers ...func(*http.Request)) (*http.Request, *httputil.ClientConn, error) {
c, err := SockConn(time.Duration(10*time.Second), daemon)
if err != nil {
return nil, nil, fmt.Errorf("could not dial docker daemon: %v", err)
}
client := httputil.NewClientConn(c, nil)
req, err := http.NewRequest(method, endpoint, data)
if err != nil {
client.Close()
return nil, nil, fmt.Errorf("could not create new request: %v", err)
}
for _, opt := range modifiers {
opt(req)
}
if ct != "" {
req.Header.Set("Content-Type", ct)
}
return req, client, nil
}
// SockRequest create a request against the specified host (with method, endpoint and other request modifier) and
// returns the status code, and the content as an byte slice
// Deprecated: use request.Do instead
func SockRequest(method, endpoint string, data interface{}, daemon string, modifiers ...func(*http.Request)) (int, []byte, error) {
jsonData := bytes.NewBuffer(nil)
if err := json.NewEncoder(jsonData).Encode(data); err != nil {
return -1, nil, err
}
res, body, err := SockRequestRaw(method, endpoint, jsonData, "application/json", daemon, modifiers...)
if err != nil {
return -1, nil, err
}
b, err := ReadBody(body)
return res.StatusCode, b, err
}
// ReadBody read the specified ReadCloser content and returns it
func ReadBody(b io.ReadCloser) ([]byte, error) {
defer b.Close()
return ioutil.ReadAll(b)
}
// SockRequestRaw create a request against the specified host (with method, endpoint and other request modifier) and
// returns the http response, the output as a io.ReadCloser
// Deprecated: use request.Do (or Get, Delete, Post) instead
func SockRequestRaw(method, endpoint string, data io.Reader, ct, daemon string, modifiers ...func(*http.Request)) (*http.Response, io.ReadCloser, error) {
req, client, err := newRequestClient(method, endpoint, data, ct, daemon, modifiers...)
if err != nil {
return nil, nil, err
}
resp, err := client.Do(req)
if err != nil {
client.Close()
return resp, nil, err
}
body := ioutils.NewReadCloserWrapper(resp.Body, func() error {
defer resp.Body.Close()
return client.Close()
})
return resp, body, err
}
// SockRequestHijack creates a connection to specified host (with method, contenttype, …) and returns a hijacked connection
// and the output as a `bufio.Reader`
func SockRequestHijack(method, endpoint string, data io.Reader, ct string, daemon string, modifiers ...func(*http.Request)) (net.Conn, *bufio.Reader, error) {
req, client, err := newRequestClient(method, endpoint, data, ct, daemon, modifiers...)
if err != nil {
return nil, nil, err
}
client.Do(req)
conn, br := client.Hijack()
return conn, br, nil
}
// SockConn opens a connection on the specified socket
func SockConn(timeout time.Duration, daemon string) (net.Conn, error) {
daemonURL, err := url.Parse(daemon)

View File

@ -17,7 +17,6 @@ import (
"github.com/docker/docker/integration-cli/checker"
"github.com/docker/docker/integration-cli/cli"
"github.com/docker/docker/integration-cli/fixtures/plugin"
"github.com/docker/docker/integration-cli/request"
"github.com/docker/go-connections/tlsconfig"
"github.com/go-check/check"
"github.com/gotestyourself/gotestyourself/icmd"
@ -230,11 +229,10 @@ func (s *DockerTrustSuite) setupTrustedImage(c *check.C, name string) string {
func (s *DockerTrustSuite) setupTrustedplugin(c *check.C, source, name string) string {
repoName := fmt.Sprintf("%v/dockercli/%s:latest", privateRegistryURL, name)
client, err := request.NewClient()
c.Assert(err, checker.IsNil, check.Commentf("could not create test client"))
client := testEnv.APIClient()
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
err = plugin.Create(ctx, client, repoName)
err := plugin.Create(ctx, client, repoName)
cancel()
c.Assert(err, checker.IsNil, check.Commentf("could not create test plugin"))