[ARVADOS] created: 1a4a2f3219906220c0b4d7fd9b90325fa529408a

Git user git at public.curoverse.com
Thu Mar 30 18:02:48 EDT 2017


        at  1a4a2f3219906220c0b4d7fd9b90325fa529408a (commit)


commit 1a4a2f3219906220c0b4d7fd9b90325fa529408a
Author: Peter Amstutz <peter.amstutz at curoverse.com>
Date:   Thu Mar 30 18:02:11 2017 -0400

    9132: Fix ContainerCreate to include HostConfig, container UUID as name.

diff --git a/services/crunch-run/crunchrun.go b/services/crunch-run/crunchrun.go
index 64e79a6..ad0a337 100644
--- a/services/crunch-run/crunchrun.go
+++ b/services/crunch-run/crunchrun.go
@@ -743,7 +743,7 @@ func (runner *ContainerRunner) CreateContainer() error {
 		}
 	}
 
-	createdBody, err := runner.Docker.ContainerCreate(context.TODO(), &runner.ContainerConfig, nil, nil, "")
+	createdBody, err := runner.Docker.ContainerCreate(context.TODO(), &runner.ContainerConfig, &runner.HostConfig, nil, runner.Container.UUID)
 	if err != nil {
 		return fmt.Errorf("While creating container: %v", err)
 	}

commit d6703f161c75a780ff645dc1ec980fca8a3e315b
Author: Peter Amstutz <peter.amstutz at curoverse.com>
Date:   Thu Mar 30 14:19:42 2017 -0400

    9132: Fix after rebase

diff --git a/services/crunch-run/crunchrun.go b/services/crunch-run/crunchrun.go
index 40d6ffd..64e79a6 100644
--- a/services/crunch-run/crunchrun.go
+++ b/services/crunch-run/crunchrun.go
@@ -716,8 +716,7 @@ func (runner *ContainerRunner) CreateContainer() error {
 		runner.ContainerConfig.Env = append(runner.ContainerConfig.Env, k+"="+v)
 	}
 
-	runner.ContainerID = createdBody.ID
-	runner.HostConfig = dockerclient.HostConfig{
+	runner.HostConfig = dockercontainer.HostConfig{
 		Binds:  runner.Binds,
 		Cgroup: dockercontainer.CgroupSpec(runner.setCgroupParent),
 		LogConfig: dockercontainer.LogConfig{
@@ -735,12 +734,12 @@ func (runner *ContainerRunner) CreateContainer() error {
 			"ARVADOS_API_HOST="+os.Getenv("ARVADOS_API_HOST"),
 			"ARVADOS_API_HOST_INSECURE="+os.Getenv("ARVADOS_API_HOST_INSECURE"),
 		)
-		runner.HostConfig.NetworkMode = runner.networkMode
+		runner.HostConfig.NetworkMode = dockercontainer.NetworkMode(runner.networkMode)
 	} else {
 		if runner.enableNetwork == "always" {
-			runner.HostConfig.NetworkMode = runner.networkMode
+			runner.HostConfig.NetworkMode = dockercontainer.NetworkMode(runner.networkMode)
 		} else {
-			runner.HostConfig.NetworkMode = "none"
+			runner.HostConfig.NetworkMode = dockercontainer.NetworkMode("none")
 		}
 	}
 
@@ -749,6 +748,8 @@ func (runner *ContainerRunner) CreateContainer() error {
 		return fmt.Errorf("While creating container: %v", err)
 	}
 
+	runner.ContainerID = createdBody.ID
+
 	return runner.AttachStreams()
 }
 

commit bebac87e773d73788de9273d65ca92db6878b2e7
Author: radhika <radhika at curoverse.com>
Date:   Wed Mar 22 16:47:44 2017 -0400

    9132: Use ThinDockerClientProxy to overcome the import issue around "github.com/docker/docker/vendor/golang.org/x/net/context".
    Perform most of the test updates needed to use the new API.

diff --git a/services/crunch-run/crunchrun.go b/services/crunch-run/crunchrun.go
index 80ca27f..40d6ffd 100644
--- a/services/crunch-run/crunchrun.go
+++ b/services/crunch-run/crunchrun.go
@@ -60,15 +60,62 @@ type MkTempDir func(string, string) (string, error)
 
 // ThinDockerClient is the minimal Docker client interface used by crunch-run.
 type ThinDockerClient interface {
-	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)
+	ContainerAttach(ctx context.Context, container string, options dockertypes.ContainerAttachOptions) (dockertypes.HijackedResponse, error)
 	ContainerCreate(ctx context.Context, config *dockercontainer.Config, hostConfig *dockercontainer.HostConfig,
 		networkingConfig *dockernetwork.NetworkingConfig, containerName string) (dockercontainer.ContainerCreateCreatedBody, error)
 	ContainerStart(ctx context.Context, container string, options dockertypes.ContainerStartOptions) error
-	ContainerAttach(ctx context.Context, container string, options dockertypes.ContainerAttachOptions) (dockertypes.HijackedResponse, error)
 	ContainerStop(ctx context.Context, container string, timeout *time.Duration) error
 	ContainerWait(ctx context.Context, container string) (int64, 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)
+}
+
+// ThinDockerClientProxy is a proxy implementation of ThinDockerClient
+// that executes the docker requests on dockerclient.Client
+type ThinDockerClientProxy struct {
+	Docker *dockerclient.Client
+}
+
+// ContainerAttach invokes dockerclient.Client.ContainerAttach
+func (proxy ThinDockerClientProxy) ContainerAttach(ctx context.Context, container string, options dockertypes.ContainerAttachOptions) (dockertypes.HijackedResponse, error) {
+	return proxy.Docker.ContainerAttach(ctx, container, options)
+}
+
+// ContainerCreate invokes dockerclient.Client.ContainerCreate
+func (proxy ThinDockerClientProxy) ContainerCreate(ctx context.Context, config *dockercontainer.Config, hostConfig *dockercontainer.HostConfig,
+	networkingConfig *dockernetwork.NetworkingConfig, containerName string) (dockercontainer.ContainerCreateCreatedBody, error) {
+	return proxy.Docker.ContainerCreate(ctx, config, hostConfig, networkingConfig, containerName)
+}
+
+// ContainerStart invokes dockerclient.Client.ContainerStart
+func (proxy ThinDockerClientProxy) ContainerStart(ctx context.Context, container string, options dockertypes.ContainerStartOptions) error {
+	return proxy.Docker.ContainerStart(ctx, container, options)
+}
+
+// ContainerStop invokes dockerclient.Client.ContainerStop
+func (proxy ThinDockerClientProxy) ContainerStop(ctx context.Context, container string, timeout *time.Duration) error {
+	return proxy.Docker.ContainerStop(ctx, container, timeout)
+}
+
+// ContainerWait invokes dockerclient.Client.ContainerWait
+func (proxy ThinDockerClientProxy) ContainerWait(ctx context.Context, container string) (int64, error) {
+	return proxy.Docker.ContainerWait(ctx, container)
+}
+
+// ImageInspectWithRaw invokes dockerclient.Client.ImageInspectWithRaw
+func (proxy ThinDockerClientProxy) ImageInspectWithRaw(ctx context.Context, image string) (dockertypes.ImageInspect, []byte, error) {
+	return proxy.Docker.ImageInspectWithRaw(ctx, image)
+}
+
+// ImageLoad invokes dockerclient.Client.ImageLoad
+func (proxy ThinDockerClientProxy) ImageLoad(ctx context.Context, input io.Reader, quiet bool) (dockertypes.ImageLoadResponse, error) {
+	return proxy.Docker.ImageLoad(ctx, input, quiet)
+}
+
+// ImageRemove invokes dockerclient.Client.ImageRemove
+func (proxy ThinDockerClientProxy) ImageRemove(ctx context.Context, image string, options dockertypes.ImageRemoveOptions) ([]dockertypes.ImageDeleteResponseItem, error) {
+	return proxy.Docker.ImageRemove(ctx, image, options)
 }
 
 // ContainerRunner is the main stateful struct used for a single execution of a
