mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-03 01:06:27 +00:00
Merge pull request #1805 from vishh/update_deps
Updating docker client to the latest version
This commit is contained in:
commit
f006923a67
4
Godeps/Godeps.json
generated
4
Godeps/Godeps.json
generated
@ -60,8 +60,8 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/fsouza/go-dockerclient",
|
"ImportPath": "github.com/fsouza/go-dockerclient",
|
||||||
"Comment": "0.2.1-241-g0dbb508",
|
"Comment": "0.2.1-267-g15d2c6e",
|
||||||
"Rev": "0dbb508e94dd899a6743d035d8f249c7634d26da"
|
"Rev": "15d2c6e3eb670c545d0af0604d7f9aff3871af04"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/golang/glog",
|
"ImportPath": "github.com/golang/glog",
|
||||||
|
2
Godeps/_workspace/src/github.com/fsouza/go-dockerclient/.travis.yml
generated
vendored
2
Godeps/_workspace/src/github.com/fsouza/go-dockerclient/.travis.yml
generated
vendored
@ -1,7 +1,7 @@
|
|||||||
language: go
|
language: go
|
||||||
go:
|
go:
|
||||||
- 1.1.2
|
- 1.1.2
|
||||||
- 1.2
|
- 1.2.2
|
||||||
- 1.3.1
|
- 1.3.1
|
||||||
- tip
|
- tip
|
||||||
env:
|
env:
|
||||||
|
3
Godeps/_workspace/src/github.com/fsouza/go-dockerclient/AUTHORS
generated
vendored
3
Godeps/_workspace/src/github.com/fsouza/go-dockerclient/AUTHORS
generated
vendored
@ -5,9 +5,11 @@ 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>
|
||||||
Ben McCann <benmccann.com>
|
Ben McCann <benmccann.com>
|
||||||
|
Carlos Diaz-Padron <cpadron@mozilla.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>
|
||||||
|
CMGS <ilskdw@gmail.com>
|
||||||
Daniel, Dao Quang Minh <dqminh89@gmail.com>
|
Daniel, Dao Quang Minh <dqminh89@gmail.com>
|
||||||
David Huie <dahuie@gmail.com>
|
David Huie <dahuie@gmail.com>
|
||||||
Ed <edrocksit@gmail.com>
|
Ed <edrocksit@gmail.com>
|
||||||
@ -29,6 +31,7 @@ Paul Morie <pmorie@gmail.com>
|
|||||||
Peter Jihoon Kim <raingrove@gmail.com>
|
Peter Jihoon Kim <raingrove@gmail.com>
|
||||||
Philippe Lafoucrière <philippe.lafoucriere@tech-angels.com>
|
Philippe Lafoucrière <philippe.lafoucriere@tech-angels.com>
|
||||||
Rafe Colton <r.colton@modcloth.com>
|
Rafe Colton <r.colton@modcloth.com>
|
||||||
|
Robert Williamson <williamson.robert@gmail.com>
|
||||||
Salvador Gironès <salvadorgirones@gmail.com>
|
Salvador Gironès <salvadorgirones@gmail.com>
|
||||||
Simon Eskildsen <sirup@sirupsen.com>
|
Simon Eskildsen <sirup@sirupsen.com>
|
||||||
Simon Menke <simon.menke@gmail.com>
|
Simon Menke <simon.menke@gmail.com>
|
||||||
|
1
Godeps/_workspace/src/github.com/fsouza/go-dockerclient/README.markdown
generated
vendored
1
Godeps/_workspace/src/github.com/fsouza/go-dockerclient/README.markdown
generated
vendored
@ -30,7 +30,6 @@ func main() {
|
|||||||
fmt.Println("Size: ", img.Size)
|
fmt.Println("Size: ", img.Size)
|
||||||
fmt.Println("VirtualSize: ", img.VirtualSize)
|
fmt.Println("VirtualSize: ", img.VirtualSize)
|
||||||
fmt.Println("ParentId: ", img.ParentId)
|
fmt.Println("ParentId: ", img.ParentId)
|
||||||
fmt.Println("Repository: ", img.Repository)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
2
Godeps/_workspace/src/github.com/fsouza/go-dockerclient/change.go
generated
vendored
2
Godeps/_workspace/src/github.com/fsouza/go-dockerclient/change.go
generated
vendored
@ -16,7 +16,7 @@ const (
|
|||||||
|
|
||||||
// Change represents a change in a container.
|
// Change represents a change in a container.
|
||||||
//
|
//
|
||||||
// See http://goo.gl/DpGyzK for more details.
|
// See http://goo.gl/QkW9sH for more details.
|
||||||
type Change struct {
|
type Change struct {
|
||||||
Path string
|
Path string
|
||||||
Kind ChangeType
|
Kind ChangeType
|
||||||
|
16
Godeps/_workspace/src/github.com/fsouza/go-dockerclient/client.go
generated
vendored
16
Godeps/_workspace/src/github.com/fsouza/go-dockerclient/client.go
generated
vendored
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
// Package docker provides a client for the Docker remote API.
|
// Package docker provides a client for the Docker remote API.
|
||||||
//
|
//
|
||||||
// See http://goo.gl/mxyql for more details on the remote API.
|
// See http://goo.gl/G3plxW for more details on the remote API.
|
||||||
package docker
|
package docker
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -356,20 +356,30 @@ func (c *Client) stream(method, path string, setRawTerminal, rawJSONStream bool,
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) hijack(method, path string, success chan struct{}, setRawTerminal bool, in io.Reader, stderr, stdout io.Writer) error {
|
func (c *Client) hijack(method, path string, success chan struct{}, setRawTerminal bool, in io.Reader, stderr, stdout io.Writer, data interface{}) error {
|
||||||
if path != "/version" && !c.SkipServerVersionCheck && c.expectedApiVersion == nil {
|
if path != "/version" && !c.SkipServerVersionCheck && c.expectedApiVersion == nil {
|
||||||
err := c.checkApiVersion()
|
err := c.checkApiVersion()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var params io.Reader
|
||||||
|
if data != nil {
|
||||||
|
buf, err := json.Marshal(data)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
params = bytes.NewBuffer(buf)
|
||||||
|
}
|
||||||
|
|
||||||
if stdout == nil {
|
if stdout == nil {
|
||||||
stdout = ioutil.Discard
|
stdout = ioutil.Discard
|
||||||
}
|
}
|
||||||
if stderr == nil {
|
if stderr == nil {
|
||||||
stderr = ioutil.Discard
|
stderr = ioutil.Discard
|
||||||
}
|
}
|
||||||
req, err := http.NewRequest(method, c.getURL(path), nil)
|
req, err := http.NewRequest(method, c.getURL(path), params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
80
Godeps/_workspace/src/github.com/fsouza/go-dockerclient/container.go
generated
vendored
80
Godeps/_workspace/src/github.com/fsouza/go-dockerclient/container.go
generated
vendored
@ -18,7 +18,7 @@ import (
|
|||||||
|
|
||||||
// ListContainersOptions specify parameters to the ListContainers function.
|
// ListContainersOptions specify parameters to the ListContainers function.
|
||||||
//
|
//
|
||||||
// See http://goo.gl/QpCnDN for more details.
|
// See http://goo.gl/XqtcyU for more details.
|
||||||
type ListContainersOptions struct {
|
type ListContainersOptions struct {
|
||||||
All bool
|
All bool
|
||||||
Size bool
|
Size bool
|
||||||
@ -51,7 +51,7 @@ type APIContainers struct {
|
|||||||
|
|
||||||
// ListContainers returns a slice of containers matching the given criteria.
|
// ListContainers returns a slice of containers matching the given criteria.
|
||||||
//
|
//
|
||||||
// See http://goo.gl/QpCnDN for more details.
|
// See http://goo.gl/XqtcyU for more details.
|
||||||
func (c *Client) ListContainers(opts ListContainersOptions) ([]APIContainers, error) {
|
func (c *Client) ListContainers(opts ListContainersOptions) ([]APIContainers, error) {
|
||||||
path := "/containers/json?" + queryString(opts)
|
path := "/containers/json?" + queryString(opts)
|
||||||
body, _, err := c.do("GET", path, nil)
|
body, _, err := c.do("GET", path, nil)
|
||||||
@ -161,6 +161,7 @@ type Config struct {
|
|||||||
Memory int64 `json:"Memory,omitempty" yaml:"Memory,omitempty"`
|
Memory int64 `json:"Memory,omitempty" yaml:"Memory,omitempty"`
|
||||||
MemorySwap int64 `json:"MemorySwap,omitempty" yaml:"MemorySwap,omitempty"`
|
MemorySwap int64 `json:"MemorySwap,omitempty" yaml:"MemorySwap,omitempty"`
|
||||||
CpuShares int64 `json:"CpuShares,omitempty" yaml:"CpuShares,omitempty"`
|
CpuShares int64 `json:"CpuShares,omitempty" yaml:"CpuShares,omitempty"`
|
||||||
|
CpuSet string `json:"CpuSet,omitempty" yaml:"CpuSet,omitempty"`
|
||||||
AttachStdin bool `json:"AttachStdin,omitempty" yaml:"AttachStdin,omitempty"`
|
AttachStdin bool `json:"AttachStdin,omitempty" yaml:"AttachStdin,omitempty"`
|
||||||
AttachStdout bool `json:"AttachStdout,omitempty" yaml:"AttachStdout,omitempty"`
|
AttachStdout bool `json:"AttachStdout,omitempty" yaml:"AttachStdout,omitempty"`
|
||||||
AttachStderr bool `json:"AttachStderr,omitempty" yaml:"AttachStderr,omitempty"`
|
AttachStderr bool `json:"AttachStderr,omitempty" yaml:"AttachStderr,omitempty"`
|
||||||
@ -208,7 +209,7 @@ type Container struct {
|
|||||||
|
|
||||||
// InspectContainer returns information about a container by its ID.
|
// InspectContainer returns information about a container by its ID.
|
||||||
//
|
//
|
||||||
// See http://goo.gl/2o52Sx for more details.
|
// See http://goo.gl/CxVuJ5 for more details.
|
||||||
func (c *Client) InspectContainer(id string) (*Container, error) {
|
func (c *Client) InspectContainer(id string) (*Container, error) {
|
||||||
path := "/containers/" + id + "/json"
|
path := "/containers/" + id + "/json"
|
||||||
body, status, err := c.do("GET", path, nil)
|
body, status, err := c.do("GET", path, nil)
|
||||||
@ -228,7 +229,7 @@ func (c *Client) InspectContainer(id string) (*Container, error) {
|
|||||||
|
|
||||||
// ContainerChanges returns changes in the filesystem of the given container.
|
// ContainerChanges returns changes in the filesystem of the given container.
|
||||||
//
|
//
|
||||||
// See http://goo.gl/DpGyzK for more details.
|
// See http://goo.gl/QkW9sH for more details.
|
||||||
func (c *Client) ContainerChanges(id string) ([]Change, error) {
|
func (c *Client) ContainerChanges(id string) ([]Change, error) {
|
||||||
path := "/containers/" + id + "/changes"
|
path := "/containers/" + id + "/changes"
|
||||||
body, status, err := c.do("GET", path, nil)
|
body, status, err := c.do("GET", path, nil)
|
||||||
@ -248,7 +249,7 @@ func (c *Client) ContainerChanges(id string) ([]Change, error) {
|
|||||||
|
|
||||||
// CreateContainerOptions specify parameters to the CreateContainer function.
|
// CreateContainerOptions specify parameters to the CreateContainer function.
|
||||||
//
|
//
|
||||||
// See http://goo.gl/WPPYtB for more details.
|
// See http://goo.gl/mErxNp for more details.
|
||||||
type CreateContainerOptions struct {
|
type CreateContainerOptions struct {
|
||||||
Name string
|
Name string
|
||||||
Config *Config `qs:"-"`
|
Config *Config `qs:"-"`
|
||||||
@ -257,7 +258,7 @@ type CreateContainerOptions struct {
|
|||||||
// CreateContainer creates a new container, returning the container instance,
|
// CreateContainer creates a new container, returning the container instance,
|
||||||
// or an error in case of failure.
|
// or an error in case of failure.
|
||||||
//
|
//
|
||||||
// See http://goo.gl/tjihUc for more details.
|
// See http://goo.gl/mErxNp for more details.
|
||||||
func (c *Client) CreateContainer(opts CreateContainerOptions) (*Container, error) {
|
func (c *Client) CreateContainer(opts CreateContainerOptions) (*Container, error) {
|
||||||
path := "/containers/create?" + queryString(opts)
|
path := "/containers/create?" + queryString(opts)
|
||||||
body, status, err := c.do("POST", path, opts.Config)
|
body, status, err := c.do("POST", path, opts.Config)
|
||||||
@ -333,7 +334,7 @@ type HostConfig struct {
|
|||||||
|
|
||||||
// StartContainer starts a container, returning an error in case of failure.
|
// StartContainer starts a container, returning an error in case of failure.
|
||||||
//
|
//
|
||||||
// See http://goo.gl/y5GZlE for more details.
|
// See http://goo.gl/iM5GYs for more details.
|
||||||
func (c *Client) StartContainer(id string, hostConfig *HostConfig) error {
|
func (c *Client) StartContainer(id string, hostConfig *HostConfig) error {
|
||||||
if hostConfig == nil {
|
if hostConfig == nil {
|
||||||
hostConfig = &HostConfig{}
|
hostConfig = &HostConfig{}
|
||||||
@ -355,7 +356,7 @@ func (c *Client) StartContainer(id string, hostConfig *HostConfig) error {
|
|||||||
// StopContainer stops a container, killing it after the given timeout (in
|
// StopContainer stops a container, killing it after the given timeout (in
|
||||||
// seconds).
|
// seconds).
|
||||||
//
|
//
|
||||||
// See http://goo.gl/X2mj8t for more details.
|
// See http://goo.gl/EbcpXt for more details.
|
||||||
func (c *Client) StopContainer(id string, timeout uint) error {
|
func (c *Client) StopContainer(id string, timeout uint) error {
|
||||||
path := fmt.Sprintf("/containers/%s/stop?t=%d", id, timeout)
|
path := fmt.Sprintf("/containers/%s/stop?t=%d", id, timeout)
|
||||||
_, status, err := c.do("POST", path, nil)
|
_, status, err := c.do("POST", path, nil)
|
||||||
@ -374,7 +375,7 @@ func (c *Client) StopContainer(id string, timeout uint) error {
|
|||||||
// RestartContainer stops a container, killing it after the given timeout (in
|
// RestartContainer stops a container, killing it after the given timeout (in
|
||||||
// seconds), during the stop process.
|
// seconds), during the stop process.
|
||||||
//
|
//
|
||||||
// See http://goo.gl/zms73Z for more details.
|
// See http://goo.gl/VOzR2n for more details.
|
||||||
func (c *Client) RestartContainer(id string, timeout uint) error {
|
func (c *Client) RestartContainer(id string, timeout uint) error {
|
||||||
path := fmt.Sprintf("/containers/%s/restart?t=%d", id, timeout)
|
path := fmt.Sprintf("/containers/%s/restart?t=%d", id, timeout)
|
||||||
_, status, err := c.do("POST", path, nil)
|
_, status, err := c.do("POST", path, nil)
|
||||||
@ -417,8 +418,43 @@ func (c *Client) UnpauseContainer(id string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TopResult represents the list of processes running in a container, as
|
||||||
|
// returned by /containers/<id>/top.
|
||||||
|
//
|
||||||
|
// See http://goo.gl/qu4gse for more details.
|
||||||
|
type TopResult struct {
|
||||||
|
Titles []string
|
||||||
|
Processes [][]string
|
||||||
|
}
|
||||||
|
|
||||||
|
// TopContainer returns processes running inside a container
|
||||||
|
//
|
||||||
|
// See http://goo.gl/qu4gse for more details.
|
||||||
|
func (c *Client) TopContainer(id string, psArgs string) (TopResult, error) {
|
||||||
|
var args string
|
||||||
|
var result TopResult
|
||||||
|
if psArgs != "" {
|
||||||
|
args = fmt.Sprintf("?ps_args=%s", psArgs)
|
||||||
|
}
|
||||||
|
path := fmt.Sprintf("/containers/%s/top%s", id, args)
|
||||||
|
body, status, err := c.do("GET", path, nil)
|
||||||
|
if status == http.StatusNotFound {
|
||||||
|
return result, &NoSuchContainer{ID: id}
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return result, err
|
||||||
|
}
|
||||||
|
err = json.Unmarshal(body, &result)
|
||||||
|
if err != nil {
|
||||||
|
return result, err
|
||||||
|
}
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
// KillContainerOptions represents the set of options that can be used in a
|
// KillContainerOptions represents the set of options that can be used in a
|
||||||
// call to KillContainer.
|
// call to KillContainer.
|
||||||
|
//
|
||||||
|
// See http://goo.gl/TFkECx for more details.
|
||||||
type KillContainerOptions struct {
|
type KillContainerOptions struct {
|
||||||
// The ID of the container.
|
// The ID of the container.
|
||||||
ID string `qs:"-"`
|
ID string `qs:"-"`
|
||||||
@ -430,7 +466,7 @@ type KillContainerOptions struct {
|
|||||||
|
|
||||||
// KillContainer kills a container, returning an error in case of failure.
|
// KillContainer kills a container, returning an error in case of failure.
|
||||||
//
|
//
|
||||||
// See http://goo.gl/DPbbBy for more details.
|
// See http://goo.gl/TFkECx for more details.
|
||||||
func (c *Client) KillContainer(opts KillContainerOptions) error {
|
func (c *Client) KillContainer(opts KillContainerOptions) error {
|
||||||
path := "/containers/" + opts.ID + "/kill" + "?" + queryString(opts)
|
path := "/containers/" + opts.ID + "/kill" + "?" + queryString(opts)
|
||||||
_, status, err := c.do("POST", path, nil)
|
_, status, err := c.do("POST", path, nil)
|
||||||
@ -444,6 +480,8 @@ func (c *Client) KillContainer(opts KillContainerOptions) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// RemoveContainerOptions encapsulates options to remove a container.
|
// RemoveContainerOptions encapsulates options to remove a container.
|
||||||
|
//
|
||||||
|
// See http://goo.gl/ZB83ji for more details.
|
||||||
type RemoveContainerOptions struct {
|
type RemoveContainerOptions struct {
|
||||||
// The ID of the container.
|
// The ID of the container.
|
||||||
ID string `qs:"-"`
|
ID string `qs:"-"`
|
||||||
@ -459,7 +497,7 @@ type RemoveContainerOptions struct {
|
|||||||
|
|
||||||
// RemoveContainer removes a container, returning an error in case of failure.
|
// RemoveContainer removes a container, returning an error in case of failure.
|
||||||
//
|
//
|
||||||
// See http://goo.gl/PBvGdU for more details.
|
// See http://goo.gl/ZB83ji for more details.
|
||||||
func (c *Client) RemoveContainer(opts RemoveContainerOptions) error {
|
func (c *Client) RemoveContainer(opts RemoveContainerOptions) error {
|
||||||
path := "/containers/" + opts.ID + "?" + queryString(opts)
|
path := "/containers/" + opts.ID + "?" + queryString(opts)
|
||||||
_, status, err := c.do("DELETE", path, nil)
|
_, status, err := c.do("DELETE", path, nil)
|
||||||
@ -475,7 +513,7 @@ func (c *Client) RemoveContainer(opts RemoveContainerOptions) error {
|
|||||||
// CopyFromContainerOptions is the set of options that can be used when copying
|
// CopyFromContainerOptions is the set of options that can be used when copying
|
||||||
// files or folders from a container.
|
// files or folders from a container.
|
||||||
//
|
//
|
||||||
// See http://goo.gl/mnxRMl for more details.
|
// See http://goo.gl/rINMlw for more details.
|
||||||
type CopyFromContainerOptions struct {
|
type CopyFromContainerOptions struct {
|
||||||
OutputStream io.Writer `json:"-"`
|
OutputStream io.Writer `json:"-"`
|
||||||
Container string `json:"-"`
|
Container string `json:"-"`
|
||||||
@ -485,7 +523,7 @@ type CopyFromContainerOptions struct {
|
|||||||
// CopyFromContainer copy files or folders from a container, using a given
|
// CopyFromContainer copy files or folders from a container, using a given
|
||||||
// resource.
|
// resource.
|
||||||
//
|
//
|
||||||
// See http://goo.gl/mnxRMl for more details.
|
// See http://goo.gl/rINMlw for more details.
|
||||||
func (c *Client) CopyFromContainer(opts CopyFromContainerOptions) error {
|
func (c *Client) CopyFromContainer(opts CopyFromContainerOptions) error {
|
||||||
if opts.Container == "" {
|
if opts.Container == "" {
|
||||||
return &NoSuchContainer{ID: opts.Container}
|
return &NoSuchContainer{ID: opts.Container}
|
||||||
@ -505,7 +543,7 @@ func (c *Client) CopyFromContainer(opts CopyFromContainerOptions) error {
|
|||||||
// WaitContainer blocks until the given container stops, return the exit code
|
// WaitContainer blocks until the given container stops, return the exit code
|
||||||
// of the container status.
|
// of the container status.
|
||||||
//
|
//
|
||||||
// See http://goo.gl/gnHJL2 for more details.
|
// See http://goo.gl/J88DHU for more details.
|
||||||
func (c *Client) WaitContainer(id string) (int, error) {
|
func (c *Client) WaitContainer(id string) (int, error) {
|
||||||
body, status, err := c.do("POST", "/containers/"+id+"/wait", nil)
|
body, status, err := c.do("POST", "/containers/"+id+"/wait", nil)
|
||||||
if status == http.StatusNotFound {
|
if status == http.StatusNotFound {
|
||||||
@ -524,7 +562,7 @@ func (c *Client) WaitContainer(id string) (int, error) {
|
|||||||
|
|
||||||
// CommitContainerOptions aggregates parameters to the CommitContainer method.
|
// CommitContainerOptions aggregates parameters to the CommitContainer method.
|
||||||
//
|
//
|
||||||
// See http://goo.gl/628gxm for more details.
|
// See http://goo.gl/Jn8pe8 for more details.
|
||||||
type CommitContainerOptions struct {
|
type CommitContainerOptions struct {
|
||||||
Container string
|
Container string
|
||||||
Repository string `qs:"repo"`
|
Repository string `qs:"repo"`
|
||||||
@ -536,7 +574,7 @@ type CommitContainerOptions struct {
|
|||||||
|
|
||||||
// CommitContainer creates a new image from a container's changes.
|
// CommitContainer creates a new image from a container's changes.
|
||||||
//
|
//
|
||||||
// See http://goo.gl/628gxm for more details.
|
// See http://goo.gl/Jn8pe8 for more details.
|
||||||
func (c *Client) CommitContainer(opts CommitContainerOptions) (*Image, error) {
|
func (c *Client) CommitContainer(opts CommitContainerOptions) (*Image, error) {
|
||||||
path := "/commit?" + queryString(opts)
|
path := "/commit?" + queryString(opts)
|
||||||
body, status, err := c.do("POST", path, opts.Run)
|
body, status, err := c.do("POST", path, opts.Run)
|
||||||
@ -557,7 +595,7 @@ func (c *Client) CommitContainer(opts CommitContainerOptions) (*Image, error) {
|
|||||||
// AttachToContainerOptions is the set of options that can be used when
|
// AttachToContainerOptions is the set of options that can be used when
|
||||||
// attaching to a container.
|
// attaching to a container.
|
||||||
//
|
//
|
||||||
// See http://goo.gl/oPzcqH for more details.
|
// See http://goo.gl/RRAhws for more details.
|
||||||
type AttachToContainerOptions struct {
|
type AttachToContainerOptions struct {
|
||||||
Container string `qs:"-"`
|
Container string `qs:"-"`
|
||||||
InputStream io.Reader `qs:"-"`
|
InputStream io.Reader `qs:"-"`
|
||||||
@ -592,13 +630,13 @@ type AttachToContainerOptions struct {
|
|||||||
|
|
||||||
// AttachToContainer attaches to a container, using the given options.
|
// AttachToContainer attaches to a container, using the given options.
|
||||||
//
|
//
|
||||||
// See http://goo.gl/oPzcqH for more details.
|
// See http://goo.gl/RRAhws for more details.
|
||||||
func (c *Client) AttachToContainer(opts AttachToContainerOptions) error {
|
func (c *Client) AttachToContainer(opts AttachToContainerOptions) error {
|
||||||
if opts.Container == "" {
|
if opts.Container == "" {
|
||||||
return &NoSuchContainer{ID: opts.Container}
|
return &NoSuchContainer{ID: opts.Container}
|
||||||
}
|
}
|
||||||
path := "/containers/" + opts.Container + "/attach?" + queryString(opts)
|
path := "/containers/" + opts.Container + "/attach?" + queryString(opts)
|
||||||
return c.hijack("POST", path, opts.Success, opts.RawTerminal, opts.InputStream, opts.ErrorStream, opts.OutputStream)
|
return c.hijack("POST", path, opts.Success, opts.RawTerminal, opts.InputStream, opts.ErrorStream, opts.OutputStream, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// LogsOptions represents the set of options used when getting logs from a
|
// LogsOptions represents the set of options used when getting logs from a
|
||||||
@ -645,7 +683,7 @@ func (c *Client) ResizeContainerTTY(id string, height, width int) error {
|
|||||||
// ExportContainerOptions is the set of parameters to the ExportContainer
|
// ExportContainerOptions is the set of parameters to the ExportContainer
|
||||||
// method.
|
// method.
|
||||||
//
|
//
|
||||||
// See http://goo.gl/Lqk0FZ for more details.
|
// See http://goo.gl/hnzE62 for more details.
|
||||||
type ExportContainerOptions struct {
|
type ExportContainerOptions struct {
|
||||||
ID string
|
ID string
|
||||||
OutputStream io.Writer
|
OutputStream io.Writer
|
||||||
@ -654,7 +692,7 @@ type ExportContainerOptions struct {
|
|||||||
// ExportContainer export the contents of container id as tar archive
|
// ExportContainer export the contents of container id as tar archive
|
||||||
// and prints the exported contents to stdout.
|
// and prints the exported contents to stdout.
|
||||||
//
|
//
|
||||||
// See http://goo.gl/Lqk0FZ for more details.
|
// See http://goo.gl/hnzE62 for more details.
|
||||||
func (c *Client) ExportContainer(opts ExportContainerOptions) error {
|
func (c *Client) ExportContainer(opts ExportContainerOptions) error {
|
||||||
if opts.ID == "" {
|
if opts.ID == "" {
|
||||||
return &NoSuchContainer{ID: opts.ID}
|
return &NoSuchContainer{ID: opts.ID}
|
||||||
|
79
Godeps/_workspace/src/github.com/fsouza/go-dockerclient/container_test.go
generated
vendored
79
Godeps/_workspace/src/github.com/fsouza/go-dockerclient/container_test.go
generated
vendored
@ -1414,3 +1414,82 @@ func TestNeverRestart(t *testing.T) {
|
|||||||
t.Errorf("NeverRestart(): wrong MaximumRetryCount. Want 0. Got %d", policy.MaximumRetryCount)
|
t.Errorf("NeverRestart(): wrong MaximumRetryCount. Want 0. Got %d", policy.MaximumRetryCount)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestTopContainer(t *testing.T) {
|
||||||
|
jsonTop := `{
|
||||||
|
"Processes": [
|
||||||
|
[
|
||||||
|
"ubuntu",
|
||||||
|
"3087",
|
||||||
|
"815",
|
||||||
|
"0",
|
||||||
|
"01:44",
|
||||||
|
"?",
|
||||||
|
"00:00:00",
|
||||||
|
"cmd1"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"root",
|
||||||
|
"3158",
|
||||||
|
"3087",
|
||||||
|
"0",
|
||||||
|
"01:44",
|
||||||
|
"?",
|
||||||
|
"00:00:01",
|
||||||
|
"cmd2"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"Titles": [
|
||||||
|
"UID",
|
||||||
|
"PID",
|
||||||
|
"PPID",
|
||||||
|
"C",
|
||||||
|
"STIME",
|
||||||
|
"TTY",
|
||||||
|
"TIME",
|
||||||
|
"CMD"
|
||||||
|
]
|
||||||
|
}`
|
||||||
|
var expected TopResult
|
||||||
|
err := json.Unmarshal([]byte(jsonTop), &expected)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
id := "4fa6e0f0"
|
||||||
|
fakeRT := &FakeRoundTripper{message: jsonTop, status: http.StatusOK}
|
||||||
|
client := newTestClient(fakeRT)
|
||||||
|
processes, err := client.TopContainer(id, "")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(processes, expected) {
|
||||||
|
t.Errorf("TopContainer: Expected %#v. Got %#v.", expected, processes)
|
||||||
|
}
|
||||||
|
if len(processes.Processes) != 2 || len(processes.Processes[0]) != 8 ||
|
||||||
|
processes.Processes[0][7] != "cmd1" {
|
||||||
|
t.Errorf("TopContainer: Process list to include cmd1. Got %#v.", expected, processes)
|
||||||
|
}
|
||||||
|
expectedURI := "/containers/" + id + "/top"
|
||||||
|
if !strings.HasSuffix(fakeRT.requests[0].URL.String(), expectedURI) {
|
||||||
|
t.Errorf("TopContainer: Expected URI to have %q. Got %q.", expectedURI, fakeRT.requests[0].URL.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTopContainerNotFound(t *testing.T) {
|
||||||
|
client := newTestClient(&FakeRoundTripper{message: "no such container", status: http.StatusNotFound})
|
||||||
|
_, err := client.TopContainer("abef348", "")
|
||||||
|
expected := &NoSuchContainer{ID: "abef348"}
|
||||||
|
if !reflect.DeepEqual(err, expected) {
|
||||||
|
t.Errorf("StopContainer: Wrong error returned. Want %#v. Got %#v.", expected, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTopContainerWithPsArgs(t *testing.T) {
|
||||||
|
fakeRT := &FakeRoundTripper{message: "no such container", status: http.StatusNotFound}
|
||||||
|
client := newTestClient(fakeRT)
|
||||||
|
client.TopContainer("abef348", "aux")
|
||||||
|
expectedURI := "/containers/abef348/top?ps_args=aux"
|
||||||
|
if !strings.HasSuffix(fakeRT.requests[0].URL.String(), expectedURI) {
|
||||||
|
t.Errorf("TopContainer: Expected URI to have %q. Got %q.", expectedURI, fakeRT.requests[0].URL.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
126
Godeps/_workspace/src/github.com/fsouza/go-dockerclient/exec.go
generated
vendored
Normal file
126
Godeps/_workspace/src/github.com/fsouza/go-dockerclient/exec.go
generated
vendored
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
// Docs can currently be found at https://github.com/docker/docker/blob/master/docs/sources/reference/api/docker_remote_api_v1.15.md#exec-create
|
||||||
|
|
||||||
|
package docker
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CreateExecOptions specify parameters to the CreateExecContainer function.
|
||||||
|
//
|
||||||
|
// See http://goo.gl/8izrzI for more details
|
||||||
|
type CreateExecOptions struct {
|
||||||
|
AttachStdin bool `json:"AttachStdin,omitempty" yaml:"AttachStdin,omitempty"`
|
||||||
|
AttachStdout bool `json:"AttachStdout,omitempty" yaml:"AttachStdout,omitempty"`
|
||||||
|
AttachStderr bool `json:"AttachStderr,omitempty" yaml:"AttachStderr,omitempty"`
|
||||||
|
Tty bool `json:"Tty,omitempty" yaml:"Tty,omitempty"`
|
||||||
|
Cmd []string `json:"Cmd,omitempty" yaml:"Cmd,omitempty"`
|
||||||
|
Container string `json:"Container,omitempty" yaml:"Container,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// StartExecOptions specify parameters to the StartExecContainer function.
|
||||||
|
//
|
||||||
|
// See http://goo.gl/JW8Lxl for more details
|
||||||
|
type StartExecOptions struct {
|
||||||
|
Detach bool `json:"Detach,omitempty" yaml:"Detach,omitempty"`
|
||||||
|
|
||||||
|
Tty bool `json:"Tty,omitempty" yaml:"Tty,omitempty"`
|
||||||
|
|
||||||
|
InputStream io.Reader `qs:"-"`
|
||||||
|
OutputStream io.Writer `qs:"-"`
|
||||||
|
ErrorStream io.Writer `qs:"-"`
|
||||||
|
|
||||||
|
// Use raw terminal? Usually true when the container contains a TTY.
|
||||||
|
RawTerminal bool `qs:"-"`
|
||||||
|
|
||||||
|
// If set, after a successful connect, a sentinel will be sent and then the
|
||||||
|
// client will block on receive before continuing.
|
||||||
|
//
|
||||||
|
// It must be an unbuffered channel. Using a buffered channel can lead
|
||||||
|
// to unexpected behavior.
|
||||||
|
Success chan struct{} `json:"-"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Exec struct {
|
||||||
|
Id string `json:"Id,omitempty" yaml:"Id,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateExec sets up an exec instance in a running container `id`, returning the exec
|
||||||
|
// instance, or an error in case of failure.
|
||||||
|
//
|
||||||
|
// 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)
|
||||||
|
if status == http.StatusNotFound {
|
||||||
|
return nil, &NoSuchContainer{ID: opts.Container}
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var exec Exec
|
||||||
|
err = json.Unmarshal(body, &exec)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &exec, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Starts a previously set up exec instance id. If opts.Detach is true, it returns
|
||||||
|
// after starting the exec command. Otherwise, it sets up an interactive session
|
||||||
|
// with the exec command.
|
||||||
|
//
|
||||||
|
// See http://goo.gl/JW8Lxl for more details
|
||||||
|
func (c *Client) StartExec(id string, opts StartExecOptions) error {
|
||||||
|
if id == "" {
|
||||||
|
return &NoSuchExec{ID: id}
|
||||||
|
}
|
||||||
|
|
||||||
|
path := fmt.Sprintf("/exec/%s/start", id)
|
||||||
|
|
||||||
|
if opts.Detach {
|
||||||
|
_, status, err := c.do("POST", path, opts)
|
||||||
|
if status == http.StatusNotFound {
|
||||||
|
return &NoSuchExec{ID: id}
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.hijack("POST", path, opts.Success, opts.RawTerminal, opts.InputStream, opts.ErrorStream, opts.OutputStream, opts)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Resizes the tty session used by the exec command id. This API is valid only
|
||||||
|
// if Tty was specified as part of creating and starting the exec command.
|
||||||
|
//
|
||||||
|
// See http://goo.gl/YDSx1f for more details
|
||||||
|
func (c *Client) ResizeExecTTY(id string, height, width int) error {
|
||||||
|
params := make(url.Values)
|
||||||
|
params.Set("h", strconv.Itoa(height))
|
||||||
|
params.Set("w", strconv.Itoa(width))
|
||||||
|
|
||||||
|
path := fmt.Sprintf("/exec/%s/resize?%s", id, params.Encode())
|
||||||
|
_, _, err := c.do("POST", path, nil)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// NoSuchExec is the error returned when a given exec instance does not exist.
|
||||||
|
type NoSuchExec struct {
|
||||||
|
ID string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (err *NoSuchExec) Error() string {
|
||||||
|
return "No such exec instance: " + err.ID
|
||||||
|
}
|
128
Godeps/_workspace/src/github.com/fsouza/go-dockerclient/exec_test.go
generated
vendored
Normal file
128
Godeps/_workspace/src/github.com/fsouza/go-dockerclient/exec_test.go
generated
vendored
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
// 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 (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"net/url"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestExecCreate(t *testing.T) {
|
||||||
|
jsonContainer := `{"Id": "4fa6e0f0c6786287e131c3852c58a2e01cc697a68231826813597e4994f1d6e2"}`
|
||||||
|
var expected struct{ Id string }
|
||||||
|
err := json.Unmarshal([]byte(jsonContainer), &expected)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
fakeRT := &FakeRoundTripper{message: jsonContainer, status: http.StatusOK}
|
||||||
|
client := newTestClient(fakeRT)
|
||||||
|
config := CreateExecOptions{
|
||||||
|
Container: "test",
|
||||||
|
AttachStdin: true,
|
||||||
|
AttachStdout: true,
|
||||||
|
AttachStderr: false,
|
||||||
|
Tty: false,
|
||||||
|
Cmd: []string{"touch", "/tmp/file"},
|
||||||
|
}
|
||||||
|
execObj, err := client.CreateExec(config)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
expectedId := "4fa6e0f0c6786287e131c3852c58a2e01cc697a68231826813597e4994f1d6e2"
|
||||||
|
if execObj.Id != expectedId {
|
||||||
|
t.Errorf("ExecCreate: wrong ID. Want %q. Got %q.", expectedId, execObj.Id)
|
||||||
|
}
|
||||||
|
req := fakeRT.requests[0]
|
||||||
|
if req.Method != "POST" {
|
||||||
|
t.Errorf("ExecCreate: wrong HTTP method. Want %q. Got %q.", "POST", req.Method)
|
||||||
|
}
|
||||||
|
expectedURL, _ := url.Parse(client.getURL("/containers/test/exec"))
|
||||||
|
if gotPath := req.URL.Path; gotPath != expectedURL.Path {
|
||||||
|
t.Errorf("ExecCreate: Wrong path in request. Want %q. Got %q.", expectedURL.Path, gotPath)
|
||||||
|
}
|
||||||
|
var gotBody struct{ Id string }
|
||||||
|
err = json.NewDecoder(req.Body).Decode(&gotBody)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestExecStartDetached(t *testing.T) {
|
||||||
|
execId := "4fa6e0f0c6786287e131c3852c58a2e01cc697a68231826813597e4994f1d6e2"
|
||||||
|
fakeRT := &FakeRoundTripper{status: http.StatusOK}
|
||||||
|
client := newTestClient(fakeRT)
|
||||||
|
config := StartExecOptions{
|
||||||
|
Detach: true,
|
||||||
|
}
|
||||||
|
err := client.StartExec(execId, config)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
req := fakeRT.requests[0]
|
||||||
|
if req.Method != "POST" {
|
||||||
|
t.Errorf("ExecStart: wrong HTTP method. Want %q. Got %q.", "POST", req.Method)
|
||||||
|
}
|
||||||
|
expectedURL, _ := url.Parse(client.getURL("/exec/" + execId + "/start"))
|
||||||
|
if gotPath := req.URL.Path; gotPath != expectedURL.Path {
|
||||||
|
t.Errorf("ExecCreate: Wrong path in request. Want %q. Got %q.", expectedURL.Path, gotPath)
|
||||||
|
}
|
||||||
|
t.Log(req.Body)
|
||||||
|
var gotBody struct{ Detach bool }
|
||||||
|
err = json.NewDecoder(req.Body).Decode(&gotBody)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if !gotBody.Detach {
|
||||||
|
t.Fatal("Expected Detach in StartExecOptions to be true")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestExecStartAndAttach(t *testing.T) {
|
||||||
|
var reader = strings.NewReader("send value")
|
||||||
|
var req http.Request
|
||||||
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.Write([]byte{1, 0, 0, 0, 0, 0, 0, 5})
|
||||||
|
w.Write([]byte("hello"))
|
||||||
|
req = *r
|
||||||
|
}))
|
||||||
|
defer server.Close()
|
||||||
|
client, _ := NewClient(server.URL)
|
||||||
|
client.SkipServerVersionCheck = true
|
||||||
|
var stdout, stderr bytes.Buffer
|
||||||
|
success := make(chan struct{})
|
||||||
|
execId := "4fa6e0f0c6786287e131c3852c58a2e01cc697a68231826813597e4994f1d6e2"
|
||||||
|
opts := StartExecOptions{
|
||||||
|
OutputStream: &stdout,
|
||||||
|
ErrorStream: &stderr,
|
||||||
|
InputStream: reader,
|
||||||
|
RawTerminal: true,
|
||||||
|
Success: success,
|
||||||
|
}
|
||||||
|
go client.StartExec(execId, opts)
|
||||||
|
<-success
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestExecResize(t *testing.T) {
|
||||||
|
execId := "4fa6e0f0c6786287e131c3852c58a2e01cc697a68231826813597e4994f1d6e2"
|
||||||
|
fakeRT := &FakeRoundTripper{status: http.StatusOK}
|
||||||
|
client := newTestClient(fakeRT)
|
||||||
|
err := client.ResizeExecTTY(execId, 10, 20)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
req := fakeRT.requests[0]
|
||||||
|
if req.Method != "POST" {
|
||||||
|
t.Errorf("ExecStart: wrong HTTP method. Want %q. Got %q.", "POST", req.Method)
|
||||||
|
}
|
||||||
|
expectedURL, _ := url.Parse(client.getURL("/exec/" + execId + "/resize?h=10&w=20"))
|
||||||
|
if gotPath := req.URL.RequestURI(); gotPath != expectedURL.RequestURI() {
|
||||||
|
t.Errorf("ExecCreate: Wrong path in request. Want %q. Got %q.", expectedURL.Path, gotPath)
|
||||||
|
}
|
||||||
|
}
|
96
Godeps/_workspace/src/github.com/fsouza/go-dockerclient/image.go
generated
vendored
96
Godeps/_workspace/src/github.com/fsouza/go-dockerclient/image.go
generated
vendored
@ -42,6 +42,16 @@ type Image struct {
|
|||||||
Size int64 `json:"Size,omitempty" yaml:"Size,omitempty"`
|
Size int64 `json:"Size,omitempty" yaml:"Size,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ImageHistory represent a layer in an image's history returned by the
|
||||||
|
// ImageHistory call.
|
||||||
|
type ImageHistory struct {
|
||||||
|
ID string `json:"Id" yaml:"Id"`
|
||||||
|
Tags []string `json:"Tags,omitempty" yaml:"Tags,omitempty"`
|
||||||
|
Created int64 `json:"Created,omitempty" yaml:"Created,omitempty"`
|
||||||
|
CreatedBy string `json:"CreatedBy,omitempty" yaml:"CreatedBy,omitempty"`
|
||||||
|
Size int64 `json:"Size,omitempty" yaml:"Size,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
type ImagePre012 struct {
|
type ImagePre012 struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
Parent string `json:"parent,omitempty"`
|
Parent string `json:"parent,omitempty"`
|
||||||
@ -71,7 +81,7 @@ var (
|
|||||||
|
|
||||||
// ListImages returns the list of available images in the server.
|
// ListImages returns the list of available images in the server.
|
||||||
//
|
//
|
||||||
// See http://goo.gl/dkMrwP for more details.
|
// See http://goo.gl/VmcR6v for more details.
|
||||||
func (c *Client) ListImages(all bool) ([]APIImages, error) {
|
func (c *Client) ListImages(all bool) ([]APIImages, error) {
|
||||||
path := "/images/json?all="
|
path := "/images/json?all="
|
||||||
if all {
|
if all {
|
||||||
@ -91,9 +101,28 @@ func (c *Client) ListImages(all bool) ([]APIImages, error) {
|
|||||||
return images, nil
|
return images, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ImageHistory returns the history of the image by its name or ID.
|
||||||
|
//
|
||||||
|
// 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)
|
||||||
|
if status == http.StatusNotFound {
|
||||||
|
return nil, ErrNoSuchImage
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var history []ImageHistory
|
||||||
|
err = json.Unmarshal(body, &history)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return history, nil
|
||||||
|
}
|
||||||
|
|
||||||
// RemoveImage removes an image by its name or ID.
|
// RemoveImage removes an image by its name or ID.
|
||||||
//
|
//
|
||||||
// See http://goo.gl/7hjHHy for more details.
|
// See http://goo.gl/znj0wM for more details.
|
||||||
func (c *Client) RemoveImage(name string) error {
|
func (c *Client) RemoveImage(name string) error {
|
||||||
_, status, err := c.do("DELETE", "/images/"+name, nil)
|
_, status, err := c.do("DELETE", "/images/"+name, nil)
|
||||||
if status == http.StatusNotFound {
|
if status == http.StatusNotFound {
|
||||||
@ -104,7 +133,7 @@ func (c *Client) RemoveImage(name string) error {
|
|||||||
|
|
||||||
// InspectImage returns an image by its name or ID.
|
// InspectImage returns an image by its name or ID.
|
||||||
//
|
//
|
||||||
// See http://goo.gl/pHEbma for more details.
|
// See http://goo.gl/Q112NY for more details.
|
||||||
func (c *Client) InspectImage(name string) (*Image, error) {
|
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)
|
||||||
if status == http.StatusNotFound {
|
if status == http.StatusNotFound {
|
||||||
@ -147,7 +176,7 @@ func (c *Client) InspectImage(name string) (*Image, error) {
|
|||||||
|
|
||||||
// PushImageOptions represents options to use in the PushImage method.
|
// PushImageOptions represents options to use in the PushImage method.
|
||||||
//
|
//
|
||||||
// See http://goo.gl/GBmyhc for more details.
|
// See http://goo.gl/pN8A3P for more details.
|
||||||
type PushImageOptions struct {
|
type PushImageOptions struct {
|
||||||
// Name of the image
|
// Name of the image
|
||||||
Name string
|
Name string
|
||||||
@ -158,7 +187,8 @@ type PushImageOptions struct {
|
|||||||
// Registry server to push the image
|
// Registry server to push the image
|
||||||
Registry string
|
Registry string
|
||||||
|
|
||||||
OutputStream io.Writer `qs:"-"`
|
OutputStream io.Writer `qs:"-"`
|
||||||
|
RawJSONStream bool `qs:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// AuthConfiguration represents authentication options to use in the PushImage
|
// AuthConfiguration represents authentication options to use in the PushImage
|
||||||
@ -174,7 +204,7 @@ type AuthConfiguration struct {
|
|||||||
// An empty instance of AuthConfiguration may be used for unauthenticated
|
// An empty instance of AuthConfiguration may be used for unauthenticated
|
||||||
// pushes.
|
// pushes.
|
||||||
//
|
//
|
||||||
// See http://goo.gl/GBmyhc for more details.
|
// See http://goo.gl/pN8A3P for more details.
|
||||||
func (c *Client) PushImage(opts PushImageOptions, auth AuthConfiguration) error {
|
func (c *Client) PushImage(opts PushImageOptions, auth AuthConfiguration) error {
|
||||||
if opts.Name == "" {
|
if opts.Name == "" {
|
||||||
return ErrNoSuchImage
|
return ErrNoSuchImage
|
||||||
@ -188,13 +218,13 @@ 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, false, headers, nil, opts.OutputStream, nil)
|
return c.stream("POST", path, true, opts.RawJSONStream, 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
|
||||||
// from a registry.
|
// from a registry.
|
||||||
//
|
//
|
||||||
// See http://goo.gl/PhBKnS for more details.
|
// See http://goo.gl/ACyYNS for more details.
|
||||||
type PullImageOptions struct {
|
type PullImageOptions struct {
|
||||||
Repository string `qs:"fromImage"`
|
Repository string `qs:"fromImage"`
|
||||||
Registry string
|
Registry string
|
||||||
@ -205,7 +235,7 @@ type PullImageOptions struct {
|
|||||||
|
|
||||||
// PullImage pulls an image from a remote registry, logging progress to w.
|
// PullImage pulls an image from a remote registry, logging progress to w.
|
||||||
//
|
//
|
||||||
// See http://goo.gl/PhBKnS for more details.
|
// See http://goo.gl/ACyYNS for more details.
|
||||||
func (c *Client) PullImage(opts PullImageOptions, auth AuthConfiguration) error {
|
func (c *Client) PullImage(opts PullImageOptions, auth AuthConfiguration) error {
|
||||||
if opts.Repository == "" {
|
if opts.Repository == "" {
|
||||||
return ErrNoSuchImage
|
return ErrNoSuchImage
|
||||||
@ -288,9 +318,11 @@ func (c *Client) ImportImage(opts ImportImageOptions) error {
|
|||||||
return c.createImage(queryString(&opts), nil, opts.InputStream, opts.OutputStream, false)
|
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
|
||||||
// an image from a tarfile with a Dockerfile in it,the details about Dockerfile
|
// image from a tarfile with a Dockerfile in it.
|
||||||
// see http://docs.docker.io/en/latest/reference/builder/
|
//
|
||||||
|
// For more details about the Docker building process, see
|
||||||
|
// http://goo.gl/tlPXPu.
|
||||||
type BuildImageOptions struct {
|
type BuildImageOptions struct {
|
||||||
Name string `qs:"t"`
|
Name string `qs:"t"`
|
||||||
NoCache bool `qs:"nocache"`
|
NoCache bool `qs:"nocache"`
|
||||||
@ -299,11 +331,14 @@ type BuildImageOptions struct {
|
|||||||
ForceRmTmpContainer bool `qs:"forcerm"`
|
ForceRmTmpContainer bool `qs:"forcerm"`
|
||||||
InputStream io.Reader `qs:"-"`
|
InputStream io.Reader `qs:"-"`
|
||||||
OutputStream io.Writer `qs:"-"`
|
OutputStream io.Writer `qs:"-"`
|
||||||
|
RawJSONStream bool `qs:"-"`
|
||||||
Remote string `qs:"remote"`
|
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
|
||||||
// stream.
|
// stream.
|
||||||
|
//
|
||||||
|
// See http://goo.gl/wRsW76 for more details.
|
||||||
func (c *Client) BuildImage(opts BuildImageOptions) error {
|
func (c *Client) BuildImage(opts BuildImageOptions) error {
|
||||||
if opts.OutputStream == nil {
|
if opts.OutputStream == nil {
|
||||||
return ErrMissingOutputStream
|
return ErrMissingOutputStream
|
||||||
@ -318,17 +353,21 @@ 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, false, headers, opts.InputStream, opts.OutputStream, nil)
|
queryString(&opts)), true, opts.RawJSONStream, 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.
|
||||||
|
//
|
||||||
|
// See http://goo.gl/5g6qFy for more details.
|
||||||
type TagImageOptions struct {
|
type TagImageOptions struct {
|
||||||
Repo string
|
Repo string
|
||||||
Tag string
|
Tag string
|
||||||
Force bool
|
Force bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// TagImage adds a tag to the image 'name'
|
// TagImage adds a tag to the image identified by the given name.
|
||||||
|
//
|
||||||
|
// See http://goo.gl/5g6qFy for more details.
|
||||||
func (c *Client) TagImage(name string, opts TagImageOptions) error {
|
func (c *Client) TagImage(name string, opts TagImageOptions) error {
|
||||||
if name == "" {
|
if name == "" {
|
||||||
return ErrNoSuchImage
|
return ErrNoSuchImage
|
||||||
@ -349,3 +388,30 @@ func isURL(u string) bool {
|
|||||||
}
|
}
|
||||||
return p.Scheme == "http" || p.Scheme == "https"
|
return p.Scheme == "http" || p.Scheme == "https"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// APIImageSearch reflect the result of a search on the dockerHub
|
||||||
|
//
|
||||||
|
// See http://goo.gl/xI5lLZ for more details.
|
||||||
|
type APIImageSearch struct {
|
||||||
|
Description string `json:"description,omitempty" yaml:"description,omitempty"`
|
||||||
|
IsOfficial bool `json:"is_official,omitempty" yaml:"is_official,omitempty"`
|
||||||
|
IsAutomated bool `json:"is_automated,omitempty" yaml:"is_automated,omitempty"`
|
||||||
|
Name string `json:"name,omitempty" yaml:"name,omitempty"`
|
||||||
|
StarCount int `json:"star_count,omitempty" yaml:"star_count,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SearchImages search the docker hub with a specific given term.
|
||||||
|
//
|
||||||
|
// 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)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var searchResult []APIImageSearch
|
||||||
|
err = json.Unmarshal(body, &searchResult)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return searchResult, nil
|
||||||
|
}
|
||||||
|
151
Godeps/_workspace/src/github.com/fsouza/go-dockerclient/image_test.go
generated
vendored
151
Godeps/_workspace/src/github.com/fsouza/go-dockerclient/image_test.go
generated
vendored
@ -122,6 +122,48 @@ func TestListImagesParameters(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestImageHistory(t *testing.T) {
|
||||||
|
body := `[
|
||||||
|
{
|
||||||
|
"Id": "25daec02219d2d852f7526137213a9b199926b4b24e732eab5b8bc6c49bd470e",
|
||||||
|
"Tags": [
|
||||||
|
"debian:7.6",
|
||||||
|
"debian:latest",
|
||||||
|
"debian:7",
|
||||||
|
"debian:wheezy"
|
||||||
|
],
|
||||||
|
"Created": 1409856216,
|
||||||
|
"CreatedBy": "/bin/sh -c #(nop) CMD [/bin/bash]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": "41026a5347fb5be6ed16115bf22df8569697139f246186de9ae8d4f67c335dce",
|
||||||
|
"Created": 1409856213,
|
||||||
|
"CreatedBy": "/bin/sh -c #(nop) ADD file:1ee9e97209d00e3416a4543b23574cc7259684741a46bbcbc755909b8a053a38 in /",
|
||||||
|
"Size": 85178663
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": "511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158",
|
||||||
|
"Tags": [
|
||||||
|
"scratch:latest"
|
||||||
|
],
|
||||||
|
"Created": 1371157430
|
||||||
|
}
|
||||||
|
]`
|
||||||
|
var expected []ImageHistory
|
||||||
|
err := json.Unmarshal([]byte(body), &expected)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
client := newTestClient(&FakeRoundTripper{message: body, status: http.StatusOK})
|
||||||
|
history, err := client.ImageHistory("debian:latest")
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(history, expected) {
|
||||||
|
t.Errorf("ImageHistory: Wrong return value. Want %#v. Got %#v.", expected, history)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestRemoveImage(t *testing.T) {
|
func TestRemoveImage(t *testing.T) {
|
||||||
name := "test"
|
name := "test"
|
||||||
fakeRT := &FakeRoundTripper{message: "", status: http.StatusNoContent}
|
fakeRT := &FakeRoundTripper{message: "", status: http.StatusNoContent}
|
||||||
@ -224,6 +266,35 @@ func TestPushImage(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPushImageWithRawJSON(t *testing.T) {
|
||||||
|
body := `
|
||||||
|
{"status":"Pushing..."}
|
||||||
|
{"status":"Pushing", "progress":"1/? (n/a)", "progressDetail":{"current":1}}}
|
||||||
|
{"status":"Image successfully pushed"}
|
||||||
|
`
|
||||||
|
fakeRT := &FakeRoundTripper{
|
||||||
|
message: body,
|
||||||
|
status: http.StatusOK,
|
||||||
|
header: map[string]string{
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
client := newTestClient(fakeRT)
|
||||||
|
var buf bytes.Buffer
|
||||||
|
|
||||||
|
err := client.PushImage(PushImageOptions{
|
||||||
|
Name: "test",
|
||||||
|
OutputStream: &buf,
|
||||||
|
RawJSONStream: true,
|
||||||
|
}, AuthConfiguration{})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if buf.String() != body {
|
||||||
|
t.Errorf("PushImage: Wrong raw output. Want %q. Got %q.", body, buf.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestPushImageWithAuthentication(t *testing.T) {
|
func TestPushImageWithAuthentication(t *testing.T) {
|
||||||
fakeRT := &FakeRoundTripper{message: "Pushing 1/100", status: http.StatusOK}
|
fakeRT := &FakeRoundTripper{message: "Pushing 1/100", status: http.StatusOK}
|
||||||
client := newTestClient(fakeRT)
|
client := newTestClient(fakeRT)
|
||||||
@ -579,7 +650,7 @@ func TestBuildImageParametersForRemoteBuild(t *testing.T) {
|
|||||||
expected := map[string][]string{"t": {opts.Name}, "remote": {opts.Remote}, "q": {"1"}}
|
expected := map[string][]string{"t": {opts.Name}, "remote": {opts.Remote}, "q": {"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("ImportImage: wrong query string. Want %#v. Got %#v.", expected, got)
|
t.Errorf("BuildImage: wrong query string. Want %#v. Got %#v.", expected, got)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -608,6 +679,44 @@ func TestBuildImageMissingOutputStream(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestBuildImageWithRawJSON(t *testing.T) {
|
||||||
|
body := `
|
||||||
|
{"stream":"Step 0 : FROM ubuntu:latest\n"}
|
||||||
|
{"stream":" ---\u003e 4300eb9d3c8d\n"}
|
||||||
|
{"stream":"Step 1 : MAINTAINER docker <eng@docker.com>\n"}
|
||||||
|
{"stream":" ---\u003e Using cache\n"}
|
||||||
|
{"stream":" ---\u003e 3a3ed758c370\n"}
|
||||||
|
{"stream":"Step 2 : CMD /usr/bin/top\n"}
|
||||||
|
{"stream":" ---\u003e Running in 36b1479cc2e4\n"}
|
||||||
|
{"stream":" ---\u003e 4b6188aebe39\n"}
|
||||||
|
{"stream":"Removing intermediate container 36b1479cc2e4\n"}
|
||||||
|
{"stream":"Successfully built 4b6188aebe39\n"}
|
||||||
|
`
|
||||||
|
fakeRT := &FakeRoundTripper{
|
||||||
|
message: body,
|
||||||
|
status: http.StatusOK,
|
||||||
|
header: map[string]string{
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
client := newTestClient(fakeRT)
|
||||||
|
var buf bytes.Buffer
|
||||||
|
opts := BuildImageOptions{
|
||||||
|
Name: "testImage",
|
||||||
|
RmTmpContainer: true,
|
||||||
|
InputStream: &buf,
|
||||||
|
OutputStream: &buf,
|
||||||
|
RawJSONStream: true,
|
||||||
|
}
|
||||||
|
err := client.BuildImage(opts)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if buf.String() != body {
|
||||||
|
t.Errorf("BuildImage: Wrong raw output. Want %q. Got %q.", body, buf.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestBuildImageRemoteWithoutName(t *testing.T) {
|
func TestBuildImageRemoteWithoutName(t *testing.T) {
|
||||||
fakeRT := &FakeRoundTripper{message: "", status: http.StatusOK}
|
fakeRT := &FakeRoundTripper{message: "", status: http.StatusOK}
|
||||||
client := newTestClient(fakeRT)
|
client := newTestClient(fakeRT)
|
||||||
@ -710,3 +819,43 @@ func TestExportImage(t *testing.T) {
|
|||||||
t.Errorf("ExportIMage: wrong path. Expected %q. Got %q.", expectedPath, req.URL.Path)
|
t.Errorf("ExportIMage: wrong path. Expected %q. Got %q.", expectedPath, req.URL.Path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSearchImages(t *testing.T) {
|
||||||
|
body := `[
|
||||||
|
{
|
||||||
|
"description":"A container with Cassandra 2.0.3",
|
||||||
|
"is_official":true,
|
||||||
|
"is_automated":true,
|
||||||
|
"name":"poklet/cassandra",
|
||||||
|
"star_count":17
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description":"A container with Cassandra 2.0.3",
|
||||||
|
"is_official":true,
|
||||||
|
"is_automated":false,
|
||||||
|
"name":"poklet/cassandra",
|
||||||
|
"star_count":17
|
||||||
|
}
|
||||||
|
,
|
||||||
|
{
|
||||||
|
"description":"A container with Cassandra 2.0.3",
|
||||||
|
"is_official":false,
|
||||||
|
"is_automated":true,
|
||||||
|
"name":"poklet/cassandra",
|
||||||
|
"star_count":17
|
||||||
|
}
|
||||||
|
]`
|
||||||
|
var expected []APIImageSearch
|
||||||
|
err := json.Unmarshal([]byte(body), &expected)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
client := newTestClient(&FakeRoundTripper{message: body, status: http.StatusOK})
|
||||||
|
result, err := client.SearchImages("cassandra")
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(result, expected) {
|
||||||
|
t.Errorf("SearchImages: Wrong return value. Want %#v. Got %#v.", expected, result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
6
Godeps/_workspace/src/github.com/fsouza/go-dockerclient/misc.go
generated
vendored
6
Godeps/_workspace/src/github.com/fsouza/go-dockerclient/misc.go
generated
vendored
@ -11,7 +11,7 @@ import (
|
|||||||
|
|
||||||
// Version returns version information about the docker server.
|
// Version returns version information about the docker server.
|
||||||
//
|
//
|
||||||
// See http://goo.gl/IqKNRE for more details.
|
// See http://goo.gl/BOZrF5 for more details.
|
||||||
func (c *Client) Version() (*Env, error) {
|
func (c *Client) Version() (*Env, error) {
|
||||||
body, _, err := c.do("GET", "/version", nil)
|
body, _, err := c.do("GET", "/version", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -24,9 +24,9 @@ func (c *Client) Version() (*Env, error) {
|
|||||||
return &env, nil
|
return &env, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Info returns system-wide information, like the number of running containers.
|
// Info returns system-wide information about the Docker server.
|
||||||
//
|
//
|
||||||
// See http://goo.gl/LOmySw for more details.
|
// See http://goo.gl/wmqZsW for more details.
|
||||||
func (c *Client) Info() (*Env, error) {
|
func (c *Client) Info() (*Env, error) {
|
||||||
body, _, err := c.do("GET", "/info", nil)
|
body, _, err := c.do("GET", "/info", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
26
Godeps/_workspace/src/github.com/fsouza/go-dockerclient/testing/server.go
generated
vendored
26
Godeps/_workspace/src/github.com/fsouza/go-dockerclient/testing/server.go
generated
vendored
@ -31,7 +31,7 @@ import (
|
|||||||
// It can used in standalone mode, listening for connections or as an arbitrary
|
// It can used in standalone mode, listening for connections or as an arbitrary
|
||||||
// HTTP handler.
|
// HTTP handler.
|
||||||
//
|
//
|
||||||
// For more details on the remote API, check http://goo.gl/yMI1S.
|
// For more details on the remote API, check http://goo.gl/G3plxW.
|
||||||
type DockerServer struct {
|
type DockerServer struct {
|
||||||
containers []*docker.Container
|
containers []*docker.Container
|
||||||
cMut sync.RWMutex
|
cMut sync.RWMutex
|
||||||
@ -88,6 +88,7 @@ func (s *DockerServer) buildMuxer() {
|
|||||||
s.mux.Path("/containers/json").Methods("GET").HandlerFunc(s.handlerWrapper(s.listContainers))
|
s.mux.Path("/containers/json").Methods("GET").HandlerFunc(s.handlerWrapper(s.listContainers))
|
||||||
s.mux.Path("/containers/create").Methods("POST").HandlerFunc(s.handlerWrapper(s.createContainer))
|
s.mux.Path("/containers/create").Methods("POST").HandlerFunc(s.handlerWrapper(s.createContainer))
|
||||||
s.mux.Path("/containers/{id:.*}/json").Methods("GET").HandlerFunc(s.handlerWrapper(s.inspectContainer))
|
s.mux.Path("/containers/{id:.*}/json").Methods("GET").HandlerFunc(s.handlerWrapper(s.inspectContainer))
|
||||||
|
s.mux.Path("/containers/{id:.*}/top").Methods("GET").HandlerFunc(s.handlerWrapper(s.topContainer))
|
||||||
s.mux.Path("/containers/{id:.*}/start").Methods("POST").HandlerFunc(s.handlerWrapper(s.startContainer))
|
s.mux.Path("/containers/{id:.*}/start").Methods("POST").HandlerFunc(s.handlerWrapper(s.startContainer))
|
||||||
s.mux.Path("/containers/{id:.*}/stop").Methods("POST").HandlerFunc(s.handlerWrapper(s.stopContainer))
|
s.mux.Path("/containers/{id:.*}/stop").Methods("POST").HandlerFunc(s.handlerWrapper(s.stopContainer))
|
||||||
s.mux.Path("/containers/{id:.*}/pause").Methods("POST").HandlerFunc(s.handlerWrapper(s.pauseContainer))
|
s.mux.Path("/containers/{id:.*}/pause").Methods("POST").HandlerFunc(s.handlerWrapper(s.pauseContainer))
|
||||||
@ -339,6 +340,29 @@ func (s *DockerServer) inspectContainer(w http.ResponseWriter, r *http.Request)
|
|||||||
json.NewEncoder(w).Encode(container)
|
json.NewEncoder(w).Encode(container)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *DockerServer) topContainer(w http.ResponseWriter, r *http.Request) {
|
||||||
|
id := mux.Vars(r)["id"]
|
||||||
|
container, _, err := s.findContainer(id)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusNotFound)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !container.State.Running {
|
||||||
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
|
fmt.Fprintf(w, "Container %s is not running", id)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
result := docker.TopResult{
|
||||||
|
Titles: []string{"UID", "PID", "PPID", "C", "STIME", "TTY", "TIME", "CMD"},
|
||||||
|
Processes: [][]string{
|
||||||
|
{"root", "7535", "7516", "0", "03:20", "?", "00:00:00", container.Path + " " + strings.Join(container.Args, " ")},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
json.NewEncoder(w).Encode(result)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *DockerServer) startContainer(w http.ResponseWriter, r *http.Request) {
|
func (s *DockerServer) startContainer(w http.ResponseWriter, r *http.Request) {
|
||||||
id := mux.Vars(r)["id"]
|
id := mux.Vars(r)["id"]
|
||||||
container, _, err := s.findContainer(id)
|
container, _, err := s.findContainer(id)
|
||||||
|
52
Godeps/_workspace/src/github.com/fsouza/go-dockerclient/testing/server_test.go
generated
vendored
52
Godeps/_workspace/src/github.com/fsouza/go-dockerclient/testing/server_test.go
generated
vendored
@ -343,6 +343,58 @@ func TestInspectContainerNotFound(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestTopContainer(t *testing.T) {
|
||||||
|
server := DockerServer{}
|
||||||
|
addContainers(&server, 1)
|
||||||
|
server.containers[0].State.Running = true
|
||||||
|
server.buildMuxer()
|
||||||
|
recorder := httptest.NewRecorder()
|
||||||
|
path := fmt.Sprintf("/containers/%s/top", server.containers[0].ID)
|
||||||
|
request, _ := http.NewRequest("GET", path, nil)
|
||||||
|
server.ServeHTTP(recorder, request)
|
||||||
|
if recorder.Code != http.StatusOK {
|
||||||
|
t.Errorf("TopContainer: wrong status. Want %d. Got %d.", http.StatusOK, recorder.Code)
|
||||||
|
}
|
||||||
|
var got docker.TopResult
|
||||||
|
err := json.NewDecoder(recorder.Body).Decode(&got)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(got.Titles, []string{"UID", "PID", "PPID", "C", "STIME", "TTY", "TIME", "CMD"}) {
|
||||||
|
t.Fatalf("TopContainer: Unexpected titles, got: %#v", got.Titles)
|
||||||
|
}
|
||||||
|
if len(got.Processes) != 1 {
|
||||||
|
t.Fatalf("TopContainer: Unexpected process len, got: %d", len(got.Processes))
|
||||||
|
}
|
||||||
|
if got.Processes[0][len(got.Processes[0])-1] != "ls -la .." {
|
||||||
|
t.Fatalf("TopContainer: Unexpected command name, got: %s", got.Processes[0][len(got.Processes[0])-1])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTopContainerNotFound(t *testing.T) {
|
||||||
|
server := DockerServer{}
|
||||||
|
server.buildMuxer()
|
||||||
|
recorder := httptest.NewRecorder()
|
||||||
|
request, _ := http.NewRequest("GET", "/containers/xyz/top", nil)
|
||||||
|
server.ServeHTTP(recorder, request)
|
||||||
|
if recorder.Code != http.StatusNotFound {
|
||||||
|
t.Errorf("TopContainer: wrong status. Want %d. Got %d.", http.StatusNotFound, recorder.Code)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTopContainerStopped(t *testing.T) {
|
||||||
|
server := DockerServer{}
|
||||||
|
addContainers(&server, 1)
|
||||||
|
server.buildMuxer()
|
||||||
|
recorder := httptest.NewRecorder()
|
||||||
|
path := fmt.Sprintf("/containers/%s/top", server.containers[0].ID)
|
||||||
|
request, _ := http.NewRequest("GET", path, nil)
|
||||||
|
server.ServeHTTP(recorder, request)
|
||||||
|
if recorder.Code != http.StatusInternalServerError {
|
||||||
|
t.Errorf("TopContainer: wrong status. Want %d. Got %d.", http.StatusInternalServerError, recorder.Code)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestStartContainer(t *testing.T) {
|
func TestStartContainer(t *testing.T) {
|
||||||
server := DockerServer{}
|
server := DockerServer{}
|
||||||
addContainers(&server, 1)
|
addContainers(&server, 1)
|
||||||
|
Loading…
Reference in New Issue
Block a user