@@ -271,6 +271,7 @@ func CreateTestingNS(baseName string, c clientset.Interface, labels map[string]s
271271 var err error
272272 got , err = c .CoreV1 ().Namespaces ().Create (ctx , namespaceObj , metav1.CreateOptions {})
273273 if err != nil {
274+ if k8serrors .IsAlreadyExists (err ) {
274275 // regenerate on conflict
275276 namespaceObj .Name = fmt .Sprintf ("%v-%v" , baseName , uid )
276277 }
@@ -511,6 +512,7 @@ func CreateOrUpdateJobsFromFile(ctx context.Context, cli clientset.Interface, na
511512
512513 // create or update the job
513514 _ , err = cli .BatchV1 ().Jobs (namespace ).Get (ctx , job .Name , metav1.GetOptions {})
515+ if ! k8serrors .IsNotFound (err ) {
514516 // update the job
515517 _ , err = cli .BatchV1 ().Jobs (namespace ).Update (ctx , job , metav1.UpdateOptions {})
516518 if err != nil {
@@ -872,3 +874,45 @@ func getEnvVarOrDefault[T any](key string, defaultValue T) T {
872874 }
873875 return val
874876}
877+
878+ // waitForDaemonSetsReady waits for DaemonSets in a namespace to be ready, optionally filtered by label selector
879+ func waitForDaemonSetsReady (ctx context.Context , client kubernetes.Interface , namespace , labelSelector string ) error {
880+ EventuallyWithOffset (1 , func (g Gomega ) error {
881+ dsList , err := client .AppsV1 ().DaemonSets (namespace ).List (ctx , metav1.ListOptions {
882+ LabelSelector : labelSelector ,
883+ })
884+ if err != nil {
885+ return err
886+ }
887+
888+ if len (dsList .Items ) == 0 {
889+ return fmt .Errorf ("no daemonsets found in namespace %s with selector '%s'" , namespace , labelSelector )
890+ }
891+
892+ for _ , ds := range dsList .Items {
893+ // Skip if no pods are desired
894+ if ds .Status .DesiredNumberScheduled == 0 {
895+ continue
896+ }
897+
898+ if ds .Status .NumberReady != ds .Status .DesiredNumberScheduled {
899+ return fmt .Errorf ("daemonset %s/%s rollout incomplete: %d/%d pods ready" ,
900+ namespace , ds .Name , ds .Status .NumberReady , ds .Status .DesiredNumberScheduled )
901+ }
902+
903+ if ds .Status .UpdatedNumberScheduled != ds .Status .DesiredNumberScheduled {
904+ return fmt .Errorf ("daemonset %s/%s update incomplete: %d/%d pods updated" ,
905+ namespace , ds .Name , ds .Status .UpdatedNumberScheduled , ds .Status .DesiredNumberScheduled )
906+ }
907+
908+ // Check generation to ensure we're looking at the latest spec
909+ if ds .Generation != ds .Status .ObservedGeneration {
910+ return fmt .Errorf ("daemonset %s/%s generation mismatch: %d != %d" ,
911+ namespace , ds .Name , ds .Generation , ds .Status .ObservedGeneration )
912+ }
913+ }
914+
915+ return nil
916+ }).WithContext (ctx ).WithPolling (2 * time .Second ).WithTimeout (5 * time .Minute ).Should (Succeed ())
917+ return nil
918+ }
0 commit comments