Merge pull request #6027 from inteon/remove_deprecated

Replace deprecated wait.PollImmediateUntil
This commit is contained in:
jetstack-bot 2023-05-09 10:07:48 +01:00 committed by GitHub
commit c52ba69548
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 65 additions and 84 deletions

View File

@ -118,10 +118,7 @@ func (o *Options) Run(ctx context.Context) {
}
log.SetOutput(o.ErrOut) // Log all intermediate errors to stderr
pollContext, cancel := context.WithTimeout(ctx, o.Wait)
defer cancel()
pollErr := wait.PollImmediateUntil(o.Interval, func() (done bool, err error) {
pollErr := wait.PollUntilContextTimeout(ctx, o.Interval, o.Wait, true, func(ctx context.Context) (bool, error) {
if err := o.APIChecker.Check(ctx); err != nil {
if !o.Verbose && errors.Unwrap(err) != nil {
err = errors.Unwrap(err)
@ -132,16 +129,16 @@ func (o *Options) Run(ctx context.Context) {
}
return true, nil
}, pollContext.Done())
})
log.SetOutput(o.Out) // Log conclusion to stdout
if pollErr != nil {
if errors.Is(pollContext.Err(), context.DeadlineExceeded) && o.Wait > 0 {
if errors.Is(pollErr, context.DeadlineExceeded) && o.Wait > 0 {
log.Printf("Timed out after %s", o.Wait)
}
cmcmdutil.SetExitCode(pollContext.Err())
cmcmdutil.SetExitCode(pollErr)
runtime.Goexit() // Do soft exit (handle all defers, that should set correct exit code)
}

View File

@ -114,7 +114,7 @@ func StartWebhookServer(t *testing.T, ctx context.Context, args []string, argume
// Determine the random port number that was chosen
var listenPort int
if err = wait.PollImmediateUntil(100*time.Millisecond, func() (bool, error) {
if err := wait.PollUntilContextCancel(ctx, 100*time.Millisecond, true, func(_ context.Context) (bool, error) {
listenPort, err = srv.Port()
if err != nil {
if errors.Is(err, server.ErrNotListening) {
@ -123,7 +123,7 @@ func StartWebhookServer(t *testing.T, ctx context.Context, args []string, argume
return false, err
}
return true, nil
}, ctx.Done()); err != nil {
}); err != nil {
t.Fatalf("Failed waiting for ListenPort to be allocated (got error: %v)", err)
}

View File

@ -138,19 +138,14 @@ func (d *DynamicAuthority) Run(ctx context.Context) error {
// been missed that could cause us to get into an idle state where the
// Secret resource does not exist and so the informers handler functions
// are not triggered.
if err = wait.PollImmediateUntil(time.Second*10, func() (done bool, err error) {
if err := wait.PollUntilContextCancel(ctx, time.Second*10, true, func(ctx context.Context) (done bool, err error) {
if err := d.ensureCA(ctx); err != nil {
d.log.Error(err, "error ensuring CA")
}
// never return 'done'.
// this poll only ends when stopCh is closed.
return false, nil
}, ctx.Done()); err != nil {
// If error cause was context, return that error instead
if ctx.Err() != nil {
return ctx.Err()
}
}); err != nil {
return err
}

View File

@ -141,7 +141,7 @@ func (f *DynamicSource) Run(ctx context.Context) error {
}()
// check the current certificate every 10s in case it needs updating
if err := wait.PollImmediateUntil(time.Second*10, func() (done bool, err error) {
if err := wait.PollUntilContextCancel(ctx, time.Second*10, true, func(ctx context.Context) (done bool, err error) {
// regenerate the serving certificate if the root CA has been rotated
select {
// if the authority has stopped for whatever reason, exit and return the error
@ -177,17 +177,12 @@ func (f *DynamicSource) Run(ctx context.Context) error {
return true, context.Canceled
}
return false, nil
}, ctx.Done()); err != nil {
}); err != nil {
// In case of an error, the stopCh is closed; wait for all channels to close
<-authorityErrChan
<-rotationChan
<-renewalChan
// If there was an ErrWaitTimeout error, this must be caused by closing stopCh
if errors.Is(err, wait.ErrWaitTimeout) {
return context.Canceled
}
return err
}

View File

@ -210,7 +210,7 @@ func TestAcmeOrdersController(t *testing.T) {
// Wait for the Challenge to be created.
var chal *cmacme.Challenge
err = wait.PollImmediateUntil(time.Millisecond*100, func() (done bool, err error) {
err = wait.PollUntilContextCancel(ctx, time.Millisecond*100, true, func(ctx context.Context) (done bool, err error) {
chals, err := cmCl.AcmeV1().Challenges(testName).List(ctx, metav1.ListOptions{})
if err != nil {
return false, err
@ -230,7 +230,7 @@ func TestAcmeOrdersController(t *testing.T) {
return false, fmt.Errorf("found an unexpected Challenge resource: %v", chal.Name)
}
return true, nil
}, ctx.Done())
})
if err != nil {
t.Fatal(err)
}
@ -259,9 +259,7 @@ func TestAcmeOrdersController(t *testing.T) {
// Reason field on Order's status. Change this test once we are setting
// Reasons on intermittent Order states.
var pendingOrder *cmacme.Order
timeoutCtx, timeoutCancel := context.WithTimeout(ctx, acmeorders.RequeuePeriod)
defer timeoutCancel()
err = wait.PollImmediateUntil(time.Millisecond*200, func() (bool, error) {
err = wait.PollUntilContextTimeout(ctx, time.Millisecond*200, acmeorders.RequeuePeriod, true, func(ctx context.Context) (bool, error) {
pendingOrder, err = cmCl.AcmeV1().Orders(testName).Get(ctx, testName, metav1.GetOptions{})
if err != nil {
return false, err
@ -270,16 +268,12 @@ func TestAcmeOrdersController(t *testing.T) {
return true, nil
}
return false, nil
}, timeoutCtx.Done())
})
switch {
case err == nil:
t.Fatalf("Expected Order to have pending status instead got: %v", pendingOrder.Status.State)
case err == wait.ErrWaitTimeout:
if ctx.Err() != nil {
t.Error(ctx.Err())
}
// 'happy case' - Order remained pending
case err == context.DeadlineExceeded:
// this is the expected 'happy case'
default:
t.Fatal(err)
}
@ -288,7 +282,7 @@ func TestAcmeOrdersController(t *testing.T) {
acmeOrder.Status = acmeapi.StatusReady
// Wait for the status of the Order to become Valid.
err = wait.PollImmediateUntil(time.Millisecond*100, func() (bool, error) {
err = wait.PollUntilContextCancel(ctx, time.Millisecond*100, true, func(ctx context.Context) (done bool, err error) {
o, err := cmCl.AcmeV1().Orders(testName).Get(ctx, testName, metav1.GetOptions{})
if err != nil {
return false, err
@ -298,7 +292,7 @@ func TestAcmeOrdersController(t *testing.T) {
return false, nil
}
return true, nil
}, ctx.Done())
})
if err != nil {
t.Fatal(err)
}

View File

@ -217,7 +217,7 @@ func TestIssuingController(t *testing.T) {
// Wait for the Certificate to have the 'Issuing' condition removed, and
// for the signed certificate, ca, and private key stored in the Secret.
err = wait.PollImmediateUntil(time.Millisecond*100, func() (done bool, err error) {
err = wait.PollUntilContextCancel(ctx, time.Millisecond*100, true, func(ctx context.Context) (done bool, err error) {
crt, err = cmCl.CertmanagerV1().Certificates(namespace).Get(ctx, crtName, metav1.GetOptions{})
if err != nil {
t.Logf("Failed to fetch Certificate resource, retrying: %v", err)
@ -266,7 +266,7 @@ func TestIssuingController(t *testing.T) {
}
return true, nil
}, ctx.Done())
})
if err != nil {
t.Fatalf("Failed to wait for final state: %+v", crt)
@ -440,7 +440,7 @@ func TestIssuingController_PKCS8_PrivateKey(t *testing.T) {
// Wait for the Certificate to have the 'Issuing' condition removed, and for
// the signed certificate, ca, and private key stored in the Secret.
err = wait.PollImmediateUntil(time.Millisecond*100, func() (done bool, err error) {
err = wait.PollUntilContextCancel(ctx, time.Millisecond*100, true, func(ctx context.Context) (done bool, err error) {
crt, err = cmCl.CertmanagerV1().Certificates(namespace).Get(ctx, crtName, metav1.GetOptions{})
if err != nil {
t.Logf("Failed to fetch Certificate resource, retrying: %v", err)
@ -489,7 +489,7 @@ func TestIssuingController_PKCS8_PrivateKey(t *testing.T) {
}
return true, nil
}, ctx.Done())
})
if err != nil {
t.Fatalf("Failed to wait for final state: %+v", crt)
}
@ -658,7 +658,7 @@ func Test_IssuingController_SecretTemplate(t *testing.T) {
// Wait for the Certificate to have the 'Issuing' condition removed, and for
// the signed certificate, ca, and private key stored in the Secret.
err = wait.PollImmediateUntil(time.Millisecond*100, func() (done bool, err error) {
err = wait.PollUntilContextCancel(ctx, time.Millisecond*100, true, func(ctx context.Context) (done bool, err error) {
crt, err = cmCl.CertmanagerV1().Certificates(namespace).Get(ctx, crtName, metav1.GetOptions{})
if err != nil {
t.Logf("Failed to fetch Certificate resource, retrying: %v", err)
@ -671,7 +671,10 @@ func Test_IssuingController_SecretTemplate(t *testing.T) {
}
return true, nil
}, ctx.Done())
})
if err != nil {
t.Fatal(err)
}
// Add labels and annotations to the SecretTemplate.
annotations := map[string]string{"annotation-1": "abc", "annotation-2": "123"}
@ -683,7 +686,7 @@ func Test_IssuingController_SecretTemplate(t *testing.T) {
}
// Wait for the Annotations and Labels to be observed on the Secret.
err = wait.PollImmediateUntil(time.Millisecond*100, func() (done bool, err error) {
err = wait.PollUntilContextCancel(ctx, time.Millisecond*100, true, func(ctx context.Context) (done bool, err error) {
secret, err := kubeClient.CoreV1().Secrets(namespace).Get(ctx, secretName, metav1.GetOptions{})
if err != nil {
t.Logf("Failed to fetch Secret resource, retrying: %s", err)
@ -700,7 +703,7 @@ func Test_IssuingController_SecretTemplate(t *testing.T) {
}
}
return true, nil
}, ctx.Done())
})
if err != nil {
t.Fatal(err)
}
@ -713,7 +716,7 @@ func Test_IssuingController_SecretTemplate(t *testing.T) {
}
// Wait for the Annotations and Labels to be removed from the Secret.
err = wait.PollImmediateUntil(time.Millisecond*100, func() (done bool, err error) {
err = wait.PollUntilContextCancel(ctx, time.Millisecond*100, true, func(ctx context.Context) (done bool, err error) {
secret, err := kubeClient.CoreV1().Secrets(namespace).Get(ctx, secretName, metav1.GetOptions{})
if err != nil {
t.Logf("Failed to fetch Secret resource, retrying: %s", err)
@ -732,7 +735,7 @@ func Test_IssuingController_SecretTemplate(t *testing.T) {
}
}
return true, nil
}, ctx.Done())
})
if err != nil {
t.Fatal(err)
}
@ -904,7 +907,7 @@ func Test_IssuingController_AdditionalOutputFormats(t *testing.T) {
// Wait for the Certificate to have the 'Issuing' condition removed, and for
// the signed certificate, ca, and private key stored in the Secret.
err = wait.PollImmediateUntil(time.Millisecond*100, func() (done bool, err error) {
err = wait.PollUntilContextCancel(ctx, time.Millisecond*100, true, func(ctx context.Context) (done bool, err error) {
crt, err = cmCl.CertmanagerV1().Certificates(namespace).Get(ctx, crtName, metav1.GetOptions{})
if err != nil {
t.Logf("Failed to fetch Certificate resource, retrying: %v", err)
@ -917,7 +920,10 @@ func Test_IssuingController_AdditionalOutputFormats(t *testing.T) {
}
return true, nil
}, ctx.Done())
})
if err != nil {
t.Fatal(err)
}
// Add additional output formats
crt = gen.CertificateFrom(crt, gen.SetCertificateAdditionalOutputFormats(
@ -934,7 +940,7 @@ func Test_IssuingController_AdditionalOutputFormats(t *testing.T) {
combinedPEM := append(append(pkBytes, '\n'), certPEM...)
// Wait for the additional output format values to to be observed on the Secret.
err = wait.PollImmediateUntil(time.Millisecond*100, func() (done bool, err error) {
err = wait.PollUntilContextCancel(ctx, time.Millisecond*100, true, func(ctx context.Context) (done bool, err error) {
secret, err := kubeClient.CoreV1().Secrets(namespace).Get(ctx, secretName, metav1.GetOptions{})
if err != nil {
t.Logf("Failed to fetch Secret resource, retrying: %s", err)
@ -944,7 +950,7 @@ func Test_IssuingController_AdditionalOutputFormats(t *testing.T) {
"ca.crt": certPEM, "tls.crt": certPEM, "tls.key": pkBytes,
"key.der": pkDER, "tls-combined.pem": combinedPEM,
}, secret.Data), nil
}, ctx.Done())
})
if err != nil {
t.Fatal(err)
}
@ -957,7 +963,7 @@ func Test_IssuingController_AdditionalOutputFormats(t *testing.T) {
}
// Wait for the additional output formats to be removed from the Secret.
err = wait.PollImmediateUntil(time.Millisecond*100, func() (done bool, err error) {
err = wait.PollUntilContextCancel(ctx, time.Millisecond*100, true, func(ctx context.Context) (done bool, err error) {
secret, err := kubeClient.CoreV1().Secrets(namespace).Get(ctx, secretName, metav1.GetOptions{})
if err != nil {
t.Logf("Failed to fetch Secret resource, retrying: %s", err)
@ -966,7 +972,7 @@ func Test_IssuingController_AdditionalOutputFormats(t *testing.T) {
return reflect.DeepEqual(map[string][]byte{
"ca.crt": certPEM, "tls.crt": certPEM, "tls.key": pkBytes,
}, secret.Data), nil
}, ctx.Done())
})
if err != nil {
t.Fatal(err)
}

View File

@ -150,14 +150,14 @@ func TestMetricsController(t *testing.T) {
}
waitForMetrics := func(expectedOutput string) {
err := wait.PollImmediateUntil(time.Millisecond*100, func() (done bool, err error) {
err = wait.PollUntilContextCancel(ctx, time.Millisecond*100, true, func(ctx context.Context) (done bool, err error) {
if err := testMetrics(expectedOutput); err != nil {
lastErr = err
return false, nil
}
return true, nil
}, ctx.Done())
})
if err != nil {
t.Fatalf("%s: failed to wait for expected metrics to be exposed: %s", err, lastErr)
}

View File

@ -154,7 +154,7 @@ func TestRevisionManagerController(t *testing.T) {
var crs []cmapi.CertificateRequest
// Wait for 3 CertificateRequests to be deleted, and that they have the correct revisions
err = wait.PollImmediateUntil(time.Millisecond*100, func() (done bool, err error) {
err = wait.PollUntilContextCancel(ctx, time.Millisecond*100, true, func(ctx context.Context) (done bool, err error) {
requests, err := cmCl.CertmanagerV1().CertificateRequests(namespace).List(ctx, metav1.ListOptions{})
if err != nil {
return false, err
@ -168,7 +168,7 @@ func TestRevisionManagerController(t *testing.T) {
crs = requests.Items
return true, nil
}, ctx.Done())
})
if err != nil {
t.Fatal(err)
}

View File

@ -341,10 +341,8 @@ func TestTriggerController_ExpBackoff(t *testing.T) {
func ensureCertificateDoesNotHaveIssuingCondition(t *testing.T, ctx context.Context, cmCl cmclient.Interface, namespace, name string) {
t.Helper()
timeoutCtx, cancel := context.WithTimeout(ctx, time.Second*2)
defer cancel()
err := wait.PollImmediateUntil(time.Millisecond*200, func() (done bool, err error) {
err := wait.PollUntilContextTimeout(ctx, time.Millisecond*200, time.Second*2, true, func(ctx context.Context) (bool, error) {
c, err := cmCl.CertmanagerV1().Certificates(namespace).Get(ctx, name, metav1.GetOptions{})
if err != nil {
return false, err
@ -357,15 +355,11 @@ func ensureCertificateDoesNotHaveIssuingCondition(t *testing.T, ctx context.Cont
return true, nil
}
return false, nil
}, timeoutCtx.Done())
})
switch {
case err == nil:
t.Fatal("expected Certificate to not have the Issuing condition")
case err == wait.ErrWaitTimeout:
if ctx.Err() != nil {
t.Error(ctx.Err())
}
case err == context.DeadlineExceeded:
// this is the expected 'happy case'
default:
t.Fatal(err)
@ -374,7 +368,7 @@ func ensureCertificateDoesNotHaveIssuingCondition(t *testing.T, ctx context.Cont
func ensureCertificateHasIssuingCondition(t *testing.T, ctx context.Context, cmCl cmclient.Interface, namespace, name string) {
t.Helper()
err := wait.PollImmediateUntil(time.Millisecond*200, func() (done bool, err error) {
err := wait.PollUntilContextCancel(ctx, time.Millisecond*200, true, func(ctx context.Context) (done bool, err error) {
c, err := cmCl.CertmanagerV1().Certificates(namespace).Get(ctx, name, metav1.GetOptions{})
if err != nil {
return false, err
@ -386,7 +380,7 @@ func ensureCertificateHasIssuingCondition(t *testing.T, ctx context.Context, cmC
return true, nil
}
return false, nil
}, ctx.Done())
})
if err != nil {
t.Error("Failed waiting for Certificate to have Issuing condition")
}

View File

@ -312,13 +312,13 @@ func TestCtlCreateCRSuccessful(t *testing.T) {
}()
go func() {
defer close(errCh)
err = wait.PollImmediateUntil(time.Second, func() (done bool, err error) {
req, err = cmCl.CertmanagerV1().CertificateRequests(test.inputNamespace).Get(pollCtx, test.inputArgs[0], metav1.GetOptions{})
err = wait.PollUntilContextCancel(pollCtx, time.Second, true, func(ctx context.Context) (done bool, err error) {
req, err = cmCl.CertmanagerV1().CertificateRequests(test.inputNamespace).Get(ctx, test.inputArgs[0], metav1.GetOptions{})
if err != nil {
return false, nil
}
return true, nil
}, pollCtx.Done())
})
if err != nil {
errCh <- fmt.Errorf("timeout when waiting for CertificateRequest to be created, error: %v", err)
return

View File

@ -95,7 +95,7 @@ func WaitForOpenAPIResourcesToBeLoaded(t *testing.T, ctx context.Context, config
t.Fatal(err)
}
err = wait.PollImmediateUntil(time.Second, func() (bool, error) {
err = wait.PollUntilContextCancel(ctx, time.Second, true, func(ctx context.Context) (done bool, err error) {
og := openapi.NewOpenAPIGetter(dc)
oapiResource, err := openapi.NewOpenAPIParser(og).Parse()
if err != nil {
@ -106,7 +106,7 @@ func WaitForOpenAPIResourcesToBeLoaded(t *testing.T, ctx context.Context, config
return true, nil
}
return false, nil
}, ctx.Done())
})
if err != nil {
t.Fatal("Our GVK isn't loaded into the OpenAPI resources API after waiting for 2 minutes", err)

View File

@ -84,7 +84,7 @@ func TestDynamicAuthority_Bootstrap(t *testing.T) {
cl := kubernetes.NewForConfigOrDie(config)
// allow the controller to provision the Secret
if err := wait.PollImmediateUntil(time.Millisecond*500, authoritySecretReadyConditionFunc(t, ctx, cl, auth.SecretNamespace, auth.SecretName), ctx.Done()); err != nil {
if err := wait.PollUntilContextCancel(ctx, time.Millisecond*500, true, authoritySecretReadyConditionFunc(t, cl, auth.SecretNamespace, auth.SecretName)); err != nil {
t.Errorf("Failed waiting for Secret to contain valid certificate: %v", err)
return
}
@ -132,7 +132,7 @@ func TestDynamicAuthority_Recreates(t *testing.T) {
cl := kubernetes.NewForConfigOrDie(config)
// allow the controller to provision the Secret
if err := wait.PollImmediateUntil(time.Millisecond*500, authoritySecretReadyConditionFunc(t, ctx, cl, auth.SecretNamespace, auth.SecretName), ctx.Done()); err != nil {
if err := wait.PollUntilContextCancel(ctx, time.Millisecond*500, true, authoritySecretReadyConditionFunc(t, cl, auth.SecretNamespace, auth.SecretName)); err != nil {
t.Errorf("Failed waiting for Secret to contain valid certificate: %v", err)
return
}
@ -143,7 +143,7 @@ func TestDynamicAuthority_Recreates(t *testing.T) {
}
// allow the controller to provision the Secret again
if err := wait.PollImmediateUntil(time.Millisecond*500, authoritySecretReadyConditionFunc(t, ctx, cl, auth.SecretNamespace, auth.SecretName), ctx.Done()); err != nil {
if err := wait.PollUntilContextCancel(ctx, time.Millisecond*500, true, authoritySecretReadyConditionFunc(t, cl, auth.SecretNamespace, auth.SecretName)); err != nil {
t.Errorf("Failed waiting for Secret to be recreated: %v", err)
return
}
@ -152,8 +152,8 @@ func TestDynamicAuthority_Recreates(t *testing.T) {
// authoritySecretReadyConditionFunc will check a named Secret resource and
// check if it contains a valid CA keypair used by the authority.
// This can be used with the `k8s.io/apimachinery/pkg/util/wait` package.
func authoritySecretReadyConditionFunc(t *testing.T, ctx context.Context, cl kubernetes.Interface, namespace, name string) wait.ConditionFunc {
return func() (done bool, err error) {
func authoritySecretReadyConditionFunc(t *testing.T, cl kubernetes.Interface, namespace, name string) wait.ConditionWithContextFunc {
return func(ctx context.Context) (done bool, err error) {
s, err := cl.CoreV1().Secrets(namespace).Get(ctx, name, metav1.GetOptions{})
if apierrors.IsNotFound(err) {
t.Logf("Secret resource %s/%s does not yet exist, waiting...", namespace, name)

View File

@ -82,7 +82,7 @@ func TestDynamicSource_Bootstrap(t *testing.T) {
// allow the controller 5s to provision the Secret - this is far longer
// than it should ever take.
if err := wait.PollImmediateUntil(time.Millisecond*500, func() (done bool, err error) {
if err := wait.PollUntilContextCancel(ctx, time.Millisecond*500, true, func(ctx context.Context) (done bool, err error) {
cert, err := source.GetCertificate(nil)
if err == tls.ErrNotAvailable {
t.Logf("GetCertificate has no certificate available, waiting...")
@ -96,7 +96,7 @@ func TestDynamicSource_Bootstrap(t *testing.T) {
}
t.Logf("Got non-nil certificate from dynamic source")
return true, nil
}, ctx.Done()); err != nil {
}); err != nil {
t.Errorf("Failed waiting for source to return a certificate: %v", err)
return
}
@ -148,7 +148,7 @@ func TestDynamicSource_CARotation(t *testing.T) {
var serialNumber *big.Int
// allow the controller 5s to provision the Secret - this is far longer
// than it should ever take.
if err := wait.PollImmediateUntil(time.Millisecond*500, func() (done bool, err error) {
if err := wait.PollUntilContextCancel(ctx, time.Millisecond*500, true, func(ctx context.Context) (done bool, err error) {
cert, err := source.GetCertificate(nil)
if err == tls.ErrNotAvailable {
t.Logf("GetCertificate has no certificate available, waiting...")
@ -169,7 +169,7 @@ func TestDynamicSource_CARotation(t *testing.T) {
serialNumber = x509cert.SerialNumber
return true, nil
}, ctx.Done()); err != nil {
}); err != nil {
t.Errorf("Failed waiting for source to return a certificate: %v", err)
return
}
@ -181,7 +181,7 @@ func TestDynamicSource_CARotation(t *testing.T) {
// wait for the serving certificate to have a new serial number (which
// indicates it has been regenerated)
if err := wait.PollImmediateUntil(time.Millisecond*500, func() (done bool, err error) {
if err := wait.PollUntilContextCancel(ctx, time.Millisecond*500, true, func(ctx context.Context) (done bool, err error) {
cert, err := source.GetCertificate(nil)
if err == tls.ErrNotAvailable {
t.Logf("GetCertificate has no certificate available, waiting...")
@ -206,7 +206,7 @@ func TestDynamicSource_CARotation(t *testing.T) {
}
return true, nil
}, ctx.Done()); err != nil {
}); err != nil {
t.Errorf("Failed waiting for source to return a certificate: %v", err)
return
}