Properly invalidate client after CRD install

As the CRDs are installed before the capabilities are gathered, the
current call to invalidate the discovery client is premature and
expensive.

What actually is required is an invalidation of the REST mapper, as
otherwise the Helm install action may later on fail with a `resource
mapping not found` error. More specifically when the caller of the
action is making use of a persisting[1] `RESTClientGetter`.

Which is not something done by the Helm CLI (albeit it could, and this
would potentially save quite some resources?). But is a default
configuration offered by the Helm SDK via `kube.New` when a nil value
is provided as the `getter`.

[1]: https://github.com/kubernetes/cli-runtime/blob/v0.26.2/pkg/genericclioptions/config_flags.go#L118

Signed-off-by: Hidde Beydals <hidde@hhh.computer>
Signed-off-by: Drew Gonzales <drew.gonzales@datadoghq.com>
pull/11760/head
Hidde Beydals 3 years ago committed by Drew Gonzales
parent cf4b05ccad
commit 17a96bd767
No known key found for this signature in database

@ -34,6 +34,7 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
v1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors" apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/cli-runtime/pkg/resource" "k8s.io/cli-runtime/pkg/resource"
"sigs.k8s.io/yaml" "sigs.k8s.io/yaml"
@ -164,22 +165,38 @@ func (i *Install) installCRDs(crds []chart.CRD) error {
totalItems = append(totalItems, res...) totalItems = append(totalItems, res...)
} }
if len(totalItems) > 0 { if len(totalItems) > 0 {
// Invalidate the local cache, since it will not have the new CRDs
// present.
discoveryClient, err := i.cfg.RESTClientGetter.ToDiscoveryClient()
if err != nil {
return err
}
i.cfg.Log("Clearing discovery cache")
discoveryClient.Invalidate()
// Give time for the CRD to be recognized. // Give time for the CRD to be recognized.
if err := i.cfg.KubeClient.Wait(totalItems, 60*time.Second); err != nil { if err := i.cfg.KubeClient.Wait(totalItems, 60*time.Second); err != nil {
return err return err
} }
// Make sure to force a rebuild of the cache. // If we have already gathered the capabilities, we need to invalidate
discoveryClient.ServerGroups() // the cache so that the new CRDs are recognized. This should only be
// the case when an action configuration is reused for multiple actions,
// as otherwise it is later loaded by ourselves when getCapabilities
// is called later on in the installation process.
if i.cfg.Capabilities != nil {
discoveryClient, err := i.cfg.RESTClientGetter.ToDiscoveryClient()
if err != nil {
return err
}
i.cfg.Log("Clearing discovery cache")
discoveryClient.Invalidate()
_, _ = discoveryClient.ServerGroups()
}
// Invalidate the REST mapper, since it will not have the new CRDs
// present.
restMapper, err := i.cfg.RESTClientGetter.ToRESTMapper()
if err != nil {
return err
}
if resettable, ok := restMapper.(meta.ResettableRESTMapper); ok {
i.cfg.Log("Clearing REST mapper cache")
resettable.Reset()
}
} }
return nil return nil
} }

Loading…
Cancel
Save