diff --git a/test/e2e_node/apparmor_test.go b/test/e2e_node/apparmor_test.go index 7dd5f63a8eb..47dbe6d826e 100644 --- a/test/e2e_node/apparmor_test.go +++ b/test/e2e_node/apparmor_test.go @@ -30,9 +30,13 @@ import ( "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/fields" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" watchtools "k8s.io/client-go/tools/watch" + "k8s.io/klog" "k8s.io/kubernetes/pkg/security/apparmor" "k8s.io/kubernetes/test/e2e/framework" e2epod "k8s.io/kubernetes/test/e2e/framework/pod" @@ -40,7 +44,6 @@ import ( "github.com/davecgh/go-spew/spew" "github.com/onsi/ginkgo" "github.com/onsi/gomega" - "k8s.io/klog" ) var _ = framework.KubeDescribe("AppArmor [Feature:AppArmor][NodeFeature:AppArmor]", func() { @@ -151,11 +154,33 @@ func runAppArmorTest(f *framework.Framework, shouldRun bool, profile string) v1. f.ClientSet, pod.Name, f.Namespace.Name, framework.PodStartTimeout)) } else { // Pod should remain in the pending state. Wait for the Reason to be set to "AppArmor". - w, err := f.PodClient().Watch(context.TODO(), metav1.SingleObject(metav1.ObjectMeta{Name: pod.Name})) - framework.ExpectNoError(err) + fieldSelector := fields.OneTermEqualSelector("metadata.name", pod.Name).String() + w := &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + options.FieldSelector = fieldSelector + return f.PodClient().List(context.TODO(), options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + options.FieldSelector = fieldSelector + return f.PodClient().Watch(context.TODO(), options) + }, + } + preconditionFunc := func(store cache.Store) (bool, error) { + _, exists, err := store.Get(&metav1.ObjectMeta{Namespace: pod.Namespace, Name: pod.Name}) + if err != nil { + return true, err + } + if !exists { + // We need to make sure we see the object in the cache before we start waiting for events + // or we would be waiting for the timeout if such object didn't exist. + return true, apierrors.NewNotFound(v1.Resource("pods"), pod.Name) + } + + return false, nil + } ctx, cancel := watchtools.ContextWithOptionalTimeout(context.Background(), framework.PodStartTimeout) defer cancel() - _, err = watchtools.UntilWithoutRetry(ctx, w, func(e watch.Event) (bool, error) { + _, err := watchtools.UntilWithSync(ctx, w, &v1.Pod{}, preconditionFunc, func(e watch.Event) (bool, error) { switch e.Type { case watch.Deleted: return false, apierrors.NewNotFound(schema.GroupResource{Resource: "pods"}, pod.Name)