mirror of https://github.com/k3s-io/k3s
Merge pull request #49495 from deads2k/controller-12-toleration
Automatic merge from submit-queue (batch tested with PRs 49665, 49689, 49495, 49146, 48934) make it possible to allow discovery errors for controllers Update the discovery client to return partial discovery information *and* an error. Since we can aggregate API servers, discovery of some resources can fail independently. Callers of this function who want to tolerate the errors can, existing callers will still get an error and fail in normal blocks. @kubernetes/sig-api-machinery-misc @stttspull/6/head
commit
803cb9303b
|
@ -111,6 +111,7 @@ go_library(
|
||||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library",
|
||||||
|
"//vendor/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library",
|
||||||
"//vendor/k8s.io/apiserver/pkg/server/healthz:go_default_library",
|
"//vendor/k8s.io/apiserver/pkg/server/healthz:go_default_library",
|
||||||
|
|
|
@ -33,6 +33,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
|
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||||
"k8s.io/apimachinery/pkg/util/sets"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
"k8s.io/apimachinery/pkg/util/wait"
|
"k8s.io/apimachinery/pkg/util/wait"
|
||||||
|
|
||||||
|
@ -366,7 +367,10 @@ func GetAvailableResources(clientBuilder controller.ControllerClientBuilder) (ma
|
||||||
|
|
||||||
resourceMap, err := discoveryClient.ServerResources()
|
resourceMap, err := discoveryClient.ServerResources()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to get supported resources from server: %v", err)
|
utilruntime.HandleError(fmt.Errorf("unable to get all supported resources from server: %v", err))
|
||||||
|
}
|
||||||
|
if len(resourceMap) == 0 {
|
||||||
|
return nil, fmt.Errorf("unable to get any supported resources from server")
|
||||||
}
|
}
|
||||||
|
|
||||||
allResources := map[schema.GroupVersionResource]bool{}
|
allResources := map[schema.GroupVersionResource]bool{}
|
||||||
|
|
|
@ -31,6 +31,7 @@ import (
|
||||||
"k8s.io/api/core/v1"
|
"k8s.io/api/core/v1"
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
"k8s.io/apimachinery/pkg/runtime/serializer"
|
"k8s.io/apimachinery/pkg/runtime/serializer"
|
||||||
|
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||||
"k8s.io/client-go/discovery"
|
"k8s.io/client-go/discovery"
|
||||||
"k8s.io/client-go/dynamic"
|
"k8s.io/client-go/dynamic"
|
||||||
|
@ -302,7 +303,10 @@ func startGarbageCollectorController(ctx ControllerContext) (bool, error) {
|
||||||
gcClientset := ctx.ClientBuilder.ClientOrDie("generic-garbage-collector")
|
gcClientset := ctx.ClientBuilder.ClientOrDie("generic-garbage-collector")
|
||||||
preferredResources, err := gcClientset.Discovery().ServerPreferredResources()
|
preferredResources, err := gcClientset.Discovery().ServerPreferredResources()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return true, fmt.Errorf("failed to get supported resources from server: %v", err)
|
utilruntime.HandleError(fmt.Errorf("unable to get all supported resources from server: %v", err))
|
||||||
|
}
|
||||||
|
if len(preferredResources) == 0 {
|
||||||
|
return true, fmt.Errorf("unable to get any supported resources from server: %v", err)
|
||||||
}
|
}
|
||||||
deletableResources := discovery.FilteredBy(discovery.SupportsAllVerbs{Verbs: []string{"get", "list", "watch", "patch", "update", "delete"}}, preferredResources)
|
deletableResources := discovery.FilteredBy(discovery.SupportsAllVerbs{Verbs: []string{"get", "list", "watch", "patch", "update", "delete"}}, preferredResources)
|
||||||
deletableGroupVersionResources, err := discovery.GroupVersionResources(deletableResources)
|
deletableGroupVersionResources, err := discovery.GroupVersionResources(deletableResources)
|
||||||
|
|
|
@ -20,6 +20,7 @@ go_library(
|
||||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/util/errors:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/util/errors:go_default_library",
|
||||||
|
"//vendor/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||||
"//vendor/k8s.io/client-go/discovery:go_default_library",
|
"//vendor/k8s.io/client-go/discovery:go_default_library",
|
||||||
"//vendor/k8s.io/client-go/dynamic:go_default_library",
|
"//vendor/k8s.io/client-go/dynamic:go_default_library",
|
||||||
|
|
|
@ -30,6 +30,7 @@ import (
|
||||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
||||||
|
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||||
"k8s.io/apimachinery/pkg/util/sets"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
"k8s.io/client-go/discovery"
|
"k8s.io/client-go/discovery"
|
||||||
"k8s.io/client-go/dynamic"
|
"k8s.io/client-go/dynamic"
|
||||||
|
@ -165,7 +166,10 @@ func (d *namespacedResourcesDeleter) initOpCache() {
|
||||||
// TODO(sttts): get rid of opCache and http 405 logic around it and trust discovery info
|
// TODO(sttts): get rid of opCache and http 405 logic around it and trust discovery info
|
||||||
resources, err := d.discoverResourcesFn()
|
resources, err := d.discoverResourcesFn()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Fatalf("Failed to get supported resources: %v", err)
|
utilruntime.HandleError(fmt.Errorf("unable to get all supported resources from server: %v", err))
|
||||||
|
}
|
||||||
|
if len(resources) == 0 {
|
||||||
|
glog.Fatalf("Unable to get any supported resources from server: %v", err)
|
||||||
}
|
}
|
||||||
deletableGroupVersionResources := []schema.GroupVersionResource{}
|
deletableGroupVersionResources := []schema.GroupVersionResource{}
|
||||||
for _, rl := range resources {
|
for _, rl := range resources {
|
||||||
|
|
|
@ -187,7 +187,7 @@ func (d *DiscoveryClient) ServerResourcesForGroupVersion(groupVersion string) (r
|
||||||
}
|
}
|
||||||
|
|
||||||
// serverResources returns the supported resources for all groups and versions.
|
// serverResources returns the supported resources for all groups and versions.
|
||||||
func (d *DiscoveryClient) serverResources(failEarly bool) ([]*metav1.APIResourceList, error) {
|
func (d *DiscoveryClient) serverResources() ([]*metav1.APIResourceList, error) {
|
||||||
apiGroups, err := d.ServerGroups()
|
apiGroups, err := d.ServerGroups()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -203,9 +203,6 @@ func (d *DiscoveryClient) serverResources(failEarly bool) ([]*metav1.APIResource
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// TODO: maybe restrict this to NotFound errors
|
// TODO: maybe restrict this to NotFound errors
|
||||||
failedGroups[gv] = err
|
failedGroups[gv] = err
|
||||||
if failEarly {
|
|
||||||
return nil, &ErrGroupDiscoveryFailed{Groups: failedGroups}
|
|
||||||
}
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,7 +246,7 @@ func IsGroupDiscoveryFailedError(err error) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
// serverPreferredResources returns the supported resources with the version preferred by the server.
|
// serverPreferredResources returns the supported resources with the version preferred by the server.
|
||||||
func (d *DiscoveryClient) serverPreferredResources(failEarly bool) ([]*metav1.APIResourceList, error) {
|
func (d *DiscoveryClient) serverPreferredResources() ([]*metav1.APIResourceList, error) {
|
||||||
serverGroupList, err := d.ServerGroups()
|
serverGroupList, err := d.ServerGroups()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -269,9 +266,6 @@ func (d *DiscoveryClient) serverPreferredResources(failEarly bool) ([]*metav1.AP
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// TODO: maybe restrict this to NotFound errors
|
// TODO: maybe restrict this to NotFound errors
|
||||||
failedGroups[groupVersion] = err
|
failedGroups[groupVersion] = err
|
||||||
if failEarly {
|
|
||||||
return nil, &ErrGroupDiscoveryFailed{Groups: failedGroups}
|
|
||||||
}
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -316,9 +310,7 @@ func (d *DiscoveryClient) serverPreferredResources(failEarly bool) ([]*metav1.AP
|
||||||
// ServerPreferredResources returns the supported resources with the version preferred by the
|
// ServerPreferredResources returns the supported resources with the version preferred by the
|
||||||
// server.
|
// server.
|
||||||
func (d *DiscoveryClient) ServerPreferredResources() ([]*metav1.APIResourceList, error) {
|
func (d *DiscoveryClient) ServerPreferredResources() ([]*metav1.APIResourceList, error) {
|
||||||
return withRetries(defaultRetries, func(retryEarly bool) ([]*metav1.APIResourceList, error) {
|
return withRetries(defaultRetries, d.serverPreferredResources)
|
||||||
return d.serverPreferredResources(retryEarly)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ServerPreferredNamespacedResources returns the supported namespaced resources with the
|
// ServerPreferredNamespacedResources returns the supported namespaced resources with the
|
||||||
|
@ -394,12 +386,11 @@ func (d *DiscoveryClient) OpenAPISchema() (*openapi_v2.Document, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// withRetries retries the given recovery function in case the groups supported by the server change after ServerGroup() returns.
|
// withRetries retries the given recovery function in case the groups supported by the server change after ServerGroup() returns.
|
||||||
func withRetries(maxRetries int, f func(failEarly bool) ([]*metav1.APIResourceList, error)) ([]*metav1.APIResourceList, error) {
|
func withRetries(maxRetries int, f func() ([]*metav1.APIResourceList, error)) ([]*metav1.APIResourceList, error) {
|
||||||
var result []*metav1.APIResourceList
|
var result []*metav1.APIResourceList
|
||||||
var err error
|
var err error
|
||||||
for i := 0; i < maxRetries; i++ {
|
for i := 0; i < maxRetries; i++ {
|
||||||
failEarly := i < maxRetries-1
|
result, err = f()
|
||||||
result, err = f(failEarly)
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue