Merge component 'engine' from git@github.com:moby/moby master

This commit is contained in:
GordonTheTurtle
2017-12-06 17:04:14 +00:00
12 changed files with 179 additions and 22 deletions

View File

@ -52,6 +52,7 @@ RUN apt-get update && apt-get install -y \
libapparmor-dev \
libcap-dev \
libdevmapper-dev \
libnet-dev \
libnl-3-dev \
libprotobuf-c0-dev \
libprotobuf-dev \
@ -94,11 +95,9 @@ ENV PATH /go/bin:/usr/local/go/bin:$PATH
ENV GOPATH /go
# Install CRIU for checkpoint/restore support
ENV CRIU_VERSION 2.12.1
# Install dependancy packages specific to criu
RUN apt-get install libnet-dev -y && \
mkdir -p /usr/src/criu \
&& curl -sSL https://github.com/xemul/criu/archive/v${CRIU_VERSION}.tar.gz | tar -v -C /usr/src/criu/ -xz --strip-components=1 \
ENV CRIU_VERSION 3.6
RUN mkdir -p /usr/src/criu \
&& curl -sSL https://github.com/checkpoint-restore/criu/archive/v${CRIU_VERSION}.tar.gz | tar -C /usr/src/criu/ -xz --strip-components=1 \
&& cd /usr/src/criu \
&& make \
&& make install-criu

View File

@ -7259,6 +7259,9 @@ paths:
User:
type: "string"
description: "The user, and optionally, group to run the exec process inside the container. Format is one of: `user`, `user:group`, `uid`, or `uid:gid`."
WorkingDir:
type: "string"
description: "The working directory for the exec process inside the container."
example:
AttachStdin: false
AttachStdout: true

View File

@ -50,6 +50,7 @@ type ExecConfig struct {
Detach bool // Execute in detach mode
DetachKeys string // Escape keys for detach
Env []string // Environment variables
WorkingDir string // Working directory
Cmd []string // Execution commands and args
}

View File

