diff --git a/dockerclient.go b/dockerclient.go index 6fa614f..47213e4 100644 --- a/dockerclient.go +++ b/dockerclient.go @@ -66,7 +66,25 @@ func NewDockerClientTimeout(daemonUrl string, tlsConfig *tls.Config, timeout tim func (client *DockerClient) doRequest(method string, path string, body []byte, headers map[string]string) ([]byte, error) { b := bytes.NewBuffer(body) - req, err := http.NewRequest(method, client.URL.String()+path, b) + + reader, err := client.doStreamRequest(method, path, b, headers) + if err != nil { + return nil, err + } + + defer reader.Close() + data, err := ioutil.ReadAll(reader) + if err != nil { + return nil, err + } + return data, nil +} + +func (client *DockerClient) doStreamRequest(method string, path string, in io.Reader, headers map[string]string) (io.ReadCloser, error) { + if (method == "POST" || method == "PUT") && in == nil { + in = bytes.NewReader(nil) + } + req, err := http.NewRequest(method, client.URL.String()+path, in) if err != nil { return nil, err } @@ -83,18 +101,19 @@ func (client *DockerClient) doRequest(method string, path string, body []byte, h } return nil, err } - defer resp.Body.Close() - data, err := ioutil.ReadAll(resp.Body) - if err != nil { - return nil, err - } if resp.StatusCode == 404 { return nil, ErrNotFound } if resp.StatusCode >= 400 { + defer resp.Body.Close() + data, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } return nil, Error{StatusCode: resp.StatusCode, Status: resp.Status, msg: string(data)} } - return data, nil + + return resp.Body, nil } func (client *DockerClient) Info() (*Info, error) { @@ -464,3 +483,25 @@ func (client *DockerClient) RenameContainer(oldName string, newName string) erro _, err := client.doRequest("POST", uri, nil, nil) return err } + +func (client *DockerClient) ImportImage(source string, repository string, tag string, tar io.Reader) (io.ReadCloser, error) { + var fromSrc string + v := &url.Values{} + if source == "" { + fromSrc = "-" + } else { + fromSrc = source + } + + v.Set("fromSrc", fromSrc) + v.Set("repo", repository) + if tag != "" { + v.Set("tag", tag) + } + + var in io.Reader + if fromSrc == "-" { + in = tar + } + return client.doStreamRequest("POST", "/images/create?"+v.Encode(), in, nil) +} diff --git a/interface.go b/interface.go index f29a434..0a7eb1e 100644 --- a/interface.go +++ b/interface.go @@ -34,4 +34,5 @@ type Client interface { 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) } diff --git a/mockclient/mock.go b/mockclient/mock.go index fe24329..3b2f269 100644 --- a/mockclient/mock.go +++ b/mockclient/mock.go @@ -135,3 +135,8 @@ func (client *MockClient) RenameContainer(oldName string, newName string) error args := client.Mock.Called(oldName, newName) return args.Error(0) } + +func (client *MockClient) ImportImage(source string, repository string, tag string, tar io.Reader) (io.ReadCloser, error) { + args := client.Mock.Called(source, repository, tag, tar) + return args.Get(0).(io.ReadCloser), args.Error(1) +}