bump(github.com/fsouza/go-dockerclient): a735a3dbbfdd1822886f6b4235318c8809b41538

pull/6/head
Brendan Burns 2014-06-16 14:49:30 -07:00
parent b1531bbcf5
commit 5d2eb7dfff
12 changed files with 517 additions and 48 deletions

View File

@ -4,6 +4,7 @@ Andrews Medina <andrewsmedina@gmail.com>
Andy Goldstein <andy.goldstein@redhat.com>
Ben McCann <benmccann.com>
Cezar Sa Espinola <cezar.sa@corp.globo.com>
Cheah Chu Yeow <chuyeow@gmail.com>
cheneydeng <cheneydeng@qq.com>
Ed <edrocksit@gmail.com>
Eric Anderson <anderson@copperegg.com>
@ -14,6 +15,7 @@ Jean-Baptiste Dalido <jeanbaptiste@appgratis.com>
Jeff Mitchell <jeffrey.mitchell@gmail.com>
Jeffrey Hulten <jhulten@gmail.com>
Lucas Clemente <lucas@clemente.io>
Omeid Matten <public@omeid.me>
Paul Morie <pmorie@gmail.com>
Peter Jihoon Kim <raingrove@gmail.com>
Philippe Lafoucrière <philippe.lafoucriere@tech-angels.com>

View File