@@ -195,10 +242,10 @@ func (runner *ContainerRunner) LoadImage() (err error) {
 		}
 
 		response, err := runner.Docker.ImageLoad(context.TODO(), readCloser, false)
-		response.Body.Close()
 		if err != nil {
 			return fmt.Errorf("While loading container image into Docker: %v", err)
 		}
+		response.Body.Close()
 	} else {
 		runner.CrunchLog.Print("Docker image is available")
 	}
@@ -732,11 +779,9 @@ func (runner *ContainerRunner) WaitFinish() error {
 		return fmt.Errorf("container wait: %v", err)
 	}
 
-	if waitDocker != 0 { // what is the acceptable waitDocker code?
-		runner.CrunchLog.Printf("container wait API status code: %v", waitDocker)
-		code := int(waitDocker)
-		runner.ExitCode = &code
-	}
+	runner.CrunchLog.Printf("container wait API status code: %v", waitDocker)
+	code := int(waitDocker)
+	runner.ExitCode = &code
 
 	waitMount := runner.ArvMountExit
 	select {
@@ -1205,7 +1250,9 @@ func main() {
 		log.Fatalf("%s: %v", containerId, err)
 	}
 
-	cr := NewContainerRunner(api, kc, docker, containerId)
+	dockerClientProxy := ThinDockerClientProxy{Docker: docker}
+
+	cr := NewContainerRunner(api, kc, dockerClientProxy, containerId)
 	cr.statInterval = *statInterval
 	cr.cgroupRoot = *cgroupRoot
 	cr.expectCgroupParent = *cgroupParent
diff --git a/services/crunch-run/crunchrun_test.go b/services/crunch-run/crunchrun_test.go
index 7224c4f..5cd0d41 100644
--- a/services/crunch-run/crunchrun_test.go
+++ b/services/crunch-run/crunchrun_test.go
@@ -1,7 +1,9 @@
 package main
 
 import (
+	"bufio"
 	"bytes"
+	"context"
 	"crypto/md5"
 	"encoding/json"
 	"errors"
@@ -23,7 +25,10 @@ import (
 	"git.curoverse.com/arvados.git/sdk/go/arvadosclient"
 	"git.curoverse.com/arvados.git/sdk/go/keepclient"
 	"git.curoverse.com/arvados.git/sdk/go/manifest"
-	"github.com/curoverse/dockerclient"
+
+	dockertypes "github.com/docker/docker/api/types"
+	dockercontainer "github.com/docker/docker/api/types/container"
+	dockernetwork "github.com/docker/docker/api/types/network"
 	. "gopkg.in/check.v1"
 )
 
@@ -73,55 +78,36 @@ type TestDockerClient struct {
 	logReader   io.ReadCloser
 	logWriter   io.WriteCloser
 	fn          func(t *TestDockerClient)
-	finish      chan dockerclient.WaitResult
+	finish      int
 	stop        chan bool
 	cwd         string
 	env         []string
 	api         *ArvTestClient
 }
 
-func NewTestDockerClient() *TestDockerClient {
+func NewTestDockerClient(exitCode int) *TestDockerClient {
 	t := &TestDockerClient{}
 	t.logReader, t.logWriter = io.Pipe()
-	t.finish = make(chan dockerclient.WaitResult)
+	t.finish = exitCode
 	t.stop = make(chan bool)
 	t.cwd = "/"
 	return t
 }
 
-func (t *TestDockerClient) StopContainer(id string, timeout int) error {
-	t.stop <- true
-	return nil
-}
-
-func (t *TestDockerClient) InspectImage(id string) (*dockerclient.ImageInfo, error) {
-	if t.imageLoaded == id {
-		return &dockerclient.ImageInfo{}, nil
-	} else {
-		return nil, errors.New("")
-	}
+func (t *TestDockerClient) ContainerAttach(ctx context.Context, container string, options dockertypes.ContainerAttachOptions) (dockertypes.HijackedResponse, error) {
+	return dockertypes.HijackedResponse{Reader: bufio.NewReader(t.logReader)}, nil
 }
 
-func (t *TestDockerClient) LoadImage(reader io.Reader) error {
-	_, err := io.Copy(ioutil.Discard, reader)
-	if err != nil {
-		return err
-	} else {
-		t.imageLoaded = hwImageId
-		return nil
-	}
-}
-
-func (t *TestDockerClient) CreateContainer(config *dockerclient.ContainerConfig, name string, authConfig *dockerclient.AuthConfig) (string, error) {
+func (t *TestDockerClient) ContainerCreate(ctx context.Context, config *dockercontainer.Config, hostConfig *dockercontainer.HostConfig, networkingConfig *dockernetwork.NetworkingConfig, containerName string) (dockercontainer.ContainerCreateCreatedBody, error) {
 	if config.WorkingDir != "" {
 		t.cwd = config.WorkingDir
 	}
 	t.env = config.Env
-	return "abcde", nil
+	return dockercontainer.ContainerCreateCreatedBody{ID: "abcde"}, nil
 }
 
-func (t *TestDockerClient) StartContainer(id string, config *dockerclient.HostConfig) error {
-	if id == "abcde" {
+func (t *TestDockerClient) ContainerStart(ctx context.Context, container string, options dockertypes.ContainerStartOptions) error {
+	if container == "abcde" {
 		go t.fn(t)
 		return nil
 	} else {
@@ -129,15 +115,34 @@ func (t *TestDockerClient) StartContainer(id string, config *dockerclient.HostCo
 	}
 }
 
-func (t *TestDockerClient) AttachContainer(id string, options *dockerclient.AttachOptions) (io.ReadCloser, error) {
-	return t.logReader, nil
+func (t *TestDockerClient) ContainerStop(ctx context.Context, container string, timeout *time.Duration) error {
+	t.stop <- true
+	return nil
+}
+
+func (t *TestDockerClient) ContainerWait(ctx context.Context, container string) (int64, error) {
+	return int64(t.finish), nil
 }
 
-func (t *TestDockerClient) Wait(id string) <-chan dockerclient.WaitResult {
-	return t.finish
+func (t *TestDockerClient) ImageInspectWithRaw(ctx context.Context, image string) (dockertypes.ImageInspect, []byte, error) {
+	if t.imageLoaded == image {
+		return dockertypes.ImageInspect{}, nil, nil
+	} else {
+		return dockertypes.ImageInspect{}, nil, errors.New("")
+	}
 }
 
-func (*TestDockerClient) RemoveImage(name string, force bool) ([]*dockerclient.ImageDelete, error) {
+func (t *TestDockerClient) ImageLoad(ctx context.Context, input io.Reader, quiet bool) (dockertypes.ImageLoadResponse, error) {
+	_, err := io.Copy(ioutil.Discard, input)
+	if err != nil {
+		return dockertypes.ImageLoadResponse{}, err
+	} else {
+		t.imageLoaded = hwImageId
+		return dockertypes.ImageLoadResponse{Body: ioutil.NopCloser(input)}, nil
+	}
+}
+
+func (*TestDockerClient) ImageRemove(ctx context.Context, image string, options dockertypes.ImageRemoveOptions) ([]dockertypes.ImageDeleteResponseItem, error) {
 	return nil, nil
 }
 
@@ -287,12 +292,12 @@ func (client *KeepTestClient) ManifestFileReader(m manifest.Manifest, filename s
 
 func (s *TestSuite) TestLoadImage(c *C) {
 	kc := &KeepTestClient{}
-	docker := NewTestDockerClient()
+	docker := NewTestDockerClient(0)
 	cr := NewContainerRunner(&ArvTestClient{}, kc, docker, "zzzzz-zzzzz-zzzzzzzzzzzzzzz")
 
-	_, err := cr.Docker.RemoveImage(hwImageId, true)
+	_, err := cr.Docker.ImageRemove(nil, hwImageId, dockertypes.ImageRemoveOptions{})
 
-	_, err = cr.Docker.InspectImage(hwImageId)
+	_, _, err = cr.Docker.ImageInspectWithRaw(nil, hwImageId)
 	c.Check(err, NotNil)
 
 	cr.Container.ContainerImage = hwPDH
@@ -305,13 +310,13 @@ func (s *TestSuite) TestLoadImage(c *C) {
 
 	c.Check(err, IsNil)
 	defer func() {
-		cr.Docker.RemoveImage(hwImageId, true)
+		cr.Docker.ImageRemove(nil, hwImageId, dockertypes.ImageRemoveOptions{})
 	}()
 
 	c.Check(kc.Called, Equals, true)
 	c.Check(cr.ContainerConfig.Image, Equals, hwImageId)
 
-	_, err = cr.Docker.InspectImage(hwImageId)
+	_, _, err = cr.Docker.ImageInspectWithRaw(nil, hwImageId)
 	c.Check(err, IsNil)
 
 	// (2) Test using image that's already loaded
@@ -403,7 +408,7 @@ func (s *TestSuite) TestLoadImageArvError(c *C) {
 
 func (s *TestSuite) TestLoadImageKeepError(c *C) {
 	// (2) Keep error
-	docker := NewTestDockerClient()
+	docker := NewTestDockerClient(0)
 	cr := NewContainerRunner(&ArvTestClient{}, KeepErrorTestClient{}, docker, "zzzzz-zzzzz-zzzzzzzzzzzzzzz")
 	cr.Container.ContainerImage = hwPDH
 
@@ -422,7 +427,7 @@ func (s *TestSuite) TestLoadImageCollectionError(c *C) {
 
 func (s *TestSuite) TestLoadImageKeepReadError(c *C) {
 	// (4) Collection doesn't contain image
-	docker := NewTestDockerClient()
+	docker := NewTestDockerClient(0)
 	cr := NewContainerRunner(&ArvTestClient{}, KeepReadErrorTestClient{}, docker, "zzzzz-zzzzz-zzzzzzzzzzzzzzz")
 	cr.Container.ContainerImage = hwPDH
 
@@ -463,11 +468,10 @@ func dockerLog(fd byte, msg string) []byte {
 }
 
 func (s *TestSuite) TestRunContainer(c *C) {
-	docker := NewTestDockerClient()
+	docker := NewTestDockerClient(0)
 	docker.fn = func(t *TestDockerClient) {
 		t.logWriter.Write(dockerLog(1, "Hello world\n"))
 		t.logWriter.Close()
-		t.finish <- dockerclient.WaitResult{}
 	}
 	cr := NewContainerRunner(&ArvTestClient{}, &KeepTestClient{}, docker, "zzzzz-zzzzz-zzzzzzzzzzzzzzz")
 
@@ -559,14 +563,14 @@ func (s *TestSuite) TestUpdateContainerCancelled(c *C) {
 
 // Used by the TestFullRun*() test below to DRY up boilerplate setup to do full
 // dress rehearsal of the Run() function, starting from a JSON container record.
-func FullRunHelper(c *C, record string, extraMounts []string, fn func(t *TestDockerClient)) (api *ArvTestClient, cr *ContainerRunner, realTemp string) {
+func FullRunHelper(c *C, record string, extraMounts []string, exitCode int, fn func(t *TestDockerClient)) (api *ArvTestClient, cr *ContainerRunner, realTemp string) {
 	rec := arvados.Container{}
 	err := json.Unmarshal([]byte(record), &rec)
 	c.Check(err, IsNil)
 
-	docker := NewTestDockerClient()
+	docker := NewTestDockerClient(exitCode)
 	docker.fn = fn
-	docker.RemoveImage(hwImageId, true)
+	docker.ImageRemove(nil, hwImageId, dockertypes.ImageRemoveOptions{})
 
 	api = &ArvTestClient{Container: rec}
 	docker.api = api
@@ -626,10 +630,9 @@ func (s *TestSuite) TestFullRunHello(c *C) {
     "output_path": "/tmp",
     "priority": 1,
     "runtime_constraints": {}
-}`, nil, func(t *TestDockerClient) {
+}`, nil, 0, func(t *TestDockerClient) {
 		t.logWriter.Write(dockerLog(1, "hello world\n"))
 		t.logWriter.Close()
-		t.finish <- dockerclient.WaitResult{}
 	})
 
 	c.Check(api.CalledWith("container.exit_code", 0), NotNil)
@@ -648,10 +651,9 @@ func (s *TestSuite) TestCrunchstat(c *C) {
 		"output_path": "/tmp",
 		"priority": 1,
 		"runtime_constraints": {}
-	}`, nil, func(t *TestDockerClient) {
+	}`, nil, 0, func(t *TestDockerClient) {
 		time.Sleep(time.Second)
 		t.logWriter.Close()
-		t.finish <- dockerclient.WaitResult{}
 	})
 
 	c.Check(api.CalledWith("container.exit_code", 0), NotNil)
@@ -731,11 +733,10 @@ func (s *TestSuite) TestFullRunStderr(c *C) {
     "output_path": "/tmp",
     "priority": 1,
     "runtime_constraints": {}
-}`, nil, func(t *TestDockerClient) {
+}`, nil, 1, func(t *TestDockerClient) {
 		t.logWriter.Write(dockerLog(1, "hello\n"))
 		t.logWriter.Write(dockerLog(2, "world\n"))
 		t.logWriter.Close()
-		t.finish <- dockerclient.WaitResult{ExitCode: 1}
 	})
 
 	final := api.CalledWith("container.state", "Complete")
@@ -757,10 +758,9 @@ func (s *TestSuite) TestFullRunDefaultCwd(c *C) {
     "output_path": "/tmp",
     "priority": 1,
     "runtime_constraints": {}
-}`, nil, func(t *TestDockerClient) {
+}`, nil, 0, func(t *TestDockerClient) {
 		t.logWriter.Write(dockerLog(1, t.cwd+"\n"))
 		t.logWriter.Close()
-		t.finish <- dockerclient.WaitResult{ExitCode: 0}
 	})
 
 	c.Check(api.CalledWith("container.exit_code", 0), NotNil)
@@ -779,10 +779,9 @@ func (s *TestSuite) TestFullRunSetCwd(c *C) {
     "output_path": "/tmp",
     "priority": 1,
     "runtime_constraints": {}
-}`, nil, func(t *TestDockerClient) {
+}`, nil, 0, func(t *TestDockerClient) {
 		t.logWriter.Write(dockerLog(1, t.cwd+"\n"))
 		t.logWriter.Close()
-		t.finish <- dockerclient.WaitResult{ExitCode: 0}
 	})
 
 	c.Check(api.CalledWith("container.exit_code", 0), NotNil)
@@ -827,14 +826,13 @@ func (s *TestSuite) testStopContainer(c *C, setup func(cr *ContainerRunner)) {
 	err := json.Unmarshal([]byte(record), &rec)
 	c.Check(err, IsNil)
 
-	docker := NewTestDockerClient()
+	docker := NewTestDockerClient(0)
 	docker.fn = func(t *TestDockerClient) {
 		<-t.stop
 		t.logWriter.Write(dockerLog(1, "foo\n"))
 		t.logWriter.Close()
-		t.finish <- dockerclient.WaitResult{ExitCode: 0}
 	}
-	docker.RemoveImage(hwImageId, true)
+	docker.ImageRemove(nil, hwImageId, dockertypes.ImageRemoveOptions{})
 
 	api := &ArvTestClient{Container: rec}
 	cr := NewContainerRunner(api, &KeepTestClient{}, docker, "zzzzz-zzzzz-zzzzzzzzzzzzzzz")
@@ -872,10 +870,9 @@ func (s *TestSuite) TestFullRunSetEnv(c *C) {
     "output_path": "/tmp",
     "priority": 1,
     "runtime_constraints": {}
-}`, nil, func(t *TestDockerClient) {
+}`, nil, 0, func(t *TestDockerClient) {
 		t.logWriter.Write(dockerLog(1, t.env[0][7:]+"\n"))
 		t.logWriter.Close()
-		t.finish <- dockerclient.WaitResult{ExitCode: 0}
 	})
 
 	c.Check(api.CalledWith("container.exit_code", 0), NotNil)
@@ -1130,10 +1127,9 @@ func (s *TestSuite) TestStdout(c *C) {
 		"runtime_constraints": {}
 	}`
 
-	api, _, _ := FullRunHelper(c, helperRecord, nil, func(t *TestDockerClient) {
+	api, _, _ := FullRunHelper(c, helperRecord, nil, 0, func(t *TestDockerClient) {
 		t.logWriter.Write(dockerLog(1, t.env[0][7:]+"\n"))
 		t.logWriter.Close()
-		t.finish <- dockerclient.WaitResult{ExitCode: 0}
 	})
 
 	c.Check(api.CalledWith("container.exit_code", 0), NotNil)
@@ -1147,9 +1143,9 @@ func StdoutErrorRunHelper(c *C, record string, fn func(t *TestDockerClient)) (ap
 	err = json.Unmarshal([]byte(record), &rec)
 	c.Check(err, IsNil)
 
-	docker := NewTestDockerClient()
+	docker := NewTestDockerClient(0)
 	docker.fn = fn
-	docker.RemoveImage(hwImageId, true)
+	docker.ImageRemove(nil, hwImageId, dockertypes.ImageRemoveOptions{})
 
 	api = &ArvTestClient{Container: rec}
 	cr = NewContainerRunner(api, &KeepTestClient{}, docker, "zzzzz-zzzzz-zzzzzzzzzzzzzzz")
@@ -1202,10 +1198,9 @@ func (s *TestSuite) TestFullRunWithAPI(c *C) {
     "output_path": "/tmp",
     "priority": 1,
     "runtime_constraints": {"API": true}
-}`, nil, func(t *TestDockerClient) {
+}`, nil, 0, func(t *TestDockerClient) {
 		t.logWriter.Write(dockerLog(1, t.env[1][17:]+"\n"))
 		t.logWriter.Close()
-		t.finish <- dockerclient.WaitResult{ExitCode: 0}
 	})
 
 	c.Check(api.CalledWith("container.exit_code", 0), NotNil)
@@ -1226,10 +1221,9 @@ func (s *TestSuite) TestFullRunSetOutput(c *C) {
     "output_path": "/tmp",
     "priority": 1,
     "runtime_constraints": {"API": true}
-}`, nil, func(t *TestDockerClient) {
+}`, nil, 0, func(t *TestDockerClient) {
 		t.api.Container.Output = "d4ab34d3d4f8a72f5c4973051ae69fab+122"
 		t.logWriter.Close()
-		t.finish <- dockerclient.WaitResult{ExitCode: 0}
 	})
 
 	c.Check(api.CalledWith("container.exit_code", 0), NotNil)
@@ -1258,10 +1252,9 @@ func (s *TestSuite) TestStdoutWithExcludeFromOutputMountPointUnderOutputDir(c *C
 
 	extraMounts := []string{"a3e8f74c6f101eae01fa08bfb4e49b3a+54"}
 
-	api, _, _ := FullRunHelper(c, helperRecord, extraMounts, func(t *TestDockerClient) {
+	api, _, _ := FullRunHelper(c, helperRecord, extraMounts, 0, func(t *TestDockerClient) {
 		t.logWriter.Write(dockerLog(1, t.env[0][7:]+"\n"))
 		t.logWriter.Close()
-		t.finish <- dockerclient.WaitResult{ExitCode: 0}
 	})
 
 	c.Check(api.CalledWith("container.exit_code", 0), NotNil)
@@ -1294,10 +1287,9 @@ func (s *TestSuite) TestStdoutWithMultipleMountPointsUnderOutputDir(c *C) {
 		"a0def87f80dd594d4675809e83bd4f15+367/subdir1/subdir2/file2_in_subdir2.txt",
 	}
 
-	api, runner, realtemp := FullRunHelper(c, helperRecord, extraMounts, func(t *TestDockerClient) {
+	api, runner, realtemp := FullRunHelper(c, helperRecord, extraMounts, 0, func(t *TestDockerClient) {
 		t.logWriter.Write(dockerLog(1, t.env[0][7:]+"\n"))
 		t.logWriter.Close()
-		t.finish <- dockerclient.WaitResult{ExitCode: 0}
 	})
 
 	c.Check(runner.Binds, DeepEquals, []string{realtemp + "/2:/tmp",
@@ -1347,10 +1339,9 @@ func (s *TestSuite) TestStdoutWithMountPointsUnderOutputDirDenormalizedManifest(
 		"b0def87f80dd594d4675809e83bd4f15+367/subdir1/file2_in_subdir1.txt",
 	}
 
-	api, _, _ := FullRunHelper(c, helperRecord, extraMounts, func(t *TestDockerClient) {
+	api, _, _ := FullRunHelper(c, helperRecord, extraMounts, 0, func(t *TestDockerClient) {
 		t.logWriter.Write(dockerLog(1, t.env[0][7:]+"\n"))
 		t.logWriter.Close()
-		t.finish <- dockerclient.WaitResult{ExitCode: 0}
 	})
 
 	c.Check(api.CalledWith("container.exit_code", 0), NotNil)

commit e8e9262a0f5e1e5908d338ac1655a2cdfaecf23a
Author: Peter Amstutz <peter.amstutz at curoverse.com>
Date:   Thu Mar 30 14:09:28 2017 -0400

    9132: few more updates to use the new API

diff --git a/services/crunch-run/crunchrun.go b/services/crunch-run/crunchrun.go
index 8f6f847..80ca27f 100644
--- a/services/crunch-run/crunchrun.go
+++ b/services/crunch-run/crunchrun.go
@@ -25,8 +25,10 @@ import (
 	"git.curoverse.com/arvados.git/sdk/go/arvadosclient"
 	"git.curoverse.com/arvados.git/sdk/go/keepclient"
 	"git.curoverse.com/arvados.git/sdk/go/manifest"
+
 	dockertypes "github.com/docker/docker/api/types"
-	containertypes "github.com/docker/docker/api/types/container"
+	dockercontainer "github.com/docker/docker/api/types/container"
+	dockernetwork "github.com/docker/docker/api/types/network"
 	dockerclient "github.com/docker/docker/client"
 )
 
@@ -61,8 +63,8 @@ type ThinDockerClient interface {
 	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)
-	ContainerCreate(ctx context.Context, config *container.Config, hostConfig *container.HostConfig,
-		networkingConfig *network.NetworkingConfig, containerName string) (container.ContainerCreateCreatedBody, error)
+	ContainerCreate(ctx context.Context, config *dockercontainer.Config, hostConfig *dockercontainer.HostConfig,
+		networkingConfig *dockernetwork.NetworkingConfig, containerName string) (dockercontainer.ContainerCreateCreatedBody, error)
 	ContainerStart(ctx context.Context, container string, options dockertypes.ContainerStartOptions) error
 	ContainerAttach(ctx context.Context, container string, options dockertypes.ContainerAttachOptions) (dockertypes.HijackedResponse, error)
 	ContainerStop(ctx context.Context, container string, timeout *time.Duration) error
@@ -76,8 +78,8 @@ type ContainerRunner struct {
 	ArvClient IArvadosClient
 	Kc        IKeepClient
 	arvados.Container
-	ContainerConfig containertypes.Config
-	dockerclient.HostConfig
+	ContainerConfig dockercontainer.Config
+	dockercontainer.HostConfig
 	token       string
 	ContainerID string
 	ExitCode    *int
@@ -150,7 +152,8 @@ func (runner *ContainerRunner) stop() {
 	}
 	runner.cCancelled = true
 	if runner.cStarted {
-		err := runner.Docker.ContainerStop(context.TODO(), runner.ContainerID, 10)
+		timeout := time.Duration(10)
+		err := runner.Docker.ContainerStop(context.TODO(), runner.ContainerID, &(timeout))
 		if err != nil {
 			log.Printf("StopContainer failed: %s", err)
 		}
@@ -191,7 +194,7 @@ func (runner *ContainerRunner) LoadImage() (err error) {
 			return fmt.Errorf("While creating ManifestFileReader for container image: %v", err)
 		}
 
-		response, err = runner.Docker.ImageLoad(context.TODO(), readCloser, false)
+		response, err := runner.Docker.ImageLoad(context.TODO(), readCloser, false)
 		response.Body.Close()
 		if err != nil {
 			return fmt.Errorf("While loading container image into Docker: %v", err)
@@ -613,9 +616,8 @@ func (runner *ContainerRunner) AttachStreams() (err error) {
 
 	runner.CrunchLog.Print("Attaching container streams")
 
-	var containerReader io.Reader
-	containerReader, err = runner.Docker.ContainerAttach(context.TODO(), runner.ContainerID,
-		&dockertypes.ContainerAttachOptions{Stream: true, Stdout: true, Stderr: true})
+	response, err := runner.Docker.ContainerAttach(context.TODO(), runner.ContainerID,
+		dockertypes.ContainerAttachOptions{Stream: true, Stdout: true, Stderr: true})
 	if err != nil {
 		return fmt.Errorf("While attaching container stdout/stderr streams: %v", err)
 	}
@@ -649,7 +651,7 @@ func (runner *ContainerRunner) AttachStreams() (err error) {
 	}
 	runner.Stderr = NewThrottledLogger(runner.NewLogWriter("stderr"))
 
-	go runner.ProcessDockerAttach(containerReader)
+	go runner.ProcessDockerAttach(response.Reader)
 
 	return nil
 }
@@ -669,9 +671,9 @@ func (runner *ContainerRunner) CreateContainer() error {
 
 	runner.ContainerID = createdBody.ID
 	runner.HostConfig = dockerclient.HostConfig{
-		Binds:        runner.Binds,
-		CgroupParent: runner.setCgroupParent,
-		LogConfig: dockerclient.LogConfig{
+		Binds:  runner.Binds,
+		Cgroup: dockercontainer.CgroupSpec(runner.setCgroupParent),
+		LogConfig: dockercontainer.LogConfig{
 			Type: "none",
 		},
 	}
@@ -711,7 +713,8 @@ func (runner *ContainerRunner) StartContainer() error {
 	if runner.cCancelled {
 		return ErrCancelled
 	}
-	err := runner.Docker.StartContainer(runner.ContainerID, &runner.HostConfig)
+	err := runner.Docker.ContainerStart(context.TODO(), runner.ContainerID,
+		dockertypes.ContainerStartOptions{})
 	if err != nil {
 		return fmt.Errorf("could not start container: %v", err)
 	}
@@ -724,21 +727,24 @@ func (runner *ContainerRunner) StartContainer() error {
 func (runner *ContainerRunner) WaitFinish() error {
 	runner.CrunchLog.Print("Waiting for container to finish")
 
-	waitDocker := runner.Docker.Wait(runner.ContainerID)
+	waitDocker, err := runner.Docker.ContainerWait(context.TODO(), runner.ContainerID)
+	if err != nil {
+		return fmt.Errorf("container wait: %v", err)
+	}
+
+	if waitDocker != 0 { // what is the acceptable waitDocker code?
+		runner.CrunchLog.Printf("container wait API status code: %v", waitDocker)
+		code := int(waitDocker)
+		runner.ExitCode = &code
+	}
+
 	waitMount := runner.ArvMountExit
-	for waitDocker != nil {
-		select {
-		case err := <-waitMount:
-			runner.CrunchLog.Printf("arv-mount exited before container finished: %v", err)
-			waitMount = nil
-			runner.stop()
-		case wr := <-waitDocker:
-			if wr.Error != nil {
-				return fmt.Errorf("While waiting for container to finish: %v", wr.Error)
-			}
-			runner.ExitCode = &wr.ExitCode
-			waitDocker = nil
-		}
+	select {
+	case err := <-waitMount:
+		runner.CrunchLog.Printf("arv-mount exited before container finished: %v", err)
+		waitMount = nil
+		runner.stop()
+	default:
 	}
 
 	// wait for stdout/stderr to complete

commit 6fe136c2c7419dfb38a9af42898682701646b518
Author: Peter Amstutz <peter.amstutz at curoverse.com>
Date:   Thu Mar 30 14:07:01 2017 -0400

    9132: WIP switching to using official Docker Go client.

diff --git a/services/crunch-run/crunchrun.go b/services/crunch-run/crunchrun.go
index 062126d..8f6f847 100644
--- a/services/crunch-run/crunchrun.go
+++ b/services/crunch-run/crunchrun.go
@@ -1,6 +1,7 @@
 package main
 
 import (
+	"context"
 	"encoding/json"
 	"errors"
 	"flag"
@@ -24,7 +25,9 @@ import (
 	"git.curoverse.com/arvados.git/sdk/go/arvadosclient"
 	"git.curoverse.com/arvados.git/sdk/go/keepclient"
 	"git.curoverse.com/arvados.git/sdk/go/manifest"
-	"github.com/curoverse/dockerclient"
+	dockertypes "github.com/docker/docker/api/types"
+	containertypes "github.com/docker/docker/api/types/container"
+	dockerclient "github.com/docker/docker/client"
 )
 
 // IArvadosClient is the minimal Arvados API methods used by crunch-run.
@@ -55,14 +58,15 @@ type MkTempDir func(string, string) (string, error)
 
 // ThinDockerClient is the minimal Docker client interface used by crunch-run.
 type ThinDockerClient interface {
-	StopContainer(id string, timeout int) error
-	InspectImage(id string) (*dockerclient.ImageInfo, error)
-	LoadImage(reader io.Reader) error
-	CreateContainer(config *dockerclient.ContainerConfig, name string, authConfig *dockerclient.AuthConfig) (string, error)
-	StartContainer(id string, config *dockerclient.HostConfig) error
-	AttachContainer(id string, options *dockerclient.AttachOptions) (io.ReadCloser, error)
-	Wait(id string) <-chan dockerclient.WaitResult
-	RemoveImage(name string, force bool) ([]*dockerclient.ImageDelete, 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)
+	ContainerCreate(ctx context.Context, config *container.Config, hostConfig *container.HostConfig,
+		networkingConfig *network.NetworkingConfig, containerName string) (container.ContainerCreateCreatedBody, error)
+	ContainerStart(ctx context.Context, container string, options dockertypes.ContainerStartOptions) error
+	ContainerAttach(ctx context.Context, container string, options dockertypes.ContainerAttachOptions) (dockertypes.HijackedResponse, error)
+	ContainerStop(ctx context.Context, container string, timeout *time.Duration) error
+	ContainerWait(ctx context.Context, container string) (int64, error)
 }
 
 // ContainerRunner is the main stateful struct used for a single execution of a
@@ -72,7 +76,7 @@ type ContainerRunner struct {
 	ArvClient IArvadosClient
 	Kc        IKeepClient
 	arvados.Container
-	dockerclient.ContainerConfig
+	ContainerConfig containertypes.Config
 	dockerclient.HostConfig
 	token       string
 	ContainerID string
@@ -146,7 +150,7 @@ func (runner *ContainerRunner) stop() {
 	}
 	runner.cCancelled = true
 	if runner.cStarted {
-		err := runner.Docker.StopContainer(runner.ContainerID, 10)
+		err := runner.Docker.ContainerStop(context.TODO(), runner.ContainerID, 10)
 		if err != nil {
 			log.Printf("StopContainer failed: %s", err)
 		}
@@ -177,7 +181,7 @@ func (runner *ContainerRunner) LoadImage() (err error) {
 
 	runner.CrunchLog.Printf("Using Docker image id '%s'", imageID)
 
-	_, err = runner.Docker.InspectImage(imageID)
+	_, _, err = runner.Docker.ImageInspectWithRaw(context.TODO(), imageID)
 	if err != nil {
 		runner.CrunchLog.Print("Loading Docker image from keep")
 
@@ -187,7 +191,8 @@ func (runner *ContainerRunner) LoadImage() (err error) {
 			return fmt.Errorf("While creating ManifestFileReader for container image: %v", err)
 		}
 
-		err = runner.Docker.LoadImage(readCloser)
+		response, err = runner.Docker.ImageLoad(context.TODO(), readCloser, false)
+		response.Body.Close()
 		if err != nil {
 			return fmt.Errorf("While loading container image into Docker: %v", err)
 		}
@@ -609,8 +614,8 @@ func (runner *ContainerRunner) AttachStreams() (err error) {
 	runner.CrunchLog.Print("Attaching container streams")
 
 	var containerReader io.Reader
-	containerReader, err = runner.Docker.AttachContainer(runner.ContainerID,
-		&dockerclient.AttachOptions{Stream: true, Stdout: true, Stderr: true})
+	containerReader, err = runner.Docker.ContainerAttach(context.TODO(), runner.ContainerID,
+		&dockertypes.ContainerAttachOptions{Stream: true, Stdout: true, Stderr: true})
 	if err != nil {
 		return fmt.Errorf("While attaching container stdout/stderr streams: %v", err)
 	}
@@ -662,6 +667,7 @@ func (runner *ContainerRunner) CreateContainer() error {
 		runner.ContainerConfig.Env = append(runner.ContainerConfig.Env, k+"="+v)
 	}
 
+	runner.ContainerID = createdBody.ID
 	runner.HostConfig = dockerclient.HostConfig{
 		Binds:        runner.Binds,
 		CgroupParent: runner.setCgroupParent,
@@ -689,8 +695,7 @@ func (runner *ContainerRunner) CreateContainer() error {
 		}
 	}
 
-	var err error
-	runner.ContainerID, err = runner.Docker.CreateContainer(&runner.ContainerConfig, "", nil)
+	createdBody, err := runner.Docker.ContainerCreate(context.TODO(), &runner.ContainerConfig, nil, nil, "")
 	if err != nil {
 		return fmt.Errorf("While creating container: %v", err)
 	}
@@ -1186,8 +1191,10 @@ func main() {
 	}
 	kc.Retries = 4
 
-	var docker *dockerclient.DockerClient
-	docker, err = dockerclient.NewDockerClient("unix:///var/run/docker.sock", nil)
+	var docker *dockerclient.Client
+	// API version 1.21 corresponds to Docker 1.9, which is currently the
+	// minimum version we want to support.
+	docker, err = dockerclient.NewClient(dockerclient.DefaultDockerHost, "1.21", nil, nil)
 	if err != nil {
 		log.Fatalf("%s: %v", containerId, err)
 	}

-----------------------------------------------------------------------


hooks/post-receive
-- 




More information about the arvados-commits mailing list