Merge component 'engine' from git@github.com:moby/moby master
This commit is contained in:
@@ -21,13 +21,14 @@ RUN contrib/download-frozen-image-v2.sh /output/docker-frozen-images \
|
||||
debian:jessie@sha256:287a20c5f73087ab406e6b364833e3fb7b3ae63ca0eb3486555dc27ed32c6e60 \
|
||||
hello-world:latest@sha256:be0cd392e45be79ffeffa6b05338b98ebb16c87b255f48e297ec7f98e123905c
|
||||
|
||||
# Download Docker CLI binary
|
||||
COPY hack/dockerfile hack/dockerfile
|
||||
RUN hack/dockerfile/install.sh dockercli
|
||||
# Install dockercli
|
||||
# Please edit hack/dockerfile/install/<name>.installer to update them.
|
||||
COPY hack/dockerfile/install hack/dockerfile/install
|
||||
RUN ./hack/dockerfile/install/install.sh dockercli
|
||||
|
||||
# Set tag and add sources
|
||||
ARG DOCKER_GITCOMMIT
|
||||
ENV DOCKER_GITCOMMIT=$DOCKER_GITCOMMIT
|
||||
ENV DOCKER_GITCOMMIT=${DOCKER_GITCOMMIT:-undefined}
|
||||
ADD . .
|
||||
|
||||
# Build DockerSuite.TestBuild* dependency
|
||||
|
||||
@@ -93,7 +93,7 @@ func (c *containerManager) Run(ctx context.Context, cID string, stdout, stderr i
|
||||
close(finished)
|
||||
logCancellationError(cancelErrCh,
|
||||
fmt.Sprintf("a non-zero code from ContainerWait: %d", status.ExitCode()))
|
||||
return &statusCodeError{code: status.ExitCode(), err: err}
|
||||
return &statusCodeError{code: status.ExitCode(), err: status.Err()}
|
||||
}
|
||||
|
||||
close(finished)
|
||||
@@ -112,6 +112,9 @@ type statusCodeError struct {
|
||||
}
|
||||
|
||||
func (e *statusCodeError) Error() string {
|
||||
if e.err == nil {
|
||||
return ""
|
||||
}
|
||||
return e.err.Error()
|
||||
}
|
||||
|
||||
|
||||
@@ -348,11 +348,15 @@ func dispatchRun(d dispatchRequest, c *instructions.RunCommand) error {
|
||||
if err := d.builder.containerManager.Run(d.builder.clientCtx, cID, d.builder.Stdout, d.builder.Stderr); err != nil {
|
||||
if err, ok := err.(*statusCodeError); ok {
|
||||
// TODO: change error type, because jsonmessage.JSONError assumes HTTP
|
||||
msg := fmt.Sprintf(
|
||||
"The command '%s' returned a non-zero code: %d",
|
||||
strings.Join(runConfig.Cmd, " "), err.StatusCode())
|
||||
if err.Error() != "" {
|
||||
msg = fmt.Sprintf("%s: %s", msg, err.Error())
|
||||
}
|
||||
return &jsonmessage.JSONError{
|
||||
Message: fmt.Sprintf(
|
||||
"The command '%s' returned a non-zero code: %d",
|
||||
strings.Join(runConfig.Cmd, " "), err.StatusCode()),
|
||||
Code: err.StatusCode(),
|
||||
Message: msg,
|
||||
Code: err.StatusCode(),
|
||||
}
|
||||
}
|
||||
return err
|
||||
|
||||
@@ -29,7 +29,7 @@ type State struct {
|
||||
Dead bool
|
||||
Pid int
|
||||
ExitCodeValue int `json:"ExitCode"`
|
||||
ErrorMsg string `json:"Error"` // contains last known error during container start or remove
|
||||
ErrorMsg string `json:"Error"` // contains last known error during container start, stop, or remove
|
||||
StartedAt time.Time
|
||||
FinishedAt time.Time
|
||||
Health *Health
|
||||
|
||||
@@ -69,6 +69,9 @@ func (daemon *Daemon) ProcessEvent(id string, e libcontainerd.EventType, ei libc
|
||||
c.RestartCount++
|
||||
c.SetRestarting(&exitStatus)
|
||||
} else {
|
||||
if ei.Error != nil {
|
||||
c.SetError(ei.Error)
|
||||
}
|
||||
c.SetStopped(&exitStatus)
|
||||
defer daemon.autoRemove(c)
|
||||
}
|
||||
|
||||
@@ -42,6 +42,8 @@ func (s *DockerNetworkSuite) TestDockerNetworkMacvlanPersistance(c *check.C) {
|
||||
master := "dm-dummy0"
|
||||
// simulate the master link the vlan tagged subinterface parent link will use
|
||||
createMasterDummy(c, master)
|
||||
// cleanup the master interface that also collects the slave dev
|
||||
defer deleteInterface(c, master)
|
||||
// create a network specifying the desired sub-interface name
|
||||
dockerCmd(c, "network", "create", "--driver=macvlan", "-o", "parent=dm-dummy0.60", "dm-persist")
|
||||
assertNwIsAvailable(c, "dm-persist")
|
||||
@@ -49,8 +51,6 @@ func (s *DockerNetworkSuite) TestDockerNetworkMacvlanPersistance(c *check.C) {
|
||||
s.d.Restart(c)
|
||||
// verify network is recreated from persistence
|
||||
assertNwIsAvailable(c, "dm-persist")
|
||||
// cleanup the master interface that also collects the slave dev
|
||||
deleteInterface(c, "dm-dummy0")
|
||||
}
|
||||
|
||||
func (s *DockerNetworkSuite) TestDockerNetworkIpvlanPersistance(c *check.C) {
|
||||
@@ -60,6 +60,8 @@ func (s *DockerNetworkSuite) TestDockerNetworkIpvlanPersistance(c *check.C) {
|
||||
master := "di-dummy0"
|
||||
// simulate the master link the vlan tagged subinterface parent link will use
|
||||
createMasterDummy(c, master)
|
||||
// cleanup the master interface that also collects the slave dev
|
||||
defer deleteInterface(c, master)
|
||||
// create a network specifying the desired sub-interface name
|
||||
dockerCmd(c, "network", "create", "--driver=ipvlan", "-o", "parent=di-dummy0.70", "di-persist")
|
||||
assertNwIsAvailable(c, "di-persist")
|
||||
@@ -67,8 +69,6 @@ func (s *DockerNetworkSuite) TestDockerNetworkIpvlanPersistance(c *check.C) {
|
||||
s.d.Restart(c)
|
||||
// verify network is recreated from persistence
|
||||
assertNwIsAvailable(c, "di-persist")
|
||||
// cleanup the master interface that also collects the slave dev
|
||||
deleteInterface(c, "di-dummy0")
|
||||
}
|
||||
|
||||
func (s *DockerNetworkSuite) TestDockerNetworkMacvlanSubIntCreate(c *check.C) {
|
||||
@@ -78,11 +78,11 @@ func (s *DockerNetworkSuite) TestDockerNetworkMacvlanSubIntCreate(c *check.C) {
|
||||
master := "dm-dummy0"
|
||||
// simulate the master link the vlan tagged subinterface parent link will use
|
||||
createMasterDummy(c, master)
|
||||
// cleanup the master interface which also collects the slave dev
|
||||
defer deleteInterface(c, master)
|
||||
// create a network specifying the desired sub-interface name
|
||||
dockerCmd(c, "network", "create", "--driver=macvlan", "-o", "parent=dm-dummy0.50", "dm-subinterface")
|
||||
assertNwIsAvailable(c, "dm-subinterface")
|
||||
// cleanup the master interface which also collects the slave dev
|
||||
deleteInterface(c, "dm-dummy0")
|
||||
}
|
||||
|
||||
func (s *DockerNetworkSuite) TestDockerNetworkIpvlanSubIntCreate(c *check.C) {
|
||||
@@ -92,11 +92,11 @@ func (s *DockerNetworkSuite) TestDockerNetworkIpvlanSubIntCreate(c *check.C) {
|
||||
master := "di-dummy0"
|
||||
// simulate the master link the vlan tagged subinterface parent link will use
|
||||
createMasterDummy(c, master)
|
||||
// cleanup the master interface which also collects the slave dev
|
||||
defer deleteInterface(c, master)
|
||||
// create a network specifying the desired sub-interface name
|
||||
dockerCmd(c, "network", "create", "--driver=ipvlan", "-o", "parent=di-dummy0.60", "di-subinterface")
|
||||
assertNwIsAvailable(c, "di-subinterface")
|
||||
// cleanup the master interface which also collects the slave dev
|
||||
deleteInterface(c, "di-dummy0")
|
||||
}
|
||||
|
||||
func (s *DockerNetworkSuite) TestDockerNetworkMacvlanOverlapParent(c *check.C) {
|
||||
@@ -105,6 +105,8 @@ func (s *DockerNetworkSuite) TestDockerNetworkMacvlanOverlapParent(c *check.C) {
|
||||
// master dummy interface 'dm' abbreviation represents 'docker macvlan'
|
||||
master := "dm-dummy0"
|
||||
createMasterDummy(c, master)
|
||||
// cleanup the master interface which also collects the slave dev
|
||||
defer deleteInterface(c, master)
|
||||
createVlanInterface(c, master, "dm-dummy0.40", "40")
|
||||
// create a network using an existing parent interface
|
||||
dockerCmd(c, "network", "create", "--driver=macvlan", "-o", "parent=dm-dummy0.40", "dm-subinterface")
|
||||
@@ -113,8 +115,6 @@ func (s *DockerNetworkSuite) TestDockerNetworkMacvlanOverlapParent(c *check.C) {
|
||||
out, _, err := dockerCmdWithError("network", "create", "--driver=macvlan", "-o", "parent=dm-dummy0.40", "dm-parent-net-overlap")
|
||||
// verify that the overlap returns an error
|
||||
c.Assert(err, check.NotNil, check.Commentf(out))
|
||||
// cleanup the master interface which also collects the slave dev
|
||||
deleteInterface(c, "dm-dummy0")
|
||||
}
|
||||
|
||||
func (s *DockerNetworkSuite) TestDockerNetworkIpvlanOverlapParent(c *check.C) {
|
||||
@@ -123,6 +123,8 @@ func (s *DockerNetworkSuite) TestDockerNetworkIpvlanOverlapParent(c *check.C) {
|
||||
// master dummy interface 'dm' abbreviation represents 'docker ipvlan'
|
||||
master := "di-dummy0"
|
||||
createMasterDummy(c, master)
|
||||
// cleanup the master interface which also collects the slave dev
|
||||
defer deleteInterface(c, master)
|
||||
createVlanInterface(c, master, "di-dummy0.30", "30")
|
||||
// create a network using an existing parent interface
|
||||
dockerCmd(c, "network", "create", "--driver=ipvlan", "-o", "parent=di-dummy0.30", "di-subinterface")
|
||||
@@ -131,8 +133,6 @@ func (s *DockerNetworkSuite) TestDockerNetworkIpvlanOverlapParent(c *check.C) {
|
||||
out, _, err := dockerCmdWithError("network", "create", "--driver=ipvlan", "-o", "parent=di-dummy0.30", "di-parent-net-overlap")
|
||||
// verify that the overlap returns an error
|
||||
c.Assert(err, check.NotNil, check.Commentf(out))
|
||||
// cleanup the master interface which also collects the slave dev
|
||||
deleteInterface(c, "di-dummy0")
|
||||
}
|
||||
|
||||
func (s *DockerNetworkSuite) TestDockerNetworkMacvlanMultiSubnet(c *check.C) {
|
||||
@@ -471,6 +471,7 @@ func (s *DockerSuite) TestDockerNetworkMacVlanExistingParent(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux, macvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon)
|
||||
netName := "dm-parent-exists"
|
||||
createMasterDummy(c, "dm-dummy0")
|
||||
defer deleteInterface(c, "dm-dummy0")
|
||||
//out, err := createVlanInterface(c, "dm-parent", "dm-slave", "macvlan", "bridge")
|
||||
// create a network using an existing parent interface
|
||||
dockerCmd(c, "network", "create", "--driver=macvlan", "-o", "parent=dm-dummy0", netName)
|
||||
@@ -480,7 +481,6 @@ func (s *DockerSuite) TestDockerNetworkMacVlanExistingParent(c *check.C) {
|
||||
assertNwNotAvailable(c, netName)
|
||||
// verify the network delete did not delete the predefined link
|
||||
linkExists(c, "dm-dummy0")
|
||||
deleteInterface(c, "dm-dummy0")
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestDockerNetworkMacVlanSubinterface(c *check.C) {
|
||||
@@ -488,6 +488,8 @@ func (s *DockerSuite) TestDockerNetworkMacVlanSubinterface(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux, macvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon)
|
||||
netName := "dm-subinterface"
|
||||
createMasterDummy(c, "dm-dummy0")
|
||||
// delete the parent interface which also collects the slave
|
||||
defer deleteInterface(c, "dm-dummy0")
|
||||
createVlanInterface(c, "dm-dummy0", "dm-dummy0.20", "20")
|
||||
// create a network using an existing parent interface
|
||||
dockerCmd(c, "network", "create", "--driver=macvlan", "-o", "parent=dm-dummy0.20", netName)
|
||||
@@ -510,8 +512,6 @@ func (s *DockerSuite) TestDockerNetworkMacVlanSubinterface(c *check.C) {
|
||||
assertNwNotAvailable(c, netName)
|
||||
// verify the network delete did not delete the predefined sub-interface
|
||||
linkExists(c, "dm-dummy0.20")
|
||||
// delete the parent interface which also collects the slave
|
||||
deleteInterface(c, "dm-dummy0")
|
||||
}
|
||||
|
||||
func createMasterDummy(c *check.C, master string) {
|
||||
|
||||
@@ -1203,7 +1203,13 @@ func (c *client) shutdownContainer(ctr *container) error {
|
||||
if err != nil {
|
||||
c.logger.WithError(err).WithField("container", ctr.id).
|
||||
Debug("failed to shutdown container, terminating it")
|
||||
return c.terminateContainer(ctr)
|
||||
terminateErr := c.terminateContainer(ctr)
|
||||
if terminateErr != nil {
|
||||
c.logger.WithError(terminateErr).WithField("container", ctr.id).
|
||||
Error("failed to shutdown container, and subsequent terminate also failed")
|
||||
return fmt.Errorf("%s: subsequent terminate failed %s", err, terminateErr)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -1234,6 +1240,8 @@ func (c *client) reapProcess(ctr *container, p *process) int {
|
||||
"process": p.id,
|
||||
})
|
||||
|
||||
var eventErr error
|
||||
|
||||
// Block indefinitely for the process to exit.
|
||||
if err := p.hcsProcess.Wait(); err != nil {
|
||||
if herr, ok := err.(*hcsshim.ProcessError); ok && herr.Err != windows.ERROR_BROKEN_PIPE {
|
||||
@@ -1263,6 +1271,8 @@ func (c *client) reapProcess(ctr *container, p *process) int {
|
||||
|
||||
if err := p.hcsProcess.Close(); err != nil {
|
||||
logger.WithError(err).Warnf("failed to cleanup hcs process resources")
|
||||
exitCode = -1
|
||||
eventErr = fmt.Errorf("hcsProcess.Close() failed %s", err)
|
||||
}
|
||||
|
||||
var pendingUpdates bool
|
||||
@@ -1286,13 +1296,27 @@ func (c *client) reapProcess(ctr *container, p *process) int {
|
||||
}
|
||||
|
||||
if err := c.shutdownContainer(ctr); err != nil {
|
||||
exitCode = -1
|
||||
logger.WithError(err).Warn("failed to shutdown container")
|
||||
thisErr := fmt.Errorf("failed to shutdown container: %s", err)
|
||||
if eventErr != nil {
|
||||
eventErr = fmt.Errorf("%s: %s", eventErr, thisErr)
|
||||
} else {
|
||||
eventErr = thisErr
|
||||
}
|
||||
} else {
|
||||
logger.Debug("completed container shutdown")
|
||||
}
|
||||
|
||||
if err := ctr.hcsContainer.Close(); err != nil {
|
||||
exitCode = -1
|
||||
logger.WithError(err).Error("failed to clean hcs container resources")
|
||||
thisErr := fmt.Errorf("failed to terminate container: %s", err)
|
||||
if eventErr != nil {
|
||||
eventErr = fmt.Errorf("%s: %s", eventErr, thisErr)
|
||||
} else {
|
||||
eventErr = thisErr
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1305,6 +1329,7 @@ func (c *client) reapProcess(ctr *container, p *process) int {
|
||||
ExitCode: uint32(exitCode),
|
||||
ExitedAt: exitedAt,
|
||||
UpdatePending: pendingUpdates,
|
||||
Error: eventErr,
|
||||
}
|
||||
c.logger.WithFields(logrus.Fields{
|
||||
"container": ctr.id,
|
||||
|
||||
@@ -73,6 +73,7 @@ type EventInfo struct {
|
||||
OOMKilled bool
|
||||
// Windows Only field
|
||||
UpdatePending bool
|
||||
Error error
|
||||
}
|
||||
|
||||
// Backend defines callbacks that the client of the library needs to implement.
|
||||
|
||||
Reference in New Issue
Block a user