Skip to content

Commit 220a894

Browse files
Merge pull request kubernetes#22149 from mfojtik/mfojtik-wait-for-crd-discovery
UPSTREAM: 00000: wait for CRD discovery to be successful once before Origin-commit: 9ffad072ee9a512a7344dba700b5a15bcad5349a
2 parents 7593dd2 + 16e3fbb commit 220a894

File tree

3 files changed

+75
-11
lines changed

3 files changed

+75
-11
lines changed

staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/apiserver.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,15 @@ import (
2121
"net/http"
2222
"time"
2323

24+
"github.com/golang/glog"
25+
2426
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
27+
"k8s.io/apimachinery/pkg/labels"
2528
"k8s.io/apimachinery/pkg/runtime"
2629
"k8s.io/apimachinery/pkg/runtime/schema"
2730
"k8s.io/apimachinery/pkg/runtime/serializer"
31+
"k8s.io/apimachinery/pkg/util/sets"
32+
"k8s.io/apimachinery/pkg/util/wait"
2833
"k8s.io/apimachinery/pkg/version"
2934
"k8s.io/apiserver/pkg/endpoints/discovery"
3035
genericregistry "k8s.io/apiserver/pkg/registry/generic"
@@ -208,6 +213,52 @@ func (c completedConfig) New(delegationTarget genericapiserver.DelegationTarget)
208213
go finalizingController.Run(5, context.StopCh)
209214
return nil
210215
})
216+
s.GenericAPIServer.AddPostStartHookOrDie("crd-discovery-available", func(context genericapiserver.PostStartHookContext) error {
217+
return wait.PollImmediateUntil(100*time.Millisecond, func() (bool, error) {
218+
// only check if we have a valid list for a given resourceversion
219+
if !s.Informers.Apiextensions().InternalVersion().CustomResourceDefinitions().Informer().HasSynced() {
220+
return false, nil
221+
}
222+
223+
_, serverGroupsAndResources, err := crdClient.Discovery().ServerGroupsAndResources()
224+
if err != nil {
225+
return false, err
226+
}
227+
228+
serverCRDs, err := s.Informers.Apiextensions().InternalVersion().CustomResourceDefinitions().Lister().List(labels.Everything())
229+
if err != nil {
230+
return false, err
231+
}
232+
233+
crdGroupsAndResources := sets.NewString()
234+
for _, crd := range serverCRDs {
235+
// Skip not active CRD
236+
if !apiextensions.IsCRDConditionTrue(crd, apiextensions.Established) {
237+
continue
238+
}
239+
for _, version := range crd.Spec.Versions {
240+
// Skip versions that are not served
241+
if !version.Served {
242+
continue
243+
}
244+
crdGroupsAndResources.Insert(fmt.Sprintf("%s.%s.%s", crd.Spec.Names.Plural, version.Name, crd.Spec.Group))
245+
}
246+
}
247+
248+
discoveryGroupsAndResources := sets.NewString()
249+
for _, resource := range serverGroupsAndResources {
250+
for _, apiResource := range resource.APIResources {
251+
discoveryGroupsAndResources.Insert(fmt.Sprintf("%s.%s.%s", apiResource.Name, apiResource.Version, apiResource.Group))
252+
}
253+
}
254+
255+
if !discoveryGroupsAndResources.HasAll(crdGroupsAndResources.List()...) {
256+
glog.Infof("waiting for CRD resources in discovery: %#v", discoveryGroupsAndResources.Difference(crdGroupsAndResources))
257+
return false, nil
258+
}
259+
return true, nil
260+
}, context.StopCh)
261+
})
211262

212263
// we don't want to report healthy until we can handle all CRDs that have already been registered. Waiting for the informer
213264
// to sync makes sure that the lister will be valid before we begin. There may still be races for CRDs added after startup,

staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/customresource_discovery_controller.go

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@ func NewDiscoveryController(crdInformer informers.CustomResourceDefinitionInform
7474
}
7575

