mirror of
https://github.com/containrrr/watchtower.git
synced 2026-02-18 13:18:08 +01:00
Add godeps
This commit is contained in:
parent
c36d1dfffe
commit
ff277f9903
66 changed files with 10603 additions and 2073 deletions
17
Godeps/_workspace/src/github.com/samalba/dockerclient/README.md
generated
vendored
17
Godeps/_workspace/src/github.com/samalba/dockerclient/README.md
generated
vendored
|
|
@ -15,6 +15,7 @@ import (
|
|||
"github.com/samalba/dockerclient"
|
||||
"log"
|
||||
"time"
|
||||
"os"
|
||||
)
|
||||
|
||||
// Callback used to listen to Docker's events
|
||||
|
|
@ -42,13 +43,27 @@ func main() {
|
|||
log.Println(info)
|
||||
}
|
||||
|
||||
// Build a docker image
|
||||
// some.tar contains the build context (Dockerfile any any files it needs to add/copy)
|
||||
dockerBuildContext, err := os.Open("some.tar")
|
||||
defer dockerBuildContext.Close()
|
||||
buildImageConfig := &dockerclient.BuildImage{
|
||||
Context: dockerBuildContext,
|
||||
RepoName: "your_image_name",
|
||||
SuppressOutput: false,
|
||||
}
|
||||
reader, err := docker.BuildImage(buildImageConfig)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Create a container
|
||||
containerConfig := &dockerclient.ContainerConfig{
|
||||
Image: "ubuntu:14.04",
|
||||
Cmd: []string{"bash"},
|
||||
AttachStdin: true,
|
||||
Tty: true}
|
||||
containerId, err := docker.CreateContainer(containerConfig, "foobar")
|
||||
containerId, err := docker.CreateContainer(containerConfig, "foobar", nil)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
|
|
|||
30
Godeps/_workspace/src/github.com/samalba/dockerclient/auth.go
generated
vendored
30
Godeps/_workspace/src/github.com/samalba/dockerclient/auth.go
generated
vendored
|
|
@ -8,14 +8,32 @@ import (
|
|||
|
||||
// AuthConfig hold parameters for authenticating with the docker registry
|
||||
type AuthConfig struct {
|
||||
Username string `json:"username,omitempty"`
|
||||
Password string `json:"password,omitempty"`
|
||||
Email string `json:"email,omitempty"`
|
||||
Username string `json:"username,omitempty"`
|
||||
Password string `json:"password,omitempty"`
|
||||
Email string `json:"email,omitempty"`
|
||||
RegistryToken string `json:"registrytoken,omitempty"`
|
||||
}
|
||||
|
||||
// encode the auth configuration struct into base64 for the X-Registry-Auth header
|
||||
func (c *AuthConfig) encode() string {
|
||||
func (c *AuthConfig) encode() (string, error) {
|
||||
var buf bytes.Buffer
|
||||
json.NewEncoder(&buf).Encode(c)
|
||||
return base64.URLEncoding.EncodeToString(buf.Bytes())
|
||||
if err := json.NewEncoder(&buf).Encode(c); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return base64.URLEncoding.EncodeToString(buf.Bytes()), nil
|
||||
}
|
||||
|
||||
// ConfigFile holds parameters for authenticating during a BuildImage request
|
||||
type ConfigFile struct {
|
||||
Configs map[string]AuthConfig `json:"configs,omitempty"`
|
||||
rootPath string
|
||||
}
|
||||
|
||||
// encode the configuration struct into base64 for the X-Registry-Config header
|
||||
func (c *ConfigFile) encode() (string, error) {
|
||||
var buf bytes.Buffer
|
||||
if err := json.NewEncoder(&buf).Encode(c); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return base64.URLEncoding.EncodeToString(buf.Bytes()), nil
|
||||
}
|
||||
|
|
|
|||
15
Godeps/_workspace/src/github.com/samalba/dockerclient/auth_test.go
generated
vendored
15
Godeps/_workspace/src/github.com/samalba/dockerclient/auth_test.go
generated
vendored
|
|
@ -1,15 +0,0 @@
|
|||
package dockerclient
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestAuthEncode(t *testing.T) {
|
||||
a := AuthConfig{Username: "foo", Password: "password", Email: "bar@baz.com"}
|
||||
expected := "eyJ1c2VybmFtZSI6ImZvbyIsInBhc3N3b3JkIjoicGFzc3dvcmQiLCJlbWFpbCI6ImJhckBiYXouY29tIn0K"
|
||||
got := a.encode()
|
||||
|
||||
if expected != got {
|
||||
t.Errorf("testAuthEncode failed. Expected [%s] got [%s]", expected, got)
|
||||
}
|
||||
}
|
||||
496
Godeps/_workspace/src/github.com/samalba/dockerclient/dockerclient.go
generated
vendored
496
Godeps/_workspace/src/github.com/samalba/dockerclient/dockerclient.go
generated
vendored
|
|
@ -16,12 +16,23 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
var _ Client = (*DockerClient)(nil)
|
||||
|
||||
const (
|
||||
// APIVersion is currently hardcoded to v1.15
|
||||
// TODO: bump the API version or allow users to choose which API version to
|
||||
// use the client with. The current value does not make sense for many
|
||||
// methods, such as ContainerStats, StartMonitorStats, and StopAllMonitorStats
|
||||
// (v1.17) and
|
||||
// ListVolumes, {Remove,Create}Volume, ListNetworks,
|
||||
// {Inspect,Create,Connect,Disconnect,Remove}Network (v1.21)
|
||||
APIVersion = "v1.15"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrNotFound = errors.New("Not found")
|
||||
ErrImageNotFound = errors.New("Image not found")
|
||||
ErrNotFound = errors.New("Not found")
|
||||
ErrConnectionRefused = errors.New("Cannot connect to the docker engine endpoint")
|
||||
|
||||
defaultTimeout = 30 * time.Second
|
||||
)
|
||||
|
|
@ -45,10 +56,10 @@ func (e Error) Error() string {
|
|||
}
|
||||
|
||||
func NewDockerClient(daemonUrl string, tlsConfig *tls.Config) (*DockerClient, error) {
|
||||
return NewDockerClientTimeout(daemonUrl, tlsConfig, time.Duration(defaultTimeout))
|
||||
return NewDockerClientTimeout(daemonUrl, tlsConfig, time.Duration(defaultTimeout), nil)
|
||||
}
|
||||
|
||||
func NewDockerClientTimeout(daemonUrl string, tlsConfig *tls.Config, timeout time.Duration) (*DockerClient, error) {
|
||||
func NewDockerClientTimeout(daemonUrl string, tlsConfig *tls.Config, timeout time.Duration, setUserTimeout tcpFunc) (*DockerClient, error) {
|
||||
u, err := url.Parse(daemonUrl)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -60,7 +71,7 @@ func NewDockerClientTimeout(daemonUrl string, tlsConfig *tls.Config, timeout tim
|
|||
u.Scheme = "https"
|
||||
}
|
||||
}
|
||||
httpClient := newHTTPClient(u, tlsConfig, timeout)
|
||||
httpClient := newHTTPClient(u, tlsConfig, timeout, setUserTimeout)
|
||||
return &DockerClient{u, httpClient, tlsConfig, 0, nil}, nil
|
||||
}
|
||||
|
||||
|
|
@ -99,9 +110,24 @@ func (client *DockerClient) doStreamRequest(method string, path string, in io.Re
|
|||
if !strings.Contains(err.Error(), "connection refused") && client.TLSConfig == nil {
|
||||
return nil, fmt.Errorf("%v. Are you trying to connect to a TLS-enabled daemon without TLS?", err)
|
||||
}
|
||||
if strings.Contains(err.Error(), "connection refused") {
|
||||
return nil, ErrConnectionRefused
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
if resp.StatusCode == 404 {
|
||||
defer resp.Body.Close()
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, ErrNotFound
|
||||
}
|
||||
if len(data) > 0 {
|
||||
// check if is image not found error
|
||||
if strings.Index(string(data), "No such image") != -1 {
|
||||
return nil, ErrImageNotFound
|
||||
}
|
||||
return nil, errors.New(string(data))
|
||||
}
|
||||
return nil, ErrNotFound
|
||||
}
|
||||
if resp.StatusCode >= 400 {
|
||||
|
|
@ -171,7 +197,7 @@ func (client *DockerClient) InspectContainer(id string) (*ContainerInfo, error)
|
|||
return info, nil
|
||||
}
|
||||
|
||||
func (client *DockerClient) CreateContainer(config *ContainerConfig, name string) (string, error) {
|
||||
func (client *DockerClient) CreateContainer(config *ContainerConfig, name string, auth *AuthConfig) (string, error) {
|
||||
data, err := json.Marshal(config)
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
|
@ -182,14 +208,22 @@ func (client *DockerClient) CreateContainer(config *ContainerConfig, name string
|
|||
v.Set("name", name)
|
||||
uri = fmt.Sprintf("%s?%s", uri, v.Encode())
|
||||
}
|
||||
data, err = client.doRequest("POST", uri, data, nil)
|
||||
headers := map[string]string{}
|
||||
if auth != nil {
|
||||
encoded_auth, err := auth.encode()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
headers["X-Registry-Auth"] = encoded_auth
|
||||
}
|
||||
data, err = client.doRequest("POST", uri, data, headers)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
result := &RespContainersCreate{}
|
||||
err = json.Unmarshal(data, result)
|
||||
if err != nil {
|
||||
return "", err
|
||||
return "", fmt.Errorf(string(data))
|
||||
}
|
||||
return result.Id, nil
|
||||
}
|
||||
|
|
@ -231,25 +265,64 @@ func (client *DockerClient) ContainerChanges(id string) ([]*ContainerChanges, er
|
|||
return changes, nil
|
||||
}
|
||||
|
||||
func (client *DockerClient) ContainerStats(id string, stopChan <-chan struct{}) (<-chan StatsOrError, error) {
|
||||
uri := fmt.Sprintf("/%s/containers/%s/stats", APIVersion, id)
|
||||
resp, err := client.HTTPClient.Get(client.URL.String() + uri)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
decode := func(decoder *json.Decoder) decodingResult {
|
||||
var containerStats Stats
|
||||
if err := decoder.Decode(&containerStats); err != nil {
|
||||
return decodingResult{err: err}
|
||||
} else {
|
||||
return decodingResult{result: containerStats}
|
||||
}
|
||||
}
|
||||
decodingResultChan := client.readJSONStream(resp.Body, decode, stopChan)
|
||||
statsOrErrorChan := make(chan StatsOrError)
|
||||
go func() {
|
||||
for decodingResult := range decodingResultChan {
|
||||
stats, _ := decodingResult.result.(Stats)
|
||||
statsOrErrorChan <- StatsOrError{
|
||||
Stats: stats,
|
||||
Error: decodingResult.err,
|
||||
}
|
||||
}
|
||||
close(statsOrErrorChan)
|
||||
}()
|
||||
return statsOrErrorChan, nil
|
||||
}
|
||||
|
||||
func (client *DockerClient) readJSONStream(stream io.ReadCloser, decode func(*json.Decoder) decodingResult, stopChan <-chan struct{}) <-chan decodingResult {
|
||||
resultChan := make(chan decodingResult)
|
||||
|
||||
go func() {
|
||||
decoder := json.NewDecoder(stream)
|
||||
stopped := make(chan struct{})
|
||||
decodeChan := make(chan decodingResult)
|
||||
|
||||
go func() {
|
||||
<-stopChan
|
||||
stream.Close()
|
||||
stopped <- struct{}{}
|
||||
decoder := json.NewDecoder(stream)
|
||||
for {
|
||||
decodeResult := decode(decoder)
|
||||
decodeChan <- decodeResult
|
||||
if decodeResult.err != nil {
|
||||
close(decodeChan)
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
defer close(resultChan)
|
||||
|
||||
for {
|
||||
decodeResult := decode(decoder)
|
||||
select {
|
||||
case <-stopped:
|
||||
case <-stopChan:
|
||||
stream.Close()
|
||||
for range decodeChan {
|
||||
}
|
||||
return
|
||||
default:
|
||||
case decodeResult := <-decodeChan:
|
||||
resultChan <- decodeResult
|
||||
if decodeResult.err != nil {
|
||||
stream.Close()
|
||||
|
|
@ -257,11 +330,85 @@ func (client *DockerClient) readJSONStream(stream io.ReadCloser, decode func(*js
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}()
|
||||
|
||||
return resultChan
|
||||
}
|
||||
|
||||
func (client *DockerClient) ExecCreate(config *ExecConfig) (string, error) {
|
||||
data, err := json.Marshal(config)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
uri := fmt.Sprintf("/%s/containers/%s/exec", APIVersion, config.Container)
|
||||
resp, err := client.doRequest("POST", uri, data, nil)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
var createExecResp struct {
|
||||
Id string
|
||||
}
|
||||
if err = json.Unmarshal(resp, &createExecResp); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return createExecResp.Id, nil
|
||||
}
|
||||
|
||||
func (client *DockerClient) ExecStart(id string, config *ExecConfig) error {
|
||||
data, err := json.Marshal(config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
uri := fmt.Sprintf("/%s/exec/%s/start", APIVersion, id)
|
||||
if _, err := client.doRequest("POST", uri, data, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (client *DockerClient) ExecResize(id string, width, height int) error {
|
||||
v := url.Values{}
|
||||
|
||||
w := strconv.Itoa(width)
|
||||
h := strconv.Itoa(height)
|
||||
|
||||
v.Set("w", w)
|
||||
v.Set("h", h)
|
||||
|
||||
uri := fmt.Sprintf("/%s/exec/%s/resize?%s", APIVersion, id, v.Encode())
|
||||
if _, err := client.doRequest("POST", client.URL.String()+uri, nil, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (client *DockerClient) AttachContainer(id string, options *AttachOptions) (io.ReadCloser, error) {
|
||||
v := url.Values{}
|
||||
if options != nil {
|
||||
if options.Logs {
|
||||
v.Set("logs", "1")
|
||||
}
|
||||
if options.Stream {
|
||||
v.Set("stream", "1")
|
||||
}
|
||||
if options.Stdin {
|
||||
v.Set("stdin", "1")
|
||||
}
|
||||
if options.Stdout {
|
||||
v.Set("stdout", "1")
|
||||
}
|
||||
if options.Stderr {
|
||||
v.Set("stderr", "1")
|
||||
}
|
||||
}
|
||||
uri := fmt.Sprintf("/%s/containers/%s/attach?%s", APIVersion, id, v.Encode())
|
||||
return client.doStreamRequest("POST", uri, nil, nil)
|
||||
}
|
||||
|
||||
func (client *DockerClient) StartContainer(id string, config *HostConfig) error {
|
||||
data, err := json.Marshal(config)
|
||||
if err != nil {
|
||||
|
|
@ -302,6 +449,26 @@ func (client *DockerClient) KillContainer(id, signal string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (client *DockerClient) Wait(id string) <-chan WaitResult {
|
||||
ch := make(chan WaitResult)
|
||||
uri := fmt.Sprintf("/%s/containers/%s/wait", APIVersion, id)
|
||||
|
||||
go func() {
|
||||
data, err := client.doRequest("POST", uri, nil, nil)
|
||||
if err != nil {
|
||||
ch <- WaitResult{ExitCode: -1, Error: err}
|
||||
return
|
||||
}
|
||||
|
||||
var result struct {
|
||||
StatusCode int `json:"StatusCode"`
|
||||
}
|
||||
err = json.Unmarshal(data, &result)
|
||||
ch <- WaitResult{ExitCode: result.StatusCode, Error: err}
|
||||
}()
|
||||
return ch
|
||||
}
|
||||
|
||||
func (client *DockerClient) MonitorEvents(options *MonitorEventsOptions, stopChan <-chan struct{}) (<-chan EventOrError, error) {
|
||||
v := url.Values{}
|
||||
if options != nil {
|
||||
|
|
@ -366,13 +533,17 @@ func (client *DockerClient) StartMonitorEvents(cb Callback, ec chan error, args
|
|||
go func() {
|
||||
eventErrChan, err := client.MonitorEvents(nil, client.eventStopChan)
|
||||
if err != nil {
|
||||
ec <- err
|
||||
if ec != nil {
|
||||
ec <- err
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
for e := range eventErrChan {
|
||||
if e.Error != nil {
|
||||
ec <- err
|
||||
if ec != nil {
|
||||
ec <- e.Error
|
||||
}
|
||||
return
|
||||
}
|
||||
cb(&e.Event, ec, args...)
|
||||
|
|
@ -381,6 +552,9 @@ func (client *DockerClient) StartMonitorEvents(cb Callback, ec chan error, args
|
|||
}
|
||||
|
||||
func (client *DockerClient) StopAllMonitorEvents() {
|
||||
if client.eventStopChan == nil {
|
||||
return
|
||||
}
|
||||
close(client.eventStopChan)
|
||||
}
|
||||
|
||||
|
|
@ -441,13 +615,48 @@ func (client *DockerClient) Version() (*Version, error) {
|
|||
return version, nil
|
||||
}
|
||||
|
||||
func (client *DockerClient) PushImage(name string, tag string, auth *AuthConfig) error {
|
||||
v := url.Values{}
|
||||
if tag != "" {
|
||||
v.Set("tag", tag)
|
||||
}
|
||||
uri := fmt.Sprintf("/%s/images/%s/push?%s", APIVersion, url.QueryEscape(name), v.Encode())
|
||||
req, err := http.NewRequest("POST", client.URL.String()+uri, nil)
|
||||
if auth != nil {
|
||||
if encodedAuth, err := auth.encode(); err != nil {
|
||||
return err
|
||||
} else {
|
||||
req.Header.Add("X-Registry-Auth", encodedAuth)
|
||||
}
|
||||
}
|
||||
resp, err := client.HTTPClient.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
var finalObj map[string]interface{}
|
||||
for decoder := json.NewDecoder(resp.Body); err == nil; err = decoder.Decode(&finalObj) {
|
||||
}
|
||||
if err != io.EOF {
|
||||
return err
|
||||
}
|
||||
if err, ok := finalObj["error"]; ok {
|
||||
return fmt.Errorf("%v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (client *DockerClient) PullImage(name string, auth *AuthConfig) error {
|
||||
v := url.Values{}
|
||||
v.Set("fromImage", name)
|
||||
uri := fmt.Sprintf("/%s/images/create?%s", APIVersion, v.Encode())
|
||||
req, err := http.NewRequest("POST", client.URL.String()+uri, nil)
|
||||
if auth != nil {
|
||||
req.Header.Add("X-Registry-Auth", auth.encode())
|
||||
encoded_auth, err := auth.encode()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req.Header.Add("X-Registry-Auth", encoded_auth)
|
||||
}
|
||||
resp, err := client.HTTPClient.Do(req)
|
||||
if err != nil {
|
||||
|
|
@ -493,17 +702,9 @@ func (client *DockerClient) InspectImage(id string) (*ImageInfo, error) {
|
|||
}
|
||||
|
||||
func (client *DockerClient) LoadImage(reader io.Reader) error {
|
||||
data, err := ioutil.ReadAll(reader)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
uri := fmt.Sprintf("/%s/images/load", APIVersion)
|
||||
_, err = client.doRequest("POST", uri, data, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
_, err := client.doStreamRequest("POST", uri, reader, nil)
|
||||
return err
|
||||
}
|
||||
|
||||
func (client *DockerClient) RemoveContainer(id string, force, volumes bool) error {
|
||||
|
|
@ -521,8 +722,12 @@ func (client *DockerClient) RemoveContainer(id string, force, volumes bool) erro
|
|||
return err
|
||||
}
|
||||
|
||||
func (client *DockerClient) ListImages() ([]*Image, error) {
|
||||
uri := fmt.Sprintf("/%s/images/json", APIVersion)
|
||||
func (client *DockerClient) ListImages(all bool) ([]*Image, error) {
|
||||
argAll := 0
|
||||
if all {
|
||||
argAll = 1
|
||||
}
|
||||
uri := fmt.Sprintf("/%s/images/json?all=%d", APIVersion, argAll)
|
||||
data, err := client.doRequest("GET", uri, nil, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -534,8 +739,14 @@ func (client *DockerClient) ListImages() ([]*Image, error) {
|
|||
return images, nil
|
||||
}
|
||||
|
||||
func (client *DockerClient) RemoveImage(name string) ([]*ImageDelete, error) {
|
||||
uri := fmt.Sprintf("/%s/images/%s", APIVersion, name)
|
||||
func (client *DockerClient) RemoveImage(name string, force bool) ([]*ImageDelete, error) {
|
||||
argForce := 0
|
||||
if force {
|
||||
argForce = 1
|
||||
}
|
||||
|
||||
args := fmt.Sprintf("force=%d", argForce)
|
||||
uri := fmt.Sprintf("/%s/images/%s?%s", APIVersion, name, args)
|
||||
data, err := client.doRequest("DELETE", uri, nil, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -547,6 +758,31 @@ func (client *DockerClient) RemoveImage(name string) ([]*ImageDelete, error) {
|
|||
return imageDelete, nil
|
||||
}
|
||||
|
||||
func (client *DockerClient) SearchImages(query, registry string, auth *AuthConfig) ([]ImageSearch, error) {
|
||||
term := query
|
||||
if registry != "" {
|
||||
term = registry + "/" + term
|
||||
}
|
||||
uri := fmt.Sprintf("/%s/images/search?term=%s", APIVersion, term)
|
||||
headers := map[string]string{}
|
||||
if auth != nil {
|
||||
if encodedAuth, err := auth.encode(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
headers["X-Registry-Auth"] = encodedAuth
|
||||
}
|
||||
}
|
||||
data, err := client.doRequest("GET", uri, nil, headers)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var imageSearches []ImageSearch
|
||||
if err := json.Unmarshal(data, &imageSearches); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return imageSearches, nil
|
||||
}
|
||||
|
||||
func (client *DockerClient) PauseContainer(id string) error {
|
||||
uri := fmt.Sprintf("/%s/containers/%s/pause", APIVersion, id)
|
||||
_, err := client.doRequest("POST", uri, nil, nil)
|
||||
|
|
@ -564,30 +800,6 @@ func (client *DockerClient) UnpauseContainer(id string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (client *DockerClient) Exec(config *ExecConfig) (string, error) {
|
||||
data, err := json.Marshal(config)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
uri := fmt.Sprintf("/containers/%s/exec", config.Container)
|
||||
resp, err := client.doRequest("POST", uri, data, nil)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
var createExecResp struct {
|
||||
Id string
|
||||
}
|
||||
if err = json.Unmarshal(resp, &createExecResp); err != nil {
|
||||
return "", err
|
||||
}
|
||||
uri = fmt.Sprintf("/exec/%s/start", createExecResp.Id)
|
||||
resp, err = client.doRequest("POST", uri, data, nil)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return createExecResp.Id, nil
|
||||
}
|
||||
|
||||
func (client *DockerClient) RenameContainer(oldName string, newName string) error {
|
||||
uri := fmt.Sprintf("/containers/%s/rename?name=%s", oldName, newName)
|
||||
_, err := client.doRequest("POST", uri, nil, nil)
|
||||
|
|
@ -615,3 +827,175 @@ func (client *DockerClient) ImportImage(source string, repository string, tag st
|
|||
}
|
||||
return client.doStreamRequest("POST", "/images/create?"+v.Encode(), in, nil)
|
||||
}
|
||||
|
||||
func (client *DockerClient) BuildImage(image *BuildImage) (io.ReadCloser, error) {
|
||||
v := url.Values{}
|
||||
|
||||
if image.DockerfileName != "" {
|
||||
v.Set("dockerfile", image.DockerfileName)
|
||||
}
|
||||
if image.RepoName != "" {
|
||||
v.Set("t", image.RepoName)
|
||||
}
|
||||
if image.RemoteURL != "" {
|
||||
v.Set("remote", image.RemoteURL)
|
||||
}
|
||||
if image.NoCache {
|
||||
v.Set("nocache", "1")
|
||||
}
|
||||
if image.Pull {
|
||||
v.Set("pull", "1")
|
||||
}
|
||||
if image.Remove {
|
||||
v.Set("rm", "1")
|
||||
} else {
|
||||
v.Set("rm", "0")
|
||||
}
|
||||
if image.ForceRemove {
|
||||
v.Set("forcerm", "1")
|
||||
}
|
||||
if image.SuppressOutput {
|
||||
v.Set("q", "1")
|
||||
}
|
||||
|
||||
v.Set("memory", strconv.FormatInt(image.Memory, 10))
|
||||
v.Set("memswap", strconv.FormatInt(image.MemorySwap, 10))
|
||||
v.Set("cpushares", strconv.FormatInt(image.CpuShares, 10))
|
||||
v.Set("cpuperiod", strconv.FormatInt(image.CpuPeriod, 10))
|
||||
v.Set("cpuquota", strconv.FormatInt(image.CpuQuota, 10))
|
||||
v.Set("cpusetcpus", image.CpuSetCpus)
|
||||
v.Set("cpusetmems", image.CpuSetMems)
|
||||
v.Set("cgroupparent", image.CgroupParent)
|
||||
if image.BuildArgs != nil {
|
||||
buildArgsJSON, err := json.Marshal(image.BuildArgs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
v.Set("buildargs", string(buildArgsJSON))
|
||||
}
|
||||
|
||||
headers := make(map[string]string)
|
||||
if image.Config != nil {
|
||||
encoded_config, err := image.Config.encode()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
headers["X-Registry-Config"] = encoded_config
|
||||
}
|
||||
if image.Context != nil {
|
||||
headers["Content-Type"] = "application/tar"
|
||||
}
|
||||
|
||||
uri := fmt.Sprintf("/%s/build?%s", APIVersion, v.Encode())
|
||||
return client.doStreamRequest("POST", uri, image.Context, headers)
|
||||
}
|
||||
|
||||
func (client *DockerClient) ListVolumes() ([]*Volume, error) {
|
||||
uri := fmt.Sprintf("/%s/volumes", APIVersion)
|
||||
data, err := client.doRequest("GET", uri, nil, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var volumesList VolumesListResponse
|
||||
if err := json.Unmarshal(data, &volumesList); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return volumesList.Volumes, nil
|
||||
}
|
||||
|
||||
func (client *DockerClient) RemoveVolume(name string) error {
|
||||
uri := fmt.Sprintf("/%s/volumes/%s", APIVersion, name)
|
||||
_, err := client.doRequest("DELETE", uri, nil, nil)
|
||||
return err
|
||||
}
|
||||
|
||||
func (client *DockerClient) CreateVolume(request *VolumeCreateRequest) (*Volume, error) {
|
||||
data, err := json.Marshal(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
uri := fmt.Sprintf("/%s/volumes/create", APIVersion)
|
||||
data, err = client.doRequest("POST", uri, data, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
volume := &Volume{}
|
||||
err = json.Unmarshal(data, volume)
|
||||
return volume, err
|
||||
}
|
||||
|
||||
func (client *DockerClient) ListNetworks(filters string) ([]*NetworkResource, error) {
|
||||
uri := fmt.Sprintf("/%s/networks", APIVersion)
|
||||
|
||||
if filters != "" {
|
||||
uri += "&filters=" + filters
|
||||
}
|
||||
|
||||
data, err := client.doRequest("GET", uri, nil, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret := []*NetworkResource{}
|
||||
err = json.Unmarshal(data, &ret)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (client *DockerClient) InspectNetwork(id string) (*NetworkResource, error) {
|
||||
uri := fmt.Sprintf("/%s/networks/%s", APIVersion, id)
|
||||
|
||||
data, err := client.doRequest("GET", uri, nil, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret := &NetworkResource{}
|
||||
err = json.Unmarshal(data, ret)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (client *DockerClient) CreateNetwork(config *NetworkCreate) (*NetworkCreateResponse, error) {
|
||||
data, err := json.Marshal(config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
uri := fmt.Sprintf("/%s/networks/create", APIVersion)
|
||||
data, err = client.doRequest("POST", uri, data, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret := &NetworkCreateResponse{}
|
||||
err = json.Unmarshal(data, ret)
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (client *DockerClient) ConnectNetwork(id, container string) error {
|
||||
data, err := json.Marshal(NetworkConnect{Container: container})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
uri := fmt.Sprintf("/%s/networks/%s/connect", APIVersion, id)
|
||||
_, err = client.doRequest("POST", uri, data, nil)
|
||||
return err
|
||||
}
|
||||
|
||||
func (client *DockerClient) DisconnectNetwork(id, container string, force bool) error {
|
||||
data, err := json.Marshal(NetworkDisconnect{Container: container, Force: force})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
uri := fmt.Sprintf("/%s/networks/%s/disconnect", APIVersion, id)
|
||||
_, err = client.doRequest("POST", uri, data, nil)
|
||||
return err
|
||||
}
|
||||
|
||||
func (client *DockerClient) RemoveNetwork(id string) error {
|
||||
uri := fmt.Sprintf("/%s/networks/%s", APIVersion, id)
|
||||
_, err := client.doRequest("DELETE", uri, nil, nil)
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
219
Godeps/_workspace/src/github.com/samalba/dockerclient/dockerclient_test.go
generated
vendored
219
Godeps/_workspace/src/github.com/samalba/dockerclient/dockerclient_test.go
generated
vendored
|
|
@ -1,219 +0,0 @@
|
|||
package dockerclient
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/docker/pkg/stdcopy"
|
||||
)
|
||||
|
||||
func assertEqual(t *testing.T, a interface{}, b interface{}, message string) {
|
||||
if a == b {
|
||||
return
|
||||
}
|
||||
if len(message) == 0 {
|
||||
message = fmt.Sprintf("%v != %v", a, b)
|
||||
}
|
||||
t.Fatal(message)
|
||||
}
|
||||
|
||||
func testDockerClient(t *testing.T) *DockerClient {
|
||||
client, err := NewDockerClient(testHTTPServer.URL, nil)
|
||||
if err != nil {
|
||||
t.Fatal("Cannot init the docker client")
|
||||
}
|
||||
return client
|
||||
}
|
||||
|
||||
func TestInfo(t *testing.T) {
|
||||
client := testDockerClient(t)
|
||||
info, err := client.Info()
|
||||
if err != nil {
|
||||
t.Fatal("Cannot get server info")
|
||||
}
|
||||
assertEqual(t, info.Images, int64(1), "")
|
||||
assertEqual(t, info.Containers, int64(2), "")
|
||||
}
|
||||
|
||||
func TestKillContainer(t *testing.T) {
|
||||
client := testDockerClient(t)
|
||||
if err := client.KillContainer("23132acf2ac", "5"); err != nil {
|
||||
t.Fatal("cannot kill container: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPullImage(t *testing.T) {
|
||||
client := testDockerClient(t)
|
||||
err := client.PullImage("busybox", nil)
|
||||
if err != nil {
|
||||
t.Fatal("unable to pull busybox")
|
||||
}
|
||||
|
||||
err = client.PullImage("haproxy", nil)
|
||||
if err != nil {
|
||||
t.Fatal("unable to pull haproxy")
|
||||
}
|
||||
|
||||
err = client.PullImage("wrongimg", nil)
|
||||
if err == nil {
|
||||
t.Fatal("should return error when it fails to pull wrongimg")
|
||||
}
|
||||
}
|
||||
|
||||
func TestListContainers(t *testing.T) {
|
||||
client := testDockerClient(t)
|
||||
containers, err := client.ListContainers(true, false, "")
|
||||
if err != nil {
|
||||
t.Fatal("cannot get containers: %s", err)
|
||||
}
|
||||
assertEqual(t, len(containers), 1, "")
|
||||
cnt := containers[0]
|
||||
assertEqual(t, cnt.SizeRw, int64(0), "")
|
||||
}
|
||||
|
||||
func TestContainerChanges(t *testing.T) {
|
||||
client := testDockerClient(t)
|
||||
changes, err := client.ContainerChanges("foobar")
|
||||
if err != nil {
|
||||
t.Fatal("cannot get container changes: %s", err)
|
||||
}
|
||||
assertEqual(t, len(changes), 3, "unexpected number of changes")
|
||||
c := changes[0]
|
||||
assertEqual(t, c.Path, "/dev", "unexpected")
|
||||
assertEqual(t, c.Kind, 0, "unexpected")
|
||||
}
|
||||
|
||||
func TestListContainersWithSize(t *testing.T) {
|
||||
client := testDockerClient(t)
|
||||
containers, err := client.ListContainers(true, true, "")
|
||||
if err != nil {
|
||||
t.Fatal("cannot get containers: %s", err)
|
||||
}
|
||||
assertEqual(t, len(containers), 1, "")
|
||||
cnt := containers[0]
|
||||
assertEqual(t, cnt.SizeRw, int64(123), "")
|
||||
}
|
||||
func TestListContainersWithFilters(t *testing.T) {
|
||||
client := testDockerClient(t)
|
||||
containers, err := client.ListContainers(true, true, "{'id':['332375cfbc23edb921a21026314c3497674ba8bdcb2c85e0e65ebf2017f688ce']}")
|
||||
if err != nil {
|
||||
t.Fatal("cannot get containers: %s", err)
|
||||
}
|
||||
assertEqual(t, len(containers), 1, "")
|
||||
|
||||
containers, err = client.ListContainers(true, true, "{'id':['332375cfbc23edb921a21026314c3497674ba8bdcb2c85e0e65ebf2017f688cf']}")
|
||||
if err != nil {
|
||||
t.Fatal("cannot get containers: %s", err)
|
||||
}
|
||||
assertEqual(t, len(containers), 0, "")
|
||||
}
|
||||
|
||||
func TestContainerLogs(t *testing.T) {
|
||||
client := testDockerClient(t)
|
||||
containerId := "foobar"
|
||||
logOptions := &LogOptions{
|
||||
Follow: true,
|
||||
Stdout: true,
|
||||
Stderr: true,
|
||||
Timestamps: true,
|
||||
Tail: 10,
|
||||
}
|
||||
logsReader, err := client.ContainerLogs(containerId, logOptions)
|
||||
if err != nil {
|
||||
t.Fatal("cannot read logs from server")
|
||||
}
|
||||
|
||||
stdoutBuffer := new(bytes.Buffer)
|
||||
stderrBuffer := new(bytes.Buffer)
|
||||
if _, err = stdcopy.StdCopy(stdoutBuffer, stderrBuffer, logsReader); err != nil {
|
||||
t.Fatal("cannot read logs from logs reader")
|
||||
}
|
||||
stdoutLogs := strings.TrimSpace(stdoutBuffer.String())
|
||||
stderrLogs := strings.TrimSpace(stderrBuffer.String())
|
||||
stdoutLogLines := strings.Split(stdoutLogs, "\n")
|
||||
stderrLogLines := strings.Split(stderrLogs, "\n")
|
||||
if len(stdoutLogLines) != 5 {
|
||||
t.Fatalf("wrong number of stdout logs: len=%d", len(stdoutLogLines))
|
||||
}
|
||||
if len(stderrLogLines) != 5 {
|
||||
t.Fatalf("wrong number of stderr logs: len=%d", len(stdoutLogLines))
|
||||
}
|
||||
for i, line := range stdoutLogLines {
|
||||
expectedSuffix := fmt.Sprintf("Z line %d", 41+2*i)
|
||||
if !strings.HasSuffix(line, expectedSuffix) {
|
||||
t.Fatalf("expected stdout log line \"%s\" to end with \"%s\"", line, expectedSuffix)
|
||||
}
|
||||
}
|
||||
for i, line := range stderrLogLines {
|
||||
expectedSuffix := fmt.Sprintf("Z line %d", 40+2*i)
|
||||
if !strings.HasSuffix(line, expectedSuffix) {
|
||||
t.Fatalf("expected stderr log line \"%s\" to end with \"%s\"", line, expectedSuffix)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMonitorEvents(t *testing.T) {
|
||||
client := testDockerClient(t)
|
||||
decoder := json.NewDecoder(bytes.NewBufferString(eventsResp))
|
||||
var expectedEvents []Event
|
||||
for {
|
||||
var event Event
|
||||
if err := decoder.Decode(&event); err != nil {
|
||||
if err == io.EOF {
|
||||
break
|
||||
} else {
|
||||
t.Fatalf("cannot parse expected resp: %s", err.Error())
|
||||
}
|
||||
} else {
|
||||
expectedEvents = append(expectedEvents, event)
|
||||
}
|
||||
}
|
||||
|
||||
// test passing stop chan
|
||||
stopChan := make(chan struct{})
|
||||
eventInfoChan, err := client.MonitorEvents(nil, stopChan)
|
||||
if err != nil {
|
||||
t.Fatalf("cannot get events from server: %s", err.Error())
|
||||
}
|
||||
|
||||
eventInfo := <-eventInfoChan
|
||||
if eventInfo.Error != nil || eventInfo.Event != expectedEvents[0] {
|
||||
t.Fatalf("got:\n%#v\nexpected:\n%#v", eventInfo, expectedEvents[0])
|
||||
}
|
||||
close(stopChan)
|
||||
for i := 0; i < 3; i++ {
|
||||
_, ok := <-eventInfoChan
|
||||
if i == 2 && ok {
|
||||
t.Fatalf("read more than 2 events successfully after closing stopChan")
|
||||
}
|
||||
}
|
||||
|
||||
// test when you don't pass stop chan
|
||||
eventInfoChan, err = client.MonitorEvents(nil, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("cannot get events from server: %s", err.Error())
|
||||
}
|
||||
|
||||
for i, expectedEvent := range expectedEvents {
|
||||
t.Logf("on iter %d\n", i)
|
||||
eventInfo := <-eventInfoChan
|
||||
if eventInfo.Error != nil || eventInfo.Event != expectedEvent {
|
||||
t.Fatalf("index %d, got:\n%#v\nexpected:\n%#v", i, eventInfo, expectedEvent)
|
||||
}
|
||||
t.Logf("done with iter %d\n", i)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDockerClientInterface(t *testing.T) {
|
||||
iface := reflect.TypeOf((*Client)(nil)).Elem()
|
||||
test := testDockerClient(t)
|
||||
|
||||
if !reflect.TypeOf(test).Implements(iface) {
|
||||
t.Fatalf("DockerClient does not implement the Client interface")
|
||||
}
|
||||
}
|
||||
235
Godeps/_workspace/src/github.com/samalba/dockerclient/engine_mock_test.go
generated
vendored
235
Godeps/_workspace/src/github.com/samalba/dockerclient/engine_mock_test.go
generated
vendored
|
|
@ -1,235 +0,0 @@
|
|||
package dockerclient
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/pkg/ioutils"
|
||||
"github.com/docker/docker/pkg/jsonlog"
|
||||
"github.com/docker/docker/pkg/stdcopy"
|
||||
"github.com/docker/docker/pkg/timeutils"
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
var (
|
||||
testHTTPServer *httptest.Server
|
||||
)
|
||||
|
||||
func init() {
|
||||
r := mux.NewRouter()
|
||||
baseURL := "/" + APIVersion
|
||||
r.HandleFunc(baseURL+"/info", handlerGetInfo).Methods("GET")
|
||||
r.HandleFunc(baseURL+"/containers/json", handlerGetContainers).Methods("GET")
|
||||
r.HandleFunc(baseURL+"/containers/{id}/logs", handleContainerLogs).Methods("GET")
|
||||
r.HandleFunc(baseURL+"/containers/{id}/changes", handleContainerChanges).Methods("GET")
|
||||
r.HandleFunc(baseURL+"/containers/{id}/kill", handleContainerKill).Methods("POST")
|
||||
r.HandleFunc(baseURL+"/images/create", handleImagePull).Methods("POST")
|
||||
r.HandleFunc(baseURL+"/events", handleEvents).Methods("GET")
|
||||
testHTTPServer = httptest.NewServer(handlerAccessLog(r))
|
||||
}
|
||||
|
||||
func handlerAccessLog(handler http.Handler) http.Handler {
|
||||
logHandler := func(w http.ResponseWriter, r *http.Request) {
|
||||
log.Printf("%s \"%s %s\"", r.RemoteAddr, r.Method, r.URL)
|
||||
handler.ServeHTTP(w, r)
|
||||
}
|
||||
return http.HandlerFunc(logHandler)
|
||||
}
|
||||
|
||||
func handleContainerKill(w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Fprintf(w, "{%q:%q", "Id", "421373210afd132")
|
||||
}
|
||||
|
||||
func handleImagePull(w http.ResponseWriter, r *http.Request) {
|
||||
imageName := r.URL.Query()["fromImage"][0]
|
||||
responses := []map[string]interface{}{{
|
||||
"status": fmt.Sprintf("Pulling repository mydockerregistry/%s", imageName),
|
||||
}}
|
||||
switch imageName {
|
||||
case "busybox":
|
||||
responses = append(responses, map[string]interface{}{
|
||||
"status": "Status: Image is up to date for mydockerregistry/busybox",
|
||||
})
|
||||
case "haproxy":
|
||||
fmt.Fprintf(w, haproxyPullOutput)
|
||||
return
|
||||
default:
|
||||
errorMsg := fmt.Sprintf("Error: image %s not found", imageName)
|
||||
responses = append(responses, map[string]interface{}{
|
||||
"errorDetail": map[string]interface{}{
|
||||
"message": errorMsg,
|
||||
},
|
||||
"error": errorMsg,
|
||||
})
|
||||
}
|
||||
for _, response := range responses {
|
||||
json.NewEncoder(w).Encode(response)
|
||||
}
|
||||
}
|
||||
|
||||
func handleContainerLogs(w http.ResponseWriter, r *http.Request) {
|
||||
var outStream, errStream io.Writer
|
||||
outStream = ioutils.NewWriteFlusher(w)
|
||||
|
||||
// not sure how to test follow
|
||||
if err := r.ParseForm(); err != nil {
|
||||
http.Error(w, err.Error(), 500)
|
||||
}
|
||||
stdout, stderr := getBoolValue(r.Form.Get("stdout")), getBoolValue(r.Form.Get("stderr"))
|
||||
if stderr {
|
||||
errStream = stdcopy.NewStdWriter(outStream, stdcopy.Stderr)
|
||||
}
|
||||
if stdout {
|
||||
outStream = stdcopy.NewStdWriter(outStream, stdcopy.Stdout)
|
||||
}
|
||||
var i int
|
||||
if tail, err := strconv.Atoi(r.Form.Get("tail")); err == nil && tail > 0 {
|
||||
i = 50 - tail
|
||||
if i < 0 {
|
||||
i = 0
|
||||
}
|
||||
}
|
||||
for ; i < 50; i++ {
|
||||
line := fmt.Sprintf("line %d", i)
|
||||
if getBoolValue(r.Form.Get("timestamps")) {
|
||||
l := &jsonlog.JSONLog{Log: line, Created: time.Now()}
|
||||
line = fmt.Sprintf("%s %s", l.Created.Format(timeutils.RFC3339NanoFixed), line)
|
||||
}
|
||||
if i%2 == 0 && stderr {
|
||||
fmt.Fprintln(errStream, line)
|
||||
} else if i%2 == 1 && stdout {
|
||||
fmt.Fprintln(outStream, line)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func handleContainerChanges(w http.ResponseWriter, r *http.Request) {
|
||||
writeHeaders(w, 200, "changes")
|
||||
body := `[
|
||||
{
|
||||
"Path": "/dev",
|
||||
"Kind": 0
|
||||
},
|
||||
{
|
||||
"Path": "/dev/kmsg",
|
||||
"Kind": 1
|
||||
},
|
||||
{
|
||||
"Path": "/test",
|
||||
"Kind": 1
|
||||
}
|
||||
]`
|
||||
w.Write([]byte(body))
|
||||
}
|
||||
|
||||
func getBoolValue(boolString string) bool {
|
||||
switch boolString {
|
||||
case "1":
|
||||
return true
|
||||
case "True":
|
||||
return true
|
||||
case "true":
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func writeHeaders(w http.ResponseWriter, code int, jobName string) {
|
||||
h := w.Header()
|
||||
h.Add("Content-Type", "application/json")
|
||||
if jobName != "" {
|
||||
h.Add("Job-Name", jobName)
|
||||
}
|
||||
w.WriteHeader(code)
|
||||
}
|
||||
|
||||
func handlerGetInfo(w http.ResponseWriter, r *http.Request) {
|
||||
writeHeaders(w, 200, "info")
|
||||
body := `{
|
||||
"Containers": 2,
|
||||
"Debug": 1,
|
||||
"Driver": "aufs",
|
||||
"DriverStatus": [["Root Dir", "/mnt/sda1/var/lib/docker/aufs"],
|
||||
["Dirs", "0"]],
|
||||
"ExecutionDriver": "native-0.2",
|
||||
"IPv4Forwarding": 1,
|
||||
"Images": 1,
|
||||
"IndexServerAddress": "https://index.docker.io/v1/",
|
||||
"InitPath": "/usr/local/bin/docker",
|
||||
"InitSha1": "",
|
||||
"KernelVersion": "3.16.4-tinycore64",
|
||||
"MemoryLimit": 1,
|
||||
"NEventsListener": 0,
|
||||
"NFd": 10,
|
||||
"NGoroutines": 11,
|
||||
"OperatingSystem": "Boot2Docker 1.3.1 (TCL 5.4); master : a083df4 - Thu Jan 01 00:00:00 UTC 1970",
|
||||
"SwapLimit": 1}`
|
||||
w.Write([]byte(body))
|
||||
}
|
||||
|
||||
func handlerGetContainers(w http.ResponseWriter, r *http.Request) {
|
||||
writeHeaders(w, 200, "containers")
|
||||
body := `[
|
||||
{
|
||||
"Status": "Up 39 seconds",
|
||||
"Ports": [
|
||||
{
|
||||
"Type": "tcp",
|
||||
"PublicPort": 49163,
|
||||
"PrivatePort": 8080,
|
||||
"IP": "0.0.0.0"
|
||||
}
|
||||
],
|
||||
"Names": [
|
||||
"/trusting_heisenberg"
|
||||
],
|
||||
"Image": "foo:latest",
|
||||
"Id": "332375cfbc23edb921a21026314c3497674ba8bdcb2c85e0e65ebf2017f688ce",
|
||||
"Created": 1415720105,
|
||||
"Command": "/bin/go-run"
|
||||
}
|
||||
]`
|
||||
if v, ok := r.URL.Query()["size"]; ok {
|
||||
if v[0] == "1" {
|
||||
body = `[
|
||||
{
|
||||
"Status": "Up 39 seconds",
|
||||
"Ports": [
|
||||
{
|
||||
"Type": "tcp",
|
||||
"PublicPort": 49163,
|
||||
"PrivatePort": 8080,
|
||||
"IP": "0.0.0.0"
|
||||
}
|
||||
],
|
||||
"Names": [
|
||||
"/trusting_heisenberg"
|
||||
],
|
||||
"Image": "foo:latest",
|
||||
"Id": "332375cfbc23edb921a21026314c3497674ba8bdcb2c85e0e65ebf2017f688ce",
|
||||
"Created": 1415720105,
|
||||
"SizeRootFs": 12345,
|
||||
"SizeRW": 123,
|
||||
"Command": "/bin/go-run"
|
||||
}
|
||||
]`
|
||||
}
|
||||
}
|
||||
if v, ok := r.URL.Query()["filters"]; ok {
|
||||
if v[0] != "{'id':['332375cfbc23edb921a21026314c3497674ba8bdcb2c85e0e65ebf2017f688ce']}" {
|
||||
body = "[]"
|
||||
}
|
||||
}
|
||||
w.Write([]byte(body))
|
||||
}
|
||||
|
||||
func handleEvents(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte(eventsResp))
|
||||
}
|
||||
2
Godeps/_workspace/src/github.com/samalba/dockerclient/example_responses.go
generated
vendored
2
Godeps/_workspace/src/github.com/samalba/dockerclient/example_responses.go
generated
vendored
|
|
@ -10,4 +10,6 @@ var haproxyPullOutput = `{"status":"The image you are pulling has been verified"
|
|||
{"status":"Already exists","progressDetail":{},"id":"511136ea3c5a"}{"status":"Already exists","progressDetail":{},"id":"1aeada447715"}{"status":"Already exists","progressDetail":{},"id":"479215127fa7"}{"status":"Already exists","progressDetail":{},"id":"66301eb54a7d"}{"status":"Already exists","progressDetail":{},"id":"e3990b07573f"}{"status":"Already exists","progressDetail":{},"id":"ecb4b23ca7ce"}{"status":"Already exists","progressDetail":{},"id":"f453e940c177"}{"status":"Already exists","progressDetail":{},"id":"fc5ea1bc05ab"}{"status":"Already exists","progressDetail":{},"id":"380557f8f7b3"}{"status":"Status: Image is up to date for haproxy"}
|
||||
`
|
||||
|
||||
var statsResp = `{"read":"2015-02-02T17:06:08.187833376-05:00","network":{"rx_bytes":99988,"rx_packets":928,"rx_errors":0,"rx_dropped":0,"tx_bytes":1786548,"tx_packets":877,"tx_errors":0,"tx_dropped":0},"cpu_stats":{"cpu_usage":{"total_usage":170018598,"percpu_usage":[170018598],"usage_in_kernelmode":30000000,"usage_in_usermode":70000000},"system_cpu_usage":9020930000000,"throttling_data":{"periods":0,"throttled_periods":0,"throttled_time":0}},"memory_stats":{"usage":18022400,"max_usage":20541440,"stats":{"active_anon":6213632,"active_file":176128,"cache":11808768,"hierarchical_memory_limit":9223372036854775807,"hierarchical_memsw_limit":9223372036854775807,"inactive_anon":0,"inactive_file":11632640,"mapped_file":5165056,"pgfault":2535,"pgmajfault":13,"pgpgin":4293,"pgpgout":1937,"rss":6213632,"rss_huge":2097152,"swap":0,"total_active_anon":6213632,"total_active_file":176128,"total_cache":11808768,"total_inactive_anon":0,"total_inactive_file":11632640,"total_mapped_file":5165056,"total_pgfault":2535,"total_pgmajfault":13,"total_pgpgin":4293,"total_pgpgout":1937,"total_rss":6213632,"total_rss_huge":2097152,"total_swap":0,"total_unevictable":0,"unevictable":0},"failcnt":0,"limit":1041051648},"blkio_stats":{"io_service_bytes_recursive":[{"major":7,"minor":0,"op":"Read","value":28672},{"major":7,"minor":0,"op":"Write","value":0},{"major":7,"minor":0,"op":"Sync","value":0},{"major":7,"minor":0,"op":"Async","value":28672},{"major":7,"minor":0,"op":"Total","value":28672},{"major":253,"minor":0,"op":"Read","value":28672},{"major":253,"minor":0,"op":"Write","value":0},{"major":253,"minor":0,"op":"Sync","value":0},{"major":253,"minor":0,"op":"Async","value":28672},{"major":253,"minor":0,"op":"Total","value":28672},{"major":253,"minor":7,"op":"Read","value":11718656},{"major":253,"minor":7,"op":"Write","value":0},{"major":253,"minor":7,"op":"Sync","value":0},{"major":253,"minor":7,"op":"Async","value":11718656},{"major":253,"minor":7,"op":"Total","value":11718656},{"major":202,"minor":0,"op":"Read","value":0},{"major":202,"minor":0,"op":"Write","value":0},{"major":202,"minor":0,"op":"Sync","value":0},{"major":202,"minor":0,"op":"Async","value":0},{"major":202,"minor":0,"op":"Total","value":0}],"io_serviced_recursive":[{"major":7,"minor":0,"op":"Read","value":7},{"major":7,"minor":0,"op":"Write","value":0},{"major":7,"minor":0,"op":"Sync","value":0},{"major":7,"minor":0,"op":"Async","value":7},{"major":7,"minor":0,"op":"Total","value":7},{"major":253,"minor":0,"op":"Read","value":7},{"major":253,"minor":0,"op":"Write","value":0},{"major":253,"minor":0,"op":"Sync","value":0},{"major":253,"minor":0,"op":"Async","value":7},{"major":253,"minor":0,"op":"Total","value":7},{"major":253,"minor":7,"op":"Read","value":312},{"major":253,"minor":7,"op":"Write","value":0},{"major":253,"minor":7,"op":"Sync","value":0},{"major":253,"minor":7,"op":"Async","value":312},{"major":253,"minor":7,"op":"Total","value":312},{"major":202,"minor":0,"op":"Read","value":0},{"major":202,"minor":0,"op":"Write","value":0},{"major":202,"minor":0,"op":"Sync","value":0},{"major":202,"minor":0,"op":"Async","value":0},{"major":202,"minor":0,"op":"Total","value":0}],"io_queue_recursive":[],"io_service_time_recursive":[],"io_wait_time_recursive":[],"io_merged_recursive":[],"io_time_recursive":[],"sectors_recursive":[]}}`
|
||||
|
||||
var eventsResp = `{"status":"pull","id":"nginx:latest","time":1428620433}{"status":"create","id":"9b818c3b8291708fdcecd7c4086b75c222cb503be10a93d9c11040886032a48b","from":"nginx:latest","time":1428620433}{"status":"start","id":"9b818c3b8291708fdcecd7c4086b75c222cb503be10a93d9c11040886032a48b","from":"nginx:latest","time":1428620433}{"status":"die","id":"9b818c3b8291708fdcecd7c4086b75c222cb503be10a93d9c11040886032a48b","from":"nginx:latest","time":1428620442}{"status":"create","id":"352d0b412aae5a5d2b14ae9d88be59dc276602d9edb9dcc33e138e475b3e4720","from":"52.11.96.81/foobar/ubuntu:latest","time":1428620444}{"status":"start","id":"352d0b412aae5a5d2b14ae9d88be59dc276602d9edb9dcc33e138e475b3e4720","from":"52.11.96.81/foobar/ubuntu:latest","time":1428620444}{"status":"die","id":"352d0b412aae5a5d2b14ae9d88be59dc276602d9edb9dcc33e138e475b3e4720","from":"52.11.96.81/foobar/ubuntu:latest","time":1428620444}{"status":"pull","id":"debian:latest","time":1428620453}{"status":"create","id":"668887b5729946546b3072655dc6da08f0e3210111b68b704eb842adfce53f6c","from":"debian:latest","time":1428620453}{"status":"start","id":"668887b5729946546b3072655dc6da08f0e3210111b68b704eb842adfce53f6c","from":"debian:latest","time":1428620453}{"status":"die","id":"668887b5729946546b3072655dc6da08f0e3210111b68b704eb842adfce53f6c","from":"debian:latest","time":1428620453}{"status":"create","id":"eb4a19ec21ab29bbbffbf3ee2e2df9d99cb749780e1eff06a591cee5ba505180","from":"nginx:latest","time":1428620458}{"status":"start","id":"eb4a19ec21ab29bbbffbf3ee2e2df9d99cb749780e1eff06a591cee5ba505180","from":"nginx:latest","time":1428620458}{"status":"pause","id":"eb4a19ec21ab29bbbffbf3ee2e2df9d99cb749780e1eff06a591cee5ba505180","from":"nginx:latest","time":1428620462}{"status":"unpause","id":"eb4a19ec21ab29bbbffbf3ee2e2df9d99cb749780e1eff06a591cee5ba505180","from":"nginx:latest","time":1428620466}{"status":"die","id":"eb4a19ec21ab29bbbffbf3ee2e2df9d99cb749780e1eff06a591cee5ba505180","from":"nginx:latest","time":1428620469}`
|
||||
|
|
|
|||
39
Godeps/_workspace/src/github.com/samalba/dockerclient/examples/events.go
generated
vendored
39
Godeps/_workspace/src/github.com/samalba/dockerclient/examples/events.go
generated
vendored
|
|
@ -1,39 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"github.com/samalba/dockerclient"
|
||||
"log"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func eventCallback(e *dockerclient.Event, ec chan error, args ...interface{}) {
|
||||
log.Println(e)
|
||||
}
|
||||
|
||||
var (
|
||||
client *dockerclient.DockerClient
|
||||
)
|
||||
|
||||
func waitForInterrupt() {
|
||||
sigChan := make(chan os.Signal, 1)
|
||||
signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT)
|
||||
for _ = range sigChan {
|
||||
client.StopAllMonitorEvents()
|
||||
os.Exit(0)
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
docker, err := dockerclient.NewDockerClient(os.Getenv("DOCKER_HOST"), nil)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
client = docker
|
||||
|
||||
client.StartMonitorEvents(eventCallback, nil)
|
||||
|
||||
waitForInterrupt()
|
||||
}
|
||||
43
Godeps/_workspace/src/github.com/samalba/dockerclient/examples/stats/stats.go
generated
vendored
43
Godeps/_workspace/src/github.com/samalba/dockerclient/examples/stats/stats.go
generated
vendored
|
|
@ -1,43 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"github.com/samalba/dockerclient"
|
||||
"log"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func statCallback(id string, stat *dockerclient.Stats, ec chan error, args ...interface{}) {
|
||||
log.Println(stat)
|
||||
}
|
||||
|
||||
func waitForInterrupt() {
|
||||
sigChan := make(chan os.Signal, 1)
|
||||
signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT)
|
||||
for _ = range sigChan {
|
||||
os.Exit(0)
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
docker, err := dockerclient.NewDockerClient(os.Getenv("DOCKER_HOST"), nil)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
containerConfig := &dockerclient.ContainerConfig{Image: "busybox", Cmd: []string{"sh"}}
|
||||
containerId, err := docker.CreateContainer(containerConfig, "")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Start the container
|
||||
err = docker.StartContainer(containerId, nil)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
docker.StartMonitorStats(containerId, statCallback, nil)
|
||||
|
||||
waitForInterrupt()
|
||||
}
|
||||
30
Godeps/_workspace/src/github.com/samalba/dockerclient/interface.go
generated
vendored
30
Godeps/_workspace/src/github.com/samalba/dockerclient/interface.go
generated
vendored
|
|
@ -13,14 +13,24 @@ type Client interface {
|
|||
ListContainers(all, size bool, filters string) ([]Container, error)
|
||||
InspectContainer(id string) (*ContainerInfo, error)
|
||||
InspectImage(id string) (*ImageInfo, error)
|
||||
CreateContainer(config *ContainerConfig, name string) (string, error)
|
||||
CreateContainer(config *ContainerConfig, name string, authConfig *AuthConfig) (string, error)
|
||||
ContainerLogs(id string, options *LogOptions) (io.ReadCloser, error)
|
||||
ContainerChanges(id string) ([]*ContainerChanges, error)
|
||||
Exec(config *ExecConfig) (string, error)
|
||||
// ContainerStats takes a container ID and an optional stop channel and
|
||||
// returns a StatsOrError channel. If an error is ever sent, then no
|
||||
// more stats will be sent on that channel. If a stop channel is
|
||||
// provided, events will stop being monitored after the stop channel is
|
||||
// closed.
|
||||
ContainerStats(id string, stopChan <-chan struct{}) (<-chan StatsOrError, error)
|
||||
ExecCreate(config *ExecConfig) (string, error)
|
||||
ExecStart(id string, config *ExecConfig) error
|
||||
ExecResize(id string, width, height int) error
|
||||
StartContainer(id string, config *HostConfig) error
|
||||
AttachContainer(id string, options *AttachOptions) (io.ReadCloser, error)
|
||||
StopContainer(id string, timeout int) error
|
||||
RestartContainer(id string, timeout int) error
|
||||
KillContainer(id, signal string) error
|
||||
Wait(id string) <-chan WaitResult
|
||||
// MonitorEvents takes options and an optional stop channel, and returns
|
||||
// an EventOrError channel. If an error is ever sent, then no more
|
||||
// events will be sent. If a stop channel is provided, events will stop
|
||||
|
|
@ -33,12 +43,24 @@ type Client interface {
|
|||
TagImage(nameOrID string, repo string, tag string, force bool) error
|
||||
Version() (*Version, error)
|
||||
PullImage(name string, auth *AuthConfig) error
|
||||
PushImage(name string, tag string, auth *AuthConfig) error
|
||||
LoadImage(reader io.Reader) error
|
||||
RemoveContainer(id string, force, volumes bool) error
|
||||
ListImages() ([]*Image, error)
|
||||
RemoveImage(name string) ([]*ImageDelete, error)
|
||||
ListImages(all bool) ([]*Image, error)
|
||||
RemoveImage(name string, force bool) ([]*ImageDelete, error)
|
||||
SearchImages(query, registry string, auth *AuthConfig) ([]ImageSearch, error)
|
||||
PauseContainer(name string) error
|
||||
UnpauseContainer(name string) error
|
||||
RenameContainer(oldName string, newName string) error
|
||||
ImportImage(source string, repository string, tag string, tar io.Reader) (io.ReadCloser, error)
|
||||
BuildImage(image *BuildImage) (io.ReadCloser, error)
|
||||
ListVolumes() ([]*Volume, error)
|
||||
RemoveVolume(name string) error
|
||||
CreateVolume(request *VolumeCreateRequest) (*Volume, error)
|
||||
ListNetworks(filters string) ([]*NetworkResource, error)
|
||||
InspectNetwork(id string) (*NetworkResource, error)
|
||||
CreateNetwork(config *NetworkCreate) (*NetworkCreateResponse, error)
|
||||
ConnectNetwork(id, container string) error
|
||||
DisconnectNetwork(id, container string, force bool) error
|
||||
RemoveNetwork(id string) error
|
||||
}
|
||||
|
|
|
|||
99
Godeps/_workspace/src/github.com/samalba/dockerclient/mockclient/mock.go
generated
vendored
99
Godeps/_workspace/src/github.com/samalba/dockerclient/mockclient/mock.go
generated
vendored
|
|
@ -35,8 +35,8 @@ func (client *MockClient) InspectImage(id string) (*dockerclient.ImageInfo, erro
|
|||
return args.Get(0).(*dockerclient.ImageInfo), args.Error(1)
|
||||
}
|
||||
|
||||
func (client *MockClient) CreateContainer(config *dockerclient.ContainerConfig, name string) (string, error) {
|
||||
args := client.Mock.Called(config, name)
|
||||
func (client *MockClient) CreateContainer(config *dockerclient.ContainerConfig, name string, authConfig *dockerclient.AuthConfig) (string, error) {
|
||||
args := client.Mock.Called(config, name, authConfig)
|
||||
return args.String(0), args.Error(1)
|
||||
}
|
||||
|
||||
|
|
@ -50,6 +50,16 @@ func (client *MockClient) ContainerChanges(id string) ([]*dockerclient.Container
|
|||
return args.Get(0).([]*dockerclient.ContainerChanges), args.Error(1)
|
||||
}
|
||||
|
||||
func (client *MockClient) ContainerStats(id string, stopChan <-chan struct{}) (<-chan dockerclient.StatsOrError, error) {
|
||||
args := client.Mock.Called(id, stopChan)
|
||||
return args.Get(0).(<-chan dockerclient.StatsOrError), args.Error(1)
|
||||
}
|
||||
|
||||
func (client *MockClient) AttachContainer(id string, options *dockerclient.AttachOptions) (io.ReadCloser, error) {
|
||||
args := client.Mock.Called(id, options)
|
||||
return args.Get(0).(io.ReadCloser), args.Error(1)
|
||||
}
|
||||
|
||||
func (client *MockClient) StartContainer(id string, config *dockerclient.HostConfig) error {
|
||||
args := client.Mock.Called(id, config)
|
||||
return args.Error(0)
|
||||
|
|
@ -70,6 +80,11 @@ func (client *MockClient) KillContainer(id, signal string) error {
|
|||
return args.Error(0)
|
||||
}
|
||||
|
||||
func (client *MockClient) Wait(id string) <-chan dockerclient.WaitResult {
|
||||
args := client.Mock.Called(id)
|
||||
return args.Get(0).(<-chan dockerclient.WaitResult)
|
||||
}
|
||||
|
||||
func (client *MockClient) MonitorEvents(options *dockerclient.MonitorEventsOptions, stopChan <-chan struct{}) (<-chan dockerclient.EventOrError, error) {
|
||||
args := client.Mock.Called(options, stopChan)
|
||||
return args.Get(0).(<-chan dockerclient.EventOrError), args.Error(1)
|
||||
|
|
@ -106,6 +121,11 @@ func (client *MockClient) PullImage(name string, auth *dockerclient.AuthConfig)
|
|||
return args.Error(0)
|
||||
}
|
||||
|
||||
func (client *MockClient) PushImage(name string, tag string, auth *dockerclient.AuthConfig) error {
|
||||
args := client.Mock.Called(name, tag, auth)
|
||||
return args.Error(0)
|
||||
}
|
||||
|
||||
func (client *MockClient) LoadImage(reader io.Reader) error {
|
||||
args := client.Mock.Called(reader)
|
||||
return args.Error(0)
|
||||
|
|
@ -116,16 +136,21 @@ func (client *MockClient) RemoveContainer(id string, force, volumes bool) error
|
|||
return args.Error(0)
|
||||
}
|
||||
|
||||
func (client *MockClient) ListImages() ([]*dockerclient.Image, error) {
|
||||
args := client.Mock.Called()
|
||||
func (client *MockClient) ListImages(all bool) ([]*dockerclient.Image, error) {
|
||||
args := client.Mock.Called(all)
|
||||
return args.Get(0).([]*dockerclient.Image), args.Error(1)
|
||||
}
|
||||
|
||||
func (client *MockClient) RemoveImage(name string) ([]*dockerclient.ImageDelete, error) {
|
||||
args := client.Mock.Called(name)
|
||||
func (client *MockClient) RemoveImage(name string, force bool) ([]*dockerclient.ImageDelete, error) {
|
||||
args := client.Mock.Called(name, force)
|
||||
return args.Get(0).([]*dockerclient.ImageDelete), args.Error(1)
|
||||
}
|
||||
|
||||
func (client *MockClient) SearchImages(query, registry string, authConfig *dockerclient.AuthConfig) ([]dockerclient.ImageSearch, error) {
|
||||
args := client.Mock.Called(query, registry, authConfig)
|
||||
return args.Get(0).([]dockerclient.ImageSearch), args.Error(1)
|
||||
}
|
||||
|
||||
func (client *MockClient) PauseContainer(name string) error {
|
||||
args := client.Mock.Called(name)
|
||||
return args.Error(0)
|
||||
|
|
@ -136,11 +161,21 @@ func (client *MockClient) UnpauseContainer(name string) error {
|
|||
return args.Error(0)
|
||||
}
|
||||
|
||||
func (client *MockClient) Exec(config *dockerclient.ExecConfig) (string, error) {
|
||||
func (client *MockClient) ExecCreate(config *dockerclient.ExecConfig) (string, error) {
|
||||
args := client.Mock.Called(config)
|
||||
return args.String(0), args.Error(1)
|
||||
}
|
||||
|
||||
func (client *MockClient) ExecStart(id string, config *dockerclient.ExecConfig) error {
|
||||
args := client.Mock.Called(id, config)
|
||||
return args.Error(0)
|
||||
}
|
||||
|
||||
func (client *MockClient) ExecResize(id string, width, height int) error {
|
||||
args := client.Mock.Called(id, width, height)
|
||||
return args.Error(0)
|
||||
}
|
||||
|
||||
func (client *MockClient) RenameContainer(oldName string, newName string) error {
|
||||
args := client.Mock.Called(oldName, newName)
|
||||
return args.Error(0)
|
||||
|
|
@ -150,3 +185,53 @@ func (client *MockClient) ImportImage(source string, repository string, tag stri
|
|||
args := client.Mock.Called(source, repository, tag, tar)
|
||||
return args.Get(0).(io.ReadCloser), args.Error(1)
|
||||
}
|
||||
|
||||
func (client *MockClient) BuildImage(image *dockerclient.BuildImage) (io.ReadCloser, error) {
|
||||
args := client.Mock.Called(image)
|
||||
return args.Get(0).(io.ReadCloser), args.Error(1)
|
||||
}
|
||||
|
||||
func (client *MockClient) ListVolumes() ([]*dockerclient.Volume, error) {
|
||||
args := client.Mock.Called()
|
||||
return args.Get(0).([]*dockerclient.Volume), args.Error(1)
|
||||
}
|
||||
|
||||
func (client *MockClient) RemoveVolume(name string) error {
|
||||
args := client.Mock.Called(name)
|
||||
return args.Error(0)
|
||||
}
|
||||
|
||||
func (client *MockClient) CreateVolume(request *dockerclient.VolumeCreateRequest) (*dockerclient.Volume, error) {
|
||||
args := client.Mock.Called(request)
|
||||
return args.Get(0).(*dockerclient.Volume), args.Error(1)
|
||||
}
|
||||
|
||||
func (client *MockClient) ListNetworks(filters string) ([]*dockerclient.NetworkResource, error) {
|
||||
args := client.Mock.Called(filters)
|
||||
return args.Get(0).([]*dockerclient.NetworkResource), args.Error(1)
|
||||
}
|
||||
|
||||
func (client *MockClient) InspectNetwork(id string) (*dockerclient.NetworkResource, error) {
|
||||
args := client.Mock.Called(id)
|
||||
return args.Get(0).(*dockerclient.NetworkResource), args.Error(1)
|
||||
}
|
||||
|
||||
func (client *MockClient) CreateNetwork(config *dockerclient.NetworkCreate) (*dockerclient.NetworkCreateResponse, error) {
|
||||
args := client.Mock.Called(config)
|
||||
return args.Get(0).(*dockerclient.NetworkCreateResponse), args.Error(1)
|
||||
}
|
||||
|
||||
func (client *MockClient) ConnectNetwork(id, container string) error {
|
||||
args := client.Mock.Called(id, container)
|
||||
return args.Error(0)
|
||||
}
|
||||
|
||||
func (client *MockClient) DisconnectNetwork(id, container string, force bool) error {
|
||||
args := client.Mock.Called(id, container, force)
|
||||
return args.Error(0)
|
||||
}
|
||||
|
||||
func (client *MockClient) RemoveNetwork(id string) error {
|
||||
args := client.Mock.Called(id)
|
||||
return args.Error(0)
|
||||
}
|
||||
|
|
|
|||
38
Godeps/_workspace/src/github.com/samalba/dockerclient/tls.go
generated
vendored
Normal file
38
Godeps/_workspace/src/github.com/samalba/dockerclient/tls.go
generated
vendored
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
package dockerclient
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"errors"
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
// TLSConfigFromCertPath returns a configuration based on PEM files in the directory
|
||||
//
|
||||
// path is usually what is set by the environment variable `DOCKER_CERT_PATH`,
|
||||
// or `$HOME/.docker`.
|
||||
func TLSConfigFromCertPath(path string) (*tls.Config, error) {
|
||||
cert, err := ioutil.ReadFile(filepath.Join(path, "cert.pem"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
key, err := ioutil.ReadFile(filepath.Join(path, "key.pem"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ca, err := ioutil.ReadFile(filepath.Join(path, "ca.pem"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tlsCert, err := tls.X509KeyPair(cert, key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tlsConfig := &tls.Config{Certificates: []tls.Certificate{tlsCert}}
|
||||
tlsConfig.RootCAs = x509.NewCertPool()
|
||||
if !tlsConfig.RootCAs.AppendCertsFromPEM(ca) {
|
||||
return nil, errors.New("Could not add RootCA pem")
|
||||
}
|
||||
return tlsConfig, nil
|
||||
}
|
||||
305
Godeps/_workspace/src/github.com/samalba/dockerclient/types.go
generated
vendored
305
Godeps/_workspace/src/github.com/samalba/dockerclient/types.go
generated
vendored
|
|
@ -2,9 +2,10 @@ package dockerclient
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/pkg/units"
|
||||
"github.com/docker/go-units"
|
||||
)
|
||||
|
||||
type ContainerConfig struct {
|
||||
|
|
@ -22,13 +23,16 @@ type ContainerConfig struct {
|
|||
Cmd []string
|
||||
Image string
|
||||
Volumes map[string]struct{}
|
||||
VolumeDriver string
|
||||
WorkingDir string
|
||||
Entrypoint []string
|
||||
NetworkDisabled bool
|
||||
MacAddress string
|
||||
OnBuild []string
|
||||
Labels map[string]string
|
||||
StopSignal string
|
||||
|
||||
// FIXME: VolumeDriver have been removed since docker 1.9
|
||||
VolumeDriver string
|
||||
|
||||
// FIXME: The following fields have been removed since API v1.18
|
||||
Memory int64
|
||||
|
|
@ -39,42 +43,70 @@ type ContainerConfig struct {
|
|||
|
||||
// This is used only by the create command
|
||||
HostConfig HostConfig
|
||||
|
||||
// Network configuration support
|
||||
NetworkingConfig NetworkingConfig
|
||||
}
|
||||
|
||||
type HostConfig struct {
|
||||
Binds []string
|
||||
ContainerIDFile string
|
||||
LxcConf []map[string]string
|
||||
Memory int64
|
||||
MemorySwap int64
|
||||
CpuShares int64
|
||||
CpuPeriod int64
|
||||
CpusetCpus string
|
||||
CpusetMems string
|
||||
CpuQuota int64
|
||||
BlkioWeight int64
|
||||
OomKillDisable bool
|
||||
Privileged bool
|
||||
PortBindings map[string][]PortBinding
|
||||
Links []string
|
||||
PublishAllPorts bool
|
||||
Dns []string
|
||||
DnsSearch []string
|
||||
ExtraHosts []string
|
||||
VolumesFrom []string
|
||||
Devices []DeviceMapping
|
||||
NetworkMode string
|
||||
IpcMode string
|
||||
PidMode string
|
||||
UTSMode string
|
||||
CapAdd []string
|
||||
CapDrop []string
|
||||
RestartPolicy RestartPolicy
|
||||
SecurityOpt []string
|
||||
ReadonlyRootfs bool
|
||||
Ulimits []Ulimit
|
||||
LogConfig LogConfig
|
||||
CgroupParent string
|
||||
Binds []string
|
||||
ContainerIDFile string
|
||||
LxcConf []map[string]string
|
||||
Memory int64
|
||||
MemoryReservation int64
|
||||
MemorySwap int64
|
||||
KernelMemory int64
|
||||
CpuShares int64
|
||||
CpuPeriod int64
|
||||
CpusetCpus string
|
||||
CpusetMems string
|
||||
CpuQuota int64
|
||||
BlkioWeight int64
|
||||
OomKillDisable bool
|
||||
MemorySwappiness int64
|
||||
Privileged bool
|
||||
PortBindings map[string][]PortBinding
|
||||
Links []string
|
||||
PublishAllPorts bool
|
||||
Dns []string
|
||||
DNSOptions []string
|
||||
DnsSearch []string
|
||||
ExtraHosts []string
|
||||
VolumesFrom []string
|
||||
Devices []DeviceMapping
|
||||
NetworkMode string
|
||||
IpcMode string
|
||||
PidMode string
|
||||
UTSMode string
|
||||
CapAdd []string
|
||||
CapDrop []string
|
||||
GroupAdd []string
|
||||
RestartPolicy RestartPolicy
|
||||
SecurityOpt []string
|
||||
ReadonlyRootfs bool
|
||||
Ulimits []Ulimit
|
||||
LogConfig LogConfig
|
||||
CgroupParent string
|
||||
ConsoleSize [2]int
|
||||
VolumeDriver string
|
||||
OomScoreAdj int
|
||||
Tmpfs map[string]string
|
||||
ShmSize int64
|
||||
BlkioWeightDevice []WeightDevice
|
||||
BlkioDeviceReadBps []ThrottleDevice
|
||||
BlkioDeviceWriteBps []ThrottleDevice
|
||||
BlkioDeviceReadIOps []ThrottleDevice
|
||||
BlkioDeviceWriteIOps []ThrottleDevice
|
||||
}
|
||||
|
||||
type WeightDevice struct {
|
||||
Path string
|
||||
Weight uint16
|
||||
}
|
||||
|
||||
type ThrottleDevice struct {
|
||||
Path string
|
||||
Rate uint64
|
||||
}
|
||||
|
||||
type DeviceMapping struct {
|
||||
|
|
@ -101,6 +133,14 @@ type LogOptions struct {
|
|||
Tail int64
|
||||
}
|
||||
|
||||
type AttachOptions struct {
|
||||
Logs bool
|
||||
Stream bool
|
||||
Stdin bool
|
||||
Stdout bool
|
||||
Stderr bool
|
||||
}
|
||||
|
||||
type MonitorEventsFilters struct {
|
||||
Event string `json:",omitempty"`
|
||||
Image string `json:",omitempty"`
|
||||
|
|
@ -198,6 +238,14 @@ type ImageInfo struct {
|
|||
VirtualSize int64
|
||||
}
|
||||
|
||||
type ImageSearch 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"`
|
||||
}
|
||||
|
||||
type ContainerInfo struct {
|
||||
Id string
|
||||
Created string
|
||||
|
|
@ -214,6 +262,7 @@ type ContainerInfo struct {
|
|||
Gateway string
|
||||
Bridge string
|
||||
Ports map[string][]PortBinding
|
||||
Networks map[string]*EndpointSettings
|
||||
}
|
||||
SysInitPath string
|
||||
ResolvConfPath string
|
||||
|
|
@ -233,24 +282,62 @@ type Port struct {
|
|||
Type string
|
||||
}
|
||||
|
||||
// EndpointSettings stores the network endpoint details
|
||||
type EndpointSettings struct {
|
||||
// Configurations
|
||||
IPAMConfig *EndpointIPAMConfig
|
||||
Links []string
|
||||
Aliases []string
|
||||
// Operational data
|
||||
NetworkID string
|
||||
EndpointID string
|
||||
Gateway string
|
||||
IPAddress string
|
||||
IPPrefixLen int
|
||||
IPv6Gateway string
|
||||
GlobalIPv6Address string
|
||||
GlobalIPv6PrefixLen int
|
||||
MacAddress string
|
||||
}
|
||||
|
||||
// NetworkingConfig represents the container's networking configuration for each of its interfaces
|
||||
// Carries the networink configs specified in the `docker run` and `docker network connect` commands
|
||||
type NetworkingConfig struct {
|
||||
EndpointsConfig map[string]*EndpointSettings // Endpoint configs for each conencting network
|
||||
}
|
||||
|
||||
type Container struct {
|
||||
Id string
|
||||
Names []string
|
||||
Image string
|
||||
Command string
|
||||
Created int64
|
||||
Status string
|
||||
Ports []Port
|
||||
SizeRw int64
|
||||
SizeRootFs int64
|
||||
Labels map[string]string
|
||||
Id string
|
||||
Names []string
|
||||
Image string
|
||||
Command string
|
||||
Created int64
|
||||
Status string
|
||||
Ports []Port
|
||||
SizeRw int64
|
||||
SizeRootFs int64
|
||||
Labels map[string]string
|
||||
NetworkSettings struct {
|
||||
Networks map[string]EndpointSettings
|
||||
}
|
||||
}
|
||||
|
||||
type Actor struct {
|
||||
ID string
|
||||
Attributes map[string]string
|
||||
}
|
||||
|
||||
type Event struct {
|
||||
Id string
|
||||
Status string
|
||||
From string
|
||||
Time int64
|
||||
Status string `json:"status,omitempty"`
|
||||
ID string `json:"id,omitempty"`
|
||||
From string `json:"from,omitempty"`
|
||||
|
||||
Type string
|
||||
Action string
|
||||
Actor Actor
|
||||
|
||||
Time int64 `json:"time,omitempty"`
|
||||
TimeNano int64 `json:"timeNano,omitempty"`
|
||||
}
|
||||
|
||||
type Version struct {
|
||||
|
|
@ -271,7 +358,9 @@ type RespContainersCreate struct {
|
|||
type Image struct {
|
||||
Created int64
|
||||
Id string
|
||||
Labels map[string]string
|
||||
ParentId string
|
||||
RepoDigests []string
|
||||
RepoTags []string
|
||||
Size int64
|
||||
VirtualSize int64
|
||||
|
|
@ -318,11 +407,21 @@ type ImageDelete struct {
|
|||
Untagged string
|
||||
}
|
||||
|
||||
type StatsOrError struct {
|
||||
Stats
|
||||
Error error
|
||||
}
|
||||
|
||||
type EventOrError struct {
|
||||
Event
|
||||
Error error
|
||||
}
|
||||
|
||||
type WaitResult struct {
|
||||
ExitCode int
|
||||
Error error
|
||||
}
|
||||
|
||||
type decodingResult struct {
|
||||
result interface{}
|
||||
err error
|
||||
|
|
@ -338,6 +437,7 @@ type ThrottlingData struct {
|
|||
ThrottledTime uint64 `json:"throttled_time"`
|
||||
}
|
||||
|
||||
// All CPU stats are aggregated since container inception.
|
||||
type CpuUsage struct {
|
||||
// Total CPU time consumed.
|
||||
// Units: nanoseconds.
|
||||
|
|
@ -415,3 +515,110 @@ type LogConfig struct {
|
|||
Type string `json:"type"`
|
||||
Config map[string]string `json:"config"`
|
||||
}
|
||||
|
||||
type BuildImage struct {
|
||||
Config *ConfigFile
|
||||
DockerfileName string
|
||||
Context io.Reader
|
||||
RemoteURL string
|
||||
RepoName string
|
||||
SuppressOutput bool
|
||||
NoCache bool
|
||||
Remove bool
|
||||
ForceRemove bool
|
||||
Pull bool
|
||||
Memory int64
|
||||
MemorySwap int64
|
||||
CpuShares int64
|
||||
CpuPeriod int64
|
||||
CpuQuota int64
|
||||
CpuSetCpus string
|
||||
CpuSetMems string
|
||||
CgroupParent string
|
||||
BuildArgs map[string]string
|
||||
}
|
||||
|
||||
type Volume struct {
|
||||
Name string // Name is the name of the volume
|
||||
Driver string // Driver is the Driver name used to create the volume
|
||||
Mountpoint string // Mountpoint is the location on disk of the volume
|
||||
}
|
||||
|
||||
type VolumesListResponse struct {
|
||||
Volumes []*Volume // Volumes is the list of volumes being returned
|
||||
}
|
||||
|
||||
type VolumeCreateRequest struct {
|
||||
Name string // Name is the requested name of the volume
|
||||
Driver string // Driver is the name of the driver that should be used to create the volume
|
||||
DriverOpts map[string]string // DriverOpts holds the driver specific options to use for when creating the volume.
|
||||
}
|
||||
|
||||
// IPAM represents IP Address Management
|
||||
type IPAM struct {
|
||||
Driver string
|
||||
Options map[string]string //Per network IPAM driver options
|
||||
Config []IPAMConfig
|
||||
}
|
||||
|
||||
// IPAMConfig represents IPAM configurations
|
||||
type IPAMConfig struct {
|
||||
Subnet string `json:",omitempty"`
|
||||
IPRange string `json:",omitempty"`
|
||||
Gateway string `json:",omitempty"`
|
||||
AuxAddress map[string]string `json:"AuxiliaryAddresses,omitempty"`
|
||||
}
|
||||
|
||||
// EndpointIPAMConfig represents IPAM configurations for the endpoint
|
||||
type EndpointIPAMConfig struct {
|
||||
IPv4Address string `json:",omitempty"`
|
||||
IPv6Address string `json:",omitempty"`
|
||||
}
|
||||
|
||||
// NetworkResource is the body of the "get network" http response message
|
||||
type NetworkResource struct {
|
||||
Name string
|
||||
ID string `json:"Id"`
|
||||
Scope string
|
||||
Driver string
|
||||
IPAM IPAM
|
||||
//Internal bool
|
||||
Containers map[string]EndpointResource
|
||||
Options map[string]string
|
||||
}
|
||||
|
||||
// EndpointResource contains network resources allocated and used for a container in a network
|
||||
type EndpointResource struct {
|
||||
Name string
|
||||
EndpointID string
|
||||
MacAddress string
|
||||
IPv4Address string
|
||||
IPv6Address string
|
||||
}
|
||||
|
||||
// NetworkCreate is the expected body of the "create network" http request message
|
||||
type NetworkCreate struct {
|
||||
Name string
|
||||
CheckDuplicate bool
|
||||
Driver string
|
||||
IPAM IPAM
|
||||
Internal bool
|
||||
Options map[string]string
|
||||
}
|
||||
|
||||
// NetworkCreateResponse is the response message sent by the server for network create call
|
||||
type NetworkCreateResponse struct {
|
||||
ID string `json:"Id"`
|
||||
Warning string
|
||||
}
|
||||
|
||||
// NetworkConnect represents the data to be used to connect a container to the network
|
||||
type NetworkConnect struct {
|
||||
Container string
|
||||
}
|
||||
|
||||
// NetworkDisconnect represents the data to be used to disconnect a container from the network
|
||||
type NetworkDisconnect struct {
|
||||
Container string
|
||||
Force bool
|
||||
}
|
||||
|
|
|
|||
12
Godeps/_workspace/src/github.com/samalba/dockerclient/utils.go
generated
vendored
12
Godeps/_workspace/src/github.com/samalba/dockerclient/utils.go
generated
vendored
|
|
@ -8,7 +8,9 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
func newHTTPClient(u *url.URL, tlsConfig *tls.Config, timeout time.Duration) *http.Client {
|
||||
type tcpFunc func(*net.TCPConn, time.Duration) error
|
||||
|
||||
func newHTTPClient(u *url.URL, tlsConfig *tls.Config, timeout time.Duration, setUserTimeout tcpFunc) *http.Client {
|
||||
httpTransport := &http.Transport{
|
||||
TLSClientConfig: tlsConfig,
|
||||
}
|
||||
|
|
@ -16,7 +18,13 @@ func newHTTPClient(u *url.URL, tlsConfig *tls.Config, timeout time.Duration) *ht
|
|||
switch u.Scheme {
|
||||
default:
|
||||
httpTransport.Dial = func(proto, addr string) (net.Conn, error) {
|
||||
return net.DialTimeout(proto, addr, timeout)
|
||||
conn, err := net.DialTimeout(proto, addr, timeout)
|
||||
if tcpConn, ok := conn.(*net.TCPConn); ok && setUserTimeout != nil {
|
||||
// Sender can break TCP connection if the remote side doesn't
|
||||
// acknowledge packets within timeout
|
||||
setUserTimeout(tcpConn, timeout)
|
||||
}
|
||||
return conn, err
|
||||
}
|
||||
case "unix":
|
||||
socketPath := u.Path
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue