Commit 6d0f84c7 authored by Francisco Souza's avatar Francisco Souza

api/v1beta1: use go-dockerclient instead of docker-api-structs

This involves updating go-dockerclient and removing the patched code. Related to #692 and fsouza/go-dockerclient#146.
parent ee1c0838
...@@ -47,8 +47,8 @@ ...@@ -47,8 +47,8 @@
}, },
{ {
"ImportPath": "github.com/fsouza/go-dockerclient", "ImportPath": "github.com/fsouza/go-dockerclient",
"Comment": "0.2.1-216-g9061c85", "Comment": "0.2.1-241-g0dbb508",
"Rev": "9061c8580ba4374f24de44bcf9e8b77ce0553933" "Rev": "0dbb508e94dd899a6743d035d8f249c7634d26da"
}, },
{ {
"ImportPath": "github.com/golang/glog", "ImportPath": "github.com/golang/glog",
......
...@@ -2,7 +2,7 @@ language: go ...@@ -2,7 +2,7 @@ language: go
go: go:
- 1.1.2 - 1.1.2
- 1.2 - 1.2
- 1.3 - 1.3.1
- tip - tip
env: env:
- GOARCH=amd64 - GOARCH=amd64
......
# This is the official list of go-dockerclient authors for copyright purposes. # This is the official list of go-dockerclient authors for copyright purposes.
Aldrin Leal <aldrin@leal.eng.br>
Andreas Jaekle <andreas@jaekle.net> Andreas Jaekle <andreas@jaekle.net>
Andrews Medina <andrewsmedina@gmail.com> Andrews Medina <andrewsmedina@gmail.com>
Andy Goldstein <andy.goldstein@redhat.com> Andy Goldstein <andy.goldstein@redhat.com>
...@@ -7,6 +8,8 @@ Ben McCann <benmccann.com> ...@@ -7,6 +8,8 @@ Ben McCann <benmccann.com>
Cezar Sa Espinola <cezar.sa@corp.globo.com> Cezar Sa Espinola <cezar.sa@corp.globo.com>
Cheah Chu Yeow <chuyeow@gmail.com> Cheah Chu Yeow <chuyeow@gmail.com>
cheneydeng <cheneydeng@qq.com> cheneydeng <cheneydeng@qq.com>
Daniel, Dao Quang Minh <dqminh89@gmail.com>
David Huie <dahuie@gmail.com>
Ed <edrocksit@gmail.com> Ed <edrocksit@gmail.com>
Eric Anderson <anderson@copperegg.com> Eric Anderson <anderson@copperegg.com>
Fabio Rehm <fgrehm@gmail.com> Fabio Rehm <fgrehm@gmail.com>
...@@ -19,6 +22,7 @@ Jeff Mitchell <jeffrey.mitchell@gmail.com> ...@@ -19,6 +22,7 @@ Jeff Mitchell <jeffrey.mitchell@gmail.com>
Jeffrey Hulten <jhulten@gmail.com> Jeffrey Hulten <jhulten@gmail.com>
Johan Euphrosine <proppy@google.com> Johan Euphrosine <proppy@google.com>
Karan Misra <kidoman@gmail.com> Karan Misra <kidoman@gmail.com>
Kim, Hirokuni <hirokuni.kim@kvh.co.jp>
Lucas Clemente <lucas@clemente.io> Lucas Clemente <lucas@clemente.io>
Omeid Matten <public@omeid.me> Omeid Matten <public@omeid.me>
Paul Morie <pmorie@gmail.com> Paul Morie <pmorie@gmail.com>
......
...@@ -264,7 +264,7 @@ func (c *Client) do(method, path string, data interface{}) ([]byte, int, error) ...@@ -264,7 +264,7 @@ func (c *Client) do(method, path string, data interface{}) ([]byte, int, error)
return body, resp.StatusCode, nil return body, resp.StatusCode, nil
} }
func (c *Client) stream(method, path string, setRawTerminal bool, headers map[string]string, in io.Reader, stdout, stderr io.Writer) error { func (c *Client) stream(method, path string, setRawTerminal, rawJSONStream bool, headers map[string]string, in io.Reader, stdout, stderr io.Writer) error {
if (method == "POST" || method == "PUT") && in == nil { if (method == "POST" || method == "PUT") && in == nil {
in = bytes.NewReader(nil) in = bytes.NewReader(nil)
} }
...@@ -320,6 +320,12 @@ func (c *Client) stream(method, path string, setRawTerminal bool, headers map[st ...@@ -320,6 +320,12 @@ func (c *Client) stream(method, path string, setRawTerminal bool, headers map[st
return newError(resp.StatusCode, body) return newError(resp.StatusCode, body)
} }
if resp.Header.Get("Content-Type") == "application/json" { if resp.Header.Get("Content-Type") == "application/json" {
// if we want to get raw json stream, just copy it back to output
// without decoding it
if rawJSONStream {
_, err = io.Copy(stdout, resp.Body)
return err
}
dec := json.NewDecoder(resp.Body) dec := json.NewDecoder(resp.Body)
for { for {
var m jsonMessage var m jsonMessage
......
...@@ -248,16 +248,22 @@ func TestPingFailingWrongStatus(t *testing.T) { ...@@ -248,16 +248,22 @@ func TestPingFailingWrongStatus(t *testing.T) {
type FakeRoundTripper struct { type FakeRoundTripper struct {
message string message string
status int status int
header map[string]string
requests []*http.Request requests []*http.Request
} }
func (rt *FakeRoundTripper) RoundTrip(r *http.Request) (*http.Response, error) { func (rt *FakeRoundTripper) RoundTrip(r *http.Request) (*http.Response, error) {
body := strings.NewReader(rt.message) body := strings.NewReader(rt.message)
rt.requests = append(rt.requests, r) rt.requests = append(rt.requests, r)
return &http.Response{ res := &http.Response{
StatusCode: rt.status, StatusCode: rt.status,
Body: ioutil.NopCloser(body), Body: ioutil.NopCloser(body),
}, nil Header: make(http.Header),
}
for k, v := range rt.header {
res.Header.Set(k, v)
}
return res, nil
} }
func (rt *FakeRoundTripper) Reset() { func (rt *FakeRoundTripper) Reset() {
......
...@@ -493,6 +493,15 @@ func TestStartContainerNotFound(t *testing.T) { ...@@ -493,6 +493,15 @@ func TestStartContainerNotFound(t *testing.T) {
} }
} }
func TestStartContainerAlreadyRunning(t *testing.T) {
client := newTestClient(&FakeRoundTripper{message: "container already running", status: http.StatusNotModified})
err := client.StartContainer("a2334", &HostConfig{})
expected := &ContainerAlreadyRunning{ID: "a2334"}
if !reflect.DeepEqual(err, expected) {
t.Errorf("StartContainer: Wrong error returned. Want %#v. Got %#v.", expected, err)
}
}
func TestStopContainer(t *testing.T) { func TestStopContainer(t *testing.T) {
fakeRT := &FakeRoundTripper{message: "", status: http.StatusNoContent} fakeRT := &FakeRoundTripper{message: "", status: http.StatusNoContent}
client := newTestClient(fakeRT) client := newTestClient(fakeRT)
...@@ -520,6 +529,15 @@ func TestStopContainerNotFound(t *testing.T) { ...@@ -520,6 +529,15 @@ func TestStopContainerNotFound(t *testing.T) {
} }
} }
func TestStopContainerNotRunning(t *testing.T) {
client := newTestClient(&FakeRoundTripper{message: "container not running", status: http.StatusNotModified})
err := client.StopContainer("a2334", 10)
expected := &ContainerNotRunning{ID: "a2334"}
if !reflect.DeepEqual(err, expected) {
t.Errorf("StopContainer: Wrong error returned. Want %#v. Got %#v.", expected, err)
}
}
func TestRestartContainer(t *testing.T) { func TestRestartContainer(t *testing.T) {
fakeRT := &FakeRoundTripper{message: "", status: http.StatusNoContent} fakeRT := &FakeRoundTripper{message: "", status: http.StatusNoContent}
client := newTestClient(fakeRT) client := newTestClient(fakeRT)
...@@ -1313,8 +1331,12 @@ func TestExportContainerNoId(t *testing.T) { ...@@ -1313,8 +1331,12 @@ func TestExportContainerNoId(t *testing.T) {
client := Client{} client := Client{}
out := stdoutMock{bytes.NewBufferString("")} out := stdoutMock{bytes.NewBufferString("")}
err := client.ExportContainer(ExportContainerOptions{OutputStream: out}) err := client.ExportContainer(ExportContainerOptions{OutputStream: out})
if err != (NoSuchContainer{}) { e, ok := err.(*NoSuchContainer)
t.Errorf("ExportContainer: wrong error. Want %#v. Got %#v.", NoSuchContainer{}, err) if !ok {
t.Errorf("ExportContainer: wrong error. Want NoSuchContainer. Got %#v.", e)
}
if e.ID != "" {
t.Errorf("ExportContainer: wrong ID. Want %q. Got %q", "", e.ID)
} }
} }
...@@ -1361,3 +1383,34 @@ func TestPassingNameOptToCreateContainerReturnsItInContainer(t *testing.T) { ...@@ -1361,3 +1383,34 @@ func TestPassingNameOptToCreateContainerReturnsItInContainer(t *testing.T) {
t.Errorf("Container name expected to be TestCreateContainer, was %s", container.Name) t.Errorf("Container name expected to be TestCreateContainer, was %s", container.Name)
} }
} }
func TestAlwaysRestart(t *testing.T) {
policy := AlwaysRestart()
if policy.Name != "always" {
t.Errorf("AlwaysRestart(): wrong policy name. Want %q. Got %q", "always", policy.Name)
}
if policy.MaximumRetryCount != 0 {
t.Errorf("AlwaysRestart(): wrong MaximumRetryCount. Want 0. Got %d", policy.MaximumRetryCount)
}
}
func TestRestartOnFailure(t *testing.T) {
const retry = 5
policy := RestartOnFailure(retry)
if policy.Name != "on-failure" {
t.Errorf("RestartOnFailure(%d): wrong policy name. Want %q. Got %q", retry, "on-failure", policy.Name)
}
if policy.MaximumRetryCount != retry {
t.Errorf("RestartOnFailure(%d): wrong MaximumRetryCount. Want %d. Got %d", retry, retry, policy.MaximumRetryCount)
}
}
func TestNeverRestart(t *testing.T) {
policy := NeverRestart()
if policy.Name != "no" {
t.Errorf("NeverRestart(): wrong policy name. Want %q. Got %q", "always", policy.Name)
}
if policy.MaximumRetryCount != 0 {
t.Errorf("NeverRestart(): wrong MaximumRetryCount. Want 0. Got %d", policy.MaximumRetryCount)
}
}
...@@ -20,10 +20,10 @@ import ( ...@@ -20,10 +20,10 @@ import (
// APIEvents represents an event returned by the API. // APIEvents represents an event returned by the API.
type APIEvents struct { type APIEvents struct {
Status string Status string `json:"Status,omitempty" yaml:"Status,omitempty"`
ID string ID string `json:"ID,omitempty" yaml:"ID,omitempty"`
From string From string `json:"From,omitempty" yaml:"From,omitempty"`
Time int64 Time int64 `json:"Time,omitempty" yaml:"Time,omitempty"`
} }
type eventMonitoringState struct { type eventMonitoringState struct {
......
...@@ -8,10 +8,11 @@ import ( ...@@ -8,10 +8,11 @@ import (
"archive/tar" "archive/tar"
"bytes" "bytes"
"fmt" "fmt"
"github.com/fsouza/go-dockerclient"
"io" "io"
"log" "log"
"time" "time"
"github.com/fsouza/go-dockerclient"
) )
func ExampleClient_AttachToContainer() { func ExampleClient_AttachToContainer() {
......
...@@ -20,28 +20,26 @@ import ( ...@@ -20,28 +20,26 @@ import (
// APIImages represent an image returned in the ListImages call. // APIImages represent an image returned in the ListImages call.
type APIImages struct { type APIImages struct {
ID string `json:"Id"` ID string `json:"Id" yaml:"Id"`
RepoTags []string `json:",omitempty"` RepoTags []string `json:"RepoTags,omitempty" yaml:"RepoTags,omitempty"`
Created int64 Created int64 `json:"Created,omitempty" yaml:"Created,omitempty"`
Size int64 Size int64 `json:"Size,omitempty" yaml:"Size,omitempty"`
VirtualSize int64 VirtualSize int64 `json:"VirtualSize,omitempty" yaml:"VirtualSize,omitempty"`
ParentId string `json:",omitempty"` ParentId string `json:"ParentId,omitempty" yaml:"ParentId,omitempty"`
Repository string `json:",omitempty"`
Tag string `json:",omitempty"`
} }
type Image struct { type Image struct {
ID string `json:"id"` ID string `json:"Id" yaml:"Id"`
Parent string `json:"parent,omitempty"` Parent string `json:"Parent,omitempty" yaml:"Parent,omitempty"`
Comment string `json:"comment,omitempty"` Comment string `json:"Comment,omitempty" yaml:"Comment,omitempty"`
Created time.Time `json:"created"` Created time.Time `json:"Created,omitempty" yaml:"Created,omitempty"`
Container string `json:"container,omitempty"` Container string `json:"Container,omitempty" yaml:"Container,omitempty"`
ContainerConfig Config `json:"containerconfig,omitempty"` ContainerConfig Config `json:"ContainerConfig,omitempty" yaml:"ContainerConfig,omitempty"`
DockerVersion string `json:"dockerversion,omitempty"` DockerVersion string `json:"DockerVersion,omitempty" yaml:"DockerVersion,omitempty"`
Author string `json:"author,omitempty"` Author string `json:"Author,omitempty" yaml:"Author,omitempty"`
Config *Config `json:"config,omitempty"` Config *Config `json:"Config,omitempty" yaml:"Config,omitempty"`
Architecture string `json:"architecture,omitempty"` Architecture string `json:"Architecture,omitempty" yaml:"Architecture,omitempty"`
Size int64 Size int64 `json:"Size,omitempty" yaml:"Size,omitempty"`
} }
type ImagePre012 struct { type ImagePre012 struct {
...@@ -55,7 +53,7 @@ type ImagePre012 struct { ...@@ -55,7 +53,7 @@ type ImagePre012 struct {
Author string `json:"author,omitempty"` Author string `json:"author,omitempty"`
Config *Config `json:"config,omitempty"` Config *Config `json:"config,omitempty"`
Architecture string `json:"architecture,omitempty"` Architecture string `json:"architecture,omitempty"`
Size int64 Size int64 `json:"size,omitempty"`
} }
var ( var (
...@@ -164,7 +162,7 @@ type PushImageOptions struct { ...@@ -164,7 +162,7 @@ type PushImageOptions struct {
} }
// AuthConfiguration represents authentication options to use in the PushImage // AuthConfiguration represents authentication options to use in the PushImage
// method. It represents the authencation in the Docker index server. // method. It represents the authentication in the Docker index server.
type AuthConfiguration struct { type AuthConfiguration struct {
Username string `json:"username,omitempty"` Username string `json:"username,omitempty"`
Password string `json:"password,omitempty"` Password string `json:"password,omitempty"`
...@@ -190,7 +188,7 @@ func (c *Client) PushImage(opts PushImageOptions, auth AuthConfiguration) error ...@@ -190,7 +188,7 @@ func (c *Client) PushImage(opts PushImageOptions, auth AuthConfiguration) error
headers["X-Registry-Auth"] = base64.URLEncoding.EncodeToString(buf.Bytes()) headers["X-Registry-Auth"] = base64.URLEncoding.EncodeToString(buf.Bytes())
return c.stream("POST", path, true, headers, nil, opts.OutputStream, nil) return c.stream("POST", path, true, false, headers, nil, opts.OutputStream, nil)
} }
// PullImageOptions present the set of options available for pulling an image // PullImageOptions present the set of options available for pulling an image
...@@ -198,10 +196,11 @@ func (c *Client) PushImage(opts PushImageOptions, auth AuthConfiguration) error ...@@ -198,10 +196,11 @@ func (c *Client) PushImage(opts PushImageOptions, auth AuthConfiguration) error
// //
// See http://goo.gl/PhBKnS for more details. // See http://goo.gl/PhBKnS for more details.
type PullImageOptions struct { type PullImageOptions struct {
Repository string `qs:"fromImage"` Repository string `qs:"fromImage"`
Registry string Registry string
Tag string Tag string
OutputStream io.Writer `qs:"-"` OutputStream io.Writer `qs:"-"`
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 w.
...@@ -217,12 +216,41 @@ func (c *Client) PullImage(opts PullImageOptions, auth AuthConfiguration) error ...@@ -217,12 +216,41 @@ func (c *Client) PullImage(opts PullImageOptions, auth AuthConfiguration) error
json.NewEncoder(&buf).Encode(auth) json.NewEncoder(&buf).Encode(auth)
headers["X-Registry-Auth"] = base64.URLEncoding.EncodeToString(buf.Bytes()) headers["X-Registry-Auth"] = base64.URLEncoding.EncodeToString(buf.Bytes())
return c.createImage(queryString(&opts), headers, nil, opts.OutputStream) return c.createImage(queryString(&opts), headers, nil, opts.OutputStream, opts.RawJSONStream)
} }
func (c *Client) createImage(qs string, headers map[string]string, in io.Reader, w io.Writer) error { func (c *Client) createImage(qs string, headers map[string]string, in io.Reader, w io.Writer, rawJSONStream bool) error {
path := "/images/create?" + qs path := "/images/create?" + qs
return c.stream("POST", path, true, headers, in, w, nil) return c.stream("POST", path, true, rawJSONStream, headers, in, w, nil)
}
// LoadImageOptions represents the options for LoadImage Docker API Call
//
// See http://goo.gl/Y8NNCq for more details.
type LoadImageOptions struct {
InputStream io.Reader
}
// LoadImage imports a tarball docker image
//
// See http://goo.gl/Y8NNCq for more details.
func (c *Client) LoadImage(opts LoadImageOptions) error {
return c.stream("POST", "/images/load", true, false, nil, opts.InputStream, nil, nil)
}
// ExportImageOptions represent the options for ExportImage Docker API call
//
// See http://goo.gl/mi6kvk for more details.
type ExportImageOptions struct {
Name string
OutputStream io.Writer
}
// ExportImage exports an image (as a tar file) into the stream
//
// See http://goo.gl/mi6kvk for more details.
func (c *Client) ExportImage(opts ExportImageOptions) error {
return c.stream("GET", fmt.Sprintf("/images/%s/get", opts.Name), true, false, nil, nil, opts.OutputStream, nil)
} }
// ImportImageOptions present the set of informations available for importing // ImportImageOptions present the set of informations available for importing
...@@ -257,20 +285,21 @@ func (c *Client) ImportImage(opts ImportImageOptions) error { ...@@ -257,20 +285,21 @@ func (c *Client) ImportImage(opts ImportImageOptions) error {
opts.InputStream = bytes.NewBuffer(b) opts.InputStream = bytes.NewBuffer(b)
opts.Source = "-" opts.Source = "-"
} }
return c.createImage(queryString(&opts), nil, opts.InputStream, opts.OutputStream) return c.createImage(queryString(&opts), nil, opts.InputStream, opts.OutputStream, false)
} }
// BuildImageOptions present the set of informations available for building // BuildImageOptions present the set of informations available for building
// an image from a tarfile with a Dockerfile in it,the details about Dockerfile // an image from a tarfile with a Dockerfile in it,the details about Dockerfile
// see http://docs.docker.io/en/latest/reference/builder/ // see http://docs.docker.io/en/latest/reference/builder/
type BuildImageOptions struct { type BuildImageOptions struct {
Name string `qs:"t"` Name string `qs:"t"`
NoCache bool `qs:"nocache"` NoCache bool `qs:"nocache"`
SuppressOutput bool `qs:"q"` SuppressOutput bool `qs:"q"`
RmTmpContainer bool `qs:"rm"` RmTmpContainer bool `qs:"rm"`
InputStream io.Reader `qs:"-"` ForceRmTmpContainer bool `qs:"forcerm"`
OutputStream io.Writer `qs:"-"` InputStream io.Reader `qs:"-"`
Remote string `qs:"remote"` OutputStream io.Writer `qs:"-"`
Remote string `qs:"remote"`
} }
// BuildImage builds an image from a tarball's url or a Dockerfile in the input // BuildImage builds an image from a tarball's url or a Dockerfile in the input
...@@ -289,7 +318,7 @@ func (c *Client) BuildImage(opts BuildImageOptions) error { ...@@ -289,7 +318,7 @@ func (c *Client) BuildImage(opts BuildImageOptions) error {
return ErrMissingRepo return ErrMissingRepo
} }
return c.stream("POST", fmt.Sprintf("/build?%s", return c.stream("POST", fmt.Sprintf("/build?%s",
queryString(&opts)), true, headers, opts.InputStream, opts.OutputStream, nil) queryString(&opts)), true, false, headers, opts.InputStream, opts.OutputStream, nil)
} }
// TagImageOptions present the set of options to tag an image // TagImageOptions present the set of options to tag an image
......
...@@ -309,6 +309,33 @@ func TestPullImage(t *testing.T) { ...@@ -309,6 +309,33 @@ func TestPullImage(t *testing.T) {
} }
} }
func TestPullImageWithRawJSON(t *testing.T) {
body := `
{"status":"Pulling..."}
{"status":"Pulling", "progress":"1 B/ 100 B", "progressDetail":{"current":1, "total":100}}
`
fakeRT := &FakeRoundTripper{
message: body,
status: http.StatusOK,
header: map[string]string{
"Content-Type": "application/json",
},
}
client := newTestClient(fakeRT)
var buf bytes.Buffer
err := client.PullImage(PullImageOptions{
Repository: "base",
OutputStream: &buf,
RawJSONStream: true,
}, AuthConfiguration{})
if err != nil {
t.Fatal(err)
}
if buf.String() != body {
t.Errorf("PullImage: Wrong raw output. Want %q. Got %q", body, buf.String())
}
}
func TestPullImageWithoutOutputStream(t *testing.T) { func TestPullImageWithoutOutputStream(t *testing.T) {
fakeRT := &FakeRoundTripper{message: "Pulling 1/100", status: http.StatusOK} fakeRT := &FakeRoundTripper{message: "Pulling 1/100", status: http.StatusOK}
client := newTestClient(fakeRT) client := newTestClient(fakeRT)
...@@ -514,19 +541,20 @@ func TestBuildImageParameters(t *testing.T) { ...@@ -514,19 +541,20 @@ func TestBuildImageParameters(t *testing.T) {
client := newTestClient(fakeRT) client := newTestClient(fakeRT)
var buf bytes.Buffer var buf bytes.Buffer
opts := BuildImageOptions{ opts := BuildImageOptions{
Name: "testImage", Name: "testImage",
NoCache: true, NoCache: true,
SuppressOutput: true, SuppressOutput: true,
RmTmpContainer: true, RmTmpContainer: true,
InputStream: &buf, ForceRmTmpContainer: true,
OutputStream: &buf, InputStream: &buf,
OutputStream: &buf,
} }
err := client.BuildImage(opts) err := client.BuildImage(opts)
if err != nil && strings.Index(err.Error(), "build image fail") == -1 { if err != nil && strings.Index(err.Error(), "build image fail") == -1 {
t.Fatal(err) t.Fatal(err)
} }
req := fakeRT.requests[0] req := fakeRT.requests[0]
expected := map[string][]string{"t": {opts.Name}, "nocache": {"1"}, "q": {"1"}, "rm": {"1"}} expected := map[string][]string{"t": {opts.Name}, "nocache": {"1"}, "q": {"1"}, "rm": {"1"}, "forcerm": {"1"}}
got := map[string][]string(req.URL.Query()) got := map[string][]string(req.URL.Query())
if !reflect.DeepEqual(got, expected) { if !reflect.DeepEqual(got, expected) {
t.Errorf("BuildImage: wrong query string. Want %#v. Got %#v.", expected, got) t.Errorf("BuildImage: wrong query string. Want %#v. Got %#v.", expected, got)
...@@ -640,3 +668,45 @@ func TestIsUrl(t *testing.T) { ...@@ -640,3 +668,45 @@ func TestIsUrl(t *testing.T) {
t.Errorf("isURL: wrong match. Expected %#v to not be a url. Got %#v", url, result) t.Errorf("isURL: wrong match. Expected %#v to not be a url. Got %#v", url, result)
} }
} }
func TestLoadImage(t *testing.T) {
fakeRT := &FakeRoundTripper{message: "", status: http.StatusOK}
client := newTestClient(fakeRT)
tar, err := os.Open("testing/data/container.tar")
if err != nil {
t.Fatal(err)
} else {
defer tar.Close()
}
opts := LoadImageOptions{InputStream: tar}
err = client.LoadImage(opts)
if nil != err {
t.Error(err)
}
req := fakeRT.requests[0]
if req.Method != "POST" {
t.Errorf("LoadImage: wrong method. Expected %q. Got %q.", "POST", req.Method)
}
if req.URL.Path != "/images/load" {
t.Errorf("LoadImage: wrong URL. Expected %q. Got %q.", "/images/load", req.URL.Path)
}
}
func TestExportImage(t *testing.T) {
var buf bytes.Buffer
fakeRT := &FakeRoundTripper{message: "", status: http.StatusOK}
client := newTestClient(fakeRT)
opts := ExportImageOptions{Name: "testimage", OutputStream: &buf}
err := client.ExportImage(opts)
if nil != err {
t.Error(err)
}
req := fakeRT.requests[0]
if req.Method != "GET" {
t.Errorf("ExportImage: wrong method. Expected %q. Got %q.", "GET", req.Method)
}
expectedPath := "/images/testimage/get"
if req.URL.Path != expectedPath {
t.Errorf("ExportIMage: wrong path. Expected %q. Got %q.", expectedPath, req.URL.Path)
}
}
...@@ -12,8 +12,6 @@ import ( ...@@ -12,8 +12,6 @@ import (
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
"github.com/fsouza/go-dockerclient"
"github.com/gorilla/mux"
mathrand "math/rand" mathrand "math/rand"
"net" "net"
"net/http" "net/http"
...@@ -22,6 +20,9 @@ import ( ...@@ -22,6 +20,9 @@ import (
"strings" "strings"
"sync" "sync"
"time" "time"
"github.com/fsouza/go-dockerclient"
"github.com/gorilla/mux"
) )
// DockerServer represents a programmable, concurrent (not much), HTTP server // DockerServer represents a programmable, concurrent (not much), HTTP server
...@@ -102,6 +103,8 @@ func (s *DockerServer) buildMuxer() { ...@@ -102,6 +103,8 @@ func (s *DockerServer) buildMuxer() {
s.mux.Path("/images/{name:.*}/push").Methods("POST").HandlerFunc(s.handlerWrapper(s.pushImage)) s.mux.Path("/images/{name:.*}/push").Methods("POST").HandlerFunc(s.handlerWrapper(s.pushImage))
s.mux.Path("/events").Methods("GET").HandlerFunc(s.listEvents) s.mux.Path("/events").Methods("GET").HandlerFunc(s.listEvents)
s.mux.Path("/_ping").Methods("GET").HandlerFunc(s.handlerWrapper(s.pingDocker)) s.mux.Path("/_ping").Methods("GET").HandlerFunc(s.handlerWrapper(s.pingDocker))
s.mux.Path("/images/load").Methods("POST").HandlerFunc(s.handlerWrapper(s.loadImage))
s.mux.Path("/images/{id:.*}/get").Methods("GET").HandlerFunc(s.handlerWrapper(s.getImage))
} }
// PrepareFailure adds a new expected failure based on a URL regexp it receives // PrepareFailure adds a new expected failure based on a URL regexp it receives
...@@ -653,3 +656,13 @@ func (s *DockerServer) generateEvent() *docker.APIEvents { ...@@ -653,3 +656,13 @@ func (s *DockerServer) generateEvent() *docker.APIEvents {
Time: time.Now().Unix(), Time: time.Now().Unix(),
} }
} }
func (s *DockerServer) loadImage(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
}
func (s *DockerServer) getImage(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Header().Set("Content-Type", "application/tar")
}
...@@ -7,7 +7,6 @@ package testing ...@@ -7,7 +7,6 @@ package testing
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/fsouza/go-dockerclient"
"math/rand" "math/rand"
"net" "net"
"net/http" "net/http"
...@@ -17,6 +16,8 @@ import ( ...@@ -17,6 +16,8 @@ import (
"strings" "strings"
"testing" "testing"
"time" "time"
"github.com/fsouza/go-dockerclient"
) )
func TestNewServer(t *testing.T) { func TestNewServer(t *testing.T) {
......
...@@ -17,10 +17,10 @@ limitations under the License. ...@@ -17,10 +17,10 @@ limitations under the License.
package v1beta1 package v1beta1
import ( import (
"github.com/fsouza/go-dockerclient"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch" "github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
"github.com/GoogleCloudPlatform/kubernetes/third_party/docker-api-structs"
) )
// Common string formats // Common string formats
......
Copyright (c) 2014, go-dockerclient authors
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This package is a fork of part of [go-dockerclient](https://github.com/fsouza/go-dockerclient).
// Copyright 2014 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 (
"time"
)
type Container struct {
ID string `yaml:"ID,omitempty" json:"ID,omitempty"`
Created time.Time `yaml:"Created,omitempty" json:"Created,omitempty"`
Path string `yaml:"Path,omitempty" json:"Path,omitempty"`
Args []string `yaml:"Args,omitempty" json:"Args,omitempty"`
Config *Config `yaml:"Config,omitempty" json:"Config,omitempty"`
State State `yaml:"State,omitempty" json:"State,omitempty"`
Image string `yaml:"Image,omitempty" json:"Image,omitempty"`
NetworkSettings *NetworkSettings `yaml:"NetworkSettings,omitempty" json:"NetworkSettings,omitempty"`
SysInitPath string `yaml:"SysInitPath,omitempty" json:"SysInitPath,omitempty"`
ResolvConfPath string `yaml:"ResolvConfPath,omitempty" json:"ResolvConfPath,omitempty"`
HostnamePath string `yaml:"HostnamePath,omitempty" json:"HostnamePath,omitempty"`
HostsPath string `yaml:"HostsPath,omitempty" json:"HostsPath,omitempty"`
Name string `yaml:"Name,omitempty" json:"Name,omitempty"`
Driver string `yaml:"Driver,omitempty" json:"Driver,omitempty"`
Volumes map[string]string `yaml:"Volumes,omitempty" json:"Volumes,omitempty"`
VolumesRW map[string]bool `yaml:"VolumesRW,omitempty" json:"VolumesRW,omitempty"`
HostConfig *HostConfig `yaml:"HostConfig,omitempty" json:"HostConfig,omitempty"`
}
type Config struct {
Hostname string `yaml:"Hostname,omitempty" json:"Hostname,omitempty"`
Domainname string `yaml:"Domainname,omitempty" json:"Domainname,omitempty"`
User string `yaml:"User,omitempty" json:"User,omitempty"`
Memory int64 `yaml:"Memory,omitempty" json:"Memory,omitempty"`
MemorySwap int64 `yaml:"MemorySwap,omitempty" json:"MemorySwap,omitempty"`
CpuShares int64 `yaml:"CpuShares,omitempty" json:"CpuShares,omitempty"`
AttachStdin bool `yaml:"AttachStdin,omitempty" json:"AttachStdin,omitempty"`
AttachStdout bool `yaml:"AttachStdout,omitempty" json:"AttachStdout,omitempty"`
AttachStderr bool `yaml:"AttachStderr,omitempty" json:"AttachStderr,omitempty"`
PortSpecs []string `yaml:"PortSpecs,omitempty" json:"PortSpecs,omitempty"`
ExposedPorts map[Port]struct{} `yaml:"ExposedPorts,omitempty" json:"ExposedPorts,omitempty"`
Tty bool `yaml:"Tty,omitempty" json:"Tty,omitempty"`
OpenStdin bool `yaml:"OpenStdin,omitempty" json:"OpenStdin,omitempty"`
StdinOnce bool `yaml:"StdinOnce,omitempty" json:"StdinOnce,omitempty"`
Env []string `yaml:"Env,omitempty" json:"Env,omitempty"`
Cmd []string `yaml:"Cmd,omitempty" json:"Cmd,omitempty"`
Dns []string `yaml:"Dns,omitempty" json:"Dns,omitempty"`
Image string `yaml:"Image,omitempty" json:"Image,omitempty"`
Volumes map[string]struct{} `yaml:"Volumes,omitempty" json:"Volumes,omitempty"`
VolumesFrom string `yaml:"VolumesFrom,omitempty" json:"VolumesFrom,omitempty"`
WorkingDir string `yaml:"WorkingDir,omitempty" json:"WorkingDir,omitempty"`
Entrypoint []string `yaml:"Entrypoint,omitempty" json:"Entrypoint,omitempty"`
NetworkDisabled bool `yaml:"NetworkDisabled,omitempty" json:"NetworkDisabled,omitempty"`
}
type State struct {
Running bool `yaml:"Running,omitempty" json:"Running,omitempty"`
Paused bool `yaml:"Paused,omitempty" json:"Paused,omitempty"`
Pid int `yaml:"Pid,omitempty" json:"Pid,omitempty"`
ExitCode int `yaml:"ExitCode,omitempty" json:"ExitCode,omitempty"`
StartedAt time.Time `yaml:"StartedAt,omitempty" json:"StartedAt,omitempty"`
FinishedAt time.Time `yaml:"FinishedAt,omitempty" json:"FinishedAt,omitempty"`
}
type PortBinding struct {
HostIp string `yaml:"HostIp,omitempty" json:"HostIp,omitempty"`
HostPort string `yaml:"HostPort,omitempty" json:"HostPort,omitempty"`
}
type PortMapping map[string]string
type NetworkSettings struct {
IPAddress string `yaml:"IPAddress,omitempty" json:"IPAddress,omitempty"`
IPPrefixLen int `yaml:"IPPrefixLen,omitempty" json:"IPPrefixLen,omitempty"`
Gateway string `yaml:"Gateway,omitempty" json:"Gateway,omitempty"`
Bridge string `yaml:"Bridge,omitempty" json:"Bridge,omitempty"`
PortMapping map[string]PortMapping `yaml:"PortMapping,omitempty" json:"PortMapping,omitempty"`
Ports map[Port][]PortBinding `yaml:"Ports,omitempty" json:"Ports,omitempty"`
}
type KeyValuePair struct {
Key string `yaml:"Key,omitempty" json:"Key,omitempty"`
Value string `yaml:"Value,omitempty" json:"Value,omitempty"`
}
type Port string
type HostConfig struct {
Binds []string `yaml:"Binds,omitempty" json:"Binds,omitempty"`
ContainerIDFile string `yaml:"ContainerIDFile,omitempty" json:"ContainerIDFile,omitempty"`
LxcConf []KeyValuePair `yaml:"LxcConf,omitempty" json:"LxcConf,omitempty"`
Privileged bool `yaml:"Privileged,omitempty" json:"Privileged,omitempty"`
PortBindings map[Port][]PortBinding `yaml:"PortBindings,omitempty" json:"PortBindings,omitempty"`
Links []string `yaml:"Links,omitempty" json:"Links,omitempty"`
PublishAllPorts bool `yaml:"PublishAllPorts,omitempty" json:"PublishAllPorts,omitempty"`
Dns []string `yaml:"Dns,omitempty" json:"Dns,omitempty"`
DnsSearch []string `yaml:"DnsSearch,omitempty" json:"DnsSearch,omitempty"`
VolumesFrom []string `yaml:"VolumesFrom,omitempty" json:"VolumesFrom,omitempty"`
NetworkMode string `yaml:"NetworkMode,omitempty" json:"NetworkMode,omitempty"`
}
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