@ -12,7 +12,6 @@ import (
"encoding/json"
"errors"
"fmt"
"github.com/fsouza/go-dockerclient/utils"
"io"
"io/ioutil"
"net"
@ -23,6 +22,8 @@ import (
"strconv"
"strings"
"sync"
"github.com/fsouza/go-dockerclient/utils"
)
const userAgent = "go-dockerclient"
@ -33,32 +34,194 @@ var (
// ErrConnectionRefused is returned when the client cannot connect to the given endpoint.
ErrConnectionRefused = errors.New("cannot connect to Docker endpoint")
apiVersion_1_12, _ = NewApiVersion("1.12")
)
// ApiVersion is an internal representation of a version of the Remote API.
type ApiVersion []int
// NewApiVersion returns an instance of ApiVersion for the given string.
//
// The given string must be in the form <major>.<minor>.<patch>, where <major>,
// <minor> and <patch> are integer numbers.
func NewApiVersion(input string) (ApiVersion, error) {
if !strings.Contains(input, ".") {
return nil, fmt.Errorf("Unable to parse version '%s'", input)
}
arr := strings.Split(input, ".")
ret := make(ApiVersion, len(arr))
var err error
for i, val := range arr {
ret[i], err = strconv.Atoi(val)
if err != nil {
return nil, err
}
}
return ret, nil
}
func (version ApiVersion) String() string {
var str string
for i, val := range version {
str += strconv.Itoa(val)
if i < len(version)-1 {
str += "."
}
}
return str
}
func (version ApiVersion) LessThan(other ApiVersion) bool {
return version.compare(other) < 0
}
func (version ApiVersion) LessThanOrEqualTo(other ApiVersion) bool {
return version.compare(other) <= 0
}
func (version ApiVersion) GreaterThan(other ApiVersion) bool {
return version.compare(other) > 0
}
func (version ApiVersion) GreaterThanOrEqualTo(other ApiVersion) bool {
return version.compare(other) >= 0
}
func (version ApiVersion) compare(other ApiVersion) int {
for i, v := range version {
if i <= len(other)-1 {
otherVersion := other[i]
if v < otherVersion {
return -1
} else if v > otherVersion {
return 1
}
}
}
if len(version) > len(other) {
return 1
}
if len(version) < len(other) {
return -1
}
return 0
}
// Client is the basic type of this package. It provides methods for
// interaction with the API.
type Client struct {
endpoint string
endpointURL *url.URL
eventMonitor *eventMonitoringState
client *http.Client
SkipServerVersionCheck bool
endpoint string
endpointURL *url.URL
eventMonitor *eventMonitoringState
client *http.Client
requestedApiVersion ApiVersion
serverApiVersion ApiVersion
expectedApiVersion ApiVersion
}
// NewClient returns a Client instance ready for communication with the
// given server endpoint.
// NewClient returns a Client instance ready for communication with the given
// server endpoint. It will use the latest remote API version available in the
// server.
func NewClient(endpoint string) (*Client, error) {
client, err := NewVersionedClient(endpoint, "")
if err != nil {
return nil, err
}
client.SkipServerVersionCheck = true
return client, nil
}
// NewVersionedClient returns a Client instance ready for communication with
// the given server endpoint, using a specific remote API version.
func NewVersionedClient(endpoint string, apiVersionString string) (*Client, error) {
u, err := parseEndpoint(endpoint)
if err != nil {
return nil, err
}
var requestedApiVersion ApiVersion
if strings.Contains(apiVersionString, ".") {
requestedApiVersion, err = NewApiVersion(apiVersionString)
if err != nil {
return nil, err
}
}
return &Client{
endpoint: endpoint,
endpointURL: u,
client: http.DefaultClient,
eventMonitor: new(eventMonitoringState),
endpoint: endpoint,
endpointURL: u,
client: http.DefaultClient,
eventMonitor: new(eventMonitoringState),
requestedApiVersion: requestedApiVersion,
}, nil
}
func (c *Client) checkApiVersion() error {
serverApiVersionString, err := c.getServerApiVersionString()
if err != nil {
return err
}
c.serverApiVersion, err = NewApiVersion(serverApiVersionString)
if err != nil {
return err
}
if c.requestedApiVersion == nil {
c.expectedApiVersion = c.serverApiVersion
} else {
c.expectedApiVersion = c.requestedApiVersion
}
return nil
}
func parseApiVersionString(input string) (version uint16, err error) {
version = 0
if !strings.Contains(input, ".") {
return 0, fmt.Errorf("Unable to parse version '%s'", input)
}
arr := strings.Split(input, ".")
major, err := strconv.Atoi(arr[0])
if err != nil {
return version, err
}
minor, err := strconv.Atoi(arr[1])
if err != nil {
return version, err
}
version = uint16(major)<<8 | uint16(minor)
return version, nil
}
func (c *Client) getServerApiVersionString() (version string, err error) {
body, status, err := c.do("GET", "/version", nil)
if err != nil {
return "", err
}
if status != http.StatusOK {
return "", fmt.Errorf("Received unexpected status %d while trying to retrieve the server version", status)
}
var versionResponse map[string]string
err = json.Unmarshal(body, &versionResponse)
if err != nil {
return "", err
}
version = versionResponse["ApiVersion"]
return version, nil
}
func (c *Client) do(method, path string, data interface{}) ([]byte, int, error) {
var params io.Reader
if data != nil {
@ -68,6 +231,14 @@ func (c *Client) do(method, path string, data interface{}) ([]byte, int, error)
}
params = bytes.NewBuffer(buf)
}
if path != "/version" && !c.SkipServerVersionCheck && c.expectedApiVersion == nil {
err := c.checkApiVersion()
if err != nil {
return nil, -1, err
}
}
req, err := http.NewRequest(method, c.getURL(path), params)
if err != nil {
return nil, -1, err
@ -88,6 +259,9 @@ func (c *Client) do(method, path string, data interface{}) ([]byte, int, error)
}
clientconn := httputil.NewClientConn(dial, nil)
resp, err = clientconn.Do(req)
if err != nil {
return nil, -1, err
}
defer clientconn.Close()
} else {
resp, err = c.client.Do(req)
@ -113,6 +287,13 @@ func (c *Client) stream(method, path string, headers map[string]string, in io.Re
if (method == "POST" || method == "PUT") && in == nil {
in = bytes.NewReader(nil)
}
if path != "/version" && !c.SkipServerVersionCheck && c.expectedApiVersion == nil {
err := c.checkApiVersion()
if err != nil {
return err
}
}
req, err := http.NewRequest(method, c.getURL(path), in)
if err != nil {
return err
@ -183,7 +364,13 @@ func (c *Client) stream(method, path string, headers map[string]string, in io.Re
return nil
}
func (c *Client) hijack(method, path string, success chan struct{}, in io.Reader, errStream io.Writer, out io.Writer) error {
func (c *Client) hijack(method, path string, success chan struct{}, setRawTerminal bool, in io.Reader, stderr, stdout io.Writer) error {
if path != "/version" && !c.SkipServerVersionCheck && c.expectedApiVersion == nil {
err := c.checkApiVersion()
if err != nil {
return err
}
}
req, err := http.NewRequest(method, c.getURL(path), nil)
if err != nil {
return err
@ -212,10 +399,10 @@ func (c *Client) hijack(method, path string, success chan struct{}, in io.Reader
errs := make(chan error, 2)
go func() {
var err error
if in != nil {
_, err = io.Copy(out, br)
if setRawTerminal {
_, err = io.Copy(stdout, br)
} else {
_, err = utils.StdCopy(out, errStream, br)
_, err = utils.StdCopy(stdout, stderr, br)
}
errs <- err
wg.Done()
@ -244,7 +431,12 @@ func (c *Client) getURL(path string) string {
if c.endpointURL.Scheme == "unix" {
urlStr = ""
}
return fmt.Sprintf("%s%s", urlStr, path)
if c.requestedApiVersion != nil {
return fmt.Sprintf("%s/v%s%s", urlStr, c.requestedApiVersion, path)
} else {
return fmt.Sprintf("%s%s", urlStr, path)
}
}
type jsonMessage struct {

View File

@ -37,7 +37,32 @@ func TestNewAPIClient(t *testing.T) {
if client.endpoint != endpoint {
t.Errorf("Expected endpoint %s. Got %s.", endpoint, client.endpoint)
}
if !client.SkipServerVersionCheck {
t.Error("Expected SkipServerVersionCheck to be true, got false")
}
if client.requestedApiVersion != nil {
t.Errorf("Expected requestedApiVersion to be nil, got %#v.", client.requestedApiVersion)
}
}
func TestNewVersionedClient(t *testing.T) {
endpoint := "http://localhost:4243"
client, err := NewVersionedClient(endpoint, "1.12")
if err != nil {
t.Fatal(err)
}
if client.endpoint != endpoint {
t.Errorf("Expected endpoint %s. Got %s.", endpoint, client.endpoint)
}
if client.client != http.DefaultClient {
t.Errorf("Expected http.Client %#v. Got %#v.", http.DefaultClient, client.client)
}
if reqVersion := client.requestedApiVersion.String(); reqVersion != "1.12" {
t.Errorf("Wrong requestApiVersion. Want %q. Got %q.", "1.12", reqVersion)
}
if client.SkipServerVersionCheck {
t.Error("Expected SkipServerVersionCheck to be false, got true")
}
}
func TestNewClientInvalidEndpoint(t *testing.T) {
@ -73,6 +98,7 @@ func TestGetURL(t *testing.T) {
for _, tt := range tests {
client, _ := NewClient(tt.endpoint)
client.endpoint = tt.endpoint
client.SkipServerVersionCheck = true
got := client.getURL(tt.path)
if got != tt.expected {
t.Errorf("getURL(%q): Got %s. Want %s.", tt.path, got, tt.expected)
@ -122,6 +148,50 @@ func TestQueryString(t *testing.T) {
}
}
func TestApiVersions(t *testing.T) {
var tests = []struct {
a string
b string
expectedALessThanB bool
expectedALessThanOrEqualToB bool
expectedAGreaterThanB bool
expectedAGreaterThanOrEqualToB bool
}{
{"1.11", "1.11", false, true, false, true},
{"1.10", "1.11", true, true, false, false},
{"1.11", "1.10", false, false, true, true},
{"1.9", "1.11", true, true, false, false},
{"1.11", "1.9", false, false, true, true},
{"1.1.1", "1.1", false, false, true, true},
{"1.1", "1.1.1", true, true, false, false},
{"2.1", "1.1.1", false, false, true, true},
{"2.1", "1.3.1", false, false, true, true},
{"1.1.1", "2.1", true, true, false, false},
{"1.3.1", "2.1", true, true, false, false},
}
for _, tt := range tests {
a, _ := NewApiVersion(tt.a)
b, _ := NewApiVersion(tt.b)
if tt.expectedALessThanB && !a.LessThan(b) {
t.Errorf("Expected %#v < %#v", a, b)
}
if tt.expectedALessThanOrEqualToB && !a.LessThanOrEqualTo(b) {
t.Errorf("Expected %#v <= %#v", a, b)
}
if tt.expectedAGreaterThanB && !a.GreaterThan(b) {
t.Errorf("Expected %#v > %#v", a, b)
}
if tt.expectedAGreaterThanOrEqualToB && !a.GreaterThanOrEqualTo(b) {
t.Errorf("Expected %#v >= %#v", a, b)
}
}
}
type FakeRoundTripper struct {
message string
status int

View File

@ -175,7 +175,7 @@ type Config struct {
StdinOnce bool
Env []string
Cmd []string
Dns []string // For Docker API v1.9 and below only
Dns []string // For Docker API v1.9 and below only
Image string
Volumes map[string]struct{}
VolumesFrom string
@ -295,7 +295,10 @@ type HostConfig struct {
PortBindings map[Port][]PortBinding
Links []string
PublishAllPorts bool
Dns []string // For Docker API v1.10 and above only
Dns []string // For Docker API v1.10 and above only
DnsSearch []string
VolumesFrom []string
NetworkMode string
}
// StartContainer starts a container, returning an errror in case of failure.
@ -465,20 +468,6 @@ type CommitContainerOptions struct {
Run *Config `qs:"-"`
}
type Image struct {
ID string `json:"id"`
Parent string `json:"parent,omitempty"`
Comment string `json:"comment,omitempty"`
Created time.Time `json:"created"`
Container string `json:"container,omitempty"`
ContainerConfig Config `json:"container_config,omitempty"`
DockerVersion string `json:"docker_version,omitempty"`
Author string `json:"author,omitempty"`
Config *Config `json:"config,omitempty"`
Architecture string `json:"architecture,omitempty"`
Size int64
}
// CommitContainer creates a new image from a container's changes.
//
// See http://goo.gl/628gxm for more details.
@ -515,7 +504,7 @@ type AttachToContainerOptions struct {
// Stream the response?
Stream bool
// Attach to stdin, and use InputFile.
// Attach to stdin, and use InputStream.
Stdin bool
// Attach to stdout, and use OutputStream.
@ -530,6 +519,9 @@ type AttachToContainerOptions struct {
// It must be an unbuffered channel. Using a buffered channel can lead
// to unexpected behavior.
Success chan struct{}
// Use raw terminal? Usually true when the container contains a TTY.
RawTerminal bool `qs:"-"`
}
// AttachToContainer attaches to a container, using the given options.
@ -540,7 +532,31 @@ func (c *Client) AttachToContainer(opts AttachToContainerOptions) error {
return &NoSuchContainer{ID: opts.Container}
}
path := "/containers/" + opts.Container + "/attach?" + queryString(opts)
return c.hijack("POST", path, opts.Success, opts.InputStream, opts.ErrorStream, opts.OutputStream)
return c.hijack("POST", path, opts.Success, opts.RawTerminal, opts.InputStream, opts.ErrorStream, opts.OutputStream)
}
// LogsOptions represents the set of options used when getting logs from a
// container.
//
// See http://goo.gl/rLhKSU for more details.
type LogsOptions struct {
Container string `qs:"-"`
OutputStream io.Writer `qs:"-"`
Follow bool
Stdout bool
Stderr bool
Timestamps bool
}
// Logs gets stdout and stderr logs from the specified container.
//
// See http://goo.gl/rLhKSU for more details.
func (c *Client) Logs(opts LogsOptions) error {
if opts.Container == "" {
return &NoSuchContainer{ID: opts.Container}
}
path := "/containers/" + opts.Container + "/logs?" + queryString(opts)
return c.stream("GET", path, nil, nil, opts.OutputStream)
}
// ResizeContainerTTY resizes the terminal to the given height and width.

View File

@ -678,6 +678,7 @@ func TestAttachToContainerLogs(t *testing.T) {
}))
defer server.Close()
client, _ := NewClient(server.URL)
client.SkipServerVersionCheck = true
var buf bytes.Buffer
opts := AttachToContainerOptions{
Container: "a123456",
@ -722,6 +723,7 @@ func TestAttachToContainer(t *testing.T) {
}))
defer server.Close()
client, _ := NewClient(server.URL)
client.SkipServerVersionCheck = true
var stdout, stderr bytes.Buffer
opts := AttachToContainerOptions{
Container: "a123456",
@ -732,6 +734,7 @@ func TestAttachToContainer(t *testing.T) {
Stdout: true,
Stderr: true,
Stream: true,
RawTerminal: true,
}
var err = client.AttachToContainer(opts)
if err != nil {
@ -749,6 +752,80 @@ func TestAttachToContainer(t *testing.T) {
}
}
func TestAttachToContainerSentinel(t *testing.T) {
var reader = strings.NewReader("send value")
var req http.Request
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte{1, 0, 0, 0, 0, 0, 0, 5})
w.Write([]byte("hello"))
req = *r
}))
defer server.Close()
client, _ := NewClient(server.URL)
client.SkipServerVersionCheck = true
var stdout, stderr bytes.Buffer
success := make(chan struct{})
opts := AttachToContainerOptions{
Container: "a123456",
OutputStream: &stdout,
ErrorStream: &stderr,
InputStream: reader,
Stdin: true,
Stdout: true,
Stderr: true,
Stream: true,
RawTerminal: true,
Success: success,
}
go client.AttachToContainer(opts)
success <- <-success
}
func TestAttachToContainerRawTerminalFalse(t *testing.T) {
input := strings.NewReader("send value")
var req http.Request
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
prefix := []byte{1, 0, 0, 0, 0, 0, 0, 5}
w.Write(prefix)
w.Write([]byte("hello"))
req = *r
}))
defer server.Close()
client, _ := NewClient(server.URL)
client.SkipServerVersionCheck = true
var stdout, stderr bytes.Buffer
opts := AttachToContainerOptions{
Container: "a123456",
OutputStream: &stdout,
ErrorStream: &stderr,
InputStream: input,
Stdin: true,
Stdout: true,
Stderr: true,
Stream: true,
RawTerminal: false,
}
err := client.AttachToContainer(opts)
if err != nil {
t.Fatal(err)
}
expected := map[string][]string{
"stdin": {"1"},
"stdout": {"1"},
"stderr": {"1"},
"stream": {"1"},
}
got := map[string][]string(req.URL.Query())
if !reflect.DeepEqual(got, expected) {
t.Errorf("AttachToContainer: wrong query string. Want %#v. Got %#v.", expected, got)
}
t.Log(stderr.String())
t.Log(stdout.String())
if stdout.String() != "hello" {
t.Errorf("AttachToContainer: wrong content written to stdout. Want %q. Got %q.", "hello", stderr.String())
}
}
func TestAttachToContainerWithoutContainer(t *testing.T) {
var client Client
err := client.AttachToContainer(AttachToContainerOptions{})
@ -758,6 +835,60 @@ func TestAttachToContainerWithoutContainer(t *testing.T) {
}
}
func TestLogs(t *testing.T) {
var req http.Request
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("something happened!"))
req = *r
}))
defer server.Close()
client, _ := NewClient(server.URL)
client.SkipServerVersionCheck = true
var buf bytes.Buffer
opts := LogsOptions{
Container: "a123456",
OutputStream: &buf,
Follow: true,
Stdout: true,
Stderr: true,
Timestamps: true,
}
err := client.Logs(opts)
if err != nil {
t.Fatal(err)
}
expected := "something happened!"
if buf.String() != expected {
t.Errorf("Logs: wrong output. Want %q. Got %q.", expected, buf.String())
}
if req.Method != "GET" {
t.Errorf("Logs: wrong HTTP method. Want GET. Got %s.", req.Method)
}
u, _ := url.Parse(client.getURL("/containers/a123456/logs"))
if req.URL.Path != u.Path {
t.Errorf("AttachToContainer for logs: wrong HTTP path. Want %q. Got %q.", u.Path, req.URL.Path)
}
expectedQs := map[string][]string{
"follow": {"1"},
"stdout": {"1"},
"stderr": {"1"},
"timestamps": {"1"},
}
got := map[string][]string(req.URL.Query())
if !reflect.DeepEqual(got, expectedQs) {
t.Errorf("Logs: wrong query string. Want %#v. Got %#v.", expectedQs, got)
}
}
func TestLogsNoContainer(t *testing.T) {
var client Client
err := client.Logs(LogsOptions{})
expected := &NoSuchContainer{ID: ""}
if !reflect.DeepEqual(err, expected) {
t.Errorf("AttachToContainer: wrong error. Want %#v. Got %#v.", expected, err)
}
}
func TestNoSuchContainerError(t *testing.T) {
var err error = &NoSuchContainer{ID: "i345"}
expected := "No such container: i345"
@ -792,9 +923,10 @@ func TestExportContainerViaUnixSocket(t *testing.T) {
endpoint := "unix://" + tempSocket
u, _ := parseEndpoint(endpoint)
client := Client{
endpoint: endpoint,
endpointURL: u,
client: http.DefaultClient,
endpoint: endpoint,
endpointURL: u,
client: http.DefaultClient,
SkipServerVersionCheck: true,
}
listening := make(chan string)
done := make(chan int)

View File

@ -260,7 +260,7 @@ func (c *Client) eventHijack(startTime int64, eventChan chan *APIEvents, errChan
for {
var event APIEvents
if err = decoder.Decode(&event); err != nil {
if err == io.EOF {
if err == io.EOF || err == io.ErrUnexpectedEOF {
break
}
errChan <- err
@ -270,9 +270,8 @@ func (c *Client) eventHijack(startTime int64, eventChan chan *APIEvents, errChan
}
if !c.eventMonitor.isEnabled() {
return
} else {
c.eventMonitor.C <- &event
}
c.eventMonitor.C <- &event
}
}(res, conn)
return nil

View File

@ -37,6 +37,7 @@ func TestEventListeners(t *testing.T) {
if err != nil {
t.Errorf("Failed to create client: %s", err)
}
client.SkipServerVersionCheck = true
listener := make(chan *APIEvents, 10)
defer func() { time.Sleep(10 * time.Millisecond); client.RemoveEventListener(listener) }()

View File

@ -19,6 +19,7 @@ func ExampleClient_AttachToContainer() {
if err != nil {
log.Fatal(err)
}
client.SkipServerVersionCheck = true
// Reading logs from container a84849 and sending them to buf.
var buf bytes.Buffer
err = client.AttachToContainer(docker.AttachToContainerOptions{

View File

@ -15,6 +15,7 @@ import (
"net/http"
"net/url"
"os"
"time"
)
// APIImages represent an image returned in the ListImages call.
@ -29,6 +30,34 @@ type APIImages struct {
Tag string `json:",omitempty"`
}
type Image struct {
ID string `json:"id"`
Parent string `json:"parent,omitempty"`
Comment string `json:"comment,omitempty"`
Created time.Time `json:"created"`
Container string `json:"container,omitempty"`
ContainerConfig Config `json:"containerconfig,omitempty"`
DockerVersion string `json:"dockerversion,omitempty"`
Author string `json:"author,omitempty"`
Config *Config `json:"config,omitempty"`
Architecture string `json:"architecture,omitempty"`
Size int64
}
type ImagePre012 struct {
ID string `json:"id"`
Parent string `json:"parent,omitempty"`
Comment string `json:"comment,omitempty"`
Created time.Time `json:"created"`
Container string `json:"container,omitempty"`
ContainerConfig Config `json:"container_config,omitempty"`
DockerVersion string `json:"docker_version,omitempty"`
Author string `json:"author,omitempty"`
Config *Config `json:"config,omitempty"`
Architecture string `json:"architecture,omitempty"`
Size int64
}
var (
// ErrNoSuchImage is the error returned when the image does not exist.
ErrNoSuchImage = errors.New("no such image")
@ -86,11 +115,35 @@ func (c *Client) InspectImage(name string) (*Image, error) {
if err != nil {
return nil, err
}
var image Image
err = json.Unmarshal(body, &image)
if err != nil {
return nil, err
// if the caller elected to skip checking the server's version, assume it's the latest
if c.SkipServerVersionCheck || c.expectedApiVersion.GreaterThanOrEqualTo(apiVersion_1_12) {
err = json.Unmarshal(body, &image)
if err != nil {
return nil, err
}
} else {
var imagePre012 ImagePre012
err = json.Unmarshal(body, &imagePre012)
if err != nil {
return nil, err
}
image.ID = imagePre012.ID
image.Parent = imagePre012.Parent
image.Comment = imagePre012.Comment
image.Created = imagePre012.Created
image.Container = imagePre012.Container
image.ContainerConfig = imagePre012.ContainerConfig
image.DockerVersion = imagePre012.DockerVersion
image.Author = imagePre012.Author
image.Config = imagePre012.Config
image.Architecture = imagePre012.Architecture
image.Size = imagePre012.Size
}
return &image, nil
}

View File

@ -21,9 +21,10 @@ func newTestClient(rt *FakeRoundTripper) Client {
endpoint := "http://localhost:4243"
u, _ := parseEndpoint("http://localhost:4243")
client := Client{
endpoint: endpoint,
endpointURL: u,
client: &http.Client{Transport: rt},
endpoint: endpoint,
endpointURL: u,
client: &http.Client{Transport: rt},
SkipServerVersionCheck: true,
}
return client
}

View File

@ -6,8 +6,9 @@ package docker
import (
"bytes"
"github.com/fsouza/go-dockerclient/engine"
"io"
"github.com/fsouza/go-dockerclient/engine"
)
// Version returns version information about the docker server.

View File

@ -5,12 +5,13 @@
package docker
import (
"github.com/fsouza/go-dockerclient/engine"
"net/http"
"net/url"
"reflect"
"sort"
"testing"
"github.com/fsouza/go-dockerclient/engine"
)
type DockerVersion struct {