Commit 7464575b authored by Dawn Chen's avatar Dawn Chen

Merge pull request #6698 from pweil-/update-dockercli

Update to latest docker client
parents 86d30724 fb633704
......@@ -174,7 +174,7 @@
},
{
"ImportPath": "github.com/fsouza/go-dockerclient",
"Rev": "d19717788084716e4adff0515be6289aa04bec46"
"Rev": "17d39bcb22e8103ba6d1c0cb2530c6434cb870a3"
},
{
"ImportPath": "github.com/garyburd/redigo/internal",
......
# This is the official list of go-dockerclient authors for copyright purposes.
Adam Bell-Hanssen <adamb@aller.no>
Aldrin Leal <aldrin@leal.eng.br>
Andreas Jaekle <andreas@jaekle.net>
Andrews Medina <andrewsmedina@gmail.com>
Artem Sidorenko <artem@2realities.com>
Andy Goldstein <andy.goldstein@redhat.com>
Ben Marini <ben@remind101.com>
Ben McCann <benmccann.com>
Brian Lalor <blalor@bravo5.org>
Burke Libbey <burke@libbey.me>
Carlos Diaz-Padron <cpadron@mozilla.com>
Cezar Sa Espinola <cezar.sa@corp.globo.com>
Cheah Chu Yeow <chuyeow@gmail.com>
cheneydeng <cheneydeng@qq.com>
CMGS <ilskdw@gmail.com>
Daniel, Dao Quang Minh <dqminh89@gmail.com>
Darren Shepherd <darren@rancher.com>
David Huie <dahuie@gmail.com>
Dawn Chen <dawnchen@google.com>
Ed <edrocksit@gmail.com>
Eric Anderson <anderson@copperegg.com>
Fabio Rehm <fgrehm@gmail.com>
Fatih Arslan <ftharsln@gmail.com>
Fatih Arslan <ftharsln@gmail.com>
Flavia Missi <flaviamissi@gmail.com>
Francisco Souza <f@souza.cc>
Guillermo Álvarez Fernández <guillermo@cientifico.net>
Jari Kolehmainen <jari.kolehmainen@digia.com>
Jason Wilder <jwilder@litl.com>
Jawher Moussa <jawher.moussa@gmail.com>
......@@ -30,19 +36,26 @@ Johan Euphrosine <proppy@google.com>
Kamil Domanski <kamil@domanski.co>
Karan Misra <kidoman@gmail.com>
Kim, Hirokuni <hirokuni.kim@kvh.co.jp>
liron-l <levinlir@gmail.com>
Lucas Clemente <lucas@clemente.io>
Lucas Weiblen <lucasweiblen@gmail.com>
Mantas Matelis <mmatelis@coursera.org>
Martin Sweeney <martin@sweeney.io>
Máximo Cuadros Ortiz <mcuadros@gmail.com>
Michal Fojtik <mfojtik@redhat.com>
Mike Dillon <mike.dillon@synctree.com>
Mrunal Patel <mrunalp@gmail.com>
Nick Ethier <ncethier@gmail.com>
Omeid Matten <public@omeid.me>
Paul Morie <pmorie@gmail.com>
Paul Weil <pweil@redhat.com>
Peter Jihoon Kim <raingrove@gmail.com>
Philippe Lafoucrière <philippe.lafoucriere@tech-angels.com>
Rafe Colton <rafael.colton@gmail.com>
Rob Miller <rob@kalistra.com>
Robert Williamson <williamson.robert@gmail.com>
Salvador Gironès <salvadorgirones@gmail.com>
Sam Rijs <srijs@airpost.net>
Simon Eskildsen <sirup@sirupsen.com>
Simon Menke <simon.menke@gmail.com>
Skolos <skolos@gopherlab.com>
......@@ -51,5 +64,7 @@ Sridhar Ratnakumar <sridharr@activestate.com>
Summer Mousa <smousa@zenoss.com>
Tarsis Azevedo <tarsis@corp.globo.com>
Tim Schindler <tim@catalyst-zero.com>
Vincenzo Prignano <vincenzo.prignano@gmail.com>
Wiliam Souza <wiliamsouza83@gmail.com>
Ye Yin <eyniy@qq.com>
Yuriy Bogdanov <chinsay@gmail.com>
Copyright (c) 2014, go-dockerclient authors
Copyright (c) 2015, go-dockerclient authors
All rights reserved.
Redistribution and use in source and binary forms, with or without
......
......@@ -3,11 +3,12 @@
[![Build Status](https://drone.io/github.com/fsouza/go-dockerclient/status.png)](https://drone.io/github.com/fsouza/go-dockerclient/latest)
[![Build Status](https://travis-ci.org/fsouza/go-dockerclient.png)](https://travis-ci.org/fsouza/go-dockerclient)
[![GoDoc](http://godoc.org/github.com/fsouza/go-dockerclient?status.png)](http://godoc.org/github.com/fsouza/go-dockerclient)
[![GoDoc](https://godoc.org/github.com/fsouza/go-dockerclient?status.png)](https://godoc.org/github.com/fsouza/go-dockerclient)
This package presents a client for the Docker remote API.
This package presents a client for the Docker remote API. It also provides
support for the extensions in the [Swarm API](https://docs.docker.com/swarm/API/).
For more details, check the [remote API documentation](http://docs.docker.io/en/latest/reference/api/docker_remote_api/).
For more details, check the [remote API documentation](http://docs.docker.com/en/latest/reference/api/docker_remote_api/).
## Example
......@@ -15,22 +16,49 @@ For more details, check the [remote API documentation](http://docs.docker.io/en/
package main
import (
"fmt"
"github.com/fsouza/go-dockerclient"
"fmt"
"github.com/fsouza/go-dockerclient"
)
func main() {
endpoint := "unix:///var/run/docker.sock"
client, _ := docker.NewClient(endpoint)
imgs, _ := client.ListImages(docker.ListImagesOptions{All: false})
for _, img := range imgs {
fmt.Println("ID: ", img.ID)
fmt.Println("RepoTags: ", img.RepoTags)
fmt.Println("Created: ", img.Created)
fmt.Println("Size: ", img.Size)
fmt.Println("VirtualSize: ", img.VirtualSize)
fmt.Println("ParentId: ", img.ParentID)
}
}
```
## Using with Boot2Docker
Boot2Docker runs Docker with TLS enabled. In order to instantiate the client you should use NewTLSClient, passing the endpoint and path for key and certificates as parameters.
For more details about TLS support in Boot2Docker, please refer to [TLS support](https://github.com/boot2docker/boot2docker#tls-support) on Boot2Docker's readme.
```go
package main
import (
"fmt"
"github.com/fsouza/go-dockerclient"
)
func main() {
endpoint := "unix:///var/run/docker.sock"
client, _ := docker.NewClient(endpoint)
imgs, _ := client.ListImages(docker.ListImagesOptions{All: false})
for _, img := range imgs {
fmt.Println("ID: ", img.ID)
fmt.Println("RepoTags: ", img.RepoTags)
fmt.Println("Created: ", img.Created)
fmt.Println("Size: ", img.Size)
fmt.Println("VirtualSize: ", img.VirtualSize)
fmt.Println("ParentId: ", img.ParentID)
}
endpoint := "tcp://[ip]:[port]"
path := os.Getenv("DOCKER_CERT_PATH")
ca := fmt.Sprintf("%s/ca.pem", path)
cert := fmt.Sprintf("%s/cert.pem", path)
key := fmt.Sprintf("%s/key.pem", path)
client, _ := docker.NewTLSClient(endpoint, cert, key, ca)
// use client
}
```
......
// Copyright 2015 go-dockerclient authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package docker
import (
"encoding/base64"
"encoding/json"
"io"
"os"
"path"
"strings"
)
// AuthConfiguration represents authentication options to use in the PushImage
// method. It represents the authentication in the Docker index server.
type AuthConfiguration struct {
Username string `json:"username,omitempty"`
Password string `json:"password,omitempty"`
Email string `json:"email,omitempty"`
ServerAddress string `json:"serveraddress,omitempty"`
}
// AuthConfigurations represents authentication options to use for the
// PushImage method accommodating the new X-Registry-Config header
type AuthConfigurations struct {
Configs map[string]AuthConfiguration `json:"configs"`
}
// dockerConfig represents a registry authentation configuration from the
// .dockercfg file.
type dockerConfig struct {
Auth string `json:"auth"`
Email string `json:"email"`
}
// NewAuthConfigurationsFromDockerCfg returns AuthConfigurations from the
// ~/.dockercfg file.
func NewAuthConfigurationsFromDockerCfg() (*AuthConfigurations, error) {
p := path.Join(os.Getenv("HOME"), ".dockercfg")
r, err := os.Open(p)
if err != nil {
return nil, err
}
return NewAuthConfigurations(r)
}
// NewAuthConfigurations returns AuthConfigurations from a JSON encoded string in the
// same format as the .dockercfg file.
func NewAuthConfigurations(r io.Reader) (*AuthConfigurations, error) {
var auth *AuthConfigurations
var confs map[string]dockerConfig
if err := json.NewDecoder(r).Decode(&confs); err != nil {
return nil, err
}
auth, err := authConfigs(confs)
if err != nil {
return nil, err
}
return auth, nil
}
// authConfigs converts a dockerConfigs map to a AuthConfigurations object.
func authConfigs(confs map[string]dockerConfig) (*AuthConfigurations, error) {
c := &AuthConfigurations{
Configs: make(map[string]AuthConfiguration),
}
for reg, conf := range confs {
data, err := base64.StdEncoding.DecodeString(conf.Auth)
if err != nil {
return nil, err
}
userpass := strings.Split(string(data), ":")
c.Configs[reg] = AuthConfiguration{
Email: conf.Email,
Username: userpass[0],
Password: userpass[1],
ServerAddress: reg,
}
}
return c, nil
}
// Copyright 2015 go-dockerclient authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package docker
import (
"encoding/base64"
"fmt"
"strings"
"testing"
)
func TestAuthConfig(t *testing.T) {
auth := base64.StdEncoding.EncodeToString([]byte("user:pass"))
read := strings.NewReader(fmt.Sprintf(`{"docker.io":{"auth":"%s","email":"user@example.com"}}`, auth))
ac, err := NewAuthConfigurations(read)
if err != nil {
t.Error(err)
}
c, ok := ac.Configs["docker.io"]
if !ok {
t.Error("NewAuthConfigurations: Expected Configs to contain docker.io")
}
if got, want := c.Email, "user@example.com"; got != want {
t.Errorf(`AuthConfigurations.Configs["docker.io"].Email: wrong result. Want %q. Got %q`, want, got)
}
if got, want := c.Username, "user"; got != want {
t.Errorf(`AuthConfigurations.Configs["docker.io"].Username: wrong result. Want %q. Got %q`, want, got)
}
if got, want := c.Password, "pass"; got != want {
t.Errorf(`AuthConfigurations.Configs["docker.io"].Password: wrong result. Want %q. Got %q`, want, got)
}
if got, want := c.ServerAddress, "docker.io"; got != want {
t.Errorf(`AuthConfigurations.Configs["docker.io"].ServerAddress: wrong result. Want %q. Got %q`, want, got)
}
}
// Copyright 2014 go-dockerclient authors. All rights reserved.
// Copyright 2015 go-dockerclient authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
......@@ -34,7 +34,7 @@ var (
// ErrConnectionRefused is returned when the client cannot connect to the given endpoint.
ErrConnectionRefused = errors.New("cannot connect to Docker endpoint")
apiVersion1_12, _ = NewAPIVersion("1.12")
apiVersion112, _ = NewAPIVersion("1.12")
)
// APIVersion is an internal representation of a version of the Remote API.
......@@ -143,7 +143,7 @@ func NewClient(endpoint string) (*Client, error) {
// server endpoint, key and certificates . It will use the latest remote API version
// available in the server.
func NewTLSClient(endpoint string, cert, key, ca string) (*Client, error) {
client, err := NewVersionnedTLSClient(endpoint, cert, key, ca, "")
client, err := NewVersionedTLSClient(endpoint, cert, key, ca, "")
if err != nil {
return nil, err
}
......@@ -154,7 +154,7 @@ func NewTLSClient(endpoint string, cert, key, ca string) (*Client, error) {
// 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)
u, err := parseEndpoint(endpoint, false)
if err != nil {
return nil, err
}
......@@ -174,10 +174,15 @@ func NewVersionedClient(endpoint string, apiVersionString string) (*Client, erro
}, nil
}
// NewVersionnedTLSClient returns a Client instance ready for TLS communications with the givens
// server endpoint, key and certificates, using a specific remote API version.
// NewVersionnedTLSClient has been DEPRECATED, please use NewVersionedTLSClient.
func NewVersionnedTLSClient(endpoint string, cert, key, ca, apiVersionString string) (*Client, error) {
u, err := parseEndpoint(endpoint)
return NewVersionedTLSClient(endpoint, cert, key, ca, apiVersionString)
}
// NewVersionedTLSClient returns a Client instance ready for TLS communications with the givens
// server endpoint, key and certificates, using a specific remote API version.
func NewVersionedTLSClient(endpoint string, cert, key, ca, apiVersionString string) (*Client, error) {
u, err := parseEndpoint(endpoint, true)
if err != nil {
return nil, err
}
......@@ -247,7 +252,7 @@ func (c *Client) checkAPIVersion() error {
// See http://goo.gl/stJENm for more details.
func (c *Client) Ping() error {
path := "/_ping"
body, status, err := c.do("GET", path, nil)
body, status, err := c.do("GET", path, nil, false)
if err != nil {
return err
}
......@@ -258,7 +263,7 @@ func (c *Client) Ping() error {
}
func (c *Client) getServerAPIVersionString() (version string, err error) {
body, status, err := c.do("GET", "/version", nil)
body, status, err := c.do("GET", "/version", nil, false)
if err != nil {
return "", err
}
......@@ -274,9 +279,9 @@ func (c *Client) getServerAPIVersionString() (version string, err error) {
return version, nil
}
func (c *Client) do(method, path string, data interface{}) ([]byte, int, error) {
func (c *Client) do(method, path string, data interface{}, forceJSON bool) ([]byte, int, error) {
var params io.Reader
if data != nil {
if data != nil || forceJSON {
buf, err := json.Marshal(data)
if err != nil {
return nil, -1, err
......@@ -599,11 +604,14 @@ func (e *Error) Error() string {
return fmt.Sprintf("API error (%d): %s", e.Status, e.Message)
}
func parseEndpoint(endpoint string) (*url.URL, error) {
func parseEndpoint(endpoint string, tls bool) (*url.URL, error) {
u, err := url.Parse(endpoint)
if err != nil {
return nil, ErrInvalidEndpoint
}
if tls {
u.Scheme = "https"
}
if u.Scheme == "tcp" {
_, port, err := net.SplitHostPort(u.Host)
if err != nil {
......
// Copyright 2014 go-dockerclient authors. All rights reserved.
// Copyright 2015 go-dockerclient authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
......@@ -93,7 +93,7 @@ func TestNewTLSVersionedClient(t *testing.T) {
keyPath := "testing/data/key.pem"
caPath := "testing/data/ca.pem"
endpoint := "https://localhost:4243"
client, err := NewVersionnedTLSClient(endpoint, certPath, keyPath, caPath, "1.14")
client, err := NewVersionedTLSClient(endpoint, certPath, keyPath, caPath, "1.14")
if err != nil {
t.Fatal(err)
}
......@@ -113,7 +113,7 @@ func TestNewTLSVersionedClientInvalidCA(t *testing.T) {
keyPath := "testing/data/key.pem"
caPath := "testing/data/key.pem"
endpoint := "https://localhost:4243"
_, err := NewVersionnedTLSClient(endpoint, certPath, keyPath, caPath, "1.14")
_, err := NewVersionedTLSClient(endpoint, certPath, keyPath, caPath, "1.14")
if err == nil {
t.Errorf("Expected invalid ca at %s", caPath)
}
......@@ -136,14 +136,15 @@ func TestNewClientInvalidEndpoint(t *testing.T) {
}
}
func TestNewTLSClient2376(t *testing.T) {
func TestNewTLSClient(t *testing.T) {
var tests = []struct {
endpoint string
expected string
}{
{"tcp://localhost:2376", "https"},
{"tcp://localhost:2375", "http"},
{"tcp://localhost:4000", "http"},
{"tcp://localhost:2375", "https"},
{"tcp://localhost:4000", "https"},
{"http://localhost:4000", "https"},
}
for _, tt := range tests {
......
// Copyright 2014 go-dockerclient authors. All rights reserved.
// Copyright 2015 go-dockerclient authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
......@@ -7,6 +7,7 @@ package docker
import (
"bytes"
"encoding/json"
"errors"
"io/ioutil"
"net"
"net/http"
......@@ -154,6 +155,7 @@ func TestListContainersFailure(t *testing.T) {
func TestInspectContainer(t *testing.T) {
jsonContainer := `{
"Id": "4fa6e0f0c6786287e131c3852c58a2e01cc697a68231826813597e4994f1d6e2",
"AppArmorProfile": "Profile",
"Created": "2013-05-07T14:51:42.087658+02:00",
"Path": "date",
"Args": [],
......@@ -175,7 +177,10 @@ func TestInspectContainer(t *testing.T) {
],
"Image": "base",
"Volumes": {},
"VolumesFrom": ""
"VolumesFrom": "",
"SecurityOpt": [
"label:user:USER"
]
},
"State": {
"Running": false,
......@@ -184,6 +189,21 @@ func TestInspectContainer(t *testing.T) {
"StartedAt": "2013-05-07T14:51:42.087658+02:00",
"Ghost": false
},
"Node": {
"ID": "4I4E:QR4I:Z733:QEZK:5X44:Q4T7:W2DD:JRDY:KB2O:PODO:Z5SR:XRB6",
"IP": "192.168.99.105",
"Addra": "192.168.99.105:2376",
"Name": "node-01",
"Cpus": 4,
"Memory": 1048436736,
"Labels": {
"executiondriver": "native-0.2",
"kernelversion": "3.18.5-tinycore64",
"operatingsystem": "Boot2Docker 1.5.0 (TCL 5.4); master : a66bce5 - Tue Feb 10 23:31:27 UTC 2015",
"provider": "virtualbox",
"storagedriver": "aufs"
}
},
"Image": "b750fe79269d2ec9a3c593ef05b4332b1d1a02a62b4accb2c21d589ff2f5f2dc",
"NetworkSettings": {
"IpAddress": "",
......@@ -511,12 +531,17 @@ func TestStartContainerNilHostConfig(t *testing.T) {
if contentType := req.Header.Get("Content-Type"); contentType != expectedContentType {
t.Errorf("StartContainer(%q): Wrong content-type in request. Want %q. Got %q.", id, expectedContentType, contentType)
}
var buf [4]byte
req.Body.Read(buf[:])
if string(buf[:]) != "null" {
t.Errorf("Startcontainer(%q): Wrong body. Want null. Got %s", buf[:])
}
}
func TestStartContainerNotFound(t *testing.T) {
client := newTestClient(&FakeRoundTripper{message: "no such container", status: http.StatusNotFound})
err := client.StartContainer("a2344", &HostConfig{})
expected := &NoSuchContainer{ID: "a2344"}
expected := &NoSuchContainer{ID: "a2344", Err: err.(*NoSuchContainer).Err}
if !reflect.DeepEqual(err, expected) {
t.Errorf("StartContainer: Wrong error returned. Want %#v. Got %#v.", expected, err)
}
......@@ -1287,6 +1312,14 @@ func TestNoSuchContainerError(t *testing.T) {
}
}
func TestNoSuchContainerErrorMessage(t *testing.T) {
var err = &NoSuchContainer{ID: "i345", Err: errors.New("some advanced error info")}
expected := "some advanced error info"
if got := err.Error(); got != expected {
t.Errorf("NoSuchContainer: wrong message. Want %q. Got %q.", expected, got)
}
}
func TestExportContainer(t *testing.T) {
content := "exported container tar content"
out := stdoutMock{bytes.NewBufferString(content)}
......@@ -1311,7 +1344,7 @@ func TestExportContainerViaUnixSocket(t *testing.T) {
tempSocket := tempfile("export_socket")
defer os.Remove(tempSocket)
endpoint := "unix://" + tempSocket
u, _ := parseEndpoint(endpoint)
u, _ := parseEndpoint(endpoint, false)
client := Client{
HTTPClient: http.DefaultClient,
endpoint: endpoint,
......@@ -1522,3 +1555,26 @@ func TestTopContainerWithPsArgs(t *testing.T) {
t.Errorf("TopContainer: Expected URI to have %q. Got %q.", expectedURI, fakeRT.requests[0].URL.String())
}
}
func TestRenameContainer(t *testing.T) {
fakeRT := &FakeRoundTripper{message: "", status: http.StatusOK}
client := newTestClient(fakeRT)
opts := RenameContainerOptions{ID: "something_old", Name: "something_new"}
err := client.RenameContainer(opts)
if err != nil {
t.Fatal(err)
}
req := fakeRT.requests[0]
if req.Method != "POST" {
t.Errorf("RenameContainer: wrong HTTP method. Want %q. Got %q.", "POST", req.Method)
}
expectedURL, _ := url.Parse(client.getURL("/containers/something_old/rename?name=something_new"))
if gotPath := req.URL.Path; gotPath != expectedURL.Path {
t.Errorf("RenameContainer: Wrong path in request. Want %q. Got %q.", expectedURL.Path, gotPath)
}
expectedValues := expectedURL.Query()["name"]
actualValues := req.URL.Query()["name"]
if len(actualValues) != 1 || expectedValues[0] != actualValues[0] {
t.Errorf("RenameContainer: Wrong params in request. Want %q. Got %q.", expectedValues, actualValues)
}
}
// Copyright 2014 go-dockerclient authors. All rights reserved.
// Copyright 2015 go-dockerclient authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
......@@ -182,8 +182,8 @@ func (eventState *eventMonitoringState) monitorEvents(c *Client) {
eventState.terminate()
return
}
eventState.updateLastSeen(ev)
go eventState.sendEvent(ev)
go eventState.updateLastSeen(ev)
case err = <-eventState.errC:
if err == ErrNoListeners {
eventState.terminate()
......@@ -227,7 +227,7 @@ func (eventState *eventMonitoringState) sendEvent(event *APIEvents) {
eventState.Add(1)
defer eventState.Done()
if eventState.isEnabled() {
if eventState.noListeners() {
if len(eventState.listeners) == 0 {
eventState.errC <- ErrNoListeners
return
}
......
// Copyright 2014 go-dockerclient authors. All rights reserved.
// Copyright 2015 go-dockerclient authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
......@@ -90,7 +90,7 @@ type ExecInspect struct {
// See http://goo.gl/8izrzI for more details
func (c *Client) CreateExec(opts CreateExecOptions) (*Exec, error) {
path := fmt.Sprintf("/containers/%s/exec", opts.Container)
body, status, err := c.do("POST", path, opts)
body, status, err := c.do("POST", path, opts, false)
if status == http.StatusNotFound {
return nil, &NoSuchContainer{ID: opts.Container}
}
......@@ -119,7 +119,7 @@ func (c *Client) StartExec(id string, opts StartExecOptions) error {
path := fmt.Sprintf("/exec/%s/start", id)
if opts.Detach {
_, status, err := c.do("POST", path, opts)
_, status, err := c.do("POST", path, opts, false)
if status == http.StatusNotFound {
return &NoSuchExec{ID: id}
}
......@@ -143,7 +143,7 @@ func (c *Client) ResizeExecTTY(id string, height, width int) error {
params.Set("w", strconv.Itoa(width))
path := fmt.Sprintf("/exec/%s/resize?%s", id, params.Encode())
_, _, err := c.do("POST", path, nil)
_, _, err := c.do("POST", path, nil, false)
return err
}
......@@ -152,7 +152,7 @@ func (c *Client) ResizeExecTTY(id string, height, width int) error {
// See http://goo.gl/ypQULN for more details
func (c *Client) InspectExec(id string) (*ExecInspect, error) {
path := fmt.Sprintf("/exec/%s/json", id)
body, status, err := c.do("GET", path, nil)
body, status, err := c.do("GET", path, nil, false)
if status == http.StatusNotFound {
return nil, &NoSuchExec{ID: id}
}
......
// Copyright 2014 go-dockerclient authors. All rights reserved.
// Copyright 2015 go-dockerclient authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
......
// Copyright 2014 go-dockerclient authors. All rights reserved.
// Copyright 2015 go-dockerclient authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
......@@ -99,7 +99,7 @@ var (
// See http://goo.gl/2rOLFF for more details.
func (c *Client) ListImages(opts ListImagesOptions) ([]APIImages, error) {
path := "/images/json?" + queryString(opts)
body, _, err := c.do("GET", path, nil)
body, _, err := c.do("GET", path, nil, false)
if err != nil {
return nil, err
}
......@@ -115,7 +115,7 @@ func (c *Client) ListImages(opts ListImagesOptions) ([]APIImages, error) {
//
// See http://goo.gl/2oJmNs for more details.
func (c *Client) ImageHistory(name string) ([]ImageHistory, error) {
body, status, err := c.do("GET", "/images/"+name+"/history", nil)
body, status, err := c.do("GET", "/images/"+name+"/history", nil, false)
if status == http.StatusNotFound {
return nil, ErrNoSuchImage
}
......@@ -134,7 +134,29 @@ func (c *Client) ImageHistory(name string) ([]ImageHistory, error) {
//
// See http://goo.gl/znj0wM for more details.
func (c *Client) RemoveImage(name string) error {
_, status, err := c.do("DELETE", "/images/"+name, nil)
_, status, err := c.do("DELETE", "/images/"+name, nil, false)
if status == http.StatusNotFound {
return ErrNoSuchImage
}
return err
}
// RemoveImageOptions present the set of options available for removing an image
// from a registry.
//
// See http://goo.gl/6V48bF for more details.
type RemoveImageOptions struct {
Force bool `qs:"force"`
NoPrune bool `qs:"noprune"`
}
// RemoveImageExtended removes an image by its name or ID.
// Extra params can be passed, see RemoveImageOptions
//
// See http://goo.gl/znj0wM for more details.
func (c *Client) RemoveImageExtended(name string, opts RemoveImageOptions) error {
uri := fmt.Sprintf("/images/%s?%s", name, queryString(&opts))
_, status, err := c.do("DELETE", uri, nil, false)
if status == http.StatusNotFound {
return ErrNoSuchImage
}
......@@ -145,7 +167,7 @@ func (c *Client) RemoveImage(name string) error {
//
// See http://goo.gl/Q112NY for more details.
func (c *Client) InspectImage(name string) (*Image, error) {
body, status, err := c.do("GET", "/images/"+name+"/json", nil)
body, status, err := c.do("GET", "/images/"+name+"/json", nil, false)
if status == http.StatusNotFound {
return nil, ErrNoSuchImage
}
......@@ -156,7 +178,7 @@ func (c *Client) InspectImage(name string) (*Image, error) {
var image Image
// if the caller elected to skip checking the server's version, assume it's the latest
if c.SkipServerVersionCheck || c.expectedAPIVersion.GreaterThanOrEqualTo(apiVersion1_12) {
if c.SkipServerVersionCheck || c.expectedAPIVersion.GreaterThanOrEqualTo(apiVersion112) {
err = json.Unmarshal(body, &image)
if err != nil {
return nil, err
......@@ -201,21 +223,6 @@ type PushImageOptions struct {
RawJSONStream bool `qs:"-"`
}
// AuthConfiguration represents authentication options to use in the PushImage
// method. It represents the authentication in the Docker index server.
type AuthConfiguration struct {
Username string `json:"username,omitempty"`
Password string `json:"password,omitempty"`
Email string `json:"email,omitempty"`
ServerAddress string `json:"serveraddress,omitempty"`
}
// AuthConfigurations represents authentication options to use for the
// PushImage method accommodating the new X-Registry-Config header
type AuthConfigurations struct {
Configs map[string]AuthConfiguration `json:"configs"`
}
// PushImage pushes an image to a remote registry, logging progress to w.
//
// An empty instance of AuthConfiguration may be used for unauthenticated
......@@ -245,7 +252,7 @@ type PullImageOptions struct {
RawJSONStream bool `qs:"-"`
}
// PullImage pulls an image from a remote registry, logging progress to w.
// PullImage pulls an image from a remote registry, logging progress to opts.OutputStream.
//
// See http://goo.gl/ACyYNS for more details.
func (c *Client) PullImage(opts PullImageOptions, auth AuthConfiguration) error {
......@@ -333,6 +340,7 @@ func (c *Client) ImportImage(opts ImportImageOptions) error {
// http://goo.gl/tlPXPu.
type BuildImageOptions struct {
Name string `qs:"t"`
Dockerfile string `qs:"dockerfile"`
NoCache bool `qs:"nocache"`
SuppressOutput bool `qs:"q"`
RmTmpContainer bool `qs:"rm"`
......@@ -395,7 +403,8 @@ func (c *Client) TagImage(name string, opts TagImageOptions) error {
return ErrNoSuchImage
}
_, status, err := c.do("POST", fmt.Sprintf("/images/"+name+"/tag?%s",
queryString(&opts)), nil)
queryString(&opts)), nil, false)
if status == http.StatusNotFound {
return ErrNoSuchImage
}
......@@ -445,7 +454,7 @@ type APIImageSearch struct {
//
// See http://goo.gl/xI5lLZ for more details.
func (c *Client) SearchImages(term string) ([]APIImageSearch, error) {
body, _, err := c.do("GET", "/images/search?term="+term, nil)
body, _, err := c.do("GET", "/images/search?term="+term, nil, false)
if err != nil {
return nil, err
}
......
// Copyright 2014 go-dockerclient authors. All rights reserved.
// Copyright 2015 go-dockerclient authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
......@@ -19,7 +19,7 @@ import (
func newTestClient(rt *FakeRoundTripper) Client {
endpoint := "http://localhost:4243"
u, _ := parseEndpoint("http://localhost:4243")
u, _ := parseEndpoint("http://localhost:4243", false)
client := Client{
HTTPClient: &http.Client{Transport: rt},
endpoint: endpoint,
......@@ -208,6 +208,29 @@ func TestRemoveImageNotFound(t *testing.T) {
}
}
func TestRemoveImageExtended(t *testing.T) {
name := "test"
fakeRT := &FakeRoundTripper{message: "", status: http.StatusNoContent}
client := newTestClient(fakeRT)
err := client.RemoveImageExtended(name, RemoveImageOptions{Force: true, NoPrune: true})
if err != nil {
t.Fatal(err)
}
req := fakeRT.requests[0]
expectedMethod := "DELETE"
if req.Method != expectedMethod {
t.Errorf("RemoveImage(%q): Wrong HTTP method. Want %s. Got %s.", name, expectedMethod, req.Method)
}
u, _ := url.Parse(client.getURL("/images/" + name))
if req.URL.Path != u.Path {
t.Errorf("RemoveImage(%q): Wrong request path. Want %q. Got %q.", name, u.Path, req.URL.Path)
}
expectedQuery := "force=1&noprune=1"
if query := req.URL.Query().Encode(); query != expectedQuery {
t.Errorf("PushImage: Wrong query string. Want %q. Got %q.", expectedQuery, query)
}
}
func TestInspectImage(t *testing.T) {
body := `{
"id":"b750fe79269d2ec9a3c593ef05b4332b1d1a02a62b4accb2c21d589ff2f5f2dc",
......
// Copyright 2014 go-dockerclient authors. All rights reserved.
// Copyright 2015 go-dockerclient authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
......@@ -13,7 +13,7 @@ import (
//
// See http://goo.gl/BOZrF5 for more details.
func (c *Client) Version() (*Env, error) {
body, _, err := c.do("GET", "/version", nil)
body, _, err := c.do("GET", "/version", nil, false)
if err != nil {
return nil, err
}
......@@ -28,7 +28,7 @@ func (c *Client) Version() (*Env, error) {
//
// See http://goo.gl/wmqZsW for more details.
func (c *Client) Info() (*Env, error) {
body, _, err := c.do("GET", "/info", nil)
body, _, err := c.do("GET", "/info", nil, false)
if err != nil {
return nil, err
}
......
// Copyright 2014 go-dockerclient authors. All rights reserved.
// Copyright 2015 go-dockerclient authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment