Update docker, swarmkit, containerd v1.2.2
Also update the tests to account for the new "Builder" field in docker info. Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
7
vendor/github.com/docker/docker/api/types/container/host_config.go
generated
vendored
7
vendor/github.com/docker/docker/api/types/container/host_config.go
generated
vendored
@ -370,9 +370,10 @@ type HostConfig struct {
|
||||
// Applicable to UNIX platforms
|
||||
CapAdd strslice.StrSlice // List of kernel capabilities to add to the container
|
||||
CapDrop strslice.StrSlice // List of kernel capabilities to remove from the container
|
||||
DNS []string `json:"Dns"` // List of DNS server to lookup
|
||||
DNSOptions []string `json:"DnsOptions"` // List of DNSOption to look for
|
||||
DNSSearch []string `json:"DnsSearch"` // List of DNSSearch to look for
|
||||
Capabilities []string `json:"Capabilities"` // List of kernel capabilities to be available for container (this overrides the default set)
|
||||
DNS []string `json:"Dns"` // List of DNS server to lookup
|
||||
DNSOptions []string `json:"DnsOptions"` // List of DNSOption to look for
|
||||
DNSSearch []string `json:"DnsSearch"` // List of DNSSearch to look for
|
||||
ExtraHosts []string // List of extra hosts
|
||||
GroupAdd []string // List of additional groups that the container process will run as
|
||||
IpcMode IpcMode // IPC namespace to use for the container
|
||||
|
||||
1
vendor/github.com/docker/docker/api/types/types.go
generated
vendored
1
vendor/github.com/docker/docker/api/types/types.go
generated
vendored
@ -146,6 +146,7 @@ type Commit struct {
|
||||
// GET "/info"
|
||||
type Info struct {
|
||||
ID string
|
||||
Builder BuilderVersion
|
||||
Containers int
|
||||
ContainersRunning int
|
||||
ContainersPaused int
|
||||
|
||||
2
vendor/github.com/docker/docker/client/README.md
generated
vendored
2
vendor/github.com/docker/docker/client/README.md
generated
vendored
@ -16,7 +16,7 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
cli, err := client.NewEnvClient()
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
156
vendor/github.com/docker/docker/client/client.go
generated
vendored
156
vendor/github.com/docker/docker/client/client.go
generated
vendored
@ -23,7 +23,7 @@ For example, to list running containers (the equivalent of "docker ps"):
|
||||
)
|
||||
|
||||
func main() {
|
||||
cli, err := client.NewEnvClient()
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@ -47,16 +47,13 @@ import (
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/api"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/versions"
|
||||
"github.com/docker/go-connections/sockets"
|
||||
"github.com/docker/go-connections/tlsconfig"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
@ -103,145 +100,6 @@ func CheckRedirect(req *http.Request, via []*http.Request) error {
|
||||
return ErrRedirect
|
||||
}
|
||||
|
||||
// NewEnvClient initializes a new API client based on environment variables.
|
||||
// See FromEnv for a list of support environment variables.
|
||||
//
|
||||
// Deprecated: use NewClientWithOpts(FromEnv)
|
||||
func NewEnvClient() (*Client, error) {
|
||||
return NewClientWithOpts(FromEnv)
|
||||
}
|
||||
|
||||
// FromEnv configures the client with values from environment variables.
|
||||
//
|
||||
// Supported environment variables:
|
||||
// DOCKER_HOST to set the url to the docker server.
|
||||
// DOCKER_API_VERSION to set the version of the API to reach, leave empty for latest.
|
||||
// DOCKER_CERT_PATH to load the TLS certificates from.
|
||||
// DOCKER_TLS_VERIFY to enable or disable TLS verification, off by default.
|
||||
func FromEnv(c *Client) error {
|
||||
if dockerCertPath := os.Getenv("DOCKER_CERT_PATH"); dockerCertPath != "" {
|
||||
options := tlsconfig.Options{
|
||||
CAFile: filepath.Join(dockerCertPath, "ca.pem"),
|
||||
CertFile: filepath.Join(dockerCertPath, "cert.pem"),
|
||||
KeyFile: filepath.Join(dockerCertPath, "key.pem"),
|
||||
InsecureSkipVerify: os.Getenv("DOCKER_TLS_VERIFY") == "",
|
||||
}
|
||||
tlsc, err := tlsconfig.Client(options)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.client = &http.Client{
|
||||
Transport: &http.Transport{TLSClientConfig: tlsc},
|
||||
CheckRedirect: CheckRedirect,
|
||||
}
|
||||
}
|
||||
|
||||
if host := os.Getenv("DOCKER_HOST"); host != "" {
|
||||
if err := WithHost(host)(c); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if version := os.Getenv("DOCKER_API_VERSION"); version != "" {
|
||||
c.version = version
|
||||
c.manualOverride = true
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// WithTLSClientConfig applies a tls config to the client transport.
|
||||
func WithTLSClientConfig(cacertPath, certPath, keyPath string) func(*Client) error {
|
||||
return func(c *Client) error {
|
||||
opts := tlsconfig.Options{
|
||||
CAFile: cacertPath,
|
||||
CertFile: certPath,
|
||||
KeyFile: keyPath,
|
||||
ExclusiveRootPools: true,
|
||||
}
|
||||
config, err := tlsconfig.Client(opts)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to create tls config")
|
||||
}
|
||||
if transport, ok := c.client.Transport.(*http.Transport); ok {
|
||||
transport.TLSClientConfig = config
|
||||
return nil
|
||||
}
|
||||
return errors.Errorf("cannot apply tls config to transport: %T", c.client.Transport)
|
||||
}
|
||||
}
|
||||
|
||||
// WithDialer applies the dialer.DialContext to the client transport. This can be
|
||||
// used to set the Timeout and KeepAlive settings of the client.
|
||||
// Deprecated: use WithDialContext
|
||||
func WithDialer(dialer *net.Dialer) func(*Client) error {
|
||||
return WithDialContext(dialer.DialContext)
|
||||
}
|
||||
|
||||
// WithDialContext applies the dialer to the client transport. This can be
|
||||
// used to set the Timeout and KeepAlive settings of the client.
|
||||
func WithDialContext(dialContext func(ctx context.Context, network, addr string) (net.Conn, error)) func(*Client) error {
|
||||
return func(c *Client) error {
|
||||
if transport, ok := c.client.Transport.(*http.Transport); ok {
|
||||
transport.DialContext = dialContext
|
||||
return nil
|
||||
}
|
||||
return errors.Errorf("cannot apply dialer to transport: %T", c.client.Transport)
|
||||
}
|
||||
}
|
||||
|
||||
// WithVersion overrides the client version with the specified one
|
||||
func WithVersion(version string) func(*Client) error {
|
||||
return func(c *Client) error {
|
||||
c.version = version
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithHost overrides the client host with the specified one.
|
||||
func WithHost(host string) func(*Client) error {
|
||||
return func(c *Client) error {
|
||||
hostURL, err := ParseHostURL(host)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.host = host
|
||||
c.proto = hostURL.Scheme
|
||||
c.addr = hostURL.Host
|
||||
c.basePath = hostURL.Path
|
||||
if transport, ok := c.client.Transport.(*http.Transport); ok {
|
||||
return sockets.ConfigureTransport(transport, c.proto, c.addr)
|
||||
}
|
||||
return errors.Errorf("cannot apply host to transport: %T", c.client.Transport)
|
||||
}
|
||||
}
|
||||
|
||||
// WithHTTPClient overrides the client http client with the specified one
|
||||
func WithHTTPClient(client *http.Client) func(*Client) error {
|
||||
return func(c *Client) error {
|
||||
if client != nil {
|
||||
c.client = client
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithHTTPHeaders overrides the client default http headers
|
||||
func WithHTTPHeaders(headers map[string]string) func(*Client) error {
|
||||
return func(c *Client) error {
|
||||
c.customHTTPHeaders = headers
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithScheme overrides the client scheme with the specified one
|
||||
func WithScheme(scheme string) func(*Client) error {
|
||||
return func(c *Client) error {
|
||||
c.scheme = scheme
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// NewClientWithOpts initializes a new API client with default values. It takes functors
|
||||
// to modify values when creating it, like `NewClientWithOpts(WithVersion(…))`
|
||||
// It also initializes the custom http headers to add to each request.
|
||||
@ -301,18 +159,6 @@ func defaultHTTPClient(host string) (*http.Client, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
// NewClient initializes a new API client for the given host and API version.
|
||||
// It uses the given http client as transport.
|
||||
// It also initializes the custom http headers to add to each request.
|
||||
//
|
||||
// It won't send any version information if the version number is empty. It is
|
||||
// highly recommended that you set a version or your client may break if the
|
||||
// server is upgraded.
|
||||
// Deprecated: use NewClientWithOpts
|
||||
func NewClient(host string, version string, client *http.Client, httpHeaders map[string]string) (*Client, error) {
|
||||
return NewClientWithOpts(WithHost(host), WithVersion(version), WithHTTPClient(client), WithHTTPHeaders(httpHeaders))
|
||||
}
|
||||
|
||||
// Close the transport used by the client
|
||||
func (cli *Client) Close() error {
|
||||
if t, ok := cli.client.Transport.(*http.Transport); ok {
|
||||
|
||||
23
vendor/github.com/docker/docker/client/client_deprecated.go
generated
vendored
Normal file
23
vendor/github.com/docker/docker/client/client_deprecated.go
generated
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
package client
|
||||
|
||||
import "net/http"
|
||||
|
||||
// NewClient initializes a new API client for the given host and API version.
|
||||
// It uses the given http client as transport.
|
||||
// It also initializes the custom http headers to add to each request.
|
||||
//
|
||||
// It won't send any version information if the version number is empty. It is
|
||||
// highly recommended that you set a version or your client may break if the
|
||||
// server is upgraded.
|
||||
// Deprecated: use NewClientWithOpts
|
||||
func NewClient(host string, version string, client *http.Client, httpHeaders map[string]string) (*Client, error) {
|
||||
return NewClientWithOpts(WithHost(host), WithVersion(version), WithHTTPClient(client), WithHTTPHeaders(httpHeaders))
|
||||
}
|
||||
|
||||
// NewEnvClient initializes a new API client based on environment variables.
|
||||
// See FromEnv for a list of support environment variables.
|
||||
//
|
||||
// Deprecated: use NewClientWithOpts(FromEnv)
|
||||
func NewEnvClient() (*Client, error) {
|
||||
return NewClientWithOpts(FromEnv)
|
||||
}
|
||||
144
vendor/github.com/docker/docker/client/options.go
generated
vendored
Normal file
144
vendor/github.com/docker/docker/client/options.go
generated
vendored
Normal file
@ -0,0 +1,144 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/docker/go-connections/sockets"
|
||||
"github.com/docker/go-connections/tlsconfig"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// FromEnv configures the client with values from environment variables.
|
||||
//
|
||||
// Supported environment variables:
|
||||
// DOCKER_HOST to set the url to the docker server.
|
||||
// DOCKER_API_VERSION to set the version of the API to reach, leave empty for latest.
|
||||
// DOCKER_CERT_PATH to load the TLS certificates from.
|
||||
// DOCKER_TLS_VERIFY to enable or disable TLS verification, off by default.
|
||||
func FromEnv(c *Client) error {
|
||||
if dockerCertPath := os.Getenv("DOCKER_CERT_PATH"); dockerCertPath != "" {
|
||||
options := tlsconfig.Options{
|
||||
CAFile: filepath.Join(dockerCertPath, "ca.pem"),
|
||||
CertFile: filepath.Join(dockerCertPath, "cert.pem"),
|
||||
KeyFile: filepath.Join(dockerCertPath, "key.pem"),
|
||||
InsecureSkipVerify: os.Getenv("DOCKER_TLS_VERIFY") == "",
|
||||
}
|
||||
tlsc, err := tlsconfig.Client(options)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.client = &http.Client{
|
||||
Transport: &http.Transport{TLSClientConfig: tlsc},
|
||||
CheckRedirect: CheckRedirect,
|
||||
}
|
||||
}
|
||||
|
||||
if host := os.Getenv("DOCKER_HOST"); host != "" {
|
||||
if err := WithHost(host)(c); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if version := os.Getenv("DOCKER_API_VERSION"); version != "" {
|
||||
c.version = version
|
||||
c.manualOverride = true
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// WithDialer applies the dialer.DialContext to the client transport. This can be
|
||||
// used to set the Timeout and KeepAlive settings of the client.
|
||||
// Deprecated: use WithDialContext
|
||||
func WithDialer(dialer *net.Dialer) func(*Client) error {
|
||||
return WithDialContext(dialer.DialContext)
|
||||
}
|
||||
|
||||
// WithDialContext applies the dialer to the client transport. This can be
|
||||
// used to set the Timeout and KeepAlive settings of the client.
|
||||
func WithDialContext(dialContext func(ctx context.Context, network, addr string) (net.Conn, error)) func(*Client) error {
|
||||
return func(c *Client) error {
|
||||
if transport, ok := c.client.Transport.(*http.Transport); ok {
|
||||
transport.DialContext = dialContext
|
||||
return nil
|
||||
}
|
||||
return errors.Errorf("cannot apply dialer to transport: %T", c.client.Transport)
|
||||
}
|
||||
}
|
||||
|
||||
// WithHost overrides the client host with the specified one.
|
||||
func WithHost(host string) func(*Client) error {
|
||||
return func(c *Client) error {
|
||||
hostURL, err := ParseHostURL(host)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.host = host
|
||||
c.proto = hostURL.Scheme
|
||||
c.addr = hostURL.Host
|
||||
c.basePath = hostURL.Path
|
||||
if transport, ok := c.client.Transport.(*http.Transport); ok {
|
||||
return sockets.ConfigureTransport(transport, c.proto, c.addr)
|
||||
}
|
||||
return errors.Errorf("cannot apply host to transport: %T", c.client.Transport)
|
||||
}
|
||||
}
|
||||
|
||||
// WithHTTPClient overrides the client http client with the specified one
|
||||
func WithHTTPClient(client *http.Client) func(*Client) error {
|
||||
return func(c *Client) error {
|
||||
if client != nil {
|
||||
c.client = client
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithHTTPHeaders overrides the client default http headers
|
||||
func WithHTTPHeaders(headers map[string]string) func(*Client) error {
|
||||
return func(c *Client) error {
|
||||
c.customHTTPHeaders = headers
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithScheme overrides the client scheme with the specified one
|
||||
func WithScheme(scheme string) func(*Client) error {
|
||||
return func(c *Client) error {
|
||||
c.scheme = scheme
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithTLSClientConfig applies a tls config to the client transport.
|
||||
func WithTLSClientConfig(cacertPath, certPath, keyPath string) func(*Client) error {
|
||||
return func(c *Client) error {
|
||||
opts := tlsconfig.Options{
|
||||
CAFile: cacertPath,
|
||||
CertFile: certPath,
|
||||
KeyFile: keyPath,
|
||||
ExclusiveRootPools: true,
|
||||
}
|
||||
config, err := tlsconfig.Client(opts)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to create tls config")
|
||||
}
|
||||
if transport, ok := c.client.Transport.(*http.Transport); ok {
|
||||
transport.TLSClientConfig = config
|
||||
return nil
|
||||
}
|
||||
return errors.Errorf("cannot apply tls config to transport: %T", c.client.Transport)
|
||||
}
|
||||
}
|
||||
|
||||
// WithVersion overrides the client version with the specified one
|
||||
func WithVersion(version string) func(*Client) error {
|
||||
return func(c *Client) error {
|
||||
c.version = version
|
||||
return nil
|
||||
}
|
||||
}
|
||||
52
vendor/github.com/docker/docker/client/ping.go
generated
vendored
52
vendor/github.com/docker/docker/client/ping.go
generated
vendored
@ -2,34 +2,56 @@ package client // import "github.com/docker/docker/client"
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"path"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
)
|
||||
|
||||
// Ping pings the server and returns the value of the "Docker-Experimental", "Builder-Version", "OS-Type" & "API-Version" headers
|
||||
// Ping pings the server and returns the value of the "Docker-Experimental",
|
||||
// "Builder-Version", "OS-Type" & "API-Version" headers. It attempts to use
|
||||
// a HEAD request on the endpoint, but falls back to GET if HEAD is not supported
|
||||
// by the daemon.
|
||||
func (cli *Client) Ping(ctx context.Context) (types.Ping, error) {
|
||||
var ping types.Ping
|
||||
req, err := cli.buildRequest("GET", path.Join(cli.basePath, "/_ping"), nil, nil)
|
||||
req, err := cli.buildRequest("HEAD", path.Join(cli.basePath, "/_ping"), nil, nil)
|
||||
if err != nil {
|
||||
return ping, err
|
||||
}
|
||||
serverResp, err := cli.doRequest(ctx, req)
|
||||
if err == nil {
|
||||
defer ensureReaderClosed(serverResp)
|
||||
switch serverResp.statusCode {
|
||||
case http.StatusOK, http.StatusInternalServerError:
|
||||
// Server handled the request, so parse the response
|
||||
return parsePingResponse(cli, serverResp)
|
||||
}
|
||||
}
|
||||
|
||||
req, err = cli.buildRequest("GET", path.Join(cli.basePath, "/_ping"), nil, nil)
|
||||
if err != nil {
|
||||
return ping, err
|
||||
}
|
||||
serverResp, err = cli.doRequest(ctx, req)
|
||||
if err != nil {
|
||||
return ping, err
|
||||
}
|
||||
defer ensureReaderClosed(serverResp)
|
||||
|
||||
if serverResp.header != nil {
|
||||
ping.APIVersion = serverResp.header.Get("API-Version")
|
||||
|
||||
if serverResp.header.Get("Docker-Experimental") == "true" {
|
||||
ping.Experimental = true
|
||||
}
|
||||
ping.OSType = serverResp.header.Get("OSType")
|
||||
if bv := serverResp.header.Get("Builder-Version"); bv != "" {
|
||||
ping.BuilderVersion = types.BuilderVersion(bv)
|
||||
}
|
||||
}
|
||||
return ping, cli.checkResponseErr(serverResp)
|
||||
return parsePingResponse(cli, serverResp)
|
||||
}
|
||||
|
||||
func parsePingResponse(cli *Client, resp serverResponse) (types.Ping, error) {
|
||||
var ping types.Ping
|
||||
if resp.header == nil {
|
||||
return ping, cli.checkResponseErr(resp)
|
||||
}
|
||||
ping.APIVersion = resp.header.Get("API-Version")
|
||||
ping.OSType = resp.header.Get("OSType")
|
||||
if resp.header.Get("Docker-Experimental") == "true" {
|
||||
ping.Experimental = true
|
||||
}
|
||||
if bv := resp.header.Get("Builder-Version"); bv != "" {
|
||||
ping.BuilderVersion = types.BuilderVersion(bv)
|
||||
}
|
||||
return ping, cli.checkResponseErr(resp)
|
||||
}
|
||||
|
||||
36
vendor/github.com/docker/docker/client/request.go
generated
vendored
36
vendor/github.com/docker/docker/client/request.go
generated
vendored
@ -136,7 +136,7 @@ func (cli *Client) doRequest(ctx context.Context, req *http.Request) (serverResp
|
||||
}
|
||||
|
||||
if cli.scheme == "https" && strings.Contains(err.Error(), "bad certificate") {
|
||||
return serverResp, fmt.Errorf("The server probably has client authentication (--tlsverify) enabled. Please check your TLS client certification settings: %v", err)
|
||||
return serverResp, errors.Wrap(err, "The server probably has client authentication (--tlsverify) enabled. Please check your TLS client certification settings")
|
||||
}
|
||||
|
||||
// Don't decorate context sentinel errors; users may be comparing to
|
||||
@ -195,17 +195,21 @@ func (cli *Client) checkResponseErr(serverResp serverResponse) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
bodyMax := 1 * 1024 * 1024 // 1 MiB
|
||||
bodyR := &io.LimitedReader{
|
||||
R: serverResp.body,
|
||||
N: int64(bodyMax),
|
||||
}
|
||||
body, err := ioutil.ReadAll(bodyR)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if bodyR.N == 0 {
|
||||
return fmt.Errorf("request returned %s with a message (> %d bytes) for API route and version %s, check if the server supports the requested API version", http.StatusText(serverResp.statusCode), bodyMax, serverResp.reqURL)
|
||||
var body []byte
|
||||
var err error
|
||||
if serverResp.body != nil {
|
||||
bodyMax := 1 * 1024 * 1024 // 1 MiB
|
||||
bodyR := &io.LimitedReader{
|
||||
R: serverResp.body,
|
||||
N: int64(bodyMax),
|
||||
}
|
||||
body, err = ioutil.ReadAll(bodyR)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if bodyR.N == 0 {
|
||||
return fmt.Errorf("request returned %s with a message (> %d bytes) for API route and version %s, check if the server supports the requested API version", http.StatusText(serverResp.statusCode), bodyMax, serverResp.reqURL)
|
||||
}
|
||||
}
|
||||
if len(body) == 0 {
|
||||
return fmt.Errorf("request returned %s for API route and version %s, check if the server supports the requested API version", http.StatusText(serverResp.statusCode), serverResp.reqURL)
|
||||
@ -220,14 +224,14 @@ func (cli *Client) checkResponseErr(serverResp serverResponse) error {
|
||||
if (cli.version == "" || versions.GreaterThan(cli.version, "1.23")) && ct == "application/json" {
|
||||
var errorResponse types.ErrorResponse
|
||||
if err := json.Unmarshal(body, &errorResponse); err != nil {
|
||||
return fmt.Errorf("Error reading JSON: %v", err)
|
||||
return errors.Wrap(err, "Error reading JSON")
|
||||
}
|
||||
errorMessage = errorResponse.Message
|
||||
errorMessage = strings.TrimSpace(errorResponse.Message)
|
||||
} else {
|
||||
errorMessage = string(body)
|
||||
errorMessage = strings.TrimSpace(string(body))
|
||||
}
|
||||
|
||||
return fmt.Errorf("Error response from daemon: %s", strings.TrimSpace(errorMessage))
|
||||
return errors.Wrap(errors.New(errorMessage), "Error response from daemon")
|
||||
}
|
||||
|
||||
func (cli *Client) addHeaders(req *http.Request, headers headers) *http.Request {
|
||||
|
||||
55
vendor/github.com/docker/docker/errdefs/helpers.go
generated
vendored
55
vendor/github.com/docker/docker/errdefs/helpers.go
generated
vendored
@ -12,8 +12,8 @@ func (e errNotFound) Cause() error {
|
||||
|
||||
// NotFound is a helper to create an error of the class with the same name from any error type
|
||||
func NotFound(err error) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
if err == nil || IsNotFound(err) {
|
||||
return err
|
||||
}
|
||||
return errNotFound{err}
|
||||
}
|
||||
@ -28,8 +28,8 @@ func (e errInvalidParameter) Cause() error {
|
||||
|
||||
// InvalidParameter is a helper to create an error of the class with the same name from any error type
|
||||
func InvalidParameter(err error) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
if err == nil || IsInvalidParameter(err) {
|
||||
return err
|
||||
}
|
||||
return errInvalidParameter{err}
|
||||
}
|
||||
@ -44,8 +44,8 @@ func (e errConflict) Cause() error {
|
||||
|
||||
// Conflict is a helper to create an error of the class with the same name from any error type
|
||||
func Conflict(err error) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
if err == nil || IsConflict(err) {
|
||||
return err
|
||||
}
|
||||
return errConflict{err}
|
||||
}
|
||||
@ -60,8 +60,8 @@ func (e errUnauthorized) Cause() error {
|
||||
|
||||
// Unauthorized is a helper to create an error of the class with the same name from any error type
|
||||
func Unauthorized(err error) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
if err == nil || IsUnauthorized(err) {
|
||||
return err
|
||||
}
|
||||
return errUnauthorized{err}
|
||||
}
|
||||
@ -76,6 +76,9 @@ func (e errUnavailable) Cause() error {
|
||||
|
||||
// Unavailable is a helper to create an error of the class with the same name from any error type
|
||||
func Unavailable(err error) error {
|
||||
if err == nil || IsUnavailable(err) {
|
||||
return err
|
||||
}
|
||||
return errUnavailable{err}
|
||||
}
|
||||
|
||||
@ -89,8 +92,8 @@ func (e errForbidden) Cause() error {
|
||||
|
||||
// Forbidden is a helper to create an error of the class with the same name from any error type
|
||||
func Forbidden(err error) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
if err == nil || IsForbidden(err) {
|
||||
return err
|
||||
}
|
||||
return errForbidden{err}
|
||||
}
|
||||
@ -105,8 +108,8 @@ func (e errSystem) Cause() error {
|
||||
|
||||
// System is a helper to create an error of the class with the same name from any error type
|
||||
func System(err error) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
if err == nil || IsSystem(err) {
|
||||
return err
|
||||
}
|
||||
return errSystem{err}
|
||||
}
|
||||
@ -121,8 +124,8 @@ func (e errNotModified) Cause() error {
|
||||
|
||||
// NotModified is a helper to create an error of the class with the same name from any error type
|
||||
func NotModified(err error) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
if err == nil || IsNotModified(err) {
|
||||
return err
|
||||
}
|
||||
return errNotModified{err}
|
||||
}
|
||||
@ -137,8 +140,8 @@ func (e errAlreadyExists) Cause() error {
|
||||
|
||||
// AlreadyExists is a helper to create an error of the class with the same name from any error type
|
||||
func AlreadyExists(err error) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
if err == nil || IsAlreadyExists(err) {
|
||||
return err
|
||||
}
|
||||
return errAlreadyExists{err}
|
||||
}
|
||||
@ -153,8 +156,8 @@ func (e errNotImplemented) Cause() error {
|
||||
|
||||
// NotImplemented is a helper to create an error of the class with the same name from any error type
|
||||
func NotImplemented(err error) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
if err == nil || IsNotImplemented(err) {
|
||||
return err
|
||||
}
|
||||
return errNotImplemented{err}
|
||||
}
|
||||
@ -169,8 +172,8 @@ func (e errUnknown) Cause() error {
|
||||
|
||||
// Unknown is a helper to create an error of the class with the same name from any error type
|
||||
func Unknown(err error) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
if err == nil || IsUnknown(err) {
|
||||
return err
|
||||
}
|
||||
return errUnknown{err}
|
||||
}
|
||||
@ -185,8 +188,8 @@ func (e errCancelled) Cause() error {
|
||||
|
||||
// Cancelled is a helper to create an error of the class with the same name from any error type
|
||||
func Cancelled(err error) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
if err == nil || IsCancelled(err) {
|
||||
return err
|
||||
}
|
||||
return errCancelled{err}
|
||||
}
|
||||
@ -201,8 +204,8 @@ func (e errDeadline) Cause() error {
|
||||
|
||||
// Deadline is a helper to create an error of the class with the same name from any error type
|
||||
func Deadline(err error) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
if err == nil || IsDeadline(err) {
|
||||
return err
|
||||
}
|
||||
return errDeadline{err}
|
||||
}
|
||||
@ -217,8 +220,8 @@ func (e errDataLoss) Cause() error {
|
||||
|
||||
// DataLoss is a helper to create an error of the class with the same name from any error type
|
||||
func DataLoss(err error) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
if err == nil || IsDataLoss(err) {
|
||||
return err
|
||||
}
|
||||
return errDataLoss{err}
|
||||
}
|
||||
|
||||
4
vendor/github.com/docker/docker/pkg/archive/archive.go
generated
vendored
4
vendor/github.com/docker/docker/pkg/archive/archive.go
generated
vendored
@ -745,7 +745,7 @@ func TarWithOptions(srcPath string, options *TarOptions) (io.ReadCloser, error)
|
||||
compressWriter,
|
||||
options.ChownOpts,
|
||||
)
|
||||
ta.WhiteoutConverter = getWhiteoutConverter(options.WhiteoutFormat)
|
||||
ta.WhiteoutConverter = getWhiteoutConverter(options.WhiteoutFormat, options.InUserNS)
|
||||
|
||||
defer func() {
|
||||
// Make sure to check the error on Close.
|
||||
@ -903,7 +903,7 @@ func Unpack(decompressedArchive io.Reader, dest string, options *TarOptions) err
|
||||
var dirs []*tar.Header
|
||||
idMapping := idtools.NewIDMappingsFromMaps(options.UIDMaps, options.GIDMaps)
|
||||
rootIDs := idMapping.RootPair()
|
||||
whiteoutConverter := getWhiteoutConverter(options.WhiteoutFormat)
|
||||
whiteoutConverter := getWhiteoutConverter(options.WhiteoutFormat, options.InUserNS)
|
||||
|
||||
// Iterate through the files in the archive.
|
||||
loop:
|
||||
|
||||
179
vendor/github.com/docker/docker/pkg/archive/archive_linux.go
generated
vendored
179
vendor/github.com/docker/docker/pkg/archive/archive_linux.go
generated
vendored
@ -2,22 +2,29 @@ package archive // import "github.com/docker/docker/pkg/archive"
|
||||
|
||||
import (
|
||||
"archive/tar"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
"github.com/containerd/continuity/fs"
|
||||
"github.com/docker/docker/pkg/system"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func getWhiteoutConverter(format WhiteoutFormat) tarWhiteoutConverter {
|
||||
func getWhiteoutConverter(format WhiteoutFormat, inUserNS bool) tarWhiteoutConverter {
|
||||
if format == OverlayWhiteoutFormat {
|
||||
return overlayWhiteoutConverter{}
|
||||
return overlayWhiteoutConverter{inUserNS: inUserNS}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type overlayWhiteoutConverter struct{}
|
||||
type overlayWhiteoutConverter struct {
|
||||
inUserNS bool
|
||||
}
|
||||
|
||||
func (overlayWhiteoutConverter) ConvertWrite(hdr *tar.Header, path string, fi os.FileInfo) (wo *tar.Header, err error) {
|
||||
// convert whiteouts to AUFS format
|
||||
@ -61,13 +68,22 @@ func (overlayWhiteoutConverter) ConvertWrite(hdr *tar.Header, path string, fi os
|
||||
return
|
||||
}
|
||||
|
||||
func (overlayWhiteoutConverter) ConvertRead(hdr *tar.Header, path string) (bool, error) {
|
||||
func (c overlayWhiteoutConverter) ConvertRead(hdr *tar.Header, path string) (bool, error) {
|
||||
base := filepath.Base(path)
|
||||
dir := filepath.Dir(path)
|
||||
|
||||
// if a directory is marked as opaque by the AUFS special file, we need to translate that to overlay
|
||||
if base == WhiteoutOpaqueDir {
|
||||
err := unix.Setxattr(dir, "trusted.overlay.opaque", []byte{'y'}, 0)
|
||||
if err != nil {
|
||||
if c.inUserNS {
|
||||
if err = replaceDirWithOverlayOpaque(dir); err != nil {
|
||||
return false, errors.Wrapf(err, "replaceDirWithOverlayOpaque(%q) failed", dir)
|
||||
}
|
||||
} else {
|
||||
return false, errors.Wrapf(err, "setxattr(%q, trusted.overlay.opaque=y)", dir)
|
||||
}
|
||||
}
|
||||
// don't write the file itself
|
||||
return false, err
|
||||
}
|
||||
@ -78,7 +94,19 @@ func (overlayWhiteoutConverter) ConvertRead(hdr *tar.Header, path string) (bool,
|
||||
originalPath := filepath.Join(dir, originalBase)
|
||||
|
||||
if err := unix.Mknod(originalPath, unix.S_IFCHR, 0); err != nil {
|
||||
return false, err
|
||||
if c.inUserNS {
|
||||
// Ubuntu and a few distros support overlayfs in userns.
|
||||
//
|
||||
// Although we can't call mknod directly in userns (at least on bionic kernel 4.15),
|
||||
// we can still create 0,0 char device using mknodChar0Overlay().
|
||||
//
|
||||
// NOTE: we don't need this hack for the containerd snapshotter+unpack model.
|
||||
if err := mknodChar0Overlay(originalPath); err != nil {
|
||||
return false, errors.Wrapf(err, "failed to mknodChar0UserNS(%q)", originalPath)
|
||||
}
|
||||
} else {
|
||||
return false, errors.Wrapf(err, "failed to mknod(%q, S_IFCHR, 0)", originalPath)
|
||||
}
|
||||
}
|
||||
if err := os.Chown(originalPath, hdr.Uid, hdr.Gid); err != nil {
|
||||
return false, err
|
||||
@ -90,3 +118,144 @@ func (overlayWhiteoutConverter) ConvertRead(hdr *tar.Header, path string) (bool,
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// mknodChar0Overlay creates 0,0 char device by mounting overlayfs and unlinking.
|
||||
// This function can be used for creating 0,0 char device in userns on Ubuntu.
|
||||
//
|
||||
// Steps:
|
||||
// * Mkdir lower,upper,merged,work
|
||||
// * Create lower/dummy
|
||||
// * Mount overlayfs
|
||||
// * Unlink merged/dummy
|
||||
// * Unmount overlayfs
|
||||
// * Make sure a 0,0 char device is created as upper/dummy
|
||||
// * Rename upper/dummy to cleansedOriginalPath
|
||||
func mknodChar0Overlay(cleansedOriginalPath string) error {
|
||||
dir := filepath.Dir(cleansedOriginalPath)
|
||||
tmp, err := ioutil.TempDir(dir, "mc0o")
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to create a tmp directory under %s", dir)
|
||||
}
|
||||
defer os.RemoveAll(tmp)
|
||||
lower := filepath.Join(tmp, "l")
|
||||
upper := filepath.Join(tmp, "u")
|
||||
work := filepath.Join(tmp, "w")
|
||||
merged := filepath.Join(tmp, "m")
|
||||
for _, s := range []string{lower, upper, work, merged} {
|
||||
if err := os.MkdirAll(s, 0700); err != nil {
|
||||
return errors.Wrapf(err, "failed to mkdir %s", s)
|
||||
}
|
||||
}
|
||||
dummyBase := "d"
|
||||
lowerDummy := filepath.Join(lower, dummyBase)
|
||||
if err := ioutil.WriteFile(lowerDummy, []byte{}, 0600); err != nil {
|
||||
return errors.Wrapf(err, "failed to create a dummy lower file %s", lowerDummy)
|
||||
}
|
||||
mOpts := fmt.Sprintf("lowerdir=%s,upperdir=%s,workdir=%s", lower, upper, work)
|
||||
// docker/pkg/mount.Mount() requires procfs to be mounted. So we use syscall.Mount() directly instead.
|
||||
if err := syscall.Mount("overlay", merged, "overlay", uintptr(0), mOpts); err != nil {
|
||||
return errors.Wrapf(err, "failed to mount overlay (%s) on %s", mOpts, merged)
|
||||
}
|
||||
mergedDummy := filepath.Join(merged, dummyBase)
|
||||
if err := os.Remove(mergedDummy); err != nil {
|
||||
syscall.Unmount(merged, 0)
|
||||
return errors.Wrapf(err, "failed to unlink %s", mergedDummy)
|
||||
}
|
||||
if err := syscall.Unmount(merged, 0); err != nil {
|
||||
return errors.Wrapf(err, "failed to unmount %s", merged)
|
||||
}
|
||||
upperDummy := filepath.Join(upper, dummyBase)
|
||||
if err := isChar0(upperDummy); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := os.Rename(upperDummy, cleansedOriginalPath); err != nil {
|
||||
return errors.Wrapf(err, "failed to rename %s to %s", upperDummy, cleansedOriginalPath)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func isChar0(path string) error {
|
||||
osStat, err := os.Stat(path)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to stat %s", path)
|
||||
}
|
||||
st, ok := osStat.Sys().(*syscall.Stat_t)
|
||||
if !ok {
|
||||
return errors.Errorf("got unsupported stat for %s", path)
|
||||
}
|
||||
if os.FileMode(st.Mode)&syscall.S_IFMT != syscall.S_IFCHR {
|
||||
return errors.Errorf("%s is not a character device, got mode=%d", path, st.Mode)
|
||||
}
|
||||
if st.Rdev != 0 {
|
||||
return errors.Errorf("%s is not a 0,0 character device, got Rdev=%d", path, st.Rdev)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// replaceDirWithOverlayOpaque replaces path with a new directory with trusted.overlay.opaque
|
||||
// xattr. The contents of the directory are preserved.
|
||||
func replaceDirWithOverlayOpaque(path string) error {
|
||||
if path == "/" {
|
||||
return errors.New("replaceDirWithOverlayOpaque: path must not be \"/\"")
|
||||
}
|
||||
dir := filepath.Dir(path)
|
||||
tmp, err := ioutil.TempDir(dir, "rdwoo")
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to create a tmp directory under %s", dir)
|
||||
}
|
||||
defer os.RemoveAll(tmp)
|
||||
// newPath is a new empty directory crafted with trusted.overlay.opaque xattr.
|
||||
// we copy the content of path into newPath, remove path, and rename newPath to path.
|
||||
newPath, err := createDirWithOverlayOpaque(tmp)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "createDirWithOverlayOpaque(%q) failed", tmp)
|
||||
}
|
||||
if err := fs.CopyDir(newPath, path); err != nil {
|
||||
return errors.Wrapf(err, "CopyDir(%q, %q) failed", newPath, path)
|
||||
}
|
||||
if err := os.RemoveAll(path); err != nil {
|
||||
return err
|
||||
}
|
||||
return os.Rename(newPath, path)
|
||||
}
|
||||
|
||||
// createDirWithOverlayOpaque creates a directory with trusted.overlay.opaque xattr,
|
||||
// without calling setxattr, so as to allow creating opaque dir in userns on Ubuntu.
|
||||
func createDirWithOverlayOpaque(tmp string) (string, error) {
|
||||
lower := filepath.Join(tmp, "l")
|
||||
upper := filepath.Join(tmp, "u")
|
||||
work := filepath.Join(tmp, "w")
|
||||
merged := filepath.Join(tmp, "m")
|
||||
for _, s := range []string{lower, upper, work, merged} {
|
||||
if err := os.MkdirAll(s, 0700); err != nil {
|
||||
return "", errors.Wrapf(err, "failed to mkdir %s", s)
|
||||
}
|
||||
}
|
||||
dummyBase := "d"
|
||||
lowerDummy := filepath.Join(lower, dummyBase)
|
||||
if err := os.MkdirAll(lowerDummy, 0700); err != nil {
|
||||
return "", errors.Wrapf(err, "failed to create a dummy lower directory %s", lowerDummy)
|
||||
}
|
||||
mOpts := fmt.Sprintf("lowerdir=%s,upperdir=%s,workdir=%s", lower, upper, work)
|
||||
// docker/pkg/mount.Mount() requires procfs to be mounted. So we use syscall.Mount() directly instead.
|
||||
if err := syscall.Mount("overlay", merged, "overlay", uintptr(0), mOpts); err != nil {
|
||||
return "", errors.Wrapf(err, "failed to mount overlay (%s) on %s", mOpts, merged)
|
||||
}
|
||||
mergedDummy := filepath.Join(merged, dummyBase)
|
||||
if err := os.Remove(mergedDummy); err != nil {
|
||||
syscall.Unmount(merged, 0)
|
||||
return "", errors.Wrapf(err, "failed to rmdir %s", mergedDummy)
|
||||
}
|
||||
// upperDummy becomes a 0,0-char device file here
|
||||
if err := os.Mkdir(mergedDummy, 0700); err != nil {
|
||||
syscall.Unmount(merged, 0)
|
||||
return "", errors.Wrapf(err, "failed to mkdir %s", mergedDummy)
|
||||
}
|
||||
// upperDummy becomes a directory with trusted.overlay.opaque xattr
|
||||
// (but can't be verified in userns)
|
||||
if err := syscall.Unmount(merged, 0); err != nil {
|
||||
return "", errors.Wrapf(err, "failed to unmount %s", merged)
|
||||
}
|
||||
upperDummy := filepath.Join(upper, dummyBase)
|
||||
return upperDummy, nil
|
||||
}
|
||||
|
||||
2
vendor/github.com/docker/docker/pkg/archive/archive_other.go
generated
vendored
2
vendor/github.com/docker/docker/pkg/archive/archive_other.go
generated
vendored
@ -2,6 +2,6 @@
|
||||
|
||||
package archive // import "github.com/docker/docker/pkg/archive"
|
||||
|
||||
func getWhiteoutConverter(format WhiteoutFormat) tarWhiteoutConverter {
|
||||
func getWhiteoutConverter(format WhiteoutFormat, inUserNS bool) tarWhiteoutConverter {
|
||||
return nil
|
||||
}
|
||||
|
||||
8
vendor/github.com/docker/docker/pkg/archive/copy.go
generated
vendored
8
vendor/github.com/docker/docker/pkg/archive/copy.go
generated
vendored
@ -336,6 +336,14 @@ func RebaseArchiveEntries(srcContent io.Reader, oldBase, newBase string) io.Read
|
||||
return
|
||||
}
|
||||
|
||||
// srcContent tar stream, as served by TarWithOptions(), is
|
||||
// definitely in PAX format, but tar.Next() mistakenly guesses it
|
||||
// as USTAR, which creates a problem: if the newBase is >100
|
||||
// characters long, WriteHeader() returns an error like
|
||||
// "archive/tar: cannot encode header: Format specifies USTAR; and USTAR cannot encode Name=...".
|
||||
//
|
||||
// To fix, set the format to PAX here. See docker/for-linux issue #484.
|
||||
hdr.Format = tar.FormatPAX
|
||||
hdr.Name = strings.Replace(hdr.Name, oldBase, newBase, 1)
|
||||
if hdr.Typeflag == tar.TypeLink {
|
||||
hdr.Linkname = strings.Replace(hdr.Linkname, oldBase, newBase, 1)
|
||||
|
||||
104
vendor/github.com/docker/docker/pkg/jsonmessage/jsonmessage.go
generated
vendored
104
vendor/github.com/docker/docker/pkg/jsonmessage/jsonmessage.go
generated
vendored
@ -4,13 +4,12 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/Nvveen/Gotty"
|
||||
"github.com/docker/docker/pkg/term"
|
||||
"github.com/docker/go-units"
|
||||
"github.com/morikuni/aec"
|
||||
)
|
||||
|
||||
// RFC3339NanoFixed is time.RFC3339Nano with nanoseconds padded using zeros to
|
||||
@ -151,60 +150,23 @@ type JSONMessage struct {
|
||||
Aux *json.RawMessage `json:"aux,omitempty"`
|
||||
}
|
||||
|
||||
/* Satisfied by gotty.TermInfo as well as noTermInfo from below */
|
||||
type termInfo interface {
|
||||
Parse(attr string, params ...interface{}) (string, error)
|
||||
func clearLine(out io.Writer) {
|
||||
eraseMode := aec.EraseModes.All
|
||||
cl := aec.EraseLine(eraseMode)
|
||||
fmt.Fprint(out, cl)
|
||||
}
|
||||
|
||||
type noTermInfo struct{} // canary used when no terminfo.
|
||||
|
||||
func (ti *noTermInfo) Parse(attr string, params ...interface{}) (string, error) {
|
||||
return "", fmt.Errorf("noTermInfo")
|
||||
func cursorUp(out io.Writer, l uint) {
|
||||
fmt.Fprint(out, aec.Up(l))
|
||||
}
|
||||
|
||||
func clearLine(out io.Writer, ti termInfo) {
|
||||
// el2 (clear whole line) is not exposed by terminfo.
|
||||
|
||||
// First clear line from beginning to cursor
|
||||
if attr, err := ti.Parse("el1"); err == nil {
|
||||
fmt.Fprintf(out, "%s", attr)
|
||||
} else {
|
||||
fmt.Fprintf(out, "\x1b[1K")
|
||||
}
|
||||
// Then clear line from cursor to end
|
||||
if attr, err := ti.Parse("el"); err == nil {
|
||||
fmt.Fprintf(out, "%s", attr)
|
||||
} else {
|
||||
fmt.Fprintf(out, "\x1b[K")
|
||||
}
|
||||
func cursorDown(out io.Writer, l uint) {
|
||||
fmt.Fprint(out, aec.Down(l))
|
||||
}
|
||||
|
||||
func cursorUp(out io.Writer, ti termInfo, l int) {
|
||||
if l == 0 { // Should never be the case, but be tolerant
|
||||
return
|
||||
}
|
||||
if attr, err := ti.Parse("cuu", l); err == nil {
|
||||
fmt.Fprintf(out, "%s", attr)
|
||||
} else {
|
||||
fmt.Fprintf(out, "\x1b[%dA", l)
|
||||
}
|
||||
}
|
||||
|
||||
func cursorDown(out io.Writer, ti termInfo, l int) {
|
||||
if l == 0 { // Should never be the case, but be tolerant
|
||||
return
|
||||
}
|
||||
if attr, err := ti.Parse("cud", l); err == nil {
|
||||
fmt.Fprintf(out, "%s", attr)
|
||||
} else {
|
||||
fmt.Fprintf(out, "\x1b[%dB", l)
|
||||
}
|
||||
}
|
||||
|
||||
// Display displays the JSONMessage to `out`. `termInfo` is non-nil if `out`
|
||||
// is a terminal. If this is the case, it will erase the entire current line
|
||||
// when displaying the progressbar.
|
||||
func (jm *JSONMessage) Display(out io.Writer, termInfo termInfo) error {
|
||||
// Display displays the JSONMessage to `out`. If `isTerminal` is true, it will erase the
|
||||
// entire current line when displaying the progressbar.
|
||||
func (jm *JSONMessage) Display(out io.Writer, isTerminal bool) error {
|
||||
if jm.Error != nil {
|
||||
if jm.Error.Code == 401 {
|
||||
return fmt.Errorf("authentication is required")
|
||||
@ -212,8 +174,8 @@ func (jm *JSONMessage) Display(out io.Writer, termInfo termInfo) error {
|
||||
return jm.Error
|
||||
}
|
||||
var endl string
|
||||
if termInfo != nil && jm.Stream == "" && jm.Progress != nil {
|
||||
clearLine(out, termInfo)
|
||||
if isTerminal && jm.Stream == "" && jm.Progress != nil {
|
||||
clearLine(out)
|
||||
endl = "\r"
|
||||
fmt.Fprintf(out, endl)
|
||||
} else if jm.Progress != nil && jm.Progress.String() != "" { //disable progressbar in non-terminal
|
||||
@ -230,7 +192,7 @@ func (jm *JSONMessage) Display(out io.Writer, termInfo termInfo) error {
|
||||
if jm.From != "" {
|
||||
fmt.Fprintf(out, "(from %s) ", jm.From)
|
||||
}
|
||||
if jm.Progress != nil && termInfo != nil {
|
||||
if jm.Progress != nil && isTerminal {
|
||||
fmt.Fprintf(out, "%s %s%s", jm.Status, jm.Progress.String(), endl)
|
||||
} else if jm.ProgressMessage != "" { //deprecated
|
||||
fmt.Fprintf(out, "%s %s%s", jm.Status, jm.ProgressMessage, endl)
|
||||
@ -248,25 +210,11 @@ func (jm *JSONMessage) Display(out io.Writer, termInfo termInfo) error {
|
||||
func DisplayJSONMessagesStream(in io.Reader, out io.Writer, terminalFd uintptr, isTerminal bool, auxCallback func(JSONMessage)) error {
|
||||
var (
|
||||
dec = json.NewDecoder(in)
|
||||
ids = make(map[string]int)
|
||||
ids = make(map[string]uint)
|
||||
)
|
||||
|
||||
var termInfo termInfo
|
||||
|
||||
if isTerminal {
|
||||
term := os.Getenv("TERM")
|
||||
if term == "" {
|
||||
term = "vt102"
|
||||
}
|
||||
|
||||
var err error
|
||||
if termInfo, err = gotty.OpenTermInfo(term); err != nil {
|
||||
termInfo = &noTermInfo{}
|
||||
}
|
||||
}
|
||||
|
||||
for {
|
||||
diff := 0
|
||||
var diff uint
|
||||
var jm JSONMessage
|
||||
if err := dec.Decode(&jm); err != nil {
|
||||
if err == io.EOF {
|
||||
@ -294,15 +242,15 @@ func DisplayJSONMessagesStream(in io.Reader, out io.Writer, terminalFd uintptr,
|
||||
// when we output something that's not
|
||||
// accounted for in the map, such as a line
|
||||
// with no ID.
|
||||
line = len(ids)
|
||||
line = uint(len(ids))
|
||||
ids[jm.ID] = line
|
||||
if termInfo != nil {
|
||||
if isTerminal {
|
||||
fmt.Fprintf(out, "\n")
|
||||
}
|
||||
}
|
||||
diff = len(ids) - line
|
||||
if termInfo != nil {
|
||||
cursorUp(out, termInfo, diff)
|
||||
diff = uint(len(ids)) - line
|
||||
if isTerminal {
|
||||
cursorUp(out, diff)
|
||||
}
|
||||
} else {
|
||||
// When outputting something that isn't progress
|
||||
@ -310,11 +258,11 @@ func DisplayJSONMessagesStream(in io.Reader, out io.Writer, terminalFd uintptr,
|
||||
// don't want progress entries from some previous
|
||||
// operation to be updated (for example, pull -a
|
||||
// with multiple tags).
|
||||
ids = make(map[string]int)
|
||||
ids = make(map[string]uint)
|
||||
}
|
||||
err := jm.Display(out, termInfo)
|
||||
if jm.ID != "" && termInfo != nil {
|
||||
cursorDown(out, termInfo, diff)
|
||||
err := jm.Display(out, isTerminal)
|
||||
if jm.ID != "" && isTerminal {
|
||||
cursorDown(out, diff)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
10
vendor/github.com/docker/docker/vendor.conf
generated
vendored
10
vendor/github.com/docker/docker/vendor.conf
generated
vendored
@ -26,7 +26,7 @@ github.com/imdario/mergo v0.3.6
|
||||
golang.org/x/sync 1d60e4601c6fd243af51cc01ddf169918a5407ca
|
||||
|
||||
# buildkit
|
||||
github.com/moby/buildkit d9f75920678e35090025bb89344c5370e2efc8e7
|
||||
github.com/moby/buildkit 34ff9c2366a878ada7938d2f9ede71741b0a220c
|
||||
github.com/tonistiigi/fsutil 2862f6bc5ac9b97124e552a5c108230b38a1b0ca
|
||||
github.com/grpc-ecosystem/grpc-opentracing 8e809c8a86450a29b90dcc9efbf062d0fe6d9746
|
||||
github.com/opentracing/opentracing-go 1361b9cd60be79c4c3a7fa9841b3c132e40066a7
|
||||
@ -118,19 +118,19 @@ github.com/googleapis/gax-go v2.0.0
|
||||
google.golang.org/genproto 694d95ba50e67b2e363f3483057db5d4910c18f9
|
||||
|
||||
# containerd
|
||||
github.com/containerd/containerd aa5e000c963756778ab3ebd1a12c67449c503a34 # v1.2.1+
|
||||
github.com/containerd/containerd 9754871865f7fe2f4e74d43e2fc7ccd237edcbce # v1.2.2
|
||||
github.com/containerd/fifo 3d5202aec260678c48179c56f40e6f38a095738c
|
||||
github.com/containerd/continuity 004b46473808b3e7a4a3049c20e4376c91eb966d
|
||||
github.com/containerd/cgroups 5e610833b72089b37d0e615de9a92dfc043757c2
|
||||
github.com/containerd/console c12b1e7919c14469339a5d38f2f8ed9b64a9de23
|
||||
github.com/containerd/cri 0ca1e3c2b73b5c38e72f29bb76338d0078b23d6c # release/1.2 branch
|
||||
github.com/containerd/cri 0d5cabd006cb5319dc965046067b8432d9fa5ef8 # release/1.2 branch
|
||||
github.com/containerd/go-runc 5a6d9f37cfa36b15efba46dc7ea349fa9b7143c3
|
||||
github.com/containerd/typeurl a93fcdb778cd272c6e9b3028b2f42d813e785d40
|
||||
github.com/containerd/ttrpc 2a805f71863501300ae1976d29f0454ae003e85a
|
||||
github.com/gogo/googleapis 08a7655d27152912db7aaf4f983275eaf8d128ef
|
||||
|
||||
# cluster
|
||||
github.com/docker/swarmkit 8af8c420f491f006ab1730e08d446a795b1667d7
|
||||
github.com/docker/swarmkit ebfb0aa1118ebfd35a224d72a5d337ce0addd907
|
||||
github.com/gogo/protobuf v1.0.0
|
||||
github.com/cloudflare/cfssl 1.3.2
|
||||
github.com/fernet/fernet-go 1b2437bc582b3cfbb341ee5a29f8ef5b42912ff2
|
||||
@ -155,7 +155,7 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
|
||||
github.com/spf13/cobra v0.0.3
|
||||
github.com/spf13/pflag v1.0.1
|
||||
github.com/inconshreveable/mousetrap 76626ae9c91c4f2a10f34cad8ce83ea42c93bb75 # v1.0
|
||||
github.com/Nvveen/Gotty a8b993ba6abdb0e0c12b0125c603323a71c7790c https://github.com/ijc25/Gotty
|
||||
github.com/morikuni/aec 39771216ff4c63d11f5e604076f9c45e8be1067b
|
||||
|
||||
# metrics
|
||||
github.com/docker/go-metrics d466d4f6fd960e01820085bd7e1a24426ee7ef18
|
||||
|
||||
Reference in New Issue
Block a user