@@ -29,6 +29,10 @@ import (
2929 "k8s.io/client-go/kubernetes/scheme"
3030 "k8s.io/client-go/rest"
3131 "k8s.io/client-go/tools/clientcmd"
32+
33+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
34+ "k8s.io/apimachinery/pkg/util/wait"
35+
3236 klog "k8s.io/klog/v2"
3337
3438 "github.com/kubernetes-csi/csi-lib-utils/leaderelection"
5963 version = "unknown"
6064)
6165
66+ // Checks that the VolumeSnapshot v1 CRDs exist.
67+ func ensureCustomResourceDefinitionsExist (kubeClient * kubernetes.Clientset , client * clientset.Clientset ) error {
68+ condition := func () (bool , error ) {
69+ var err error
70+ _ , err = kubeClient .CoreV1 ().Namespaces ().Get (context .TODO (), "kube-system" , metav1.GetOptions {})
71+ if err != nil {
72+ // only execute list VolumeSnapshots if the kube-system namespace exists
73+ _ , err = client .SnapshotV1 ().VolumeSnapshots ("kube-system" ).List (context .TODO (), metav1.ListOptions {})
74+ if err != nil {
75+ klog .Errorf ("Failed to list v1 volumesnapshots with error=%+v" , err )
76+ return false , nil
77+ }
78+ }
79+ _ , err = client .SnapshotV1 ().VolumeSnapshotClasses ().List (context .TODO (), metav1.ListOptions {})
80+ if err != nil {
81+ klog .Errorf ("Failed to list v1 volumesnapshotclasses with error=%+v" , err )
82+ return false , nil
83+ }
84+ _ , err = client .SnapshotV1 ().VolumeSnapshotContents ().List (context .TODO (), metav1.ListOptions {})
85+ if err != nil {
86+ klog .Errorf ("Failed to list v1 volumesnapshotcontents with error=%+v" , err )
87+ return false , nil
88+ }
89+ return true , nil
90+ }
91+
92+ // with a Factor of 1.5 we wait up to 7.5 seconds (the 10th attempt)
93+ backoff := wait.Backoff {
94+ Duration : 100 * time .Millisecond ,
95+ Factor : 1.5 ,
96+ Steps : 10 ,
97+ }
98+ if err := wait .ExponentialBackoff (backoff , condition ); err != nil {
99+ return err
100+ }
101+
102+ return nil
103+ }
104+
62105func main () {
63106 klog .InitFlags (nil )
64107 flag .Set ("logtostderr" , "true" )
@@ -130,6 +173,11 @@ func main() {
130173 * resyncPeriod ,
131174 )
132175
176+ if err := ensureCustomResourceDefinitionsExist (kubeClient , snapClient ); err != nil {
177+ klog .Errorf ("Exiting due to failure to ensure CRDs exist during startup: %+v" , err )
178+ os .Exit (1 )
179+ }
180+
133181 run := func (context.Context ) {
134182 // run...
135183 stopCh := make (chan struct {})
0 commit comments