mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 19:56:01 +00:00
Merge pull request #7247 from guenter/update-dockerclient
Upgrade go-dockerclient dependency to support CgroupParent
This commit is contained in:
commit
7c7b661cf3
2
Godeps/Godeps.json
generated
2
Godeps/Godeps.json
generated
@ -164,7 +164,7 @@
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/fsouza/go-dockerclient",
|
||||
"Rev": "17d39bcb22e8103ba6d1c0cb2530c6434cb870a3"
|
||||
"Rev": "09334c56c63bab2cd6c4ccab924d89e2419a361f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/garyburd/redigo/internal",
|
||||
|
5
Godeps/_workspace/src/github.com/fsouza/go-dockerclient/.travis.yml
generated
vendored
5
Godeps/_workspace/src/github.com/fsouza/go-dockerclient/.travis.yml
generated
vendored
@ -7,7 +7,6 @@ env:
|
||||
- GOARCH=amd64
|
||||
- GOARCH=386
|
||||
install:
|
||||
- go get -d ./...
|
||||
- make testdeps
|
||||
script:
|
||||
- go test ./...
|
||||
- ./testing/bin/fmtpolice
|
||||
- make test
|
||||
|
3
Godeps/_workspace/src/github.com/fsouza/go-dockerclient/AUTHORS
generated
vendored
3
Godeps/_workspace/src/github.com/fsouza/go-dockerclient/AUTHORS
generated
vendored
@ -26,6 +26,7 @@ Fatih Arslan <ftharsln@gmail.com>
|
||||
Flavia Missi <flaviamissi@gmail.com>
|
||||
Francisco Souza <f@souza.cc>
|
||||
Guillermo Álvarez Fernández <guillermo@cientifico.net>
|
||||
James Bardin <jbardin@litl.com>
|
||||
Jari Kolehmainen <jari.kolehmainen@digia.com>
|
||||
Jason Wilder <jwilder@litl.com>
|
||||
Jawher Moussa <jawher.moussa@gmail.com>
|
||||
@ -49,6 +50,7 @@ Nick Ethier <ncethier@gmail.com>
|
||||
Omeid Matten <public@omeid.me>
|
||||
Paul Morie <pmorie@gmail.com>
|
||||
Paul Weil <pweil@redhat.com>
|
||||
Peter Edge <peter.edge@gmail.com>
|
||||
Peter Jihoon Kim <raingrove@gmail.com>
|
||||
Philippe Lafoucrière <philippe.lafoucriere@tech-angels.com>
|
||||
Rafe Colton <rafael.colton@gmail.com>
|
||||
@ -64,6 +66,7 @@ Sridhar Ratnakumar <sridharr@activestate.com>
|
||||
Summer Mousa <smousa@zenoss.com>
|
||||
Tarsis Azevedo <tarsis@corp.globo.com>
|
||||
Tim Schindler <tim@catalyst-zero.com>
|
||||
Tobi Knaup <tobi@mesosphere.io>
|
||||
Vincenzo Prignano <vincenzo.prignano@gmail.com>
|
||||
Wiliam Souza <wiliamsouza83@gmail.com>
|
||||
Ye Yin <eyniy@qq.com>
|
||||
|
35
Godeps/_workspace/src/github.com/fsouza/go-dockerclient/Makefile
generated
vendored
Normal file
35
Godeps/_workspace/src/github.com/fsouza/go-dockerclient/Makefile
generated
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
.PHONY: \
|
||||
all \
|
||||
deps \
|
||||
updatedeps \
|
||||
testdeps \
|
||||
updatetestdeps \
|
||||
cov \
|
||||
test \
|
||||
clean
|
||||
|
||||
all: test
|
||||
|
||||
deps:
|
||||
go get -d -v ./...
|
||||
|
||||
updatedeps:
|
||||
go get -d -v -u -f ./...
|
||||
|
||||
testdeps:
|
||||
go get -d -v -t ./...
|
||||
|
||||
updatetestdeps:
|
||||
go get -d -v -t -u -f ./...
|
||||
|
||||
cov: testdeps
|
||||
go get -v github.com/axw/gocov/gocov
|
||||
go get golang.org/x/tools/cmd/cover
|
||||
gocov test | gocov report
|
||||
|
||||
test: testdeps
|
||||
go test ./...
|
||||
./testing/bin/fmtpolice
|
||||
|
||||
clean:
|
||||
go clean ./...
|
3
Godeps/_workspace/src/github.com/fsouza/go-dockerclient/README.markdown
generated
vendored
3
Godeps/_workspace/src/github.com/fsouza/go-dockerclient/README.markdown
generated
vendored
@ -66,5 +66,4 @@ func main() {
|
||||
|
||||
You can run the tests with:
|
||||
|
||||
go get -d ./...
|
||||
go test ./...
|
||||
make test
|
||||
|
165
Godeps/_workspace/src/github.com/fsouza/go-dockerclient/client.go
generated
vendored
165
Godeps/_workspace/src/github.com/fsouza/go-dockerclient/client.go
generated
vendored
@ -252,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, false)
|
||||
body, status, err := c.do("GET", path, doOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -263,7 +263,7 @@ func (c *Client) Ping() error {
|
||||
}
|
||||
|
||||
func (c *Client) getServerAPIVersionString() (version string, err error) {
|
||||
body, status, err := c.do("GET", "/version", nil, false)
|
||||
body, status, err := c.do("GET", "/version", doOptions{})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@ -279,10 +279,15 @@ func (c *Client) getServerAPIVersionString() (version string, err error) {
|
||||
return version, nil
|
||||
}
|
||||
|
||||
func (c *Client) do(method, path string, data interface{}, forceJSON bool) ([]byte, int, error) {
|
||||
type doOptions struct {
|
||||
data interface{}
|
||||
forceJSON bool
|
||||
}
|
||||
|
||||
func (c *Client) do(method, path string, doOptions doOptions) ([]byte, int, error) {
|
||||
var params io.Reader
|
||||
if data != nil || forceJSON {
|
||||
buf, err := json.Marshal(data)
|
||||
if doOptions.data != nil || doOptions.forceJSON {
|
||||
buf, err := json.Marshal(doOptions.data)
|
||||
if err != nil {
|
||||
return nil, -1, err
|
||||
}
|
||||
@ -299,7 +304,7 @@ func (c *Client) do(method, path string, data interface{}, forceJSON bool) ([]by
|
||||
return nil, -1, err
|
||||
}
|
||||
req.Header.Set("User-Agent", userAgent)
|
||||
if data != nil {
|
||||
if doOptions.data != nil {
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
} else if method == "POST" {
|
||||
req.Header.Set("Content-Type", "plain/text")
|
||||
@ -339,9 +344,18 @@ func (c *Client) do(method, path string, data interface{}, forceJSON bool) ([]by
|
||||
return body, resp.StatusCode, nil
|
||||
}
|
||||
|
||||
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 {
|
||||
in = bytes.NewReader(nil)
|
||||
type streamOptions struct {
|
||||
setRawTerminal bool
|
||||
rawJSONStream bool
|
||||
headers map[string]string
|
||||
in io.Reader
|
||||
stdout io.Writer
|
||||
stderr io.Writer
|
||||
}
|
||||
|
||||
func (c *Client) stream(method, path string, streamOptions streamOptions) error {
|
||||
if (method == "POST" || method == "PUT") && streamOptions.in == nil {
|
||||
streamOptions.in = bytes.NewReader(nil)
|
||||
}
|
||||
if path != "/version" && !c.SkipServerVersionCheck && c.expectedAPIVersion == nil {
|
||||
err := c.checkAPIVersion()
|
||||
@ -349,7 +363,7 @@ func (c *Client) stream(method, path string, setRawTerminal, rawJSONStream bool,
|
||||
return err
|
||||
}
|
||||
}
|
||||
req, err := http.NewRequest(method, c.getURL(path), in)
|
||||
req, err := http.NewRequest(method, c.getURL(path), streamOptions.in)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -357,17 +371,17 @@ func (c *Client) stream(method, path string, setRawTerminal, rawJSONStream bool,
|
||||
if method == "POST" {
|
||||
req.Header.Set("Content-Type", "plain/text")
|
||||
}
|
||||
for key, val := range headers {
|
||||
for key, val := range streamOptions.headers {
|
||||
req.Header.Set(key, val)
|
||||
}
|
||||
var resp *http.Response
|
||||
protocol := c.endpointURL.Scheme
|
||||
address := c.endpointURL.Path
|
||||
if stdout == nil {
|
||||
stdout = ioutil.Discard
|
||||
if streamOptions.stdout == nil {
|
||||
streamOptions.stdout = ioutil.Discard
|
||||
}
|
||||
if stderr == nil {
|
||||
stderr = ioutil.Discard
|
||||
if streamOptions.stderr == nil {
|
||||
streamOptions.stderr = ioutil.Discard
|
||||
}
|
||||
if protocol == "unix" {
|
||||
dial, err := net.Dial(protocol, address)
|
||||
@ -397,8 +411,8 @@ func (c *Client) stream(method, path string, setRawTerminal, rawJSONStream bool,
|
||||
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)
|
||||
if streamOptions.rawJSONStream {
|
||||
_, err = io.Copy(streamOptions.stdout, resp.Body)
|
||||
return err
|
||||
}
|
||||
dec := json.NewDecoder(resp.Body)
|
||||
@ -410,28 +424,37 @@ func (c *Client) stream(method, path string, setRawTerminal, rawJSONStream bool,
|
||||
return err
|
||||
}
|
||||
if m.Stream != "" {
|
||||
fmt.Fprint(stdout, m.Stream)
|
||||
fmt.Fprint(streamOptions.stdout, m.Stream)
|
||||
} else if m.Progress != "" {
|
||||
fmt.Fprintf(stdout, "%s %s\r", m.Status, m.Progress)
|
||||
fmt.Fprintf(streamOptions.stdout, "%s %s\r", m.Status, m.Progress)
|
||||
} else if m.Error != "" {
|
||||
return errors.New(m.Error)
|
||||
}
|
||||
if m.Status != "" {
|
||||
fmt.Fprintln(stdout, m.Status)
|
||||
fmt.Fprintln(streamOptions.stdout, m.Status)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if setRawTerminal {
|
||||
_, err = io.Copy(stdout, resp.Body)
|
||||
if streamOptions.setRawTerminal {
|
||||
_, err = io.Copy(streamOptions.stdout, resp.Body)
|
||||
} else {
|
||||
_, err = stdCopy(stdout, stderr, resp.Body)
|
||||
_, err = stdCopy(streamOptions.stdout, streamOptions.stderr, resp.Body)
|
||||
}
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Client) hijack(method, path string, success chan struct{}, setRawTerminal bool, in io.Reader, stderr, stdout io.Writer, data interface{}) error {
|
||||
type hijackOptions struct {
|
||||
success chan struct{}
|
||||
setRawTerminal bool
|
||||
in io.Reader
|
||||
stdout io.Writer
|
||||
stderr io.Writer
|
||||
data interface{}
|
||||
}
|
||||
|
||||
func (c *Client) hijack(method, path string, hijackOptions hijackOptions) error {
|
||||
if path != "/version" && !c.SkipServerVersionCheck && c.expectedAPIVersion == nil {
|
||||
err := c.checkAPIVersion()
|
||||
if err != nil {
|
||||
@ -440,19 +463,19 @@ func (c *Client) hijack(method, path string, success chan struct{}, setRawTermin
|
||||
}
|
||||
|
||||
var params io.Reader
|
||||
if data != nil {
|
||||
buf, err := json.Marshal(data)
|
||||
if hijackOptions.data != nil {
|
||||
buf, err := json.Marshal(hijackOptions.data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
params = bytes.NewBuffer(buf)
|
||||
}
|
||||
|
||||
if stdout == nil {
|
||||
stdout = ioutil.Discard
|
||||
if hijackOptions.stdout == nil {
|
||||
hijackOptions.stdout = ioutil.Discard
|
||||
}
|
||||
if stderr == nil {
|
||||
stderr = ioutil.Discard
|
||||
if hijackOptions.stderr == nil {
|
||||
hijackOptions.stderr = ioutil.Discard
|
||||
}
|
||||
req, err := http.NewRequest(method, c.getURL(path), params)
|
||||
if err != nil {
|
||||
@ -480,9 +503,9 @@ func (c *Client) hijack(method, path string, success chan struct{}, setRawTermin
|
||||
clientconn := httputil.NewClientConn(dial, nil)
|
||||
defer clientconn.Close()
|
||||
clientconn.Do(req)
|
||||
if success != nil {
|
||||
success <- struct{}{}
|
||||
<-success
|
||||
if hijackOptions.success != nil {
|
||||
hijackOptions.success <- struct{}{}
|
||||
<-hijackOptions.success
|
||||
}
|
||||
rwc, br := clientconn.Hijack()
|
||||
defer rwc.Close()
|
||||
@ -491,18 +514,18 @@ func (c *Client) hijack(method, path string, success chan struct{}, setRawTermin
|
||||
go func() {
|
||||
defer close(exit)
|
||||
var err error
|
||||
if setRawTerminal {
|
||||
if hijackOptions.setRawTerminal {
|
||||
// When TTY is ON, use regular copy
|
||||
_, err = io.Copy(stdout, br)
|
||||
_, err = io.Copy(hijackOptions.stdout, br)
|
||||
} else {
|
||||
_, err = stdCopy(stdout, stderr, br)
|
||||
_, err = stdCopy(hijackOptions.stdout, hijackOptions.stderr, br)
|
||||
}
|
||||
errs <- err
|
||||
}()
|
||||
go func() {
|
||||
var err error
|
||||
if in != nil {
|
||||
_, err = io.Copy(rwc, in)
|
||||
if hijackOptions.in != nil {
|
||||
_, err = io.Copy(rwc, hijackOptions.in)
|
||||
}
|
||||
rwc.(interface {
|
||||
CloseWrite() error
|
||||
@ -555,39 +578,49 @@ func queryString(opts interface{}) string {
|
||||
} else if key == "-" {
|
||||
continue
|
||||
}
|
||||
v := value.Field(i)
|
||||
switch v.Kind() {
|
||||
case reflect.Bool:
|
||||
if v.Bool() {
|
||||
items.Add(key, "1")
|
||||
addQueryStringValue(items, key, value.Field(i))
|
||||
}
|
||||
return items.Encode()
|
||||
}
|
||||
|
||||
func addQueryStringValue(items url.Values, key string, v reflect.Value) {
|
||||
switch v.Kind() {
|
||||
case reflect.Bool:
|
||||
if v.Bool() {
|
||||
items.Add(key, "1")
|
||||
}
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
if v.Int() > 0 {
|
||||
items.Add(key, strconv.FormatInt(v.Int(), 10))
|
||||
}
|
||||
case reflect.Float32, reflect.Float64:
|
||||
if v.Float() > 0 {
|
||||
items.Add(key, strconv.FormatFloat(v.Float(), 'f', -1, 64))
|
||||
}
|
||||
case reflect.String:
|
||||
if v.String() != "" {
|
||||
items.Add(key, v.String())
|
||||
}
|
||||
case reflect.Ptr:
|
||||
if !v.IsNil() {
|
||||
if b, err := json.Marshal(v.Interface()); err == nil {
|
||||
items.Add(key, string(b))
|
||||
}
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
if v.Int() > 0 {
|
||||
items.Add(key, strconv.FormatInt(v.Int(), 10))
|
||||
}
|
||||
case reflect.Map:
|
||||
if len(v.MapKeys()) > 0 {
|
||||
if b, err := json.Marshal(v.Interface()); err == nil {
|
||||
items.Add(key, string(b))
|
||||
}
|
||||
case reflect.Float32, reflect.Float64:
|
||||
if v.Float() > 0 {
|
||||
items.Add(key, strconv.FormatFloat(v.Float(), 'f', -1, 64))
|
||||
}
|
||||
case reflect.String:
|
||||
if v.String() != "" {
|
||||
items.Add(key, v.String())
|
||||
}
|
||||
case reflect.Ptr:
|
||||
if !v.IsNil() {
|
||||
if b, err := json.Marshal(v.Interface()); err == nil {
|
||||
items.Add(key, string(b))
|
||||
}
|
||||
}
|
||||
case reflect.Map:
|
||||
if len(v.MapKeys()) > 0 {
|
||||
if b, err := json.Marshal(v.Interface()); err == nil {
|
||||
items.Add(key, string(b))
|
||||
}
|
||||
}
|
||||
case reflect.Array, reflect.Slice:
|
||||
vLen := v.Len()
|
||||
if vLen > 0 {
|
||||
for i := 0; i < vLen; i++ {
|
||||
addQueryStringValue(items, key, v.Index(i))
|
||||
}
|
||||
}
|
||||
}
|
||||
return items.Encode()
|
||||
}
|
||||
|
||||
// Error represents failures in the API. It represents a failure from the API.
|
||||
|
73
Godeps/_workspace/src/github.com/fsouza/go-dockerclient/container.go
generated
vendored
73
Godeps/_workspace/src/github.com/fsouza/go-dockerclient/container.go
generated
vendored
@ -56,7 +56,7 @@ type APIContainers struct {
|
||||
// See http://goo.gl/6Y4Gz7 for more details.
|
||||
func (c *Client) ListContainers(opts ListContainersOptions) ([]APIContainers, error) {
|
||||
path := "/containers/json?" + queryString(opts)
|
||||
body, _, err := c.do("GET", path, nil, false)
|
||||
body, _, err := c.do("GET", path, doOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -90,6 +90,7 @@ func (p Port) Proto() string {
|
||||
type State struct {
|
||||
Running bool `json:"Running,omitempty" yaml:"Running,omitempty"`
|
||||
Paused bool `json:"Paused,omitempty" yaml:"Paused,omitempty"`
|
||||
Restarting bool `json:"Restarting,omitempty" yaml:"Restarting,omitempty"`
|
||||
OOMKilled bool `json:"OOMKilled,omitempty" yaml:"OOMKilled,omitempty"`
|
||||
Pid int `json:"Pid,omitempty" yaml:"Pid,omitempty"`
|
||||
ExitCode int `json:"ExitCode,omitempty" yaml:"ExitCode,omitempty"`
|
||||
@ -263,7 +264,7 @@ type RenameContainerOptions struct {
|
||||
//
|
||||
// See http://goo.gl/L00hoj for more details.
|
||||
func (c *Client) RenameContainer(opts RenameContainerOptions) error {
|
||||
_, _, err := c.do("POST", fmt.Sprintf("/containers/"+opts.ID+"/rename?%s", queryString(opts)), nil, false)
|
||||
_, _, err := c.do("POST", fmt.Sprintf("/containers/"+opts.ID+"/rename?%s", queryString(opts)), doOptions{})
|
||||
return err
|
||||
}
|
||||
|
||||
@ -272,7 +273,7 @@ func (c *Client) RenameContainer(opts RenameContainerOptions) error {
|
||||
// See http://goo.gl/CxVuJ5 for more details.
|
||||
func (c *Client) InspectContainer(id string) (*Container, error) {
|
||||
path := "/containers/" + id + "/json"
|
||||
body, status, err := c.do("GET", path, nil, false)
|
||||
body, status, err := c.do("GET", path, doOptions{})
|
||||
if status == http.StatusNotFound {
|
||||
return nil, &NoSuchContainer{ID: id}
|
||||
}
|
||||
@ -292,7 +293,7 @@ func (c *Client) InspectContainer(id string) (*Container, error) {
|
||||
// See http://goo.gl/QkW9sH for more details.
|
||||
func (c *Client) ContainerChanges(id string) ([]Change, error) {
|
||||
path := "/containers/" + id + "/changes"
|
||||
body, status, err := c.do("GET", path, nil, false)
|
||||
body, status, err := c.do("GET", path, doOptions{})
|
||||
if status == http.StatusNotFound {
|
||||
return nil, &NoSuchContainer{ID: id}
|
||||
}
|
||||
@ -322,13 +323,19 @@ type CreateContainerOptions struct {
|
||||
// See http://goo.gl/mErxNp for more details.
|
||||
func (c *Client) CreateContainer(opts CreateContainerOptions) (*Container, error) {
|
||||
path := "/containers/create?" + queryString(opts)
|
||||
body, status, err := c.do("POST", path, struct {
|
||||
*Config
|
||||
HostConfig *HostConfig `json:"HostConfig,omitempty" yaml:"HostConfig,omitempty"`
|
||||
}{
|
||||
opts.Config,
|
||||
opts.HostConfig,
|
||||
}, false)
|
||||
body, status, err := c.do(
|
||||
"POST",
|
||||
path,
|
||||
doOptions{
|
||||
data: struct {
|
||||
*Config
|
||||
HostConfig *HostConfig `json:"HostConfig,omitempty" yaml:"HostConfig,omitempty"`
|
||||
}{
|
||||
opts.Config,
|
||||
opts.HostConfig,
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
if status == http.StatusNotFound {
|
||||
return nil, ErrNoSuchImage
|
||||
@ -417,6 +424,7 @@ type HostConfig struct {
|
||||
LogConfig LogConfig `json:"LogConfig,omitempty" yaml:"LogConfig,omitempty"`
|
||||
ReadonlyRootfs bool `json:"ReadonlyRootfs,omitempty" yaml:"ReadonlyRootfs,omitempty"`
|
||||
SecurityOpt []string `json:"SecurityOpt,omitempty" yaml:"SecurityOpt,omitempty"`
|
||||
CgroupParent string `json:"CgroupParent,omitempty" yaml:"CgroupParent,omitempty"`
|
||||
}
|
||||
|
||||
// StartContainer starts a container, returning an error in case of failure.
|
||||
@ -424,7 +432,7 @@ type HostConfig struct {
|
||||
// See http://goo.gl/iM5GYs for more details.
|
||||
func (c *Client) StartContainer(id string, hostConfig *HostConfig) error {
|
||||
path := "/containers/" + id + "/start"
|
||||
_, status, err := c.do("POST", path, hostConfig, true)
|
||||
_, status, err := c.do("POST", path, doOptions{data: hostConfig, forceJSON: true})
|
||||
if status == http.StatusNotFound {
|
||||
return &NoSuchContainer{ID: id, Err: err}
|
||||
}
|
||||
@ -443,7 +451,7 @@ func (c *Client) StartContainer(id string, hostConfig *HostConfig) error {
|
||||
// See http://goo.gl/EbcpXt for more details.
|
||||
func (c *Client) StopContainer(id string, timeout uint) error {
|
||||
path := fmt.Sprintf("/containers/%s/stop?t=%d", id, timeout)
|
||||
_, status, err := c.do("POST", path, nil, false)
|
||||
_, status, err := c.do("POST", path, doOptions{})
|
||||
if status == http.StatusNotFound {
|
||||
return &NoSuchContainer{ID: id}
|
||||
}
|
||||
@ -462,7 +470,7 @@ func (c *Client) StopContainer(id string, timeout uint) error {
|
||||
// See http://goo.gl/VOzR2n for more details.
|
||||
func (c *Client) RestartContainer(id string, timeout uint) error {
|
||||
path := fmt.Sprintf("/containers/%s/restart?t=%d", id, timeout)
|
||||
_, status, err := c.do("POST", path, nil, false)
|
||||
_, status, err := c.do("POST", path, doOptions{})
|
||||
if status == http.StatusNotFound {
|
||||
return &NoSuchContainer{ID: id}
|
||||
}
|
||||
@ -477,7 +485,7 @@ func (c *Client) RestartContainer(id string, timeout uint) error {
|
||||
// See http://goo.gl/AM5t42 for more details.
|
||||
func (c *Client) PauseContainer(id string) error {
|
||||
path := fmt.Sprintf("/containers/%s/pause", id)
|
||||
_, status, err := c.do("POST", path, nil, false)
|
||||
_, status, err := c.do("POST", path, doOptions{})
|
||||
if status == http.StatusNotFound {
|
||||
return &NoSuchContainer{ID: id}
|
||||
}
|
||||
@ -492,7 +500,7 @@ func (c *Client) PauseContainer(id string) error {
|
||||
// See http://goo.gl/eBrNSL for more details.
|
||||
func (c *Client) UnpauseContainer(id string) error {
|
||||
path := fmt.Sprintf("/containers/%s/unpause", id)
|
||||
_, status, err := c.do("POST", path, nil, false)
|
||||
_, status, err := c.do("POST", path, doOptions{})
|
||||
if status == http.StatusNotFound {
|
||||
return &NoSuchContainer{ID: id}
|
||||
}
|
||||
@ -521,7 +529,7 @@ func (c *Client) TopContainer(id string, psArgs string) (TopResult, error) {
|
||||
args = fmt.Sprintf("?ps_args=%s", psArgs)
|
||||
}
|
||||
path := fmt.Sprintf("/containers/%s/top%s", id, args)
|
||||
body, status, err := c.do("GET", path, nil, false)
|
||||
body, status, err := c.do("GET", path, doOptions{})
|
||||
if status == http.StatusNotFound {
|
||||
return result, &NoSuchContainer{ID: id}
|
||||
}
|
||||
@ -553,7 +561,7 @@ type KillContainerOptions struct {
|
||||
// See http://goo.gl/TFkECx for more details.
|
||||
func (c *Client) KillContainer(opts KillContainerOptions) error {
|
||||
path := "/containers/" + opts.ID + "/kill" + "?" + queryString(opts)
|
||||
_, status, err := c.do("POST", path, nil, false)
|
||||
_, status, err := c.do("POST", path, doOptions{})
|
||||
if status == http.StatusNotFound {
|
||||
return &NoSuchContainer{ID: opts.ID}
|
||||
}
|
||||
@ -584,7 +592,7 @@ type RemoveContainerOptions struct {
|
||||
// See http://goo.gl/ZB83ji for more details.
|
||||
func (c *Client) RemoveContainer(opts RemoveContainerOptions) error {
|
||||
path := "/containers/" + opts.ID + "?" + queryString(opts)
|
||||
_, status, err := c.do("DELETE", path, nil, false)
|
||||
_, status, err := c.do("DELETE", path, doOptions{})
|
||||
if status == http.StatusNotFound {
|
||||
return &NoSuchContainer{ID: opts.ID}
|
||||
}
|
||||
@ -613,7 +621,7 @@ func (c *Client) CopyFromContainer(opts CopyFromContainerOptions) error {
|
||||
return &NoSuchContainer{ID: opts.Container}
|
||||
}
|
||||
url := fmt.Sprintf("/containers/%s/copy", opts.Container)
|
||||
body, status, err := c.do("POST", url, opts, false)
|
||||
body, status, err := c.do("POST", url, doOptions{data: opts})
|
||||
if status == http.StatusNotFound {
|
||||
return &NoSuchContainer{ID: opts.Container}
|
||||
}
|
||||
@ -629,7 +637,7 @@ func (c *Client) CopyFromContainer(opts CopyFromContainerOptions) error {
|
||||
//
|
||||
// See http://goo.gl/J88DHU for more details.
|
||||
func (c *Client) WaitContainer(id string) (int, error) {
|
||||
body, status, err := c.do("POST", "/containers/"+id+"/wait", nil, false)
|
||||
body, status, err := c.do("POST", "/containers/"+id+"/wait", doOptions{})
|
||||
if status == http.StatusNotFound {
|
||||
return 0, &NoSuchContainer{ID: id}
|
||||
}
|
||||
@ -661,7 +669,7 @@ type CommitContainerOptions struct {
|
||||
// See http://goo.gl/Jn8pe8 for more details.
|
||||
func (c *Client) CommitContainer(opts CommitContainerOptions) (*Image, error) {
|
||||
path := "/commit?" + queryString(opts)
|
||||
body, status, err := c.do("POST", path, opts.Run, false)
|
||||
body, status, err := c.do("POST", path, doOptions{data: opts.Run})
|
||||
if status == http.StatusNotFound {
|
||||
return nil, &NoSuchContainer{ID: opts.Container}
|
||||
}
|
||||
@ -720,7 +728,13 @@ 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.RawTerminal, opts.InputStream, opts.ErrorStream, opts.OutputStream, nil)
|
||||
return c.hijack("POST", path, hijackOptions{
|
||||
success: opts.Success,
|
||||
setRawTerminal: opts.RawTerminal,
|
||||
in: opts.InputStream,
|
||||
stdout: opts.OutputStream,
|
||||
stderr: opts.ErrorStream,
|
||||
})
|
||||
}
|
||||
|
||||
// LogsOptions represents the set of options used when getting logs from a
|
||||
@ -752,7 +766,11 @@ func (c *Client) Logs(opts LogsOptions) error {
|
||||
opts.Tail = "all"
|
||||
}
|
||||
path := "/containers/" + opts.Container + "/logs?" + queryString(opts)
|
||||
return c.stream("GET", path, opts.RawTerminal, false, nil, nil, opts.OutputStream, opts.ErrorStream)
|
||||
return c.stream("GET", path, streamOptions{
|
||||
setRawTerminal: opts.RawTerminal,
|
||||
stdout: opts.OutputStream,
|
||||
stderr: opts.ErrorStream,
|
||||
})
|
||||
}
|
||||
|
||||
// ResizeContainerTTY resizes the terminal to the given height and width.
|
||||
@ -760,7 +778,7 @@ func (c *Client) ResizeContainerTTY(id string, height, width int) error {
|
||||
params := make(url.Values)
|
||||
params.Set("h", strconv.Itoa(height))
|
||||
params.Set("w", strconv.Itoa(width))
|
||||
_, _, err := c.do("POST", "/containers/"+id+"/resize?"+params.Encode(), nil, false)
|
||||
_, _, err := c.do("POST", "/containers/"+id+"/resize?"+params.Encode(), doOptions{})
|
||||
return err
|
||||
}
|
||||
|
||||
@ -782,7 +800,10 @@ func (c *Client) ExportContainer(opts ExportContainerOptions) error {
|
||||
return &NoSuchContainer{ID: opts.ID}
|
||||
}
|
||||
url := fmt.Sprintf("/containers/%s/export", opts.ID)
|
||||
return c.stream("GET", url, true, false, nil, nil, opts.OutputStream, nil)
|
||||
return c.stream("GET", url, streamOptions{
|
||||
setRawTerminal: true,
|
||||
stdout: opts.OutputStream,
|
||||
})
|
||||
}
|
||||
|
||||
// NoSuchContainer is the error returned when a given container does not exist.
|
||||
|
3
Godeps/_workspace/src/github.com/fsouza/go-dockerclient/container_test.go
generated
vendored
3
Godeps/_workspace/src/github.com/fsouza/go-dockerclient/container_test.go
generated
vendored
@ -229,7 +229,8 @@ func TestInspectContainer(t *testing.T) {
|
||||
]
|
||||
},
|
||||
"Links": null,
|
||||
"PublishAllPorts": false
|
||||
"PublishAllPorts": false,
|
||||
"CgroupParent": "/mesos"
|
||||
}
|
||||
}`
|
||||
var expected Container
|
||||
|
17
Godeps/_workspace/src/github.com/fsouza/go-dockerclient/exec.go
generated
vendored
17
Godeps/_workspace/src/github.com/fsouza/go-dockerclient/exec.go
generated
vendored
@ -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, false)
|
||||
body, status, err := c.do("POST", path, doOptions{data: opts})
|
||||
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, false)
|
||||
_, status, err := c.do("POST", path, doOptions{data: opts})
|
||||
if status == http.StatusNotFound {
|
||||
return &NoSuchExec{ID: id}
|
||||
}
|
||||
@ -129,7 +129,14 @@ func (c *Client) StartExec(id string, opts StartExecOptions) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
return c.hijack("POST", path, opts.Success, opts.RawTerminal, opts.InputStream, opts.ErrorStream, opts.OutputStream, opts)
|
||||
return c.hijack("POST", path, hijackOptions{
|
||||
success: opts.Success,
|
||||
setRawTerminal: opts.RawTerminal,
|
||||
in: opts.InputStream,
|
||||
stdout: opts.OutputStream,
|
||||
stderr: opts.ErrorStream,
|
||||
data: opts,
|
||||
})
|
||||
}
|
||||
|
||||
// ResizeExecTTY resizes the tty session used by the exec command id. This API
|
||||
@ -143,7 +150,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, false)
|
||||
_, _, err := c.do("POST", path, doOptions{})
|
||||
return err
|
||||
}
|
||||
|
||||
@ -152,7 +159,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, false)
|
||||
body, status, err := c.do("GET", path, doOptions{})
|
||||
if status == http.StatusNotFound {
|
||||
return nil, &NoSuchExec{ID: id}
|
||||
}
|
||||
|
81
Godeps/_workspace/src/github.com/fsouza/go-dockerclient/image.go
generated
vendored
81
Godeps/_workspace/src/github.com/fsouza/go-dockerclient/image.go
generated
vendored
@ -26,6 +26,7 @@ type APIImages struct {
|
||||
Size int64 `json:"Size,omitempty" yaml:"Size,omitempty"`
|
||||
VirtualSize int64 `json:"VirtualSize,omitempty" yaml:"VirtualSize,omitempty"`
|
||||
ParentID string `json:"ParentId,omitempty" yaml:"ParentId,omitempty"`
|
||||
RepoDigests []string `json:"RepoDigests,omitempty" yaml:"RepoDigests,omitempty"`
|
||||
}
|
||||
|
||||
// Image is the type representing a docker image and its various properties
|
||||
@ -71,10 +72,11 @@ type ImagePre012 struct {
|
||||
|
||||
// ListImagesOptions specify parameters to the ListImages function.
|
||||
//
|
||||
// See http://goo.gl/2rOLFF for more details.
|
||||
// See http://goo.gl/HRVN1Z for more details.
|
||||
type ListImagesOptions struct {
|
||||
All bool
|
||||
Filters map[string][]string
|
||||
Digests bool
|
||||
}
|
||||
|
||||
var (
|
||||
@ -92,14 +94,19 @@ var (
|
||||
// ErrMultipleContexts is the error returned when both a ContextDir and
|
||||
// InputStream are provided in BuildImageOptions
|
||||
ErrMultipleContexts = errors.New("image build may not be provided BOTH context dir and input stream")
|
||||
|
||||
// ErrMustSpecifyNames is the error rreturned when the Names field on
|
||||
// ExportImagesOptions is nil or empty
|
||||
ErrMustSpecifyNames = errors.New("must specify at least one name to export")
|
||||
)
|
||||
|
||||
// ListImages returns the list of available images in the server.
|
||||
//
|
||||
// See http://goo.gl/2rOLFF for more details.
|
||||
// See http://goo.gl/HRVN1Z for more details.
|
||||
func (c *Client) ListImages(opts ListImagesOptions) ([]APIImages, error) {
|
||||
// TODO(pedge): what happens if we specify the digest parameter when using API Version <1.18?
|
||||
path := "/images/json?" + queryString(opts)
|
||||
body, _, err := c.do("GET", path, nil, false)
|
||||
body, _, err := c.do("GET", path, doOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -115,7 +122,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, false)
|
||||
body, status, err := c.do("GET", "/images/"+name+"/history", doOptions{})
|
||||
if status == http.StatusNotFound {
|
||||
return nil, ErrNoSuchImage
|
||||
}
|
||||
@ -134,7 +141,7 @@ 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, false)
|
||||
_, status, err := c.do("DELETE", "/images/"+name, doOptions{})
|
||||
if status == http.StatusNotFound {
|
||||
return ErrNoSuchImage
|
||||
}
|
||||
@ -156,7 +163,7 @@ type RemoveImageOptions struct {
|
||||
// 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)
|
||||
_, status, err := c.do("DELETE", uri, doOptions{})
|
||||
if status == http.StatusNotFound {
|
||||
return ErrNoSuchImage
|
||||
}
|
||||
@ -167,7 +174,7 @@ func (c *Client) RemoveImageExtended(name string, opts RemoveImageOptions) 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, false)
|
||||
body, status, err := c.do("GET", "/images/"+name+"/json", doOptions{})
|
||||
if status == http.StatusNotFound {
|
||||
return nil, ErrNoSuchImage
|
||||
}
|
||||
@ -236,8 +243,12 @@ func (c *Client) PushImage(opts PushImageOptions, auth AuthConfiguration) error
|
||||
name := opts.Name
|
||||
opts.Name = ""
|
||||
path := "/images/" + name + "/push?" + queryString(&opts)
|
||||
headers := headersWithAuth(auth)
|
||||
return c.stream("POST", path, true, opts.RawJSONStream, headers, nil, opts.OutputStream, nil)
|
||||
return c.stream("POST", path, streamOptions{
|
||||
setRawTerminal: true,
|
||||
rawJSONStream: opts.RawJSONStream,
|
||||
headers: headersWithAuth(auth),
|
||||
stdout: opts.OutputStream,
|
||||
})
|
||||
}
|
||||
|
||||
// PullImageOptions present the set of options available for pulling an image
|
||||
@ -266,7 +277,13 @@ func (c *Client) PullImage(opts PullImageOptions, auth AuthConfiguration) error
|
||||
|
||||
func (c *Client) createImage(qs string, headers map[string]string, in io.Reader, w io.Writer, rawJSONStream bool) error {
|
||||
path := "/images/create?" + qs
|
||||
return c.stream("POST", path, true, rawJSONStream, headers, in, w, nil)
|
||||
return c.stream("POST", path, streamOptions{
|
||||
setRawTerminal: true,
|
||||
rawJSONStream: rawJSONStream,
|
||||
headers: headers,
|
||||
in: in,
|
||||
stdout: w,
|
||||
})
|
||||
}
|
||||
|
||||
// LoadImageOptions represents the options for LoadImage Docker API Call
|
||||
@ -280,7 +297,10 @@ type LoadImageOptions struct {
|
||||
//
|
||||
// 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)
|
||||
return c.stream("POST", "/images/load", streamOptions{
|
||||
setRawTerminal: true,
|
||||
in: opts.InputStream,
|
||||
})
|
||||
}
|
||||
|
||||
// ExportImageOptions represent the options for ExportImage Docker API call
|
||||
@ -295,7 +315,31 @@ type ExportImageOptions struct {
|
||||
//
|
||||
// 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)
|
||||
return c.stream("GET", fmt.Sprintf("/images/%s/get", opts.Name), streamOptions{
|
||||
setRawTerminal: true,
|
||||
stdout: opts.OutputStream,
|
||||
})
|
||||
}
|
||||
|
||||
// ExportImagesOptions represent the options for ExportImages Docker API call
|
||||
//
|
||||
// See http://goo.gl/YeZzQK for more details.
|
||||
type ExportImagesOptions struct {
|
||||
Names []string
|
||||
OutputStream io.Writer `qs:"-"`
|
||||
}
|
||||
|
||||
// ExportImages exports one or more images (as a tar file) into the stream
|
||||
//
|
||||
// See http://goo.gl/YeZzQK for more details.
|
||||
func (c *Client) ExportImages(opts ExportImagesOptions) error {
|
||||
if opts.Names == nil || len(opts.Names) == 0 {
|
||||
return ErrMustSpecifyNames
|
||||
}
|
||||
return c.stream("GET", "/images/get?"+queryString(&opts), streamOptions{
|
||||
setRawTerminal: true,
|
||||
stdout: opts.OutputStream,
|
||||
})
|
||||
}
|
||||
|
||||
// ImportImageOptions present the set of informations available for importing
|
||||
@ -382,8 +426,13 @@ func (c *Client) BuildImage(opts BuildImageOptions) error {
|
||||
}
|
||||
}
|
||||
|
||||
return c.stream("POST", fmt.Sprintf("/build?%s",
|
||||
queryString(&opts)), true, opts.RawJSONStream, headers, opts.InputStream, opts.OutputStream, nil)
|
||||
return c.stream("POST", fmt.Sprintf("/build?%s", queryString(&opts)), streamOptions{
|
||||
setRawTerminal: true,
|
||||
rawJSONStream: opts.RawJSONStream,
|
||||
headers: headers,
|
||||
in: opts.InputStream,
|
||||
stdout: opts.OutputStream,
|
||||
})
|
||||
}
|
||||
|
||||
// TagImageOptions present the set of options to tag an image.
|
||||
@ -403,7 +452,7 @@ 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, false)
|
||||
queryString(&opts)), doOptions{})
|
||||
|
||||
if status == http.StatusNotFound {
|
||||
return ErrNoSuchImage
|
||||
@ -454,7 +503,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, false)
|
||||
body, _, err := c.do("GET", "/images/search?term="+term, doOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
34
Godeps/_workspace/src/github.com/fsouza/go-dockerclient/image_test.go
generated
vendored
34
Godeps/_workspace/src/github.com/fsouza/go-dockerclient/image_test.go
generated
vendored
@ -860,6 +860,40 @@ func TestExportImage(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestExportImages(t *testing.T) {
|
||||
var buf bytes.Buffer
|
||||
fakeRT := &FakeRoundTripper{message: "", status: http.StatusOK}
|
||||
client := newTestClient(fakeRT)
|
||||
opts := ExportImagesOptions{Names: []string{"testimage1", "testimage2:latest"}, OutputStream: &buf}
|
||||
err := client.ExportImages(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)
|
||||
}
|
||||
expected := "http://localhost:4243/images/get?names=testimage1&names=testimage2%3Alatest"
|
||||
got := req.URL.String()
|
||||
if !reflect.DeepEqual(got, expected) {
|
||||
t.Errorf("ExportIMage: wrong path. Expected %q. Got %q.", expected, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestExportImagesNoNames(t *testing.T) {
|
||||
var buf bytes.Buffer
|
||||
fakeRT := &FakeRoundTripper{message: "", status: http.StatusOK}
|
||||
client := newTestClient(fakeRT)
|
||||
opts := ExportImagesOptions{Names: []string{}, OutputStream: &buf}
|
||||
err := client.ExportImages(opts)
|
||||
if err == nil {
|
||||
t.Error("Expected an error")
|
||||
}
|
||||
if err != ErrMustSpecifyNames {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSearchImages(t *testing.T) {
|
||||
body := `[
|
||||
{
|
||||
|
4
Godeps/_workspace/src/github.com/fsouza/go-dockerclient/misc.go
generated
vendored
4
Godeps/_workspace/src/github.com/fsouza/go-dockerclient/misc.go
generated
vendored
@ -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, false)
|
||||
body, _, err := c.do("GET", "/version", doOptions{})
|
||||
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, false)
|
||||
body, _, err := c.do("GET", "/info", doOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
9
Godeps/_workspace/src/github.com/fsouza/go-dockerclient/testing/server.go
generated
vendored
9
Godeps/_workspace/src/github.com/fsouza/go-dockerclient/testing/server.go
generated
vendored
@ -25,6 +25,8 @@ import (
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
var nameRegexp = regexp.MustCompile(`^[a-zA-Z0-9][a-zA-Z0-9_.-]+$`)
|
||||
|
||||
// DockerServer represents a programmable, concurrent (not much), HTTP server
|
||||
// implementing a fake version of the Docker remote API.
|
||||
//
|
||||
@ -339,6 +341,11 @@ func (s *DockerServer) createContainer(w http.ResponseWriter, r *http.Request) {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
name := r.URL.Query().Get("name")
|
||||
if name != "" && !nameRegexp.MatchString(name) {
|
||||
http.Error(w, "Invalid container name", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
if _, err := s.findImage(config.Image); err != nil {
|
||||
http.Error(w, err.Error(), http.StatusNotFound)
|
||||
return
|
||||
@ -363,7 +370,7 @@ func (s *DockerServer) createContainer(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
container := docker.Container{
|
||||
Name: r.URL.Query().Get("name"),
|
||||
Name: name,
|
||||
ID: s.generateID(),
|
||||
Created: time.Now(),
|
||||
Path: path,
|
||||
|
18
Godeps/_workspace/src/github.com/fsouza/go-dockerclient/testing/server_test.go
generated
vendored
18
Godeps/_workspace/src/github.com/fsouza/go-dockerclient/testing/server_test.go
generated
vendored
@ -241,6 +241,24 @@ func TestCreateContainerInvalidBody(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateContainerInvalidName(t *testing.T) {
|
||||
server := DockerServer{}
|
||||
server.buildMuxer()
|
||||
recorder := httptest.NewRecorder()
|
||||
body := `{"Hostname":"", "User":"", "Memory":0, "MemorySwap":0, "AttachStdin":false, "AttachStdout":true, "AttachStderr":true,
|
||||
"PortSpecs":null, "Tty":false, "OpenStdin":false, "StdinOnce":false, "Env":null, "Cmd":["date"],
|
||||
"Image":"base", "Volumes":{}, "VolumesFrom":""}`
|
||||
request, _ := http.NewRequest("POST", "/containers/create?name=myapp/container1", strings.NewReader(body))
|
||||
server.ServeHTTP(recorder, request)
|
||||
if recorder.Code != http.StatusInternalServerError {
|
||||
t.Errorf("CreateContainer: wrong status. Want %d. Got %d.", http.StatusInternalServerError, recorder.Code)
|
||||
}
|
||||
expectedBody := "Invalid container name\n"
|
||||
if got := recorder.Body.String(); got != expectedBody {
|
||||
t.Errorf("CreateContainer: wrong body. Want %q. Got %q.", expectedBody, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateContainerImageNotFound(t *testing.T) {
|
||||
server := DockerServer{}
|
||||
server.buildMuxer()
|
||||
|
Loading…
Reference in New Issue
Block a user