mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-29 22:46:12 +00:00
Merge pull request #702 from fsouza/update-go-dockerclient
third_party: update go-dockerclient
This commit is contained in:
commit
5443929b84
@ -289,7 +289,7 @@ func (kl *Kubelet) runContainer(pod *Pod, container *api.Container, podVolumes v
|
||||
ExposedPorts: exposedPorts,
|
||||
Hostname: container.Name,
|
||||
Image: container.Image,
|
||||
Memory: uint64(container.Memory),
|
||||
Memory: int64(container.Memory),
|
||||
CpuShares: int64(milliCPUToShares(container.CPU)),
|
||||
Volumes: volumes,
|
||||
WorkingDir: container.WorkingDir,
|
||||
|
@ -1,5 +1,6 @@
|
||||
# This is the official list of go-dockerclient authors for copyright purposes.
|
||||
|
||||
Andreas Jaekle <andreas@jaekle.net>
|
||||
Andrews Medina <andrewsmedina@gmail.com>
|
||||
Andy Goldstein <andy.goldstein@redhat.com>
|
||||
Ben McCann <benmccann.com>
|
||||
@ -8,6 +9,7 @@ Cheah Chu Yeow <chuyeow@gmail.com>
|
||||
cheneydeng <cheneydeng@qq.com>
|
||||
Ed <edrocksit@gmail.com>
|
||||
Eric Anderson <anderson@copperegg.com>
|
||||
Fabio Rehm <fgrehm@gmail.com>
|
||||
Flavia Missi <flaviamissi@gmail.com>
|
||||
Francisco Souza <f@souza.cc>
|
||||
Jari Kolehmainen <jari.kolehmainen@digia.com>
|
||||
@ -15,6 +17,8 @@ Jason Wilder <jwilder@litl.com>
|
||||
Jean-Baptiste Dalido <jeanbaptiste@appgratis.com>
|
||||
Jeff Mitchell <jeffrey.mitchell@gmail.com>
|
||||
Jeffrey Hulten <jhulten@gmail.com>
|
||||
Johan Euphrosine <proppy@google.com>
|
||||
Karan Misra <kidoman@gmail.com>
|
||||
Lucas Clemente <lucas@clemente.io>
|
||||
Omeid Matten <public@omeid.me>
|
||||
Paul Morie <pmorie@gmail.com>
|
||||
|
@ -11,27 +11,29 @@ For more details, check the [remote API documentation](http://docs.docker.io/en/
|
||||
|
||||
## Example
|
||||
|
||||
package main
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/fsouza/go-dockerclient"
|
||||
)
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/fsouza/go-dockerclient"
|
||||
)
|
||||
|
||||
func main() {
|
||||
endpoint := "unix:///var/run/docker.sock"
|
||||
client, _ := docker.NewClient(endpoint)
|
||||
imgs, _ := client.ListImages(true)
|
||||
for _, img := range imgs {
|
||||
fmt.Println("ID: ", img.ID)
|
||||
fmt.Println("RepoTags: ", img.RepoTags)
|
||||
fmt.Println("Created: ", img.Created)
|
||||
fmt.Println("Size: ", img.Size)
|
||||
fmt.Println("VirtualSize: ", img.VirtualSize)
|
||||
fmt.Println("ParentId: ", img.ParentId)
|
||||
fmt.Println("Repository: ", img.Repository)
|
||||
}
|
||||
}
|
||||
func main() {
|
||||
endpoint := "unix:///var/run/docker.sock"
|
||||
client, _ := docker.NewClient(endpoint)
|
||||
imgs, _ := client.ListImages(true)
|
||||
for _, img := range imgs {
|
||||
fmt.Println("ID: ", img.ID)
|
||||
fmt.Println("RepoTags: ", img.RepoTags)
|
||||
fmt.Println("Created: ", img.Created)
|
||||
fmt.Println("Size: ", img.Size)
|
||||
fmt.Println("VirtualSize: ", img.VirtualSize)
|
||||
fmt.Println("ParentId: ", img.ParentId)
|
||||
fmt.Println("Repository: ", img.Repository)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Developing
|
||||
|
||||
|
@ -21,7 +21,6 @@ import (
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/fsouza/go-dockerclient/utils"
|
||||
)
|
||||
@ -113,11 +112,11 @@ func (version ApiVersion) compare(other ApiVersion) int {
|
||||
// interaction with the API.
|
||||
type Client struct {
|
||||
SkipServerVersionCheck bool
|
||||
HTTPClient *http.Client
|
||||
|
||||
endpoint string
|
||||
endpointURL *url.URL
|
||||
eventMonitor *eventMonitoringState
|
||||
client *http.Client
|
||||
requestedApiVersion ApiVersion
|
||||
serverApiVersion ApiVersion
|
||||
expectedApiVersion ApiVersion
|
||||
@ -142,7 +141,6 @@ func NewVersionedClient(endpoint string, apiVersionString string) (*Client, erro
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var requestedApiVersion ApiVersion
|
||||
if strings.Contains(apiVersionString, ".") {
|
||||
requestedApiVersion, err = NewApiVersion(apiVersionString)
|
||||
@ -150,11 +148,10 @@ func NewVersionedClient(endpoint string, apiVersionString string) (*Client, erro
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return &Client{
|
||||
HTTPClient: http.DefaultClient,
|
||||
endpoint: endpoint,
|
||||
endpointURL: u,
|
||||
client: http.DefaultClient,
|
||||
eventMonitor: new(eventMonitoringState),
|
||||
requestedApiVersion: requestedApiVersion,
|
||||
}, nil
|
||||
@ -177,29 +174,6 @@ func (c *Client) checkApiVersion() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseApiVersionString(input string) (version uint16, err error) {
|
||||
version = 0
|
||||
|
||||
if !strings.Contains(input, ".") {
|
||||
return 0, fmt.Errorf("Unable to parse version '%s'", input)
|
||||
}
|
||||
|
||||
arr := strings.Split(input, ".")
|
||||
|
||||
major, err := strconv.Atoi(arr[0])
|
||||
if err != nil {
|
||||
return version, err
|
||||
}
|
||||
|
||||
minor, err := strconv.Atoi(arr[1])
|
||||
if err != nil {
|
||||
return version, err
|
||||
}
|
||||
|
||||
version = uint16(major)<<8 | uint16(minor)
|
||||
return version, nil
|
||||
}
|
||||
|
||||
// Ping pings the docker server
|
||||
//
|
||||
// See http://goo.gl/stJENm for more details.
|
||||
@ -223,13 +197,11 @@ func (c *Client) getServerApiVersionString() (version string, err error) {
|
||||
if status != http.StatusOK {
|
||||
return "", fmt.Errorf("Received unexpected status %d while trying to retrieve the server version", status)
|
||||
}
|
||||
|
||||
var versionResponse map[string]string
|
||||
err = json.Unmarshal(body, &versionResponse)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
version = versionResponse["ApiVersion"]
|
||||
return version, nil
|
||||
}
|
||||
@ -243,14 +215,12 @@ func (c *Client) do(method, path string, data interface{}) ([]byte, int, error)
|
||||
}
|
||||
params = bytes.NewBuffer(buf)
|
||||
}
|
||||
|
||||
if path != "/version" && !c.SkipServerVersionCheck && c.expectedApiVersion == nil {
|
||||
err := c.checkApiVersion()
|
||||
if err != nil {
|
||||
return nil, -1, err
|
||||
}
|
||||
}
|
||||
|
||||
req, err := http.NewRequest(method, c.getURL(path), params)
|
||||
if err != nil {
|
||||
return nil, -1, err
|
||||
@ -277,7 +247,7 @@ func (c *Client) do(method, path string, data interface{}) ([]byte, int, error)
|
||||
}
|
||||
defer clientconn.Close()
|
||||
} else {
|
||||
resp, err = c.client.Do(req)
|
||||
resp, err = c.HTTPClient.Do(req)
|
||||
}
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "connection refused") {
|
||||
@ -335,7 +305,7 @@ func (c *Client) stream(method, path string, setRawTerminal bool, headers map[st
|
||||
resp, err = clientconn.Do(req)
|
||||
defer clientconn.Close()
|
||||
} else {
|
||||
resp, err = c.client.Do(req)
|
||||
resp, err = c.HTTPClient.Do(req)
|
||||
}
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "connection refused") {
|
||||
@ -418,10 +388,10 @@ func (c *Client) hijack(method, path string, success chan struct{}, setRawTermin
|
||||
<-success
|
||||
}
|
||||
rwc, br := clientconn.Hijack()
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(2)
|
||||
errs := make(chan error, 2)
|
||||
exit := make(chan bool)
|
||||
go func() {
|
||||
defer close(exit)
|
||||
var err error
|
||||
if setRawTerminal {
|
||||
_, err = io.Copy(stdout, br)
|
||||
@ -429,7 +399,6 @@ func (c *Client) hijack(method, path string, success chan struct{}, setRawTermin
|
||||
_, err = utils.StdCopy(stdout, stderr, br)
|
||||
}
|
||||
errs <- err
|
||||
wg.Done()
|
||||
}()
|
||||
go func() {
|
||||
var err error
|
||||
@ -440,14 +409,9 @@ func (c *Client) hijack(method, path string, success chan struct{}, setRawTermin
|
||||
CloseWrite() error
|
||||
}).CloseWrite()
|
||||
errs <- err
|
||||
wg.Done()
|
||||
}()
|
||||
wg.Wait()
|
||||
close(errs)
|
||||
if err := <-errs; err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
<-exit
|
||||
return <-errs
|
||||
}
|
||||
|
||||
func (c *Client) getURL(path string) string {
|
||||
|
@ -24,10 +24,9 @@ func TestNewAPIClient(t *testing.T) {
|
||||
if client.endpoint != endpoint {
|
||||
t.Errorf("Expected endpoint %s. Got %s.", endpoint, client.endpoint)
|
||||
}
|
||||
if client.client != http.DefaultClient {
|
||||
t.Errorf("Expected http.Client %#v. Got %#v.", http.DefaultClient, client.client)
|
||||
if client.HTTPClient != http.DefaultClient {
|
||||
t.Errorf("Expected http.Client %#v. Got %#v.", http.DefaultClient, client.HTTPClient)
|
||||
}
|
||||
|
||||
// test unix socket endpoints
|
||||
endpoint = "unix:///var/run/docker.sock"
|
||||
client, err = NewClient(endpoint)
|
||||
@ -54,8 +53,8 @@ func TestNewVersionedClient(t *testing.T) {
|
||||
if client.endpoint != endpoint {
|
||||
t.Errorf("Expected endpoint %s. Got %s.", endpoint, client.endpoint)
|
||||
}
|
||||
if client.client != http.DefaultClient {
|
||||
t.Errorf("Expected http.Client %#v. Got %#v.", http.DefaultClient, client.client)
|
||||
if client.HTTPClient != http.DefaultClient {
|
||||
t.Errorf("Expected http.Client %#v. Got %#v.", http.DefaultClient, client.HTTPClient)
|
||||
}
|
||||
if reqVersion := client.requestedApiVersion.String(); reqVersion != "1.12" {
|
||||
t.Errorf("Wrong requestApiVersion. Want %q. Got %q.", "1.12", reqVersion)
|
||||
|
@ -158,8 +158,8 @@ type Config struct {
|
||||
Hostname string
|
||||
Domainname string
|
||||
User string
|
||||
Memory uint64
|
||||
MemorySwap uint64
|
||||
Memory int64
|
||||
MemorySwap int64
|
||||
CpuShares int64
|
||||
AttachStdin bool
|
||||
AttachStdout bool
|
||||
@ -297,7 +297,7 @@ type HostConfig struct {
|
||||
NetworkMode string
|
||||
}
|
||||
|
||||
// StartContainer starts a container, returning an errror in case of failure.
|
||||
// StartContainer starts a container, returning an error in case of failure.
|
||||
//
|
||||
// See http://goo.gl/y5GZlE for more details.
|
||||
func (c *Client) StartContainer(id string, hostConfig *HostConfig) error {
|
||||
|
@ -225,6 +225,88 @@ func TestInspectContainer(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestInspectContainerNegativeSwap(t *testing.T) {
|
||||
jsonContainer := `{
|
||||
"Id": "4fa6e0f0c6786287e131c3852c58a2e01cc697a68231826813597e4994f1d6e2",
|
||||
"Created": "2013-05-07T14:51:42.087658+02:00",
|
||||
"Path": "date",
|
||||
"Args": [],
|
||||
"Config": {
|
||||
"Hostname": "4fa6e0f0c678",
|
||||
"User": "",
|
||||
"Memory": 17179869184,
|
||||
"MemorySwap": -1,
|
||||
"AttachStdin": false,
|
||||
"AttachStdout": true,
|
||||
"AttachStderr": true,
|
||||
"PortSpecs": null,
|
||||
"Tty": false,
|
||||
"OpenStdin": false,
|
||||
"StdinOnce": false,
|
||||
"Env": null,
|
||||
"Cmd": [
|
||||
"date"
|
||||
],
|
||||
"Image": "base",
|
||||
"Volumes": {},
|
||||
"VolumesFrom": ""
|
||||
},
|
||||
"State": {
|
||||
"Running": false,
|
||||
"Pid": 0,
|
||||
"ExitCode": 0,
|
||||
"StartedAt": "2013-05-07T14:51:42.087658+02:00",
|
||||
"Ghost": false
|
||||
},
|
||||
"Image": "b750fe79269d2ec9a3c593ef05b4332b1d1a02a62b4accb2c21d589ff2f5f2dc",
|
||||
"NetworkSettings": {
|
||||
"IpAddress": "",
|
||||
"IpPrefixLen": 0,
|
||||
"Gateway": "",
|
||||
"Bridge": "",
|
||||
"PortMapping": null
|
||||
},
|
||||
"SysInitPath": "/home/kitty/go/src/github.com/dotcloud/docker/bin/docker",
|
||||
"ResolvConfPath": "/etc/resolv.conf",
|
||||
"Volumes": {},
|
||||
"HostConfig": {
|
||||
"Binds": null,
|
||||
"ContainerIDFile": "",
|
||||
"LxcConf": [],
|
||||
"Privileged": false,
|
||||
"PortBindings": {
|
||||
"80/tcp": [
|
||||
{
|
||||
"HostIp": "0.0.0.0",
|
||||
"HostPort": "49153"
|
||||
}
|
||||
]
|
||||
},
|
||||
"Links": null,
|
||||
"PublishAllPorts": false
|
||||
}
|
||||
}`
|
||||
var expected Container
|
||||
err := json.Unmarshal([]byte(jsonContainer), &expected)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
fakeRT := &FakeRoundTripper{message: jsonContainer, status: http.StatusOK}
|
||||
client := newTestClient(fakeRT)
|
||||
id := "4fa6e0f0c678"
|
||||
container, err := client.InspectContainer(id)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !reflect.DeepEqual(*container, expected) {
|
||||
t.Errorf("InspectContainer(%q): Expected %#v. Got %#v.", id, expected, container)
|
||||
}
|
||||
expectedURL, _ := url.Parse(client.getURL("/containers/4fa6e0f0c678/json"))
|
||||
if gotPath := fakeRT.requests[0].URL.Path; gotPath != expectedURL.Path {
|
||||
t.Errorf("InspectContainer(%q): Wrong path in request. Want %q. Got %q.", id, expectedURL.Path, gotPath)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInspectContainerFailure(t *testing.T) {
|
||||
client := newTestClient(&FakeRoundTripper{message: "server error", status: 500})
|
||||
expected := Error{Status: 500, Message: "server error"}
|
||||
@ -1184,9 +1266,9 @@ func TestExportContainerViaUnixSocket(t *testing.T) {
|
||||
endpoint := "unix://" + tempSocket
|
||||
u, _ := parseEndpoint(endpoint)
|
||||
client := Client{
|
||||
HTTPClient: http.DefaultClient,
|
||||
endpoint: endpoint,
|
||||
endpointURL: u,
|
||||
client: http.DefaultClient,
|
||||
SkipServerVersionCheck: true,
|
||||
}
|
||||
listening := make(chan string)
|
||||
|
137
third_party/src/github.com/fsouza/go-dockerclient/env.go
vendored
Normal file
137
third_party/src/github.com/fsouza/go-dockerclient/env.go
vendored
Normal file
@ -0,0 +1,137 @@
|
||||
// Copyright 2014 Docker authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the DOCKER-LICENSE file.
|
||||
|
||||
package docker
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Env []string
|
||||
|
||||
func (env *Env) Get(key string) (value string) {
|
||||
return env.Map()[key]
|
||||
}
|
||||
|
||||
func (env *Env) Exists(key string) bool {
|
||||
_, exists := env.Map()[key]
|
||||
return exists
|
||||
}
|
||||
|
||||
func (env *Env) GetBool(key string) (value bool) {
|
||||
s := strings.ToLower(strings.Trim(env.Get(key), " \t"))
|
||||
if s == "" || s == "0" || s == "no" || s == "false" || s == "none" {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (env *Env) SetBool(key string, value bool) {
|
||||
if value {
|
||||
env.Set(key, "1")
|
||||
} else {
|
||||
env.Set(key, "0")
|
||||
}
|
||||
}
|
||||
|
||||
func (env *Env) GetInt(key string) int {
|
||||
return int(env.GetInt64(key))
|
||||
}
|
||||
|
||||
func (env *Env) SetInt(key string, value int) {
|
||||
env.Set(key, strconv.Itoa(value))
|
||||
}
|
||||
|
||||
func (env *Env) GetInt64(key string) int64 {
|
||||
s := strings.Trim(env.Get(key), " \t")
|
||||
val, err := strconv.ParseInt(s, 10, 64)
|
||||
if err != nil {
|
||||
return -1
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
func (env *Env) SetInt64(key string, value int64) {
|
||||
env.Set(key, strconv.FormatInt(value, 10))
|
||||
}
|
||||
|
||||
func (env *Env) GetJson(key string, iface interface{}) error {
|
||||
sval := env.Get(key)
|
||||
if sval == "" {
|
||||
return nil
|
||||
}
|
||||
return json.Unmarshal([]byte(sval), iface)
|
||||
}
|
||||
|
||||
func (env *Env) SetJson(key string, value interface{}) error {
|
||||
sval, err := json.Marshal(value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
env.Set(key, string(sval))
|
||||
return nil
|
||||
}
|
||||
|
||||
func (env *Env) GetList(key string) []string {
|
||||
sval := env.Get(key)
|
||||
if sval == "" {
|
||||
return nil
|
||||
}
|
||||
var l []string
|
||||
if err := json.Unmarshal([]byte(sval), &l); err != nil {
|
||||
l = append(l, sval)
|
||||
}
|
||||
return l
|
||||
}
|
||||
|
||||
func (env *Env) SetList(key string, value []string) error {
|
||||
return env.SetJson(key, value)
|
||||
}
|
||||
|
||||
func (env *Env) Set(key, value string) {
|
||||
*env = append(*env, key+"="+value)
|
||||
}
|
||||
|
||||
// Decode decodes `src` as a json dictionary, and adds each decoded key-value
|
||||
// pair to the environment.
|
||||
//
|
||||
// If `src` cannot be decoded as a json dictionary, an error is returned.
|
||||
func (env *Env) Decode(src io.Reader) error {
|
||||
m := make(map[string]interface{})
|
||||
if err := json.NewDecoder(src).Decode(&m); err != nil {
|
||||
return err
|
||||
}
|
||||
for k, v := range m {
|
||||
env.SetAuto(k, v)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (env *Env) SetAuto(k string, v interface{}) {
|
||||
if fval, ok := v.(float64); ok {
|
||||
env.SetInt64(k, int64(fval))
|
||||
} else if sval, ok := v.(string); ok {
|
||||
env.Set(k, sval)
|
||||
} else if val, err := json.Marshal(v); err == nil {
|
||||
env.Set(k, string(val))
|
||||
} else {
|
||||
env.Set(k, fmt.Sprintf("%v", v))
|
||||
}
|
||||
}
|
||||
|
||||
func (env *Env) Map() map[string]string {
|
||||
if len(*env) == 0 {
|
||||
return nil
|
||||
}
|
||||
m := make(map[string]string)
|
||||
for _, kv := range *env {
|
||||
parts := strings.SplitN(kv, "=", 2)
|
||||
m[parts[0]] = parts[1]
|
||||
}
|
||||
return m
|
||||
}
|
349
third_party/src/github.com/fsouza/go-dockerclient/env_test.go
vendored
Normal file
349
third_party/src/github.com/fsouza/go-dockerclient/env_test.go
vendored
Normal file
@ -0,0 +1,349 @@
|
||||
// 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 DOCKER-LICENSE file.
|
||||
|
||||
package docker
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"reflect"
|
||||
"sort"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestGet(t *testing.T) {
|
||||
var tests = []struct {
|
||||
input []string
|
||||
query string
|
||||
expected string
|
||||
}{
|
||||
{[]string{"PATH=/usr/bin:/bin", "PYTHONPATH=/usr/local"}, "PATH", "/usr/bin:/bin"},
|
||||
{[]string{"PATH=/usr/bin:/bin", "PYTHONPATH=/usr/local"}, "PYTHONPATH", "/usr/local"},
|
||||
{[]string{"PATH=/usr/bin:/bin", "PYTHONPATH=/usr/local"}, "PYTHONPATHI", ""},
|
||||
{[]string{"WAT="}, "WAT", ""},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
env := Env(tt.input)
|
||||
got := env.Get(tt.query)
|
||||
if got != tt.expected {
|
||||
t.Errorf("Env.Get(%q): wrong result. Want %q. Got %q", tt.query, tt.expected, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestExists(t *testing.T) {
|
||||
var tests = []struct {
|
||||
input []string
|
||||
query string
|
||||
expected bool
|
||||
}{
|
||||
{[]string{"WAT=", "PYTHONPATH=/usr/local"}, "WAT", true},
|
||||
{[]string{"PATH=/usr/bin:/bin", "PYTHONPATH=/usr/local"}, "PYTHONPATH", true},
|
||||
{[]string{"PATH=/usr/bin:/bin", "PYTHONPATH=/usr/local"}, "PYTHONPATHI", false},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
env := Env(tt.input)
|
||||
got := env.Exists(tt.query)
|
||||
if got != tt.expected {
|
||||
t.Errorf("Env.Exists(%q): wrong result. Want %v. Got %v", tt.query, tt.expected, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetBool(t *testing.T) {
|
||||
var tests = []struct {
|
||||
input string
|
||||
expected bool
|
||||
}{
|
||||
{"EMTPY_VAR", false}, {"ZERO_VAR", false}, {"NO_VAR", false},
|
||||
{"FALSE_VAR", false}, {"NONE_VAR", false}, {"TRUE_VAR", true},
|
||||
{"WAT", true}, {"PATH", true}, {"ONE_VAR", true}, {"NO_VAR_TAB", false},
|
||||
}
|
||||
env := Env([]string{
|
||||
"EMPTY_VAR=", "ZERO_VAR=0", "NO_VAR=no", "FALSE_VAR=false",
|
||||
"NONE_VAR=none", "TRUE_VAR=true", "WAT=wat", "PATH=/usr/bin:/bin",
|
||||
"ONE_VAR=1", "NO_VAR_TAB=0 \t\t\t",
|
||||
})
|
||||
for _, tt := range tests {
|
||||
got := env.GetBool(tt.input)
|
||||
if got != tt.expected {
|
||||
t.Errorf("Env.GetBool(%q): wrong result. Want %v. Got %v.", tt.input, tt.expected, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetBool(t *testing.T) {
|
||||
var tests = []struct {
|
||||
input bool
|
||||
expected string
|
||||
}{
|
||||
{true, "1"}, {false, "0"},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
var env Env
|
||||
env.SetBool("SOME", tt.input)
|
||||
if got := env.Get("SOME"); got != tt.expected {
|
||||
t.Errorf("Env.SetBool(%v): wrong result. Want %q. Got %q", tt.input, tt.expected, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetInt(t *testing.T) {
|
||||
var tests = []struct {
|
||||
input string
|
||||
expected int
|
||||
}{
|
||||
{"NEGATIVE_INTEGER", -10}, {"NON_INTEGER", -1}, {"ONE", 1}, {"TWO", 2},
|
||||
}
|
||||
env := Env([]string{"NEGATIVE_INTEGER=-10", "NON_INTEGER=wat", "ONE=1", "TWO=2"})
|
||||
for _, tt := range tests {
|
||||
got := env.GetInt(tt.input)
|
||||
if got != tt.expected {
|
||||
t.Errorf("Env.GetInt(%q): wrong result. Want %d. Got %d", tt.input, tt.expected, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetInt(t *testing.T) {
|
||||
var tests = []struct {
|
||||
input int
|
||||
expected string
|
||||
}{
|
||||
{10, "10"}, {13, "13"}, {7, "7"}, {33, "33"},
|
||||
{0, "0"}, {-34, "-34"},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
var env Env
|
||||
env.SetInt("SOME", tt.input)
|
||||
if got := env.Get("SOME"); got != tt.expected {
|
||||
t.Errorf("Env.SetBool(%d): wrong result. Want %q. Got %q", tt.input, tt.expected, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetInt64(t *testing.T) {
|
||||
var tests = []struct {
|
||||
input string
|
||||
expected int64
|
||||
}{
|
||||
{"NEGATIVE_INTEGER", -10}, {"NON_INTEGER", -1}, {"ONE", 1}, {"TWO", 2},
|
||||
}
|
||||
env := Env([]string{"NEGATIVE_INTEGER=-10", "NON_INTEGER=wat", "ONE=1", "TWO=2"})
|
||||
for _, tt := range tests {
|
||||
got := env.GetInt64(tt.input)
|
||||
if got != tt.expected {
|
||||
t.Errorf("Env.GetInt64(%q): wrong result. Want %d. Got %d", tt.input, tt.expected, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetInt64(t *testing.T) {
|
||||
var tests = []struct {
|
||||
input int64
|
||||
expected string
|
||||
}{
|
||||
{10, "10"}, {13, "13"}, {7, "7"}, {33, "33"},
|
||||
{0, "0"}, {-34, "-34"},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
var env Env
|
||||
env.SetInt64("SOME", tt.input)
|
||||
if got := env.Get("SOME"); got != tt.expected {
|
||||
t.Errorf("Env.SetBool(%d): wrong result. Want %q. Got %q", tt.input, tt.expected, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetJson(t *testing.T) {
|
||||
var p struct {
|
||||
Name string `json:"name"`
|
||||
Age int `json:"age"`
|
||||
}
|
||||
var env Env
|
||||
env.Set("person", `{"name":"Gopher","age":5}`)
|
||||
err := env.GetJson("person", &p)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if p.Name != "Gopher" {
|
||||
t.Errorf("Env.GetJson(%q): wrong name. Want %q. Got %q", "person", "Gopher", p.Name)
|
||||
}
|
||||
if p.Age != 5 {
|
||||
t.Errorf("Env.GetJson(%q): wrong age. Want %d. Got %d", "person", 5, p.Age)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetJsonAbsent(t *testing.T) {
|
||||
var l []string
|
||||
var env Env
|
||||
err := env.GetJson("person", &l)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if l != nil {
|
||||
t.Errorf("Env.GetJson(): get unexpected list %v", l)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetJsonFailure(t *testing.T) {
|
||||
var p []string
|
||||
var env Env
|
||||
env.Set("list-person", `{"name":"Gopher","age":5}`)
|
||||
err := env.GetJson("list-person", &p)
|
||||
if err == nil {
|
||||
t.Errorf("Env.GetJson(%q): got unexpected <nil> error.", "list-person")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetJson(t *testing.T) {
|
||||
var p1 = struct {
|
||||
Name string `json:"name"`
|
||||
Age int `json:"age"`
|
||||
}{Name: "Gopher", Age: 5}
|
||||
var env Env
|
||||
err := env.SetJson("person", p1)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
var p2 struct {
|
||||
Name string `json:"name"`
|
||||
Age int `json:"age"`
|
||||
}
|
||||
err = env.GetJson("person", &p2)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if !reflect.DeepEqual(p1, p2) {
|
||||
t.Errorf("Env.SetJson(%q): wrong result. Want %v. Got %v", "person", p1, p2)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetJsonFailure(t *testing.T) {
|
||||
var env Env
|
||||
err := env.SetJson("person", unmarshable{})
|
||||
if err == nil {
|
||||
t.Error("Env.SetJson(): got unexpected <nil> error")
|
||||
}
|
||||
if env.Exists("person") {
|
||||
t.Errorf("Env.SetJson(): should not define the key %q, but did", "person")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetList(t *testing.T) {
|
||||
var tests = []struct {
|
||||
input string
|
||||
expected []string
|
||||
}{
|
||||
{"WAT=wat", []string{"wat"}},
|
||||
{`WAT=["wat","wet","wit","wot","wut"]`, []string{"wat", "wet", "wit", "wot", "wut"}},
|
||||
{"WAT=", nil},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
env := Env([]string{tt.input})
|
||||
got := env.GetList("WAT")
|
||||
if !reflect.DeepEqual(got, tt.expected) {
|
||||
t.Errorf("Env.GetList(%q): wrong result. Want %v. Got %v", "WAT", tt.expected, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetList(t *testing.T) {
|
||||
list := []string{"a", "b", "c"}
|
||||
var env Env
|
||||
env.SetList("SOME", list)
|
||||
if got := env.GetList("SOME"); !reflect.DeepEqual(got, list) {
|
||||
t.Errorf("Env.SetList(%v): wrong result. Got %v", list, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSet(t *testing.T) {
|
||||
var env Env
|
||||
env.Set("PATH", "/home/bin:/bin")
|
||||
env.Set("SOMETHING", "/usr/bin")
|
||||
env.Set("PATH", "/bin")
|
||||
if expected, got := "/usr/bin", env.Get("SOMETHING"); got != expected {
|
||||
t.Errorf("Env.Set(%q): wrong result. Want %q. Got %q", expected, expected, got)
|
||||
}
|
||||
if expected, got := "/bin", env.Get("PATH"); got != expected {
|
||||
t.Errorf("Env.Set(%q): wrong result. Want %q. Got %q", expected, expected, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecode(t *testing.T) {
|
||||
var tests = []struct {
|
||||
input string
|
||||
expectedOut []string
|
||||
expectedErr string
|
||||
}{
|
||||
{
|
||||
`{"PATH":"/usr/bin:/bin","containers":54,"wat":["123","345"]}`,
|
||||
[]string{"PATH=/usr/bin:/bin", "containers=54", `wat=["123","345"]`},
|
||||
"",
|
||||
},
|
||||
{"}}", nil, "invalid character '}' looking for beginning of value"},
|
||||
{`{}`, nil, ""},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
var env Env
|
||||
err := env.Decode(bytes.NewBufferString(tt.input))
|
||||
if tt.expectedErr == "" {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
} else if tt.expectedErr != err.Error() {
|
||||
t.Errorf("Env.Decode(): invalid error. Want %q. Got %q.", tt.expectedErr, err)
|
||||
}
|
||||
got := []string(env)
|
||||
sort.Strings(got)
|
||||
sort.Strings(tt.expectedOut)
|
||||
if !reflect.DeepEqual(got, tt.expectedOut) {
|
||||
t.Errorf("Env.Decode(): wrong result. Want %v. Got %v.", tt.expectedOut, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetAuto(t *testing.T) {
|
||||
buf := bytes.NewBufferString("oi")
|
||||
var tests = []struct {
|
||||
input interface{}
|
||||
expected string
|
||||
}{
|
||||
{10, "10"},
|
||||
{10.3, "10"},
|
||||
{"oi", "oi"},
|
||||
{buf, "{}"},
|
||||
{unmarshable{}, "{}"},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
var env Env
|
||||
env.SetAuto("SOME", tt.input)
|
||||
if got := env.Get("SOME"); got != tt.expected {
|
||||
t.Errorf("Env.SetAuto(%v): wrong result. Want %q. Got %q", tt.input, tt.expected, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMap(t *testing.T) {
|
||||
var tests = []struct {
|
||||
input []string
|
||||
expected map[string]string
|
||||
}{
|
||||
{[]string{"PATH=/usr/bin:/bin", "PYTHONPATH=/usr/local"}, map[string]string{"PATH": "/usr/bin:/bin", "PYTHONPATH": "/usr/local"}},
|
||||
{nil, nil},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
env := Env(tt.input)
|
||||
got := env.Map()
|
||||
if !reflect.DeepEqual(got, tt.expected) {
|
||||
t.Errorf("Env.Map(): wrong result. Want %v. Got %v", tt.expected, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type unmarshable struct {
|
||||
}
|
||||
|
||||
func (unmarshable) MarshalJSON() ([]byte, error) {
|
||||
return nil, errors.New("cannot marshal")
|
||||
}
|
@ -53,7 +53,7 @@ func TestEventListeners(t *testing.T) {
|
||||
for {
|
||||
select {
|
||||
case msg := <-listener:
|
||||
t.Logf("Received: %s", *msg)
|
||||
t.Logf("Recieved: %s", *msg)
|
||||
count++
|
||||
err = checkEvent(count, msg)
|
||||
if err != nil {
|
||||
|
@ -21,9 +21,9 @@ func newTestClient(rt *FakeRoundTripper) Client {
|
||||
endpoint := "http://localhost:4243"
|
||||
u, _ := parseEndpoint("http://localhost:4243")
|
||||
client := Client{
|
||||
HTTPClient: &http.Client{Transport: rt},
|
||||
endpoint: endpoint,
|
||||
endpointURL: u,
|
||||
client: &http.Client{Transport: rt},
|
||||
SkipServerVersionCheck: true,
|
||||
}
|
||||
return client
|
||||
|
@ -6,39 +6,32 @@ package docker
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
|
||||
"github.com/fsouza/go-dockerclient/engine"
|
||||
)
|
||||
|
||||
// Version returns version information about the docker server.
|
||||
//
|
||||
// See http://goo.gl/IqKNRE for more details.
|
||||
func (c *Client) Version() (*engine.Env, error) {
|
||||
func (c *Client) Version() (*Env, error) {
|
||||
body, _, err := c.do("GET", "/version", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out := engine.NewOutput()
|
||||
remoteVersion, err := out.AddEnv()
|
||||
if err != nil {
|
||||
var env Env
|
||||
if err := env.Decode(bytes.NewReader(body)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, err := io.Copy(out, bytes.NewReader(body)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return remoteVersion, nil
|
||||
return &env, nil
|
||||
}
|
||||
|
||||
// Info returns system-wide information, like the number of running containers.
|
||||
//
|
||||
// See http://goo.gl/LOmySw for more details.
|
||||
func (c *Client) Info() (*engine.Env, error) {
|
||||
func (c *Client) Info() (*Env, error) {
|
||||
body, _, err := c.do("GET", "/info", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var info engine.Env
|
||||
var info Env
|
||||
err = info.Decode(bytes.NewReader(body))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -10,8 +10,6 @@ import (
|
||||
"reflect"
|
||||
"sort"
|
||||
"testing"
|
||||
|
||||
"github.com/fsouza/go-dockerclient/engine"
|
||||
)
|
||||
|
||||
type DockerVersion struct {
|
||||
@ -81,7 +79,7 @@ func TestInfo(t *testing.T) {
|
||||
}`
|
||||
fakeRT := FakeRoundTripper{message: body, status: http.StatusOK}
|
||||
client := newTestClient(&fakeRT)
|
||||
expected := engine.Env{}
|
||||
expected := Env{}
|
||||
expected.SetInt("Containers", 11)
|
||||
expected.SetInt("Images", 16)
|
||||
expected.SetBool("Debug", false)
|
||||
|
@ -170,6 +170,12 @@ func (s *DockerServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
}
|
||||
|
||||
// Returns default http.Handler mux, it allows customHandlers to call the
|
||||
// default behavior if wanted.
|
||||
func (s *DockerServer) DefaultHandler() http.Handler {
|
||||
return s.mux
|
||||
}
|
||||
|
||||
func (s *DockerServer) handlerWrapper(f func(http.ResponseWriter, *http.Request)) func(http.ResponseWriter, *http.Request) {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
for errorID, urlRegexp := range s.failures {
|
||||
@ -218,6 +224,11 @@ func (s *DockerServer) listImages(w http.ResponseWriter, r *http.Request) {
|
||||
ID: image.ID,
|
||||
Created: image.Created.Unix(),
|
||||
}
|
||||
for tag, id := range s.imgIDs {
|
||||
if id == image.ID {
|
||||
result[i].RepoTags = append(result[i].RepoTags, tag)
|
||||
}
|
||||
}
|
||||
}
|
||||
s.cMut.RUnlock()
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
@ -563,8 +574,9 @@ func (s *DockerServer) pushImage(w http.ResponseWriter, r *http.Request) {
|
||||
func (s *DockerServer) removeImage(w http.ResponseWriter, r *http.Request) {
|
||||
id := mux.Vars(r)["id"]
|
||||
s.iMut.RLock()
|
||||
var tag string
|
||||
if img, ok := s.imgIDs[id]; ok {
|
||||
id = img
|
||||
id, tag = img, id
|
||||
}
|
||||
s.iMut.RUnlock()
|
||||
_, index, err := s.findImageByID(id)
|
||||
@ -577,6 +589,9 @@ func (s *DockerServer) removeImage(w http.ResponseWriter, r *http.Request) {
|
||||
defer s.iMut.Unlock()
|
||||
s.images[index] = s.images[len(s.images)-1]
|
||||
s.images = s.images[:len(s.images)-1]
|
||||
if tag != "" {
|
||||
delete(s.imgIDs, tag)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *DockerServer) inspectImage(w http.ResponseWriter, r *http.Request) {
|
||||
|
@ -780,7 +780,7 @@ func addImages(server *DockerServer, n int, repo bool) {
|
||||
|
||||
func TestListImages(t *testing.T) {
|
||||
server := DockerServer{}
|
||||
addImages(&server, 2, false)
|
||||
addImages(&server, 2, true)
|
||||
server.buildMuxer()
|
||||
recorder := httptest.NewRecorder()
|
||||
request, _ := http.NewRequest("GET", "/images/json?all=1", nil)
|
||||
@ -791,8 +791,9 @@ func TestListImages(t *testing.T) {
|
||||
expected := make([]docker.APIImages, 2)
|
||||
for i, image := range server.images {
|
||||
expected[i] = docker.APIImages{
|
||||
ID: image.ID,
|
||||
Created: image.Created.Unix(),
|
||||
ID: image.ID,
|
||||
Created: image.Created.Unix(),
|
||||
RepoTags: []string{"docker/python-" + image.ID},
|
||||
}
|
||||
}
|
||||
var got []docker.APIImages
|
||||
@ -826,7 +827,8 @@ func TestRemoveImageByName(t *testing.T) {
|
||||
addImages(&server, 1, true)
|
||||
server.buildMuxer()
|
||||
recorder := httptest.NewRecorder()
|
||||
path := "/images/docker/python-" + server.images[0].ID
|
||||
imgName := "docker/python-" + server.images[0].ID
|
||||
path := "/images/" + imgName
|
||||
request, _ := http.NewRequest("DELETE", path, nil)
|
||||
server.ServeHTTP(recorder, request)
|
||||
if recorder.Code != http.StatusNoContent {
|
||||
@ -835,6 +837,10 @@ func TestRemoveImageByName(t *testing.T) {
|
||||
if len(server.images) > 0 {
|
||||
t.Error("RemoveImage: did not remove the image.")
|
||||
}
|
||||
_, ok := server.imgIDs[imgName]
|
||||
if ok {
|
||||
t.Error("RemoveImage: did not remove image tag name.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestPrepareFailure(t *testing.T) {
|
||||
@ -945,3 +951,14 @@ func TestPing(t *testing.T) {
|
||||
t.Errorf("Ping: Expected code %d, got: %d", http.StatusOK, recorder.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDefaultHandler(t *testing.T) {
|
||||
server, err := NewServer("127.0.0.1:0", nil, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer server.listener.Close()
|
||||
if server.mux != server.DefaultHandler() {
|
||||
t.Fatalf("DefaultHandler: Expected to return server.mux, got: %#v", server.DefaultHandler())
|
||||
}
|
||||
}
|
||||
|
@ -109,7 +109,6 @@ func StdCopy(dstout, dsterr io.Writer, src io.Reader) (written int64, err error)
|
||||
// Write on stderr
|
||||
out = dsterr
|
||||
default:
|
||||
Debugf("Error selecting output fd: (%d)", buf[StdWriterFdIndex])
|
||||
return 0, ErrInvalidStdHeader
|
||||
}
|
||||
|
||||
@ -119,7 +118,6 @@ func StdCopy(dstout, dsterr io.Writer, src io.Reader) (written int64, err error)
|
||||
// Check if the buffer is big enough to read the frame.
|
||||
// Extend it if necessary.
|
||||
if frameSize+StdWriterPrefixLen > bufLen {
|
||||
Debugf("Extending buffer cap.")
|
||||
buf = append(buf, make([]byte, frameSize+StdWriterPrefixLen-len(buf)+1)...)
|
||||
bufLen = len(buf)
|
||||
}
|
||||
@ -135,7 +133,6 @@ func StdCopy(dstout, dsterr io.Writer, src io.Reader) (written int64, err error)
|
||||
nr += nr2
|
||||
break
|
||||
} else if er != nil {
|
||||
Debugf("Error reading frame: %s", er)
|
||||
return 0, er
|
||||
}
|
||||
nr += nr2
|
||||
@ -151,12 +148,10 @@ func StdCopy(dstout, dsterr io.Writer, src io.Reader) (written int64, err error)
|
||||
written += int64(nw)
|
||||
}
|
||||
if ew != nil {
|
||||
Debugf("Error writing frame: %s", ew)
|
||||
return 0, ew
|
||||
}
|
||||
// If the frame has not been fully written: error
|
||||
if nw != frameSize {
|
||||
Debugf("Error Short Write: (%d on %d)", nw, frameSize)
|
||||
return written, io.ErrShortWrite
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user