Provide a struct to configure cli streaming

Signed-off-by: Antonio Murdaca <me@runcom.ninja>
This commit is contained in:
Antonio Murdaca 2015-05-01 20:23:44 +02:00
parent 79d086c47d
commit d9639409fd
9 changed files with 61 additions and 16 deletions

View File

@ -289,7 +289,13 @@ func (cli *DockerCli) CmdBuild(args ...string) error {
if context != nil {
headers.Set("Content-Type", "application/tar")
}
err = cli.stream("POST", fmt.Sprintf("/build?%s", v.Encode()), body, cli.out, headers)
sopts := &streamOpts{
rawTerminal: true,
in: body,
out: cli.out,
headers: headers,
}
err = cli.stream("POST", fmt.Sprintf("/build?%s", v.Encode()), sopts)
if jerr, ok := err.(*jsonmessage.JSONError); ok {
// If no error code is set, default to 1
if jerr.Code == 0 {

View File

@ -47,7 +47,12 @@ func (cli *DockerCli) pullImageCustomOut(image string, out io.Writer) error {
registryAuthHeader := []string{
base64.URLEncoding.EncodeToString(buf),
}
if err = cli.stream("POST", "/images/create?"+v.Encode(), nil, out, map[string][]string{"X-Registry-Auth": registryAuthHeader}); err != nil {
sopts := &streamOpts{
rawTerminal: true,
out: out,
headers: map[string][]string{"X-Registry-Auth": registryAuthHeader},
}
if err := cli.stream("POST", "/images/create?"+v.Encode(), sopts); err != nil {
return err
}
return nil

View File

@ -63,7 +63,11 @@ func (cli *DockerCli) CmdEvents(args ...string) error {
}
v.Set("filters", filterJSON)
}
if err := cli.stream("GET", "/events?"+v.Encode(), nil, cli.out, nil); err != nil {
sopts := &streamOpts{
rawTerminal: true,
out: cli.out,
}
if err := cli.stream("GET", "/events?"+v.Encode(), sopts); err != nil {
return err
}
return nil

View File

@ -34,7 +34,11 @@ func (cli *DockerCli) CmdExport(args ...string) error {
}
image := cmd.Arg(0)
if err := cli.stream("GET", "/containers/"+image+"/export", nil, output, nil); err != nil {
sopts := &streamOpts{
rawTerminal: true,
out: output,
}
if err := cli.stream("GET", "/containers/"+image+"/export", sopts); err != nil {
return err
}

View File

@ -54,5 +54,11 @@ func (cli *DockerCli) CmdImport(args ...string) error {
in = cli.in
}
return cli.stream("POST", "/images/create?"+v.Encode(), in, cli.out, nil)
sopts := &streamOpts{
rawTerminal: true,
in: in,
out: cli.out,
}
return cli.stream("POST", "/images/create?"+v.Encode(), sopts)
}

View File

@ -29,7 +29,12 @@ func (cli *DockerCli) CmdLoad(args ...string) error {
return err
}
}
if err := cli.stream("POST", "/images/load", input, cli.out, nil); err != nil {
sopts := &streamOpts{
rawTerminal: true,
in: input,
out: cli.out,
}
if err := cli.stream("POST", "/images/load", sopts); err != nil {
return err
}
return nil

View File

@ -52,5 +52,11 @@ func (cli *DockerCli) CmdLogs(args ...string) error {
}
v.Set("tail", *tail)
return cli.streamHelper("GET", "/containers/"+name+"/logs?"+v.Encode(), c.Config.Tty, nil, cli.out, cli.err, nil)
sopts := &streamOpts{
rawTerminal: c.Config.Tty,
out: cli.out,
err: cli.err,
}
return cli.stream("GET", "/containers/"+name+"/logs?"+v.Encode(), sopts)
}

View File

@ -34,9 +34,14 @@ func (cli *DockerCli) CmdSave(args ...string) error {
return errors.New("Cowardly refusing to save to a terminal. Use the -o flag or redirect.")
}
sopts := &streamOpts{
rawTerminal: true,
out: output,
}
if len(cmd.Args()) == 1 {
image := cmd.Arg(0)
if err := cli.stream("GET", "/images/"+image+"/get", nil, output, nil); err != nil {
if err := cli.stream("GET", "/images/"+image+"/get", sopts); err != nil {
return err
}
} else {
@ -44,7 +49,7 @@ func (cli *DockerCli) CmdSave(args ...string) error {
for _, arg := range cmd.Args() {
v.Add("names", arg)
}
if err := cli.stream("GET", "/images/get?"+v.Encode(), nil, output, nil); err != nil {
if err := cli.stream("GET", "/images/get?"+v.Encode(), sopts); err != nil {
return err
}
}

View File

@ -170,19 +170,23 @@ func (cli *DockerCli) call(method, path string, data interface{}, headers map[st
return body, statusCode, err
}
func (cli *DockerCli) stream(method, path string, in io.Reader, out io.Writer, headers map[string][]string) error {
return cli.streamHelper(method, path, true, in, out, nil, headers)
type streamOpts struct {
rawTerminal bool
in io.Reader
out io.Writer
err io.Writer
headers map[string][]string
}
func (cli *DockerCli) streamHelper(method, path string, setRawTerminal bool, in io.Reader, stdout, stderr io.Writer, headers map[string][]string) error {
body, contentType, _, err := cli.clientRequest(method, path, in, headers)
func (cli *DockerCli) stream(method, path string, opts *streamOpts) error {
body, contentType, _, err := cli.clientRequest(method, path, opts.in, opts.headers)
if err != nil {
return err
}
return cli.streamBody(body, contentType, setRawTerminal, stdout, stderr)
return cli.streamBody(body, contentType, opts.rawTerminal, opts.out, opts.err)
}
func (cli *DockerCli) streamBody(body io.ReadCloser, contentType string, setRawTerminal bool, stdout, stderr io.Writer) error {
func (cli *DockerCli) streamBody(body io.ReadCloser, contentType string, rawTerminal bool, stdout, stderr io.Writer) error {
defer body.Close()
if api.MatchesContentType(contentType, "application/json") {
@ -191,7 +195,7 @@ func (cli *DockerCli) streamBody(body io.ReadCloser, contentType string, setRawT
if stdout != nil || stderr != nil {
// When TTY is ON, use regular copy
var err error
if setRawTerminal {
if rawTerminal {
_, err = io.Copy(stdout, body)
} else {
_, err = stdcopy.StdCopy(stdout, stderr, body)