diff --git a/pkg/build/builder/dockerutil.go b/pkg/build/builder/dockerutil.go index eb383b8276a2..2af58746a23c 100644 --- a/pkg/build/builder/dockerutil.go +++ b/pkg/build/builder/dockerutil.go @@ -8,6 +8,7 @@ import ( "time" s2iapi "github.com/openshift/source-to-image/pkg/api" + "k8s.io/kubernetes/pkg/util/interrupt" utilruntime "k8s.io/kubernetes/pkg/util/runtime" "github.com/docker/docker/pkg/parsers" @@ -156,40 +157,42 @@ func dockerRun(client DockerClient, createOpts docker.CreateContainerOptions, lo containerName := containerNameOrID(c) - // Container was created, so we defer its removal. - defer func() { + removeContainer := func() { glog.V(4).Infof("Removing container %q ...", containerName) if err := client.RemoveContainer(docker.RemoveContainerOptions{ID: c.ID}); err != nil { glog.Warningf("Failed to remove container %q: %v", containerName, err) } else { glog.V(4).Infof("Removed container %q", containerName) } - }() - - // Start the container. - glog.V(4).Infof("Starting container %q ...", containerName) - if err := client.StartContainer(c.ID, nil); err != nil { - return fmt.Errorf("start container %q: %v", containerName, err) } + startWaitContainer := func() error { + // Start the container. + glog.V(4).Infof("Starting container %q ...", containerName) + if err := client.StartContainer(c.ID, nil); err != nil { + return fmt.Errorf("start container %q: %v", containerName, err) + } - // Stream container logs. - logsOpts.Container = c.ID - glog.V(4).Infof("Streaming logs of container %q with options %+v ...", containerName, logsOpts) - if err := client.Logs(logsOpts); err != nil { - return fmt.Errorf("streaming logs of %q: %v", containerName, err) - } + // Stream container logs. + logsOpts.Container = c.ID + glog.V(4).Infof("Streaming logs of container %q with options %+v ...", containerName, logsOpts) + if err := client.Logs(logsOpts); err != nil { + return fmt.Errorf("streaming logs of %q: %v", containerName, err) + } - // Return an error if the exit code of the container is non-zero. - glog.V(4).Infof("Waiting for container %q to stop ...", containerName) - exitCode, err := client.WaitContainer(c.ID) - if err != nil { - return fmt.Errorf("waiting for container %q to stop: %v", containerName, err) - } - if exitCode != 0 { - return fmt.Errorf("container %q returned non-zero exit code: %d", containerName, exitCode) + // Return an error if the exit code of the container is non-zero. + glog.V(4).Infof("Waiting for container %q to stop ...", containerName) + exitCode, err := client.WaitContainer(c.ID) + if err != nil { + return fmt.Errorf("waiting for container %q to stop: %v", containerName, err) + } + if exitCode != 0 { + return fmt.Errorf("container %q returned non-zero exit code: %d", containerName, exitCode) + } + return nil } - - return nil + // the interrupt handler acts as a super-defer which will guarantee removeContainer is executed + // either when startWaitContainer finishes, or when a SIGQUIT/SIGINT/SIGTERM is received. + return interrupt.New(nil, removeContainer).Run(startWaitContainer) } func containerNameOrID(c *docker.Container) string {