Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
ea4224cb
Commit
ea4224cb
authored
Jul 23, 2014
by
Nan Deng
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
update github.com/fsouza/go-dockerclient
parent
7a8e268c
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
769 additions
and
95 deletions
+769
-95
kubelet.go
pkg/kubelet/kubelet.go
+1
-1
.travis.yml
...d_party/src/github.com/fsouza/go-dockerclient/.travis.yml
+1
-0
AUTHORS
third_party/src/github.com/fsouza/go-dockerclient/AUTHORS
+2
-0
README.markdown
...rty/src/github.com/fsouza/go-dockerclient/README.markdown
+0
-6
client.go
third_party/src/github.com/fsouza/go-dockerclient/client.go
+38
-14
client_test.go
...arty/src/github.com/fsouza/go-dockerclient/client_test.go
+54
-0
container.go
..._party/src/github.com/fsouza/go-dockerclient/container.go
+45
-11
container_test.go
...y/src/github.com/fsouza/go-dockerclient/container_test.go
+264
-3
image.go
third_party/src/github.com/fsouza/go-dockerclient/image.go
+9
-5
server.go
...y/src/github.com/fsouza/go-dockerclient/testing/server.go
+119
-46
server_test.go
.../github.com/fsouza/go-dockerclient/testing/server_test.go
+0
-0
stdcopy.go
...ty/src/github.com/fsouza/go-dockerclient/utils/stdcopy.go
+19
-9
stdcopy_test.go
...c/github.com/fsouza/go-dockerclient/utils/stdcopy_test.go
+217
-0
No files found.
pkg/kubelet/kubelet.go
View file @
ea4224cb
...
...
@@ -239,7 +239,7 @@ func (kl *Kubelet) runContainer(pod *Pod, container *api.Container, podVolumes v
ExposedPorts
:
exposedPorts
,
Hostname
:
container
.
Name
,
Image
:
container
.
Image
,
Memory
:
int64
(
container
.
Memory
),
Memory
:
u
int64
(
container
.
Memory
),
CpuShares
:
int64
(
milliCPUToShares
(
container
.
CPU
)),
Volumes
:
volumes
,
WorkingDir
:
container
.
WorkingDir
,
...
...
third_party/src/github.com/fsouza/go-dockerclient/.travis.yml
View file @
ea4224cb
...
...
@@ -2,6 +2,7 @@ language: go
go
:
-
1.1.2
-
1.2
-
1.3
-
tip
env
:
-
GOARCH=amd64
...
...
third_party/src/github.com/fsouza/go-dockerclient/AUTHORS
View file @
ea4224cb
...
...
@@ -10,6 +10,7 @@ Ed <edrocksit@gmail.com>
Eric Anderson <anderson@copperegg.com>
Flavia Missi <flaviamissi@gmail.com>
Francisco Souza <f@souza.cc>
Jari Kolehmainen <jari.kolehmainen@digia.com>
Jason Wilder <jwilder@litl.com>
Jean-Baptiste Dalido <jeanbaptiste@appgratis.com>
Jeff Mitchell <jeffrey.mitchell@gmail.com>
...
...
@@ -19,6 +20,7 @@ Omeid Matten <public@omeid.me>
Paul Morie <pmorie@gmail.com>
Peter Jihoon Kim <raingrove@gmail.com>
Philippe Lafoucrière <philippe.lafoucriere@tech-angels.com>
Rafe Colton <r.colton@modcloth.com>
Salvador Gironès <salvadorgirones@gmail.com>
Simon Eskildsen <sirup@sirupsen.com>
Simon Menke <simon.menke@gmail.com>
...
...
third_party/src/github.com/fsouza/go-dockerclient/README.markdown
View file @
ea4224cb
...
...
@@ -9,12 +9,6 @@ This package presents a client for the Docker remote API.
For more details, check the
[
remote API documentation
](
http://docs.docker.io/en/latest/reference/api/docker_remote_api/
)
.
##Versioning
*
Version 0.1 is compatible with Docker v0.7.1
*
The master is compatible with Docker's master
## Example
package main
...
...
third_party/src/github.com/fsouza/go-dockerclient/client.go
View file @
ea4224cb
...
...
@@ -47,20 +47,17 @@ type ApiVersion []int
// <minor> and <patch> are integer numbers.
func
NewApiVersion
(
input
string
)
(
ApiVersion
,
error
)
{
if
!
strings
.
Contains
(
input
,
"."
)
{
return
nil
,
fmt
.
Errorf
(
"Unable to parse version
'%s'
"
,
input
)
return
nil
,
fmt
.
Errorf
(
"Unable to parse version
%q
"
,
input
)
}
arr
:=
strings
.
Split
(
input
,
"."
)
ret
:=
make
(
ApiVersion
,
len
(
arr
))
var
err
error
for
i
,
val
:=
range
arr
{
ret
[
i
],
err
=
strconv
.
Atoi
(
val
)
if
err
!=
nil
{
return
nil
,
err
return
nil
,
fmt
.
Errorf
(
"Unable to parse version %q: %q is not an integer"
,
input
,
val
)
}
}
return
ret
,
nil
}
...
...
@@ -203,6 +200,21 @@ func parseApiVersionString(input string) (version uint16, err error) {
return
version
,
nil
}
// Ping pings the docker server
//
// See http://goo.gl/stJENm for more details.
func
(
c
*
Client
)
Ping
()
error
{
path
:=
"/_ping"
body
,
status
,
err
:=
c
.
do
(
"GET"
,
path
,
nil
)
if
err
!=
nil
{
return
err
}
if
status
!=
http
.
StatusOK
{
return
newError
(
status
,
body
)
}
return
nil
}
func
(
c
*
Client
)
getServerApiVersionString
()
(
version
string
,
err
error
)
{
body
,
status
,
err
:=
c
.
do
(
"GET"
,
"/version"
,
nil
)
if
err
!=
nil
{
...
...
@@ -257,6 +269,7 @@ func (c *Client) do(method, path string, data interface{}) ([]byte, int, error)
if
err
!=
nil
{
return
nil
,
-
1
,
err
}
defer
dial
.
Close
()
clientconn
:=
httputil
.
NewClientConn
(
dial
,
nil
)
resp
,
err
=
clientconn
.
Do
(
req
)
if
err
!=
nil
{
...
...
@@ -283,11 +296,10 @@ func (c *Client) do(method, path string, data interface{}) ([]byte, int, error)
return
body
,
resp
.
StatusCode
,
nil
}
func
(
c
*
Client
)
stream
(
method
,
path
string
,
headers
map
[
string
]
string
,
in
io
.
Reader
,
out
io
.
Writer
)
error
{
func
(
c
*
Client
)
stream
(
method
,
path
string
,
setRawTerminal
bool
,
headers
map
[
string
]
string
,
in
io
.
Reader
,
stdout
,
stderr
io
.
Writer
)
error
{
if
(
method
==
"POST"
||
method
==
"PUT"
)
&&
in
==
nil
{
in
=
bytes
.
NewReader
(
nil
)
}
if
path
!=
"/version"
&&
!
c
.
SkipServerVersionCheck
&&
c
.
expectedApiVersion
==
nil
{
err
:=
c
.
checkApiVersion
()
if
err
!=
nil
{
...
...
@@ -308,8 +320,11 @@ func (c *Client) stream(method, path string, headers map[string]string, in io.Re
var
resp
*
http
.
Response
protocol
:=
c
.
endpointURL
.
Scheme
address
:=
c
.
endpointURL
.
Path
if
out
==
nil
{
out
=
ioutil
.
Discard
if
stdout
==
nil
{
stdout
=
ioutil
.
Discard
}
if
stderr
==
nil
{
stderr
=
ioutil
.
Discard
}
if
protocol
==
"unix"
{
dial
,
err
:=
net
.
Dial
(
protocol
,
address
)
...
...
@@ -346,20 +361,23 @@ func (c *Client) stream(method, path string, headers map[string]string, in io.Re
return
err
}
if
m
.
Stream
!=
""
{
fmt
.
Fprint
(
out
,
m
.
Stream
)
fmt
.
Fprint
(
std
out
,
m
.
Stream
)
}
else
if
m
.
Progress
!=
""
{
fmt
.
Fprintf
(
out
,
"%s %s
\r
"
,
m
.
Status
,
m
.
Progress
)
fmt
.
Fprintf
(
std
out
,
"%s %s
\r
"
,
m
.
Status
,
m
.
Progress
)
}
else
if
m
.
Error
!=
""
{
return
errors
.
New
(
m
.
Error
)
}
if
m
.
Status
!=
""
{
fmt
.
Fprintln
(
out
,
m
.
Status
)
fmt
.
Fprintln
(
std
out
,
m
.
Status
)
}
}
}
else
{
if
_
,
err
:=
io
.
Copy
(
out
,
resp
.
Body
);
err
!=
nil
{
return
err
if
setRawTerminal
{
_
,
err
=
io
.
Copy
(
stdout
,
resp
.
Body
)
}
else
{
_
,
err
=
utils
.
StdCopy
(
stdout
,
stderr
,
resp
.
Body
)
}
return
err
}
return
nil
}
...
...
@@ -371,6 +389,12 @@ func (c *Client) hijack(method, path string, success chan struct{}, setRawTermin
return
err
}
}
if
stdout
==
nil
{
stdout
=
ioutil
.
Discard
}
if
stderr
==
nil
{
stderr
=
ioutil
.
Discard
}
req
,
err
:=
http
.
NewRequest
(
method
,
c
.
getURL
(
path
),
nil
)
if
err
!=
nil
{
return
err
...
...
third_party/src/github.com/fsouza/go-dockerclient/client_test.go
View file @
ea4224cb
...
...
@@ -148,6 +148,25 @@ func TestQueryString(t *testing.T) {
}
}
func
TestNewApiVersionFailures
(
t
*
testing
.
T
)
{
var
tests
=
[]
struct
{
input
string
expectedError
string
}{
{
"1-0"
,
`Unable to parse version "1-0"`
},
{
"1.0-beta"
,
`Unable to parse version "1.0-beta": "0-beta" is not an integer`
},
}
for
_
,
tt
:=
range
tests
{
v
,
err
:=
NewApiVersion
(
tt
.
input
)
if
v
!=
nil
{
t
.
Errorf
(
"Expected <nil> version, got %v."
,
v
)
}
if
err
.
Error
()
!=
tt
.
expectedError
{
t
.
Errorf
(
"NewApiVersion(%q): wrong error. Want %q. Got %q"
,
tt
.
input
,
tt
.
expectedError
,
err
.
Error
())
}
}
}
func
TestApiVersions
(
t
*
testing
.
T
)
{
var
tests
=
[]
struct
{
a
string
...
...
@@ -192,6 +211,41 @@ func TestApiVersions(t *testing.T) {
}
}
func
TestPing
(
t
*
testing
.
T
)
{
fakeRT
:=
&
FakeRoundTripper
{
message
:
""
,
status
:
http
.
StatusOK
}
client
:=
newTestClient
(
fakeRT
)
err
:=
client
.
Ping
()
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
}
func
TestPingFailing
(
t
*
testing
.
T
)
{
fakeRT
:=
&
FakeRoundTripper
{
message
:
""
,
status
:
http
.
StatusInternalServerError
}
client
:=
newTestClient
(
fakeRT
)
err
:=
client
.
Ping
()
if
err
==
nil
{
t
.
Fatal
(
"Expected non nil error, got nil"
)
}
expectedErrMsg
:=
"API error (500): "
if
err
.
Error
()
!=
expectedErrMsg
{
t
.
Fatalf
(
"Expected error to be %q, got: %q"
,
expectedErrMsg
,
err
.
Error
())
}
}
func
TestPingFailingWrongStatus
(
t
*
testing
.
T
)
{
fakeRT
:=
&
FakeRoundTripper
{
message
:
""
,
status
:
http
.
StatusAccepted
}
client
:=
newTestClient
(
fakeRT
)
err
:=
client
.
Ping
()
if
err
==
nil
{
t
.
Fatal
(
"Expected non nil error, got nil"
)
}
expectedErrMsg
:=
"API error (202): "
if
err
.
Error
()
!=
expectedErrMsg
{
t
.
Fatalf
(
"Expected error to be %q, got: %q"
,
expectedErrMsg
,
err
.
Error
())
}
}
type
FakeRoundTripper
struct
{
message
string
status
int
...
...
third_party/src/github.com/fsouza/go-dockerclient/container.go
View file @
ea4224cb
...
...
@@ -13,7 +13,6 @@ import (
"net/url"
"strconv"
"strings"
"sync"
"time"
)
...
...
@@ -87,22 +86,19 @@ func (p Port) Proto() string {
// State represents the state of a container.
type
State
struct
{
sync
.
RWMutex
Running
bool
Paused
bool
Pid
int
ExitCode
int
StartedAt
time
.
Time
FinishedAt
time
.
Time
Ghost
bool
}
// String returns the string representation of a state.
func
(
s
*
State
)
String
()
string
{
s
.
RLock
()
defer
s
.
RUnlock
()
if
s
.
Running
{
if
s
.
Ghost
{
return
"
Ghost
"
if
s
.
Paused
{
return
"
paused
"
}
return
fmt
.
Sprintf
(
"Up %s"
,
time
.
Now
()
.
UTC
()
.
Sub
(
s
.
StartedAt
))
}
...
...
@@ -162,8 +158,8 @@ type Config struct {
Hostname
string
Domainname
string
User
string
Memory
int64
MemorySwap
int64
Memory
u
int64
MemorySwap
u
int64
CpuShares
int64
AttachStdin
bool
AttachStdout
bool
...
...
@@ -351,6 +347,36 @@ func (c *Client) RestartContainer(id string, timeout uint) error {
return
nil
}
// PauseContainer pauses the given container.
//
// See http://goo.gl/AM5t42 for more details.
func
(
c
*
Client
)
PauseContainer
(
id
string
)
error
{
path
:=
fmt
.
Sprintf
(
"/containers/%s/pause"
,
id
)
_
,
status
,
err
:=
c
.
do
(
"POST"
,
path
,
nil
)
if
status
==
http
.
StatusNotFound
{
return
&
NoSuchContainer
{
ID
:
id
}
}
if
err
!=
nil
{
return
err
}
return
nil
}
// UnpauseContainer pauses the given container.
//
// See http://goo.gl/eBrNSL for more details.
func
(
c
*
Client
)
UnpauseContainer
(
id
string
)
error
{
path
:=
fmt
.
Sprintf
(
"/containers/%s/unpause"
,
id
)
_
,
status
,
err
:=
c
.
do
(
"POST"
,
path
,
nil
)
if
status
==
http
.
StatusNotFound
{
return
&
NoSuchContainer
{
ID
:
id
}
}
if
err
!=
nil
{
return
err
}
return
nil
}
// KillContainerOptions represents the set of options that can be used in a
// call to KillContainer.
type
KillContainerOptions
struct
{
...
...
@@ -542,10 +568,15 @@ func (c *Client) AttachToContainer(opts AttachToContainerOptions) error {
type
LogsOptions
struct
{
Container
string
`qs:"-"`
OutputStream
io
.
Writer
`qs:"-"`
ErrorStream
io
.
Writer
`qs:"-"`
Follow
bool
Stdout
bool
Stderr
bool
Timestamps
bool
Tail
string
// Use raw terminal? Usually true when the container contains a TTY.
RawTerminal
bool
`qs:"-"`
}
// Logs gets stdout and stderr logs from the specified container.
...
...
@@ -555,8 +586,11 @@ func (c *Client) Logs(opts LogsOptions) error {
if
opts
.
Container
==
""
{
return
&
NoSuchContainer
{
ID
:
opts
.
Container
}
}
if
opts
.
Tail
==
""
{
opts
.
Tail
=
"all"
}
path
:=
"/containers/"
+
opts
.
Container
+
"/logs?"
+
queryString
(
opts
)
return
c
.
stream
(
"GET"
,
path
,
nil
,
nil
,
opts
.
Output
Stream
)
return
c
.
stream
(
"GET"
,
path
,
opts
.
RawTerminal
,
nil
,
nil
,
opts
.
OutputStream
,
opts
.
Error
Stream
)
}
// ResizeContainerTTY resizes the terminal to the given height and width.
...
...
@@ -586,7 +620,7 @@ func (c *Client) ExportContainer(opts ExportContainerOptions) error {
return
NoSuchContainer
{
ID
:
opts
.
ID
}
}
url
:=
fmt
.
Sprintf
(
"/containers/%s/export"
,
opts
.
ID
)
return
c
.
stream
(
"GET"
,
url
,
nil
,
nil
,
opts
.
OutputStream
)
return
c
.
stream
(
"GET"
,
url
,
true
,
nil
,
nil
,
opts
.
OutputStream
,
nil
)
}
// NoSuchContainer is the error returned when a given container does not exist.
...
...
third_party/src/github.com/fsouza/go-dockerclient/container_test.go
View file @
ea4224cb
...
...
@@ -14,12 +14,32 @@ import (
"net/url"
"os"
"reflect"
"regexp"
"runtime"
"strconv"
"strings"
"testing"
"time"
)
func
TestStateString
(
t
*
testing
.
T
)
{
started
:=
time
.
Now
()
.
Add
(
-
3
*
time
.
Hour
)
var
tests
=
[]
struct
{
input
State
expected
string
}{
{
State
{
Running
:
true
,
Paused
:
true
},
"^paused$"
},
{
State
{
Running
:
true
,
StartedAt
:
started
},
"^Up 3h.*$"
},
{
State
{
Running
:
false
,
ExitCode
:
7
},
"^Exit 7$"
},
}
for
_
,
tt
:=
range
tests
{
re
:=
regexp
.
MustCompile
(
tt
.
expected
)
if
got
:=
tt
.
input
.
String
();
!
re
.
MatchString
(
got
)
{
t
.
Errorf
(
"State.String(): wrong result. Want %q. Got %q."
,
tt
.
expected
,
got
)
}
}
}
func
TestListContainers
(
t
*
testing
.
T
)
{
jsonContainers
:=
`[
{
...
...
@@ -132,8 +152,8 @@ func TestInspectContainer(t *testing.T) {
"Config": {
"Hostname": "4fa6e0f0c678",
"User": "",
"Memory":
0
,
"MemorySwap":
0
,
"Memory":
17179869184
,
"MemorySwap":
34359738368
,
"AttachStdin": false,
"AttachStdout": true,
"AttachStderr": true,
...
...
@@ -445,6 +465,60 @@ func TestRestartContainerNotFound(t *testing.T) {
}
}
func
TestPauseContainer
(
t
*
testing
.
T
)
{
fakeRT
:=
&
FakeRoundTripper
{
message
:
""
,
status
:
http
.
StatusNoContent
}
client
:=
newTestClient
(
fakeRT
)
id
:=
"4fa6e0f0c6786287e131c3852c58a2e01cc697a68231826813597e4994f1d6e2"
err
:=
client
.
PauseContainer
(
id
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
req
:=
fakeRT
.
requests
[
0
]
if
req
.
Method
!=
"POST"
{
t
.
Errorf
(
"PauseContainer(%q): wrong HTTP method. Want %q. Got %q."
,
id
,
"POST"
,
req
.
Method
)
}
expectedURL
,
_
:=
url
.
Parse
(
client
.
getURL
(
"/containers/"
+
id
+
"/pause"
))
if
gotPath
:=
req
.
URL
.
Path
;
gotPath
!=
expectedURL
.
Path
{
t
.
Errorf
(
"PauseContainer(%q): Wrong path in request. Want %q. Got %q."
,
id
,
expectedURL
.
Path
,
gotPath
)
}
}
func
TestPauseContainerNotFound
(
t
*
testing
.
T
)
{
client
:=
newTestClient
(
&
FakeRoundTripper
{
message
:
"no such container"
,
status
:
http
.
StatusNotFound
})
err
:=
client
.
PauseContainer
(
"a2334"
)
expected
:=
&
NoSuchContainer
{
ID
:
"a2334"
}
if
!
reflect
.
DeepEqual
(
err
,
expected
)
{
t
.
Errorf
(
"PauseContainer: Wrong error returned. Want %#v. Got %#v."
,
expected
,
err
)
}
}
func
TestUnpauseContainer
(
t
*
testing
.
T
)
{
fakeRT
:=
&
FakeRoundTripper
{
message
:
""
,
status
:
http
.
StatusNoContent
}
client
:=
newTestClient
(
fakeRT
)
id
:=
"4fa6e0f0c6786287e131c3852c58a2e01cc697a68231826813597e4994f1d6e2"
err
:=
client
.
UnpauseContainer
(
id
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
req
:=
fakeRT
.
requests
[
0
]
if
req
.
Method
!=
"POST"
{
t
.
Errorf
(
"PauseContainer(%q): wrong HTTP method. Want %q. Got %q."
,
id
,
"POST"
,
req
.
Method
)
}
expectedURL
,
_
:=
url
.
Parse
(
client
.
getURL
(
"/containers/"
+
id
+
"/unpause"
))
if
gotPath
:=
req
.
URL
.
Path
;
gotPath
!=
expectedURL
.
Path
{
t
.
Errorf
(
"PauseContainer(%q): Wrong path in request. Want %q. Got %q."
,
id
,
expectedURL
.
Path
,
gotPath
)
}
}
func
TestUnpauseContainerNotFound
(
t
*
testing
.
T
)
{
client
:=
newTestClient
(
&
FakeRoundTripper
{
message
:
"no such container"
,
status
:
http
.
StatusNotFound
})
err
:=
client
.
UnpauseContainer
(
"a2334"
)
expected
:=
&
NoSuchContainer
{
ID
:
"a2334"
}
if
!
reflect
.
DeepEqual
(
err
,
expected
)
{
t
.
Errorf
(
"PauseContainer: Wrong error returned. Want %#v. Got %#v."
,
expected
,
err
)
}
}
func
TestKillContainer
(
t
*
testing
.
T
)
{
fakeRT
:=
&
FakeRoundTripper
{
message
:
""
,
status
:
http
.
StatusNoContent
}
client
:=
newTestClient
(
fakeRT
)
...
...
@@ -736,7 +810,7 @@ func TestAttachToContainer(t *testing.T) {
Stream
:
true
,
RawTerminal
:
true
,
}
var
err
=
client
.
AttachToContainer
(
opts
)
err
:
=
client
.
AttachToContainer
(
opts
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
...
...
@@ -781,6 +855,63 @@ func TestAttachToContainerSentinel(t *testing.T) {
success
<-
<-
success
}
func
TestAttachToContainerNilStdout
(
t
*
testing
.
T
)
{
var
reader
=
strings
.
NewReader
(
"send value"
)
var
req
http
.
Request
server
:=
httptest
.
NewServer
(
http
.
HandlerFunc
(
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
w
.
Write
([]
byte
{
1
,
0
,
0
,
0
,
0
,
0
,
0
,
5
})
w
.
Write
([]
byte
(
"hello"
))
req
=
*
r
}))
defer
server
.
Close
()
client
,
_
:=
NewClient
(
server
.
URL
)
client
.
SkipServerVersionCheck
=
true
var
stderr
bytes
.
Buffer
opts
:=
AttachToContainerOptions
{
Container
:
"a123456"
,
OutputStream
:
nil
,
ErrorStream
:
&
stderr
,
InputStream
:
reader
,
Stdin
:
true
,
Stdout
:
true
,
Stderr
:
true
,
Stream
:
true
,
RawTerminal
:
true
,
}
err
:=
client
.
AttachToContainer
(
opts
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
}
func
TestAttachToContainerNilStderr
(
t
*
testing
.
T
)
{
var
reader
=
strings
.
NewReader
(
"send value"
)
var
req
http
.
Request
server
:=
httptest
.
NewServer
(
http
.
HandlerFunc
(
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
w
.
Write
([]
byte
{
1
,
0
,
0
,
0
,
0
,
0
,
0
,
5
})
w
.
Write
([]
byte
(
"hello"
))
req
=
*
r
}))
defer
server
.
Close
()
client
,
_
:=
NewClient
(
server
.
URL
)
client
.
SkipServerVersionCheck
=
true
var
stdout
bytes
.
Buffer
opts
:=
AttachToContainerOptions
{
Container
:
"a123456"
,
OutputStream
:
&
stdout
,
InputStream
:
reader
,
Stdin
:
true
,
Stdout
:
true
,
Stderr
:
true
,
Stream
:
true
,
RawTerminal
:
true
,
}
err
:=
client
.
AttachToContainer
(
opts
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
}
func
TestAttachToContainerRawTerminalFalse
(
t
*
testing
.
T
)
{
input
:=
strings
.
NewReader
(
"send value"
)
var
req
http
.
Request
...
...
@@ -838,6 +969,8 @@ func TestAttachToContainerWithoutContainer(t *testing.T) {
func
TestLogs
(
t
*
testing
.
T
)
{
var
req
http
.
Request
server
:=
httptest
.
NewServer
(
http
.
HandlerFunc
(
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
prefix
:=
[]
byte
{
1
,
0
,
0
,
0
,
0
,
0
,
0
,
19
}
w
.
Write
(
prefix
)
w
.
Write
([]
byte
(
"something happened!"
))
req
=
*
r
}))
...
...
@@ -873,6 +1006,7 @@ func TestLogs(t *testing.T) {
"stdout"
:
{
"1"
},
"stderr"
:
{
"1"
},
"timestamps"
:
{
"1"
},
"tail"
:
{
"all"
},
}
got
:=
map
[
string
][]
string
(
req
.
URL
.
Query
())
if
!
reflect
.
DeepEqual
(
got
,
expectedQs
)
{
...
...
@@ -880,6 +1014,133 @@ func TestLogs(t *testing.T) {
}
}
func
TestLogsNilStdoutDoesntFail
(
t
*
testing
.
T
)
{
var
req
http
.
Request
server
:=
httptest
.
NewServer
(
http
.
HandlerFunc
(
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
prefix
:=
[]
byte
{
1
,
0
,
0
,
0
,
0
,
0
,
0
,
19
}
w
.
Write
(
prefix
)
w
.
Write
([]
byte
(
"something happened!"
))
req
=
*
r
}))
defer
server
.
Close
()
client
,
_
:=
NewClient
(
server
.
URL
)
client
.
SkipServerVersionCheck
=
true
opts
:=
LogsOptions
{
Container
:
"a123456"
,
Follow
:
true
,
Stdout
:
true
,
Stderr
:
true
,
Timestamps
:
true
,
}
err
:=
client
.
Logs
(
opts
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
}
func
TestLogsNilStderrDoesntFail
(
t
*
testing
.
T
)
{
var
req
http
.
Request
server
:=
httptest
.
NewServer
(
http
.
HandlerFunc
(
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
prefix
:=
[]
byte
{
2
,
0
,
0
,
0
,
0
,
0
,
0
,
19
}
w
.
Write
(
prefix
)
w
.
Write
([]
byte
(
"something happened!"
))
req
=
*
r
}))
defer
server
.
Close
()
client
,
_
:=
NewClient
(
server
.
URL
)
client
.
SkipServerVersionCheck
=
true
opts
:=
LogsOptions
{
Container
:
"a123456"
,
Follow
:
true
,
Stdout
:
true
,
Stderr
:
true
,
Timestamps
:
true
,
}
err
:=
client
.
Logs
(
opts
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
}
func
TestLogsSpecifyingTail
(
t
*
testing
.
T
)
{
var
req
http
.
Request
server
:=
httptest
.
NewServer
(
http
.
HandlerFunc
(
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
prefix
:=
[]
byte
{
1
,
0
,
0
,
0
,
0
,
0
,
0
,
19
}
w
.
Write
(
prefix
)
w
.
Write
([]
byte
(
"something happened!"
))
req
=
*
r
}))
defer
server
.
Close
()
client
,
_
:=
NewClient
(
server
.
URL
)
client
.
SkipServerVersionCheck
=
true
var
buf
bytes
.
Buffer
opts
:=
LogsOptions
{
Container
:
"a123456"
,
OutputStream
:
&
buf
,
Follow
:
true
,
Stdout
:
true
,
Stderr
:
true
,
Timestamps
:
true
,
Tail
:
"100"
,
}
err
:=
client
.
Logs
(
opts
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
expected
:=
"something happened!"
if
buf
.
String
()
!=
expected
{
t
.
Errorf
(
"Logs: wrong output. Want %q. Got %q."
,
expected
,
buf
.
String
())
}
if
req
.
Method
!=
"GET"
{
t
.
Errorf
(
"Logs: wrong HTTP method. Want GET. Got %s."
,
req
.
Method
)
}
u
,
_
:=
url
.
Parse
(
client
.
getURL
(
"/containers/a123456/logs"
))
if
req
.
URL
.
Path
!=
u
.
Path
{
t
.
Errorf
(
"AttachToContainer for logs: wrong HTTP path. Want %q. Got %q."
,
u
.
Path
,
req
.
URL
.
Path
)
}
expectedQs
:=
map
[
string
][]
string
{
"follow"
:
{
"1"
},
"stdout"
:
{
"1"
},
"stderr"
:
{
"1"
},
"timestamps"
:
{
"1"
},
"tail"
:
{
"100"
},
}
got
:=
map
[
string
][]
string
(
req
.
URL
.
Query
())
if
!
reflect
.
DeepEqual
(
got
,
expectedQs
)
{
t
.
Errorf
(
"Logs: wrong query string. Want %#v. Got %#v."
,
expectedQs
,
got
)
}
}
func
TestLogsRawTerminal
(
t
*
testing
.
T
)
{
var
req
http
.
Request
server
:=
httptest
.
NewServer
(
http
.
HandlerFunc
(
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
w
.
Write
([]
byte
(
"something happened!"
))
req
=
*
r
}))
defer
server
.
Close
()
client
,
_
:=
NewClient
(
server
.
URL
)
client
.
SkipServerVersionCheck
=
true
var
buf
bytes
.
Buffer
opts
:=
LogsOptions
{
Container
:
"a123456"
,
OutputStream
:
&
buf
,
Follow
:
true
,
RawTerminal
:
true
,
Stdout
:
true
,
Stderr
:
true
,
Timestamps
:
true
,
Tail
:
"100"
,
}
err
:=
client
.
Logs
(
opts
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
expected
:=
"something happened!"
if
buf
.
String
()
!=
expected
{
t
.
Errorf
(
"Logs: wrong output. Want %q. Got %q."
,
expected
,
buf
.
String
())
}
}
func
TestLogsNoContainer
(
t
*
testing
.
T
)
{
var
client
Client
err
:=
client
.
Logs
(
LogsOptions
{})
...
...
third_party/src/github.com/fsouza/go-dockerclient/image.go
View file @
ea4224cb
...
...
@@ -154,6 +154,9 @@ type PushImageOptions struct {
// Name of the image
Name
string
// Tag of the image
Tag
string
// Registry server to push the image
Registry
string
...
...
@@ -187,7 +190,7 @@ func (c *Client) PushImage(opts PushImageOptions, auth AuthConfiguration) error
headers
[
"X-Registry-Auth"
]
=
base64
.
URLEncoding
.
EncodeToString
(
buf
.
Bytes
())
return
c
.
stream
(
"POST"
,
path
,
headers
,
nil
,
opts
.
OutputStream
)
return
c
.
stream
(
"POST"
,
path
,
true
,
headers
,
nil
,
opts
.
OutputStream
,
nil
)
}
// PullImageOptions present the set of options available for pulling an image
...
...
@@ -219,7 +222,7 @@ func (c *Client) PullImage(opts PullImageOptions, auth AuthConfiguration) error
func
(
c
*
Client
)
createImage
(
qs
string
,
headers
map
[
string
]
string
,
in
io
.
Reader
,
w
io
.
Writer
)
error
{
path
:=
"/images/create?"
+
qs
return
c
.
stream
(
"POST"
,
path
,
headers
,
in
,
w
)
return
c
.
stream
(
"POST"
,
path
,
true
,
headers
,
in
,
w
,
nil
)
}
// ImportImageOptions present the set of informations available for importing
...
...
@@ -286,13 +289,14 @@ func (c *Client) BuildImage(opts BuildImageOptions) error {
return
ErrMissingRepo
}
return
c
.
stream
(
"POST"
,
fmt
.
Sprintf
(
"/build?%s"
,
queryString
(
&
opts
)),
headers
,
opts
.
InputStream
,
opts
.
OutputStream
)
queryString
(
&
opts
)),
true
,
headers
,
opts
.
InputStream
,
opts
.
OutputStream
,
nil
)
}
// TagImageOptions present the set of options to tag an image
type
TagImageOptions
struct
{
Repo
string
`qs:"repo"`
Force
bool
`qs:"force"`
Repo
string
Tag
string
Force
bool
}
// TagImage adds a tag to the image 'name'
...
...
third_party/src/github.com/fsouza/go-dockerclient/testing/server.go
View file @
ea4224cb
...
...
@@ -18,7 +18,6 @@ import (
mathrand
"math/rand"
"net"
"net/http"
"reflect"
"regexp"
"strconv"
"strings"
...
...
@@ -34,43 +33,55 @@ import (
//
// For more details on the remote API, check http://goo.gl/yMI1S.
type
DockerServer
struct
{
containers
[]
*
docker
.
Container
cMut
sync
.
RWMutex
images
[]
docker
.
Image
iMut
sync
.
RWMutex
imgIDs
map
[
string
]
string
listener
net
.
Listener
mux
*
mux
.
Router
hook
func
(
*
http
.
Request
)
failures
map
[
string
]
FailureSpec
}
// FailureSpec is used with PrepareFailure and describes in which situations
// the request should fail. UrlRegex is mandatory, if a container id is sent
// on the request you can also specify the other properties.
type
FailureSpec
struct
{
UrlRegex
string
ContainerPath
string
ContainerArgs
[]
string
containers
[]
*
docker
.
Container
cMut
sync
.
RWMutex
images
[]
docker
.
Image
iMut
sync
.
RWMutex
imgIDs
map
[
string
]
string
listener
net
.
Listener
mux
*
mux
.
Router
hook
func
(
*
http
.
Request
)
failures
map
[
string
]
string
customHandlers
map
[
string
]
http
.
Handler
handlerMutex
sync
.
RWMutex
cChan
chan
<-
*
docker
.
Container
}
// NewServer returns a new instance of the fake server, in standalone mode. Use
// the method URL to get the URL of the server.
//
// It receives the bind address (use 127.0.0.1:0 for getting an available port
// on the host) and a hook function, that will be called on every request.
func
NewServer
(
bind
string
,
hook
func
(
*
http
.
Request
))
(
*
DockerServer
,
error
)
{
// on the host), a channel of containers and a hook function, that will be
// called on every request.
//
// The fake server will send containers in the channel whenever the container
// changes its state, via the HTTP API (i.e.: create, start and stop). This
// channel may be nil, which means that the server won't notify on state
// changes.
func
NewServer
(
bind
string
,
containerChan
chan
<-
*
docker
.
Container
,
hook
func
(
*
http
.
Request
))
(
*
DockerServer
,
error
)
{
listener
,
err
:=
net
.
Listen
(
"tcp"
,
bind
)
if
err
!=
nil
{
return
nil
,
err
}
server
:=
DockerServer
{
listener
:
listener
,
imgIDs
:
make
(
map
[
string
]
string
),
hook
:
hook
,
failures
:
make
(
map
[
string
]
FailureSpec
)}
server
:=
DockerServer
{
listener
:
listener
,
imgIDs
:
make
(
map
[
string
]
string
),
hook
:
hook
,
failures
:
make
(
map
[
string
]
string
),
customHandlers
:
make
(
map
[
string
]
http
.
Handler
),
cChan
:
containerChan
,
}
server
.
buildMuxer
()
go
http
.
Serve
(
listener
,
&
server
)
return
&
server
,
nil
}
func
(
s
*
DockerServer
)
notify
(
container
*
docker
.
Container
)
{
if
s
.
cChan
!=
nil
{
s
.
cChan
<-
container
}
}
func
(
s
*
DockerServer
)
buildMuxer
()
{
s
.
mux
=
mux
.
NewRouter
()
s
.
mux
.
Path
(
"/commit"
)
.
Methods
(
"POST"
)
.
HandlerFunc
(
s
.
handlerWrapper
(
s
.
commitContainer
))
...
...
@@ -79,6 +90,8 @@ func (s *DockerServer) buildMuxer() {
s
.
mux
.
Path
(
"/containers/{id:.*}/json"
)
.
Methods
(
"GET"
)
.
HandlerFunc
(
s
.
handlerWrapper
(
s
.
inspectContainer
))
s
.
mux
.
Path
(
"/containers/{id:.*}/start"
)
.
Methods
(
"POST"
)
.
HandlerFunc
(
s
.
handlerWrapper
(
s
.
startContainer
))
s
.
mux
.
Path
(
"/containers/{id:.*}/stop"
)
.
Methods
(
"POST"
)
.
HandlerFunc
(
s
.
handlerWrapper
(
s
.
stopContainer
))
s
.
mux
.
Path
(
"/containers/{id:.*}/pause"
)
.
Methods
(
"POST"
)
.
HandlerFunc
(
s
.
handlerWrapper
(
s
.
pauseContainer
))
s
.
mux
.
Path
(
"/containers/{id:.*}/unpause"
)
.
Methods
(
"POST"
)
.
HandlerFunc
(
s
.
handlerWrapper
(
s
.
unpauseContainer
))
s
.
mux
.
Path
(
"/containers/{id:.*}/wait"
)
.
Methods
(
"POST"
)
.
HandlerFunc
(
s
.
handlerWrapper
(
s
.
waitContainer
))
s
.
mux
.
Path
(
"/containers/{id:.*}/attach"
)
.
Methods
(
"POST"
)
.
HandlerFunc
(
s
.
handlerWrapper
(
s
.
attachContainer
))
s
.
mux
.
Path
(
"/containers/{id:.*}"
)
.
Methods
(
"DELETE"
)
.
HandlerFunc
(
s
.
handlerWrapper
(
s
.
removeContainer
))
...
...
@@ -89,19 +102,45 @@ func (s *DockerServer) buildMuxer() {
s
.
mux
.
Path
(
"/images/{name:.*}/json"
)
.
Methods
(
"GET"
)
.
HandlerFunc
(
s
.
handlerWrapper
(
s
.
inspectImage
))
s
.
mux
.
Path
(
"/images/{name:.*}/push"
)
.
Methods
(
"POST"
)
.
HandlerFunc
(
s
.
handlerWrapper
(
s
.
pushImage
))
s
.
mux
.
Path
(
"/events"
)
.
Methods
(
"GET"
)
.
HandlerFunc
(
s
.
listEvents
)
s
.
mux
.
Path
(
"/_ping"
)
.
Methods
(
"GET"
)
.
HandlerFunc
(
s
.
handlerWrapper
(
s
.
pingDocker
))
}
// PrepareFailure adds a new expected failure based on a
FailureSpec
//
it receives an id for the failure and the spec
.
func
(
s
*
DockerServer
)
PrepareFailure
(
id
string
,
spec
FailureSpec
)
{
s
.
failures
[
id
]
=
spec
// PrepareFailure adds a new expected failure based on a
URL regexp it receives
//
an id for the failure
.
func
(
s
*
DockerServer
)
PrepareFailure
(
id
string
,
urlRegexp
string
)
{
s
.
failures
[
id
]
=
urlRegexp
}
// ResetFailure removes an expected failure identified by the
id
// ResetFailure removes an expected failure identified by the
given id.
func
(
s
*
DockerServer
)
ResetFailure
(
id
string
)
{
delete
(
s
.
failures
,
id
)
}
// CustomHandler registers a custom handler for a specific path.
//
// For example:
//
// server.CustomHandler("/containers/json", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// http.Error(w, "Something wrong is not right", http.StatusInternalServerError)
// }))
func
(
s
*
DockerServer
)
CustomHandler
(
path
string
,
handler
http
.
Handler
)
{
s
.
handlerMutex
.
Lock
()
s
.
customHandlers
[
path
]
=
handler
s
.
handlerMutex
.
Unlock
()
}
// MutateContainer changes the state of a container, returning an error if the
// given id does not match to any container "running" in the server.
func
(
s
*
DockerServer
)
MutateContainer
(
id
string
,
state
docker
.
State
)
error
{
for
_
,
container
:=
range
s
.
containers
{
if
container
.
ID
==
id
{
container
.
State
=
state
return
nil
}
}
return
errors
.
New
(
"container not found"
)
}
// Stop stops the server.
func
(
s
*
DockerServer
)
Stop
()
{
if
s
.
listener
!=
nil
{
...
...
@@ -119,6 +158,12 @@ func (s *DockerServer) URL() string {
// ServeHTTP handles HTTP requests sent to the server.
func
(
s
*
DockerServer
)
ServeHTTP
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
s
.
handlerMutex
.
RLock
()
defer
s
.
handlerMutex
.
RUnlock
()
if
handler
,
ok
:=
s
.
customHandlers
[
r
.
URL
.
Path
];
ok
{
handler
.
ServeHTTP
(
w
,
r
)
return
}
s
.
mux
.
ServeHTTP
(
w
,
r
)
if
s
.
hook
!=
nil
{
s
.
hook
(
r
)
...
...
@@ -127,8 +172,8 @@ func (s *DockerServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
func
(
s
*
DockerServer
)
handlerWrapper
(
f
func
(
http
.
ResponseWriter
,
*
http
.
Request
))
func
(
http
.
ResponseWriter
,
*
http
.
Request
)
{
return
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
for
errorI
d
,
spec
:=
range
s
.
failures
{
matched
,
err
:=
regexp
.
MatchString
(
spec
.
UrlRegex
,
r
.
URL
.
Path
)
for
errorI
D
,
urlRegexp
:=
range
s
.
failures
{
matched
,
err
:=
regexp
.
MatchString
(
urlRegexp
,
r
.
URL
.
Path
)
if
err
!=
nil
{
http
.
Error
(
w
,
err
.
Error
(),
http
.
StatusBadRequest
)
return
...
...
@@ -136,21 +181,7 @@ func (s *DockerServer) handlerWrapper(f func(http.ResponseWriter, *http.Request)
if
!
matched
{
continue
}
id
:=
mux
.
Vars
(
r
)[
"id"
]
if
id
!=
""
{
container
,
_
,
err
:=
s
.
findContainer
(
id
)
if
err
!=
nil
{
http
.
Error
(
w
,
err
.
Error
(),
http
.
StatusBadRequest
)
return
}
if
spec
.
ContainerPath
!=
""
&&
container
.
Path
!=
spec
.
ContainerPath
{
continue
}
if
spec
.
ContainerArgs
!=
nil
&&
reflect
.
DeepEqual
(
container
.
Args
,
spec
.
ContainerArgs
)
{
continue
}
}
http
.
Error
(
w
,
errorId
,
http
.
StatusBadRequest
)
http
.
Error
(
w
,
errorID
,
http
.
StatusBadRequest
)
return
}
f
(
w
,
r
)
...
...
@@ -272,6 +303,7 @@ func (s *DockerServer) createContainer(w http.ResponseWriter, r *http.Request) {
s
.
cMut
.
Lock
()
s
.
containers
=
append
(
s
.
containers
,
&
container
)
s
.
cMut
.
Unlock
()
s
.
notify
(
&
container
)
var
c
=
struct
{
ID
string
}{
ID
:
container
.
ID
}
json
.
NewEncoder
(
w
)
.
Encode
(
c
)
}
...
...
@@ -308,6 +340,7 @@ func (s *DockerServer) startContainer(w http.ResponseWriter, r *http.Request) {
return
}
container
.
State
.
Running
=
true
s
.
notify
(
container
)
}
func
(
s
*
DockerServer
)
stopContainer
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
...
...
@@ -325,6 +358,41 @@ func (s *DockerServer) stopContainer(w http.ResponseWriter, r *http.Request) {
}
w
.
WriteHeader
(
http
.
StatusNoContent
)
container
.
State
.
Running
=
false
s
.
notify
(
container
)
}
func
(
s
*
DockerServer
)
pauseContainer
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
id
:=
mux
.
Vars
(
r
)[
"id"
]
container
,
_
,
err
:=
s
.
findContainer
(
id
)
if
err
!=
nil
{
http
.
Error
(
w
,
err
.
Error
(),
http
.
StatusNotFound
)
return
}
s
.
cMut
.
Lock
()
defer
s
.
cMut
.
Unlock
()
if
container
.
State
.
Paused
{
http
.
Error
(
w
,
"Container already paused"
,
http
.
StatusBadRequest
)
return
}
w
.
WriteHeader
(
http
.
StatusNoContent
)
container
.
State
.
Paused
=
true
}
func
(
s
*
DockerServer
)
unpauseContainer
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
id
:=
mux
.
Vars
(
r
)[
"id"
]
container
,
_
,
err
:=
s
.
findContainer
(
id
)
if
err
!=
nil
{
http
.
Error
(
w
,
err
.
Error
(),
http
.
StatusNotFound
)
return
}
s
.
cMut
.
Lock
()
defer
s
.
cMut
.
Unlock
()
if
!
container
.
State
.
Paused
{
http
.
Error
(
w
,
"Container not paused"
,
http
.
StatusBadRequest
)
return
}
w
.
WriteHeader
(
http
.
StatusNoContent
)
container
.
State
.
Paused
=
false
}
func
(
s
*
DockerServer
)
attachContainer
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
...
...
@@ -361,7 +429,8 @@ func (s *DockerServer) waitContainer(w http.ResponseWriter, r *http.Request) {
}
s
.
cMut
.
RUnlock
()
}
w
.
Write
([]
byte
(
`{"StatusCode":0}`
))
result
:=
map
[
string
]
int
{
"StatusCode"
:
container
.
State
.
ExitCode
}
json
.
NewEncoder
(
w
)
.
Encode
(
result
)
}
func
(
s
*
DockerServer
)
removeContainer
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
...
...
@@ -547,6 +616,10 @@ func (s *DockerServer) listEvents(w http.ResponseWriter, r *http.Request) {
}
}
func
(
s
*
DockerServer
)
pingDocker
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
w
.
WriteHeader
(
http
.
StatusOK
)
}
func
(
s
*
DockerServer
)
generateEvent
()
*
docker
.
APIEvents
{
var
eventType
string
switch
mathrand
.
Intn
(
4
)
{
...
...
third_party/src/github.com/fsouza/go-dockerclient/testing/server_test.go
View file @
ea4224cb
This diff is collapsed.
Click to expand it.
third_party/src/github.com/fsouza/go-dockerclient/utils/stdcopy.go
View file @
ea4224cb
...
...
@@ -87,9 +87,12 @@ func StdCopy(dstout, dsterr io.Writer, src io.Reader) (written int64, err error)
var
nr2
int
nr2
,
er
=
src
.
Read
(
buf
[
nr
:
])
if
er
==
io
.
EOF
{
return
written
,
nil
}
if
er
!=
nil
{
if
nr
<
StdWriterPrefixLen
&&
nr2
<
StdWriterPrefixLen
{
return
written
,
nil
}
nr
+=
nr2
break
}
else
if
er
!=
nil
{
return
0
,
er
}
nr
+=
nr2
...
...
@@ -117,7 +120,7 @@ func StdCopy(dstout, dsterr io.Writer, src io.Reader) (written int64, err error)
// Extend it if necessary.
if
frameSize
+
StdWriterPrefixLen
>
bufLen
{
Debugf
(
"Extending buffer cap."
)
buf
=
append
(
buf
,
make
([]
byte
,
frameSize
-
len
(
buf
)
+
1
)
...
)
buf
=
append
(
buf
,
make
([]
byte
,
frameSize
+
StdWriterPrefixLen
-
len
(
buf
)
+
1
)
...
)
bufLen
=
len
(
buf
)
}
...
...
@@ -126,9 +129,12 @@ func StdCopy(dstout, dsterr io.Writer, src io.Reader) (written int64, err error)
var
nr2
int
nr2
,
er
=
src
.
Read
(
buf
[
nr
:
])
if
er
==
io
.
EOF
{
return
written
,
nil
}
if
er
!=
nil
{
if
nr
==
0
{
return
written
,
nil
}
nr
+=
nr2
break
}
else
if
er
!=
nil
{
Debugf
(
"Error reading frame: %s"
,
er
)
return
0
,
er
}
...
...
@@ -136,7 +142,11 @@ func StdCopy(dstout, dsterr io.Writer, src io.Reader) (written int64, err error)
}
// Write the retrieved frame (without header)
nw
,
ew
=
out
.
Write
(
buf
[
StdWriterPrefixLen
:
frameSize
+
StdWriterPrefixLen
])
bound
:=
frameSize
+
StdWriterPrefixLen
if
bound
>
nr
{
bound
=
nr
}
nw
,
ew
=
out
.
Write
(
buf
[
StdWriterPrefixLen
:
bound
])
if
nw
>
0
{
written
+=
int64
(
nw
)
}
...
...
@@ -147,7 +157,7 @@ func StdCopy(dstout, dsterr io.Writer, src io.Reader) (written int64, err error)
// If the frame has not been fully written: error
if
nw
!=
frameSize
{
Debugf
(
"Error Short Write: (%d on %d)"
,
nw
,
frameSize
)
return
0
,
io
.
ErrShortWrite
return
written
,
io
.
ErrShortWrite
}
// Move the rest of the buffer to the beginning
...
...
third_party/src/github.com/fsouza/go-dockerclient/utils/stdcopy_test.go
0 → 100644
View file @
ea4224cb
// 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
utils
import
(
"bytes"
"errors"
"io"
"strings"
"testing"
"testing/iotest"
)
type
errorWriter
struct
{
}
func
(
errorWriter
)
Write
([]
byte
)
(
int
,
error
)
{
return
0
,
errors
.
New
(
"something went wrong"
)
}
func
TestStdCopy
(
t
*
testing
.
T
)
{
var
input
,
stdout
,
stderr
bytes
.
Buffer
input
.
Write
([]
byte
{
2
,
0
,
0
,
0
,
0
,
0
,
0
,
19
})
input
.
Write
([]
byte
(
"something happened!"
))
input
.
Write
([]
byte
{
1
,
0
,
0
,
0
,
0
,
0
,
0
,
12
})
input
.
Write
([]
byte
(
"just kidding"
))
input
.
Write
([]
byte
{
0
,
0
,
0
,
0
,
0
,
0
,
0
,
6
})
input
.
Write
([]
byte
(
"
\n
yeah!"
))
n
,
err
:=
StdCopy
(
&
stdout
,
&
stderr
,
&
input
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
if
expected
:=
int64
(
19
+
12
+
6
);
n
!=
expected
{
t
.
Errorf
(
"Wrong number of bytes. Want %d. Got %d."
,
expected
,
n
)
}
if
got
:=
stderr
.
String
();
got
!=
"something happened!"
{
t
.
Errorf
(
"StdCopy: wrong stderr. Want %q. Got %q."
,
"something happened!"
,
got
)
}
if
got
:=
stdout
.
String
();
got
!=
"just kidding
\n
yeah!"
{
t
.
Errorf
(
"StdCopy: wrong stdout. Want %q. Got %q."
,
"just kidding
\n
yeah!"
,
got
)
}
}
func
TestStdCopyStress
(
t
*
testing
.
T
)
{
var
input
,
stdout
,
stderr
bytes
.
Buffer
value
:=
strings
.
Repeat
(
"something "
,
4096
)
writer
:=
NewStdWriter
(
&
input
,
Stdout
)
writer
.
Write
([]
byte
(
value
))
n
,
err
:=
StdCopy
(
&
stdout
,
&
stderr
,
&
input
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
if
n
!=
40960
{
t
.
Errorf
(
"Wrong number of bytes. Want 40960. Got %d."
,
n
)
}
if
got
:=
stderr
.
String
();
got
!=
""
{
t
.
Errorf
(
"StdCopy: wrong stderr. Want empty string. Got %q"
,
got
)
}
if
got
:=
stdout
.
String
();
got
!=
value
{
t
.
Errorf
(
"StdCopy: wrong stdout. Want %q. Got %q"
,
value
,
got
)
}
}
func
TestStdCopyInvalidStdHeader
(
t
*
testing
.
T
)
{
var
input
,
stdout
,
stderr
bytes
.
Buffer
input
.
Write
([]
byte
{
3
,
0
,
0
,
0
,
0
,
0
,
0
,
19
})
n
,
err
:=
StdCopy
(
&
stdout
,
&
stderr
,
&
input
)
if
n
!=
0
{
t
.
Errorf
(
"StdCopy: wrong number of bytes. Want 0. Got %d"
,
n
)
}
if
err
!=
ErrInvalidStdHeader
{
t
.
Errorf
(
"StdCopy: wrong error. Want ErrInvalidStdHeader. Got %#v"
,
err
)
}
}
func
TestStdCopyBigFrame
(
t
*
testing
.
T
)
{
var
input
,
stdout
,
stderr
bytes
.
Buffer
input
.
Write
([]
byte
{
2
,
0
,
0
,
0
,
0
,
0
,
0
,
18
})
input
.
Write
([]
byte
(
"something happened!"
))
n
,
err
:=
StdCopy
(
&
stdout
,
&
stderr
,
&
input
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
if
expected
:=
int64
(
18
);
n
!=
expected
{
t
.
Errorf
(
"Wrong number of bytes. Want %d. Got %d."
,
expected
,
n
)
}
if
got
:=
stderr
.
String
();
got
!=
"something happened"
{
t
.
Errorf
(
"StdCopy: wrong stderr. Want %q. Got %q."
,
"something happened"
,
got
)
}
if
got
:=
stdout
.
String
();
got
!=
""
{
t
.
Errorf
(
"StdCopy: wrong stdout. Want %q. Got %q."
,
""
,
got
)
}
}
func
TestStdCopySmallFrame
(
t
*
testing
.
T
)
{
var
input
,
stdout
,
stderr
bytes
.
Buffer
input
.
Write
([]
byte
{
2
,
0
,
0
,
0
,
0
,
0
,
0
,
20
})
input
.
Write
([]
byte
(
"something happened!"
))
n
,
err
:=
StdCopy
(
&
stdout
,
&
stderr
,
&
input
)
if
err
!=
io
.
ErrShortWrite
{
t
.
Errorf
(
"StdCopy: wrong error. Want ShortWrite. Got %#v"
,
err
)
}
if
expected
:=
int64
(
19
);
n
!=
expected
{
t
.
Errorf
(
"Wrong number of bytes. Want %d. Got %d."
,
expected
,
n
)
}
if
got
:=
stderr
.
String
();
got
!=
"something happened!"
{
t
.
Errorf
(
"StdCopy: wrong stderr. Want %q. Got %q."
,
"something happened"
,
got
)
}
if
got
:=
stdout
.
String
();
got
!=
""
{
t
.
Errorf
(
"StdCopy: wrong stdout. Want %q. Got %q."
,
""
,
got
)
}
}
func
TestStdCopyEmpty
(
t
*
testing
.
T
)
{
var
input
,
stdout
,
stderr
bytes
.
Buffer
n
,
err
:=
StdCopy
(
&
stdout
,
&
stderr
,
&
input
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
if
n
!=
0
{
t
.
Errorf
(
"StdCopy: wrong number of bytes. Want 0. Got %d."
,
n
)
}
}
func
TestStdCopyCorruptedHeader
(
t
*
testing
.
T
)
{
var
input
,
stdout
,
stderr
bytes
.
Buffer
input
.
Write
([]
byte
{
2
,
0
,
0
,
0
,
0
})
n
,
err
:=
StdCopy
(
&
stdout
,
&
stderr
,
&
input
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
if
n
!=
0
{
t
.
Errorf
(
"StdCopy: wrong number of bytes. Want 0. Got %d."
,
n
)
}
}
func
TestStdCopyTruncateWriter
(
t
*
testing
.
T
)
{
var
input
,
stdout
,
stderr
bytes
.
Buffer
input
.
Write
([]
byte
{
2
,
0
,
0
,
0
,
0
,
0
,
0
,
19
})
input
.
Write
([]
byte
(
"something happened!"
))
n
,
err
:=
StdCopy
(
&
stdout
,
iotest
.
TruncateWriter
(
&
stderr
,
7
),
&
input
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
if
expected
:=
int64
(
19
);
n
!=
expected
{
t
.
Errorf
(
"Wrong number of bytes. Want %d. Got %d."
,
expected
,
n
)
}
if
got
:=
stderr
.
String
();
got
!=
"somethi"
{
t
.
Errorf
(
"StdCopy: wrong stderr. Want %q. Got %q."
,
"somethi"
,
got
)
}
if
got
:=
stdout
.
String
();
got
!=
""
{
t
.
Errorf
(
"StdCopy: wrong stdout. Want %q. Got %q."
,
""
,
got
)
}
}
func
TestStdCopyHeaderOnly
(
t
*
testing
.
T
)
{
var
input
,
stdout
,
stderr
bytes
.
Buffer
input
.
Write
([]
byte
{
2
,
0
,
0
,
0
,
0
,
0
,
0
,
19
})
n
,
err
:=
StdCopy
(
&
stdout
,
iotest
.
TruncateWriter
(
&
stderr
,
7
),
&
input
)
if
err
!=
io
.
ErrShortWrite
{
t
.
Errorf
(
"StdCopy: wrong error. Want ShortWrite. Got %#v"
,
err
)
}
if
n
!=
0
{
t
.
Errorf
(
"Wrong number of bytes. Want 0. Got %d."
,
n
)
}
if
got
:=
stderr
.
String
();
got
!=
""
{
t
.
Errorf
(
"StdCopy: wrong stderr. Want %q. Got %q."
,
""
,
got
)
}
if
got
:=
stdout
.
String
();
got
!=
""
{
t
.
Errorf
(
"StdCopy: wrong stdout. Want %q. Got %q."
,
""
,
got
)
}
}
func
TestStdCopyDataErrReader
(
t
*
testing
.
T
)
{
var
input
,
stdout
,
stderr
bytes
.
Buffer
input
.
Write
([]
byte
{
2
,
0
,
0
,
0
,
0
,
0
,
0
,
19
})
input
.
Write
([]
byte
(
"something happened!"
))
n
,
err
:=
StdCopy
(
&
stdout
,
&
stderr
,
iotest
.
DataErrReader
(
&
input
))
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
if
expected
:=
int64
(
19
);
n
!=
expected
{
t
.
Errorf
(
"Wrong number of bytes. Want %d. Got %d."
,
expected
,
n
)
}
if
got
:=
stderr
.
String
();
got
!=
"something happened!"
{
t
.
Errorf
(
"StdCopy: wrong stderr. Want %q. Got %q."
,
"something happened!"
,
got
)
}
if
got
:=
stdout
.
String
();
got
!=
""
{
t
.
Errorf
(
"StdCopy: wrong stdout. Want %q. Got %q."
,
""
,
got
)
}
}
func
TestStdCopyTimeoutReader
(
t
*
testing
.
T
)
{
var
input
,
stdout
,
stderr
bytes
.
Buffer
input
.
Write
([]
byte
{
2
,
0
,
0
,
0
,
0
,
0
,
0
,
19
})
input
.
Write
([]
byte
(
"something happened!"
))
_
,
err
:=
StdCopy
(
&
stdout
,
&
stderr
,
iotest
.
TimeoutReader
(
&
input
))
if
err
!=
iotest
.
ErrTimeout
{
t
.
Errorf
(
"StdCopy: wrong error. Want ErrTimeout. Got %#v."
,
err
)
}
}
func
TestStdCopyWriteError
(
t
*
testing
.
T
)
{
var
input
bytes
.
Buffer
input
.
Write
([]
byte
{
2
,
0
,
0
,
0
,
0
,
0
,
0
,
19
})
input
.
Write
([]
byte
(
"something happened!"
))
var
stdout
,
stderr
errorWriter
n
,
err
:=
StdCopy
(
stdout
,
stderr
,
&
input
)
if
err
.
Error
()
!=
"something went wrong"
{
t
.
Errorf
(
"StdCopy: wrong error. Want %q. Got %q"
,
"something went wrong"
,
err
)
}
if
n
!=
0
{
t
.
Errorf
(
"StdCopy: wrong number of bytes. Want 0. Got %d."
,
n
)
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment