diff --git a/api/agent/agent_test.go b/api/agent/agent_test.go index 6e15c177f..c147dc652 100644 --- a/api/agent/agent_test.go +++ b/api/agent/agent_test.go @@ -535,6 +535,60 @@ func TestDockerPullHungRepo(t *testing.T) { } } +func TestDockerPullUnAuthorizedRepo(t *testing.T) { + garbageServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + // version check seem to have a sane timeout in docker, let's serve this, then stop + if r.URL.String() == "/v2/" { + w.WriteHeader(200) + return + } + w.WriteHeader(401) + return + })) + defer garbageServer.Close() + + dest := strings.TrimPrefix(garbageServer.URL, "http://") + + app := &models.App{ID: "app_id"} + fn := &models.Fn{ + ID: "fn_id", + Image: dest + "/fnproject/fn-test-utils", + ResourceConfig: models.ResourceConfig{ + Timeout: 5, + IdleTimeout: 10, + Memory: 128, + }, + } + + url := "http://127.0.0.1:8080/invoke/" + fn.ID + + ls := logs.NewMock() + cfg, err := NewConfig() + cfg.MaxDockerRetries = 1 + cfg.HotPullTimeout = time.Duration(5) * time.Second + a := New(NewDirectCallDataAccess(ls, new(mqs.Mock)), WithConfig(cfg)) + defer checkClose(t, a) + + req, err := http.NewRequest("GET", url, &dummyReader{Reader: strings.NewReader(`{}`)}) + if err != nil { + t.Fatal("unexpected error building request", err) + } + + var out bytes.Buffer + callI, err := a.GetCall(FromHTTPFnRequest(app, fn, req), WithWriter(&out)) + if err != nil { + t.Fatal(err) + } + + err = a.Submit(callI) + if err == nil { + t.Fatal("submit should error!") + } + if models.GetAPIErrorCode(err) != http.StatusBadGateway { + t.Fatalf("unexpected error %v", err) + } +} + func TestDockerPullBadRepo(t *testing.T) { garbageServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { diff --git a/api/agent/drivers/docker/cookie.go b/api/agent/drivers/docker/cookie.go index 98f0836aa..289dc44a1 100644 --- a/api/agent/drivers/docker/cookie.go +++ b/api/agent/drivers/docker/cookie.go @@ -306,10 +306,12 @@ func (c *cookie) PullImage(ctx context.Context) error { // TODO need to inspect for hub or network errors and pick; for now, assume // 500 if not a docker error msg := err.Error() - code := http.StatusInternalServerError + code := http.StatusBadGateway if dErr, ok := err.(*docker.Error); ok { msg = dockerMsg(dErr) - code = dErr.Status // 401/404 + if dErr.Status >= 400 && dErr.Status < 500 { + code = dErr.Status // decap 4xx errors + } } return models.NewAPIError(code, fmt.Errorf("Failed to pull image '%s': %s", c.task.Image(), msg)) diff --git a/api/server/runner_fninvoke_test.go b/api/server/runner_fninvoke_test.go index 3e35b711b..f83814a6c 100644 --- a/api/server/runner_fninvoke_test.go +++ b/api/server/runner_fninvoke_test.go @@ -204,7 +204,7 @@ func TestFnInvokeRunnerExecution(t *testing.T) { {"/invoke/http_stream_fn_id", bigbuf, http.MethodPost, http.StatusRequestEntityTooLarge, nil, "", nil}, {"/invoke/dne_fn_id", ``, http.MethodPost, http.StatusNotFound, nil, "pull access denied", nil}, - {"/invoke/dnereg_fn_id", ``, http.MethodPost, http.StatusInternalServerError, nil, "connection refused", nil}, + {"/invoke/dnereg_fn_id", ``, http.MethodPost, http.StatusBadGateway, nil, "connection refused", nil}, // XXX(reed): what are these? {"/invoke/http_stream_fn_id", multiLog, http.MethodPost, http.StatusOK, nil, "", multiLogExpectHot}, diff --git a/api/server/runner_httptrigger_test.go b/api/server/runner_httptrigger_test.go index 9d42b0ff5..848c2af73 100644 --- a/api/server/runner_httptrigger_test.go +++ b/api/server/runner_httptrigger_test.go @@ -339,7 +339,7 @@ func TestTriggerRunnerExecution(t *testing.T) { {"/t/myapp/httpstream", nil, oomer, "POST", http.StatusBadGateway, nil, "error receiving function response", nil}, {"/t/myapp/mydne", nil, ``, "GET", http.StatusNotFound, nil, "pull access denied", nil}, - {"/t/myapp/mydneregistry", nil, ``, "GET", http.StatusInternalServerError, nil, "connection refused", nil}, + {"/t/myapp/mydneregistry", nil, ``, "GET", http.StatusBadGateway, nil, "connection refused", nil}, // XXX(reed): what are these? {"/t/myapp/httpstream", nil, multiLog, "GET", http.StatusOK, nil, "", multiLogExpectHot},