@ -122,6 +122,7 @@ func (d *Daemon) ContainerExecCreate(name string, config *types.ExecConfig) (str
execConfig.Tty = config.Tty
execConfig.Privileged = config.Privileged
execConfig.User = config.User
execConfig.WorkingDir = config.WorkingDir
linkedEnv, err := d.setupLinkedContainers(cntr)
if err != nil {
@ -131,6 +132,9 @@ func (d *Daemon) ContainerExecCreate(name string, config *types.ExecConfig) (str
if len(execConfig.User) == 0 {
execConfig.User = cntr.Config.User
}
if len(execConfig.WorkingDir) == 0 {
execConfig.WorkingDir = cntr.Config.WorkingDir
}
d.registerExecCommand(cntr, execConfig)
@ -211,7 +215,7 @@ func (d *Daemon) ContainerExecStart(ctx context.Context, name string, stdin io.R
Args: append([]string{ec.Entrypoint}, ec.Args...),
Env: ec.Env,
Terminal: ec.Tty,
Cwd: c.Config.WorkingDir,
Cwd: ec.WorkingDir,
}
if p.Cwd == "" {
p.Cwd = "/"

View File

@ -31,6 +31,7 @@ type Config struct {
Tty bool
Privileged bool
User string
WorkingDir string
Env []string
Pid int
}

View File

@ -824,7 +824,7 @@ func (d *Driver) ApplyDiff(id, parent string, diff io.Reader) (int64, error) {
return 0, fmt.Errorf("lcowdriver: applydiff: svm failed to boot: %s", err)
}
// TODO @jhowardmsft - the retries are temporary to overcome platform reliablity issues.
// TODO @jhowardmsft - the retries are temporary to overcome platform reliability issues.
// Obviously this will be removed as platform bugs are fixed.
retries := 0
for {

View File

@ -126,21 +126,25 @@ func TranslatePullError(err error, ref reference.Named) error {
// continueOnError returns true if we should fallback to the next endpoint
// as a result of this error.
func continueOnError(err error) bool {
func continueOnError(err error, mirrorEndpoint bool) bool {
switch v := err.(type) {
case errcode.Errors:
if len(v) == 0 {
return true
}
return continueOnError(v[0])
return continueOnError(v[0], mirrorEndpoint)
case ErrNoSupport:
return continueOnError(v.Err)
return continueOnError(v.Err, mirrorEndpoint)
case errcode.Error:
return shouldV2Fallback(v)
return mirrorEndpoint || shouldV2Fallback(v)
case *client.UnexpectedHTTPResponseError:
return true
case ImageConfigPullError:
return false
// ImageConfigPullError only happens with v2 images, v1 fallback is
// unnecessary.
// Failures from a mirror endpoint should result in fallback to the
// canonical repo.
return mirrorEndpoint
case error:
return !strings.Contains(err.Error(), strings.ToLower(syscall.ESRCH.Error()))
}

View File

@ -0,0 +1,85 @@
package distribution
import (
"errors"
"strings"
"syscall"
"testing"
"github.com/docker/distribution/registry/api/errcode"
"github.com/docker/distribution/registry/api/v2"
"github.com/docker/distribution/registry/client"
)
var alwaysContinue = []error{
&client.UnexpectedHTTPResponseError{},
// Some errcode.Errors that don't disprove the existence of a V1 image
errcode.Error{Code: errcode.ErrorCodeUnauthorized},
errcode.Error{Code: v2.ErrorCodeManifestUnknown},
errcode.Error{Code: v2.ErrorCodeNameUnknown},
errors.New("some totally unexpected error"),
}
var continueFromMirrorEndpoint = []error{
ImageConfigPullError{},
// Some other errcode.Error that doesn't indicate we should search for a V1 image.
errcode.Error{Code: errcode.ErrorCodeTooManyRequests},
}
var neverContinue = []error{
errors.New(strings.ToLower(syscall.ESRCH.Error())), // No such process
}
func TestContinueOnError_NonMirrorEndpoint(t *testing.T) {
for _, err := range alwaysContinue {
if !continueOnError(err, false) {
t.Errorf("Should continue from non-mirror endpoint: %T: '%s'", err, err.Error())
}
}
for _, err := range continueFromMirrorEndpoint {
if continueOnError(err, false) {
t.Errorf("Should only continue from mirror endpoint: %T: '%s'", err, err.Error())
}
}
}
func TestContinueOnError_MirrorEndpoint(t *testing.T) {
errs := []error{}
errs = append(errs, alwaysContinue...)
errs = append(errs, continueFromMirrorEndpoint...)
for _, err := range errs {
if !continueOnError(err, true) {
t.Errorf("Should continue from mirror endpoint: %T: '%s'", err, err.Error())
}
}
}
func TestContinueOnError_NeverContinue(t *testing.T) {
for _, isMirrorEndpoint := range []bool{true, false} {
for _, err := range neverContinue {
if continueOnError(err, isMirrorEndpoint) {
t.Errorf("Should never continue: %T: '%s'", err, err.Error())
}
}
}
}
func TestContinueOnError_UnnestsErrors(t *testing.T) {
// ContinueOnError should evaluate nested errcode.Errors.
// Assumes that v2.ErrorCodeNameUnknown is a continueable error code.
err := errcode.Errors{errcode.Error{Code: v2.ErrorCodeNameUnknown}}
if !continueOnError(err, false) {
t.Fatal("ContinueOnError should unnest, base return value on errcode.Errors")
}
// Assumes that errcode.ErrorCodeTooManyRequests is not a V1-fallback indication
err = errcode.Errors{errcode.Error{Code: errcode.ErrorCodeTooManyRequests}}
if continueOnError(err, false) {
t.Fatal("ContinueOnError should unnest, base return value on errcode.Errors")
}
}

View File

@ -74,7 +74,7 @@ func (p *v2Puller) Pull(ctx context.Context, ref reference.Named, platform strin
if _, ok := err.(fallbackError); ok {
return err
}
if continueOnError(err) {
if continueOnError(err, p.endpoint.Mirror) {
return fallbackError{
err: err,
confirmedV2: p.confirmedV2,

View File

@ -67,7 +67,7 @@ func (p *v2Pusher) Push(ctx context.Context) (err error) {
}
if err = p.pushV2Repository(ctx); err != nil {
if continueOnError(err) {
if continueOnError(err, p.endpoint.Mirror) {
return fallbackError{
err: err,
confirmedV2: p.pushState.confirmedV2,

View File

@ -132,14 +132,14 @@ can take over 15 minutes to complete.
```none
Successfully built 3d872560918e
docker run --rm -i --privileged -e BUILDFLAGS -e KEEPBUNDLE -e DOCKER_BUILD_GOGC -e DOCKER_BUILD_PKGS -e DOCKER_CLIENTONLY -e DOCKER_DEBUG -e DOCKER_EXPERIMENTAL -e DOCKER_GITCOMMIT -e DOCKER_GRAPHDRIVER=devicemapper -e DOCKER_INCREMENTAL_BINARY -e DOCKER_REMAP_ROOT -e DOCKER_STORAGE_OPTS -e DOCKER_USERLANDPROXY -e TESTDIRS -e TESTFLAGS -e TIMEOUT -v "home/ubuntu/repos/docker/bundles:/go/src/github.com/moby/moby/bundles" -t "docker-dev:dry-run-test" bash
root@f31fa223770f:/go/src/github.com/moby/moby#
root@f31fa223770f:/go/src/github.com/docker/docker#
```
At this point, your prompt reflects the container's BASH shell.
5. List the contents of the current directory (`/go/src/github.com/moby/moby`).
You should see the image's source from the `/go/src/github.com/moby/moby`
You should see the image's source from the `/go/src/github.com/docker/docker`
directory.
![List example](images/list_example.png)
@ -147,7 +147,7 @@ can take over 15 minutes to complete.
6. Make a `dockerd` binary.
```none
root@a8b2885ab900:/go/src/github.com/moby/moby# hack/make.sh binary
root@a8b2885ab900:/go/src/github.com/docker/docker# hack/make.sh binary
Removing bundles/
---> Making bundle: binary (in bundles/binary)
@ -161,7 +161,7 @@ can take over 15 minutes to complete.
`/usr/local/bin/` directory.
```none
root@a8b2885ab900:/go/src/github.com/moby/moby# make install
root@a8b2885ab900:/go/src/github.com/docker/docker# make install
```
8. Start the Engine daemon running in the background.
@ -190,7 +190,7 @@ can take over 15 minutes to complete.
9. Inside your container, check your Docker version.
```none
root@5f8630b873fe:/go/src/github.com/moby/moby# docker --version
root@5f8630b873fe:/go/src/github.com/docker/docker# docker --version
Docker version 1.12.0-dev, build 6e728fb
```
@ -201,13 +201,13 @@ can take over 15 minutes to complete.
10. Run the `hello-world` image.
```none
root@5f8630b873fe:/go/src/github.com/moby/moby# docker run hello-world
root@5f8630b873fe:/go/src/github.com/docker/docker# docker run hello-world
```
11. List the image you just downloaded.
```none
root@5f8630b873fe:/go/src/github.com/moby/moby# docker images
root@5f8630b873fe:/go/src/github.com/docker/docker# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest c54a2cc56cbb 3 months ago 1.85 kB
```
@ -296,7 +296,7 @@ example, you'll edit the help for the `attach` subcommand.
10. To view your change, run the `dockerd --help` command in the docker development container shell.
```bash
root@b0cb4f22715d:/go/src/github.com/moby/moby# dockerd --help
root@b0cb4f22715d:/go/src/github.com/docker/docker# dockerd --help
Usage: dockerd COMMAND

View File

@ -0,0 +1,60 @@
package container
import (
"context"
"io/ioutil"
"testing"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/network"
"github.com/docker/docker/api/types/strslice"
"github.com/docker/docker/integration/util/request"
"github.com/stretchr/testify/require"
)
func TestExec(t *testing.T) {
defer setupTest(t)()
ctx := context.Background()
client := request.NewAPIClient(t)
container, err := client.ContainerCreate(ctx,
&container.Config{
Image: "busybox",
Tty: true,
WorkingDir: "/root",
Cmd: strslice.StrSlice([]string{"top"}),
},
&container.HostConfig{},
&network.NetworkingConfig{},
"foo",
)
require.NoError(t, err)
err = client.ContainerStart(ctx, container.ID, types.ContainerStartOptions{})
require.NoError(t, err)
id, err := client.ContainerExecCreate(ctx, container.ID,
types.ExecConfig{
WorkingDir: "/tmp",
Env: strslice.StrSlice([]string{"FOO=BAR"}),
AttachStdout: true,
Cmd: strslice.StrSlice([]string{"sh", "-c", "env"}),
},
)
require.NoError(t, err)
resp, err := client.ContainerExecAttach(ctx, id.ID,
types.ExecStartCheck{
Detach: false,
Tty: false,
},
)
require.NoError(t, err)
defer resp.Close()
r, err := ioutil.ReadAll(resp.Reader)
require.NoError(t, err)
out := string(r)
require.NoError(t, err)
require.Contains(t, out, "PWD=/tmp", "exec command not running in expected /tmp working directory")
require.Contains(t, out, "FOO=BAR", "exec command not running with expected environment variable FOO")
}