From: Tom Clegg Date: Thu, 26 May 2016 19:50:21 +0000 (-0400) Subject: 9272: Get container auth instead of passing the dispatcher token into the container. X-Git-Tag: 1.1.0~908^2~4 X-Git-Url: https://git.arvados.org/arvados.git/commitdiff_plain/6b2f232c3d73a023d64112c609a28c8ff9cc27de 9272: Get container auth instead of passing the dispatcher token into the container. --- diff --git a/services/crunch-run/crunchrun.go b/services/crunch-run/crunchrun.go index cebebb104a..a1b246c841 100644 --- a/services/crunch-run/crunchrun.go +++ b/services/crunch-run/crunchrun.go @@ -27,6 +27,7 @@ type IArvadosClient interface { Create(resourceType string, parameters arvadosclient.Dict, output interface{}) error Get(resourceType string, uuid string, parameters arvadosclient.Dict, output interface{}) error Update(resourceType string, uuid string, parameters arvadosclient.Dict, output interface{}) (err error) + Call(method, resourceType, uuid, action string, parameters arvadosclient.Dict, output interface{}) (err error) } // ErrCancelled is the error returned when the container is cancelled. @@ -69,10 +70,16 @@ type ContainerRecord struct { Output string `json:"output"` } +// APIClientAuthorization is an arvados#api_client_authorization resource. +type APIClientAuthorization struct { + UUID string `json:"uuid"` + APIToken string `json:"api_token"` +} + // NewLogWriter is a factory function to create a new log writer. type NewLogWriter func(name string) io.WriteCloser -type RunArvMount func([]string) (*exec.Cmd, error) +type RunArvMount func(args []string, tok string) (*exec.Cmd, error) type MkTempDir func(string, string) (string, error) @@ -189,8 +196,19 @@ func (runner *ContainerRunner) LoadImage() (err error) { return nil } -func (runner *ContainerRunner) ArvMountCmd(arvMountCmd []string) (c *exec.Cmd, err error) { +func (runner *ContainerRunner) ArvMountCmd(arvMountCmd []string, token string) (c *exec.Cmd, err error) { c = exec.Command("arv-mount", arvMountCmd...) + + // Copy our environment, but override ARVADOS_API_TOKEN with + // the container auth token. + c.Env = nil + for _, s := range os.Environ() { + if !strings.HasPrefix(s, "ARVADOS_API_TOKEN=") { + c.Env = append(c.Env, s) + } + } + c.Env = append(c.Env, "ARVADOS_API_TOKEN="+token) + nt := NewThrottledLogger(runner.NewLogWriter("arv-mount")) c.Stdout = nt c.Stderr = nt @@ -328,7 +346,12 @@ func (runner *ContainerRunner) SetupMounts() (err error) { } arvMountCmd = append(arvMountCmd, runner.ArvMountPoint) - runner.ArvMount, err = runner.RunArvMount(arvMountCmd) + token, err := runner.ContainerToken() + if err != nil { + return fmt.Errorf("could not get container token: %s", err) + } + + runner.ArvMount, err = runner.RunArvMount(arvMountCmd, token) if err != nil { return fmt.Errorf("While trying to start arv-mount: %v", err) } @@ -609,6 +632,14 @@ func (runner *ContainerRunner) UpdateContainerRecordRunning() error { arvadosclient.Dict{"container": arvadosclient.Dict{"state": "Running"}}, nil) } +// ContainerToken returns the api_token the container (and any +// arv-mount processes) are allowed to use. +func (runner *ContainerRunner) ContainerToken() (string, error) { + var auth APIClientAuthorization + err := runner.ArvClient.Call("GET", "containers", runner.ContainerRecord.UUID, "auth", nil, &auth) + return auth.APIToken, err +} + // UpdateContainerRecordComplete updates the container record state on API // server to "Complete" or "Cancelled" func (runner *ContainerRunner) UpdateContainerRecordComplete() error { diff --git a/services/crunch-run/crunchrun_test.go b/services/crunch-run/crunchrun_test.go index b0646289b2..7194f2f1ed 100644 --- a/services/crunch-run/crunchrun_test.go +++ b/services/crunch-run/crunchrun_test.go @@ -56,6 +56,9 @@ var hwImageId = "9c31ee32b3d15268a0754e8edc74d4f815ee014b693bc5109058e431dd5caea var otherManifest = ". 68a84f561b1d1708c6baff5e019a9ab3+46+Ae5d0af96944a3690becb1decdf60cc1c937f556d@5693216f 0:46:md5sum.txt\n" var otherPDH = "a3e8f74c6f101eae01fa08bfb4e49b3a+54" +var fakeAuthUUID = "zzzzz-gj3su-55pqoyepgi2glem" +var fakeAuthToken = "a3ltuwzqcu2u4sc0q7yhpc2w7s00fdcqecg5d6e0u3pfohmbjt" + type TestDockerClient struct { imageLoaded string logReader io.ReadCloser @@ -158,6 +161,19 @@ func (this *ArvTestClient) Create(resourceType string, return nil } +func (this *ArvTestClient) Call(method, resourceType, uuid, action string, parameters arvadosclient.Dict, output interface{}) error { + switch { + case method == "GET" && resourceType == "containers" && action == "auth": + return json.Unmarshal([]byte(`{ + "kind": "arvados#api_client_authorization", + "uuid": "`+fakeAuthUUID+`", + "api_token": "`+fakeAuthToken+`" + }`), output) + default: + return fmt.Errorf("Not found") + } +} + func (this *ArvTestClient) Get(resourceType string, uuid string, parameters arvadosclient.Dict, output interface{}) error { if resourceType == "collections" { if uuid == hwPDH { @@ -279,6 +295,10 @@ func (this ArvErrorTestClient) Create(resourceType string, return nil } +func (this ArvErrorTestClient) Call(method, resourceType, uuid, action string, parameters arvadosclient.Dict, output interface{}) error { + return errors.New("ArvError") +} + func (this ArvErrorTestClient) Get(resourceType string, uuid string, parameters arvadosclient.Dict, output interface{}) error { return errors.New("ArvError") } @@ -689,11 +709,13 @@ func (s *TestSuite) TestFullRunSetEnv(c *C) { } type ArvMountCmdLine struct { - Cmd []string + Cmd []string + token string } -func (am *ArvMountCmdLine) ArvMountTest(c []string) (*exec.Cmd, error) { +func (am *ArvMountCmdLine) ArvMountTest(c []string, token string) (*exec.Cmd, error) { am.Cmd = c + am.token = token return nil, nil }