Implement docker exec with standalone client lib.

Signed-off-by: David Calavera <david.calavera@gmail.com>
This commit is contained in:
David Calavera 2015-12-06 00:33:38 -05:00
Родитель 057c83d7fc
Коммит 4c6bc46188
4 изменённых файлов: 64 добавлений и 8 удалений

Просмотреть файл

@ -10,7 +10,7 @@ import (
// It returns a types.HijackedConnection with the hijacked connection
// and the a reader to get output. It's up to the called to close
// the hijacked connection by calling types.HijackedResponse.Close.
func (cli *Client) ContainerAttach(options types.ContainerAttachOptions) (*types.HijackedResponse, error) {
func (cli *Client) ContainerAttach(options types.ContainerAttachOptions) (types.HijackedResponse, error) {
query := url.Values{}
if options.Stream {
query.Set("stream", "1")

49
client/exec.go Normal file
Просмотреть файл

@ -0,0 +1,49 @@
package lib
import (
"encoding/json"
"github.com/docker/docker/api/types"
"github.com/docker/docker/runconfig"
)
// ContainerExecCreate creates a new exec configuration to run an exec process.
func (cli *Client) ContainerExecCreate(config runconfig.ExecConfig) (types.ContainerExecCreateResponse, error) {
var response types.ContainerExecCreateResponse
resp, err := cli.post("/containers/"+config.Container+"/exec", nil, config, nil)
if err != nil {
return response, err
}
defer ensureReaderClosed(resp)
err = json.NewDecoder(resp.body).Decode(&response)
return response, err
}
// ContainerExecStart starts an exec process already create in the docker host.
func (cli *Client) ContainerExecStart(execID string, config types.ExecStartCheck) error {
resp, err := cli.post("/exec/"+execID+"/start", nil, config, nil)
ensureReaderClosed(resp)
return err
}
// ContainerExecAttach attaches a connection to an exec process in the server.
// It returns a types.HijackedConnection with the hijacked connection
// and the a reader to get output. It's up to the called to close
// the hijacked connection by calling types.HijackedResponse.Close.
func (cli *Client) ContainerExecAttach(execID string, config runconfig.ExecConfig) (types.HijackedResponse, error) {
headers := map[string][]string{"Content-Type": {"application/json"}}
return cli.postHijacked("/exec/"+execID+"/start", nil, config, headers)
}
// ContainerExecInspect returns information about a specific exec process on the docker host.
func (cli *Client) ContainerExecInspect(execID string) (types.ContainerExecInspect, error) {
var response types.ContainerExecInspect
resp, err := cli.get("/exec/"+execID+"/json", nil, nil)
if err != nil {
return response, err
}
defer ensureReaderClosed(resp)
err = json.NewDecoder(resp.body).Decode(&response)
return response, err
}

Просмотреть файл

@ -4,7 +4,6 @@ import (
"crypto/tls"
"errors"
"fmt"
"io"
"net"
"net/http/httputil"
"net/url"
@ -30,15 +29,15 @@ func (c *tlsClientCon) CloseWrite() error {
}
// postHijacked sends a POST request and hijacks the connection.
func (cli *Client) postHijacked(path string, query url.Values, body io.Reader, headers map[string][]string) (*types.HijackedResponse, error) {
func (cli *Client) postHijacked(path string, query url.Values, body interface{}, headers map[string][]string) (types.HijackedResponse, error) {
bodyEncoded, err := encodeData(body)
if err != nil {
return nil, err
return types.HijackedResponse{}, err
}
req, err := cli.newRequest("POST", path, query, bodyEncoded, headers)
if err != nil {
return nil, err
return types.HijackedResponse{}, err
}
req.Host = cli.Addr
@ -48,9 +47,9 @@ func (cli *Client) postHijacked(path string, query url.Values, body io.Reader, h
conn, err := dial(cli.Proto, cli.Addr, cli.tlsConfig)
if err != nil {
if strings.Contains(err.Error(), "connection refused") {
return nil, fmt.Errorf("Cannot connect to the Docker daemon. Is 'docker daemon' running on this host?")
return types.HijackedResponse{}, fmt.Errorf("Cannot connect to the Docker daemon. Is 'docker daemon' running on this host?")
}
return nil, err
return types.HijackedResponse{}, err
}
// When we set up a TCP connection for hijack, there could be long periods
@ -71,7 +70,7 @@ func (cli *Client) postHijacked(path string, query url.Values, body io.Reader, h
rwc, br := clientconn.Hijack()
return &types.HijackedResponse{rwc, br}, nil
return types.HijackedResponse{rwc, br}, nil
}
func tlsDial(network, addr string, config *tls.Config) (net.Conn, error) {

Просмотреть файл

@ -31,6 +31,14 @@ type ContainerCommitOptions struct {
JSONConfig string
}
// ContainerExecInspect holds information returned by exec inspect.
type ContainerExecInspect struct {
ExecID string
ContainerID string
Running bool
ExitCode int
}
// ContainerListOptions holds parameters to list containers with.
type ContainerListOptions struct {
Quiet bool