11714: Set CgroupParent under Resources because setting Cgroup in HostConfig
[arvados.git] / services / crunch-run / crunchrun.go
index 4676a4f495dace7d3b66eb7e4258e7151b4ed410..aea93df1dc69970ce00d388aecfafc43e842a634 100644 (file)
@@ -66,7 +66,7 @@ type ThinDockerClient interface {
                networkingConfig *dockernetwork.NetworkingConfig, containerName string) (dockercontainer.ContainerCreateCreatedBody, error)
        ContainerStart(ctx context.Context, container string, options dockertypes.ContainerStartOptions) error
        ContainerStop(ctx context.Context, container string, timeout *time.Duration) error
-       ContainerWait(ctx context.Context, container string) (int64, error)
+       ContainerWait(ctx context.Context, container string, condition dockercontainer.WaitCondition) (<-chan dockercontainer.ContainerWaitOKBody, <-chan error)
        ImageInspectWithRaw(ctx context.Context, image string) (dockertypes.ImageInspect, []byte, error)
        ImageLoad(ctx context.Context, input io.Reader, quiet bool) (dockertypes.ImageLoadResponse, error)
        ImageRemove(ctx context.Context, image string, options dockertypes.ImageRemoveOptions) ([]dockertypes.ImageDeleteResponseItem, error)
@@ -100,8 +100,8 @@ func (proxy ThinDockerClientProxy) ContainerStop(ctx context.Context, container
 }
 
 // ContainerWait invokes dockerclient.Client.ContainerWait
-func (proxy ThinDockerClientProxy) ContainerWait(ctx context.Context, container string) (int64, error) {
-       return proxy.Docker.ContainerWait(ctx, container)
+func (proxy ThinDockerClientProxy) ContainerWait(ctx context.Context, container string, condition dockercontainer.WaitCondition) (<-chan dockercontainer.ContainerWaitOKBody, <-chan error) {
+       return proxy.Docker.ContainerWait(ctx, container, condition)
 }
 
 // ImageInspectWithRaw invokes dockerclient.Client.ImageInspectWithRaw
@@ -800,11 +800,13 @@ func (runner *ContainerRunner) CreateContainer() error {
        runner.ContainerConfig.Volumes = runner.Volumes
 
        runner.HostConfig = dockercontainer.HostConfig{
-               Binds:  runner.Binds,
-               Cgroup: dockercontainer.CgroupSpec(runner.setCgroupParent),
+               Binds: runner.Binds,
                LogConfig: dockercontainer.LogConfig{
                        Type: "none",
                },
+               Resources: dockercontainer.Resources{
+                       CgroupParent: runner.setCgroupParent,
+               },
        }
 
        if wantAPI := runner.Container.RuntimeConstraints.API; wantAPI != nil && *wantAPI {
@@ -862,21 +864,28 @@ func (runner *ContainerRunner) StartContainer() error {
 
 // WaitFinish waits for the container to terminate, capture the exit code, and
 // close the stdout/stderr logging.
-func (runner *ContainerRunner) WaitFinish() error {
+func (runner *ContainerRunner) WaitFinish() (err error) {
        runner.CrunchLog.Print("Waiting for container to finish")
 
-       waitDocker, err := runner.Docker.ContainerWait(context.TODO(), runner.ContainerID)
+       waitOk, waitErr := runner.Docker.ContainerWait(context.TODO(), runner.ContainerID, "not-running")
+
+       var waitBody dockercontainer.ContainerWaitOKBody
+       select {
+       case waitBody = <-waitOk:
+       case err = <-waitErr:
+       }
+
        if err != nil {
                return fmt.Errorf("container wait: %v", err)
        }
 
-       runner.CrunchLog.Printf("Container exited with code: %v", waitDocker)
-       code := int(waitDocker)
+       runner.CrunchLog.Printf("Container exited with code: %v", waitBody.StatusCode)
+       code := int(waitBody.StatusCode)
        runner.ExitCode = &code
 
        waitMount := runner.ArvMountExit
        select {
-       case err := <-waitMount:
+       case err = <-waitMount:
                runner.CrunchLog.Printf("arv-mount exited before container finished: %v", err)
                waitMount = nil
                runner.stop()
@@ -921,8 +930,10 @@ func (runner *ContainerRunner) CaptureOutput() error {
 
        // Pre-populate output from the configured mount points
        var binds []string
-       for bind, _ := range runner.Container.Mounts {
-               binds = append(binds, bind)
+       for bind, mnt := range runner.Container.Mounts {
+               if mnt.Kind == "collection" {
+                       binds = append(binds, bind)
+               }
        }
        sort.Strings(binds)
 
@@ -949,17 +960,16 @@ func (runner *ContainerRunner) CaptureOutput() error {
                                return err
                        }
 
+                       // get path relative to output dir
                        outputSuffix := path[len(runner.HostOutputDir):]
 
                        if strings.HasPrefix(tgt, "/") {
                                // go through mounts and try reverse map to collection reference
                                for _, bind := range binds {
                                        mnt := runner.Container.Mounts[bind]
-                                       if tgt == bind || strings.HasPrefix(tgt, bind+"/") && mnt.Kind == "collection" {
+                                       if tgt == bind || strings.HasPrefix(tgt, bind+"/") {
                                                // get path relative to bind
                                                targetSuffix := tgt[len(bind):]
-                                               // get path relative to output dir
-                                               outputSuffix := path[len(runner.HostOutputDir):]
 
                                                // Copy mount and adjust the path to add path relative to the bind
                                                adjustedMount := mnt