diff --git a/storage/kubernetes/storage.go b/storage/kubernetes/storage.go index 32424321..bd48b3db 100644 --- a/storage/kubernetes/storage.go +++ b/storage/kubernetes/storage.go @@ -75,31 +75,42 @@ func (c *Config) open() (*client, error) { return nil, fmt.Errorf("create client: %v", err) } - // Don't try to synchronize this because creating third party resources is not - // a synchronous event. Even after the API server returns a 200, it can still - // take several seconds for them to actually appear. ctx, cancel := context.WithCancel(context.Background()) - go func() { - for { - if err := cli.createThirdPartyResources(); err != nil { - log.Printf("failed creating third party resources: %v", err) - } else { - return - } - select { - case <-ctx.Done(): - return - case <-time.After(30 * time.Second): + // Try to synchronously create the third party resources once. This doesn't mean + // they'll immediately be available, but ensures that the client will actually try + // once. + if err := cli.createThirdPartyResources(); err != nil { + log.Printf("failed creating third party resources: %v", err) + go func() { + for { + if err := cli.createThirdPartyResources(); err != nil { + log.Printf("failed creating third party resources: %v", err) + } else { + return + } + + select { + case <-ctx.Done(): + return + case <-time.After(30 * time.Second): + } } - } - }() + }() + } // If the client is closed, stop trying to create third party resources. cli.cancel = cancel return cli, nil } +// createThirdPartyResources attempts to create the third party resources dex +// requires or identifies that they're already enabled. +// +// Creating a third party resource does not mean that they'll be immediately available. +// +// TODO(ericchiang): Provide an option to wait for the third party resources +// to actually be available. func (cli *client) createThirdPartyResources() error { for _, r := range thirdPartyResources { err := cli.postResource("extensions/v1beta1", "", "thirdpartyresources", r) diff --git a/storage/kubernetes/storage_test.go b/storage/kubernetes/storage_test.go index 9132fd0a..769bba65 100644 --- a/storage/kubernetes/storage_test.go +++ b/storage/kubernetes/storage_test.go @@ -1,6 +1,7 @@ package kubernetes import ( + "fmt" "os" "testing" @@ -78,7 +79,7 @@ func TestURLFor(t *testing.T) { func TestStorage(t *testing.T) { client := loadClient(t) - conformance.RunTests(t, func() storage.Storage { + newStorage := func() storage.Storage { for _, resource := range []string{ resourceAuthCode, resourceAuthRequest, @@ -88,9 +89,14 @@ func TestStorage(t *testing.T) { resourcePassword, } { if err := client.deleteAll(resource); err != nil { + // Fatalf sometimes doesn't print the error message. + fmt.Fprintf(os.Stderr, "delete all %q failed: %v\n", resource, err) t.Fatalf("delete all %q failed: %v", resource, err) } } return client - }) + } + + conformance.RunTests(t, newStorage) + conformance.RunTransactionTests(t, newStorage) }