mirror of https://github.com/k3s-io/k3s
Merge pull request #53303 from liggitt/discovery-logging
Automatic merge from submit-queue (batch tested with PRs 47039, 53681, 53303, 53181, 53781). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>. Avoid fetching entire discovery tree when possible For specific commands, we use discovery to determine whether a particular resource is available. We should avoid fetching the entire discovery tree to check a single resource group version. As the number of groups grows, the performance hit and potential to encounter an error also grows. ```release-note NONE ```pull/6/head
commit
dc404d49d4
|
@ -17,7 +17,6 @@ limitations under the License.
|
||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
@ -109,17 +108,15 @@ func createDeployment(f cmdutil.Factory, cmdOut, cmdErr io.Writer,
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
resourcesList, err := clientset.Discovery().ServerResources()
|
|
||||||
// ServerResources ignores errors for old servers do not expose discovery
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to discover supported resources: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
generatorName := cmdutil.GetFlagString(cmd, "generator")
|
generatorName := cmdutil.GetFlagString(cmd, "generator")
|
||||||
|
|
||||||
// It is possible we have to modify the user-provided generator name if
|
// It is possible we have to modify the user-provided generator name if
|
||||||
// the server does not have support for the requested generator.
|
// the server does not have support for the requested generator.
|
||||||
generatorName = cmdutil.FallbackGeneratorNameIfNecessary(generatorName, resourcesList, cmdErr)
|
generatorName, err = cmdutil.FallbackGeneratorNameIfNecessary(generatorName, clientset.Discovery(), cmdErr)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
imageNames := cmdutil.GetFlagStringSlice(cmd, "image")
|
imageNames := cmdutil.GetFlagStringSlice(cmd, "image")
|
||||||
generator, ok := generatorFromName(generatorName, imageNames, deploymentName)
|
generator, ok := generatorFromName(generatorName, imageNames, deploymentName)
|
||||||
|
|
|
@ -214,16 +214,15 @@ func RunRun(f cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer, cmd *c
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
resourcesList, err := clientset.Discovery().ServerResources()
|
|
||||||
// ServerResources ignores errors for old servers do not expose discovery
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to discover supported resources: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
generatorName := cmdutil.GetFlagString(cmd, "generator")
|
generatorName := cmdutil.GetFlagString(cmd, "generator")
|
||||||
schedule := cmdutil.GetFlagString(cmd, "schedule")
|
schedule := cmdutil.GetFlagString(cmd, "schedule")
|
||||||
if len(schedule) != 0 && len(generatorName) == 0 {
|
if len(schedule) != 0 && len(generatorName) == 0 {
|
||||||
if cmdutil.Contains(resourcesList, batchv1beta1.SchemeGroupVersion.WithResource("cronjobs")) {
|
hasResource, err := cmdutil.HasResource(clientset.Discovery(), batchv1beta1.SchemeGroupVersion.WithResource("cronjobs"))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if hasResource {
|
||||||
generatorName = cmdutil.CronJobV1Beta1GeneratorName
|
generatorName = cmdutil.CronJobV1Beta1GeneratorName
|
||||||
} else {
|
} else {
|
||||||
generatorName = cmdutil.CronJobV2Alpha1GeneratorName
|
generatorName = cmdutil.CronJobV2Alpha1GeneratorName
|
||||||
|
@ -234,13 +233,21 @@ func RunRun(f cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer, cmd *c
|
||||||
case api.RestartPolicyAlways:
|
case api.RestartPolicyAlways:
|
||||||
// TODO: we need to deprecate this along with extensions/v1beta1.Deployments
|
// TODO: we need to deprecate this along with extensions/v1beta1.Deployments
|
||||||
// in favor of the new generator for apps/v1beta1.Deployments
|
// in favor of the new generator for apps/v1beta1.Deployments
|
||||||
if cmdutil.Contains(resourcesList, extensionsv1beta1.SchemeGroupVersion.WithResource("deployments")) {
|
hasResource, err := cmdutil.HasResource(clientset.Discovery(), extensionsv1beta1.SchemeGroupVersion.WithResource("deployments"))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if hasResource {
|
||||||
generatorName = cmdutil.DeploymentV1Beta1GeneratorName
|
generatorName = cmdutil.DeploymentV1Beta1GeneratorName
|
||||||
} else {
|
} else {
|
||||||
generatorName = cmdutil.RunV1GeneratorName
|
generatorName = cmdutil.RunV1GeneratorName
|
||||||
}
|
}
|
||||||
case api.RestartPolicyOnFailure:
|
case api.RestartPolicyOnFailure:
|
||||||
if cmdutil.Contains(resourcesList, batchv1.SchemeGroupVersion.WithResource("jobs")) {
|
hasResource, err := cmdutil.HasResource(clientset.Discovery(), batchv1.SchemeGroupVersion.WithResource("jobs"))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if hasResource {
|
||||||
generatorName = cmdutil.JobV1GeneratorName
|
generatorName = cmdutil.JobV1GeneratorName
|
||||||
} else {
|
} else {
|
||||||
generatorName = cmdutil.RunPodV1GeneratorName
|
generatorName = cmdutil.RunPodV1GeneratorName
|
||||||
|
@ -250,7 +257,10 @@ func RunRun(f cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer, cmd *c
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
generatorName = cmdutil.FallbackGeneratorNameIfNecessary(generatorName, resourcesList, cmdErr)
|
generatorName, err = cmdutil.FallbackGeneratorNameIfNecessary(generatorName, clientset.Discovery(), cmdErr)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
generators := f.Generators("run")
|
generators := f.Generators("run")
|
||||||
generator, found := generators[generatorName]
|
generator, found := generators[generatorName]
|
||||||
|
|
|
@ -67,7 +67,7 @@ func (d *CachedDiscoveryClient) ServerResourcesForGroupVersion(groupVersion stri
|
||||||
if err == nil {
|
if err == nil {
|
||||||
cachedResources := &metav1.APIResourceList{}
|
cachedResources := &metav1.APIResourceList{}
|
||||||
if err := runtime.DecodeInto(api.Codecs.UniversalDecoder(), cachedBytes, cachedResources); err == nil {
|
if err := runtime.DecodeInto(api.Codecs.UniversalDecoder(), cachedBytes, cachedResources); err == nil {
|
||||||
glog.V(6).Infof("returning cached discovery info from %v", filename)
|
glog.V(10).Infof("returning cached discovery info from %v", filename)
|
||||||
return cachedResources, nil
|
return cachedResources, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -114,7 +114,7 @@ func (d *CachedDiscoveryClient) ServerGroups() (*metav1.APIGroupList, error) {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
cachedGroups := &metav1.APIGroupList{}
|
cachedGroups := &metav1.APIGroupList{}
|
||||||
if err := runtime.DecodeInto(api.Codecs.UniversalDecoder(), cachedBytes, cachedGroups); err == nil {
|
if err := runtime.DecodeInto(api.Codecs.UniversalDecoder(), cachedBytes, cachedGroups); err == nil {
|
||||||
glog.V(6).Infof("returning cached discovery info from %v", filename)
|
glog.V(10).Infof("returning cached discovery info from %v", filename)
|
||||||
return cachedGroups, nil
|
return cachedGroups, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,7 @@ import (
|
||||||
|
|
||||||
appsv1beta1 "k8s.io/api/apps/v1beta1"
|
appsv1beta1 "k8s.io/api/apps/v1beta1"
|
||||||
batchv2alpha1 "k8s.io/api/batch/v2alpha1"
|
batchv2alpha1 "k8s.io/api/batch/v2alpha1"
|
||||||
|
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||||
"k8s.io/apimachinery/pkg/api/meta"
|
"k8s.io/apimachinery/pkg/api/meta"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
@ -582,24 +583,30 @@ func DefaultGenerators(cmdName string) map[string]kubectl.Generator {
|
||||||
// know.
|
// know.
|
||||||
func FallbackGeneratorNameIfNecessary(
|
func FallbackGeneratorNameIfNecessary(
|
||||||
generatorName string,
|
generatorName string,
|
||||||
resourcesList []*metav1.APIResourceList,
|
discoveryClient discovery.DiscoveryInterface,
|
||||||
cmdErr io.Writer,
|
cmdErr io.Writer,
|
||||||
) string {
|
) (string, error) {
|
||||||
switch generatorName {
|
switch generatorName {
|
||||||
case DeploymentBasicAppsV1Beta1GeneratorName:
|
case DeploymentBasicAppsV1Beta1GeneratorName:
|
||||||
if !Contains(resourcesList, appsv1beta1.SchemeGroupVersion.WithResource("deployments")) {
|
hasResource, err := HasResource(discoveryClient, appsv1beta1.SchemeGroupVersion.WithResource("deployments"))
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if !hasResource {
|
||||||
warning(cmdErr, DeploymentBasicAppsV1Beta1GeneratorName, DeploymentBasicV1Beta1GeneratorName)
|
warning(cmdErr, DeploymentBasicAppsV1Beta1GeneratorName, DeploymentBasicV1Beta1GeneratorName)
|
||||||
|
return DeploymentBasicV1Beta1GeneratorName, nil
|
||||||
return DeploymentBasicV1Beta1GeneratorName
|
|
||||||
}
|
}
|
||||||
case CronJobV2Alpha1GeneratorName:
|
case CronJobV2Alpha1GeneratorName:
|
||||||
if !Contains(resourcesList, batchv2alpha1.SchemeGroupVersion.WithResource("cronjobs")) {
|
hasResource, err := HasResource(discoveryClient, batchv2alpha1.SchemeGroupVersion.WithResource("cronjobs"))
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if !hasResource {
|
||||||
warning(cmdErr, CronJobV2Alpha1GeneratorName, JobV1GeneratorName)
|
warning(cmdErr, CronJobV2Alpha1GeneratorName, JobV1GeneratorName)
|
||||||
|
return JobV1GeneratorName, nil
|
||||||
return JobV1GeneratorName
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return generatorName
|
return generatorName, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func warning(cmdErr io.Writer, newGeneratorName, oldGeneratorName string) {
|
func warning(cmdErr io.Writer, newGeneratorName, oldGeneratorName string) {
|
||||||
|
@ -611,6 +618,24 @@ func warning(cmdErr io.Writer, newGeneratorName, oldGeneratorName string) {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func HasResource(client discovery.DiscoveryInterface, resource schema.GroupVersionResource) (bool, error) {
|
||||||
|
resources, err := client.ServerResourcesForGroupVersion(resource.GroupVersion().String())
|
||||||
|
if apierrors.IsNotFound(err) {
|
||||||
|
// entire group is missing
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
// other errors error
|
||||||
|
return false, fmt.Errorf("failed to discover supported resources: %v", err)
|
||||||
|
}
|
||||||
|
for _, serverResource := range resources.APIResources {
|
||||||
|
if serverResource.Name == resource.Resource {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
func Contains(resourcesList []*metav1.APIResourceList, resource schema.GroupVersionResource) bool {
|
func Contains(resourcesList []*metav1.APIResourceList, resource schema.GroupVersionResource) bool {
|
||||||
resources := discovery.FilteredBy(discovery.ResourcePredicateFunc(func(gv string, r *metav1.APIResource) bool {
|
resources := discovery.FilteredBy(discovery.ResourcePredicateFunc(func(gv string, r *metav1.APIResource) bool {
|
||||||
return resource.GroupVersion().String() == gv && resource.Resource == r.Name
|
return resource.GroupVersion().String() == gv && resource.Resource == r.Name
|
||||||
|
|
Loading…
Reference in New Issue