7676
func (c *DiscoveryController) sync(version schema.GroupVersion) error {
77-
7877
apiVersionsForDiscovery := []metav1.GroupVersionForDiscovery{}
7978
apiResourcesForDiscovery := []metav1.APIResource{}
8079
versionsForDiscoveryMap := map[metav1.GroupVersion]bool{}
@@ -130,6 +129,8 @@ func (c *DiscoveryController) sync(version schema.GroupVersion) error {
130129
Name: crd.Status.AcceptedNames.Plural,
131130
SingularName: crd.Status.AcceptedNames.Singular,
132131
Namespaced: crd.Spec.Scope == apiextensions.NamespaceScoped,
132+
Group: crd.Spec.Group,
133+
Version: version.Version,
133134
Kind: crd.Status.AcceptedNames.Kind,
134135
Verbs: verbs,
135136
ShortNames: crd.Status.AcceptedNames.ShortNames,
@@ -138,21 +139,29 @@ func (c *DiscoveryController) sync(version schema.GroupVersion) error {
138139

139140
if crd.Spec.Subresources != nil && crd.Spec.Subresources.Status != nil {
140141
apiResourcesForDiscovery = append(apiResourcesForDiscovery, metav1.APIResource{
141-
Name: crd.Status.AcceptedNames.Plural + "/status",
142-
Namespaced: crd.Spec.Scope == apiextensions.NamespaceScoped,
143-
Kind: crd.Status.AcceptedNames.Kind,
144-
Verbs: metav1.Verbs([]string{"get", "patch", "update"}),
142+
Name: crd.Status.AcceptedNames.Plural + "/status",
143+
SingularName: "",
144+
Namespaced: crd.Spec.Scope == apiextensions.NamespaceScoped,
145+
Group: crd.Spec.Group,
146+
Version: version.Version,
147+
Kind: crd.Status.AcceptedNames.Kind,
148+
Verbs: metav1.Verbs([]string{"get", "patch", "update"}),
149+
ShortNames: nil,
150+
Categories: nil,
145151
})
146152
}
147153

148154
if crd.Spec.Subresources != nil && crd.Spec.Subresources.Scale != nil {
149155
apiResourcesForDiscovery = append(apiResourcesForDiscovery, metav1.APIResource{
150-
Group: autoscaling.GroupName,
151-
Version: "v1",
152-
Kind: "Scale",
153-
Name: crd.Status.AcceptedNames.Plural + "/scale",
154-
Namespaced: crd.Spec.Scope == apiextensions.NamespaceScoped,
155-
Verbs: metav1.Verbs([]string{"get", "patch", "update"}),
156+
Name: crd.Status.AcceptedNames.Plural + "/scale",
157+
SingularName: "",
158+
Namespaced: crd.Spec.Scope == apiextensions.NamespaceScoped,
159+
Group: autoscaling.GroupName,
160+
Version: "v1",
161+
Kind: "Scale",
162+
Verbs: metav1.Verbs([]string{"get", "patch", "update"}),
163+
ShortNames: nil,
164+
Categories: nil,
156165
})
157166
}
158167
}

staging/src/k8s.io/apiserver/pkg/endpoints/installer.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,8 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
377377
resourcePath = itemPath
378378
resourceParams = nameParams
379379
}
380+
apiResource.Group = a.group.GroupVersion.Group
381+
apiResource.Version = a.group.GroupVersion.Version
380382
apiResource.Name = path
381383
apiResource.Namespaced = false
382384
apiResource.Kind = resourceKind
@@ -427,6 +429,8 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
427429
resourcePath = itemPath
428430
resourceParams = nameParams
429431
}
432+
apiResource.Group = a.group.GroupVersion.Group
433+
apiResource.Version = a.group.GroupVersion.Version
430434
apiResource.Name = path
431435
apiResource.Namespaced = true
432436
apiResource.Kind = resourceKind

0 commit comments

Comments
 (0)