diff --git a/test/e2e/common/BUILD b/test/e2e/common/BUILD index 72fb4670550..d599a2c6dcb 100644 --- a/test/e2e/common/BUILD +++ b/test/e2e/common/BUILD @@ -50,7 +50,6 @@ go_library( "//vendor/golang.org/x/net/websocket:go_default_library", "//vendor/k8s.io/api/autoscaling/v1:go_default_library", "//vendor/k8s.io/api/core/v1:go_default_library", - "//vendor/k8s.io/api/extensions/v1beta1:go_default_library", "//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//vendor/k8s.io/apimachinery/pkg/fields:go_default_library", diff --git a/test/e2e/common/apparmor.go b/test/e2e/common/apparmor.go index efe8716222d..a81eea8349b 100644 --- a/test/e2e/common/apparmor.go +++ b/test/e2e/common/apparmor.go @@ -20,16 +20,21 @@ import ( "fmt" api "k8s.io/api/core/v1" - extensions "k8s.io/api/extensions/v1beta1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" "k8s.io/kubernetes/pkg/security/apparmor" "k8s.io/kubernetes/test/e2e/framework" + + . "github.com/onsi/gomega" ) const ( appArmorProfilePrefix = "e2e-apparmor-test-" appArmorAllowedPath = "/expect_allowed_write" appArmorDeniedPath = "/expect_permission_denied" + + loaderLabelKey = "name" + loaderLabelValue = "e2e-apparmor-loader" ) // AppArmorDistros are distros with AppArmor support @@ -40,10 +45,8 @@ func SkipIfAppArmorNotSupported() { } func LoadAppArmorProfiles(f *framework.Framework) { - _, err := createAppArmorProfileCM(f) - framework.ExpectNoError(err) - _, err = createAppArmorProfileLoader(f) - framework.ExpectNoError(err) + createAppArmorProfileCM(f) + createAppArmorProfileLoader(f) } // CreateAppArmorTestPod creates a pod that tests apparmor profile enforcement. The pod exits with @@ -71,6 +74,18 @@ sleep 1 done`, testCmd) } + loaderAffinity := &api.Affinity{ + PodAffinity: &api.PodAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: []api.PodAffinityTerm{{ + Namespaces: []string{f.Namespace.Name}, + LabelSelector: &metav1.LabelSelector{ + MatchLabels: map[string]string{loaderLabelKey: loaderLabelValue}, + }, + TopologyKey: "kubernetes.io/hostname", + }}, + }, + } + pod := &api.Pod{ ObjectMeta: metav1.ObjectMeta{ GenerateName: "test-apparmor-", @@ -82,6 +97,7 @@ done`, testCmd) }, }, Spec: api.PodSpec{ + Affinity: loaderAffinity, Containers: []api.Container{{ Name: "test", Image: busyboxImage, @@ -95,15 +111,22 @@ done`, testCmd) pod = f.PodClient().Create(pod) framework.ExpectNoError(framework.WaitForPodSuccessInNamespace( f.ClientSet, pod.Name, f.Namespace.Name)) + var err error + pod, err = f.PodClient().Get(pod.Name, metav1.GetOptions{}) + framework.ExpectNoError(err) } else { pod = f.PodClient().CreateSync(pod) framework.ExpectNoError(f.WaitForPodReady(pod.Name)) } + // Verify Pod affinity colocated the Pods. + loader := getRunningLoaderPod(f) + Expect(pod.Spec.NodeName).To(Equal(loader.Spec.NodeName)) + return pod } -func createAppArmorProfileCM(f *framework.Framework) (*api.ConfigMap, error) { +func createAppArmorProfileCM(f *framework.Framework) { profileName := appArmorProfilePrefix + f.Namespace.Name profile := fmt.Sprintf(`#include profile %s flags=(attach_disconnected) { @@ -125,21 +148,23 @@ profile %s flags=(attach_disconnected) { profileName: profile, }, } - return f.ClientSet.Core().ConfigMaps(f.Namespace.Name).Create(cm) + _, err := f.ClientSet.Core().ConfigMaps(f.Namespace.Name).Create(cm) + framework.ExpectNoError(err, "Failed to create apparmor-profiles ConfigMap") } -func createAppArmorProfileLoader(f *framework.Framework) (*extensions.DaemonSet, error) { +func createAppArmorProfileLoader(f *framework.Framework) { True := true - // Copied from https://github.com/kubernetes/contrib/blob/master/apparmor/loader/example-configmap.yaml - loader := &extensions.DaemonSet{ + One := int32(1) + loader := &api.ReplicationController{ ObjectMeta: metav1.ObjectMeta{ Name: "apparmor-loader", Namespace: f.Namespace.Name, }, - Spec: extensions.DaemonSetSpec{ - Template: api.PodTemplateSpec{ + Spec: api.ReplicationControllerSpec{ + Replicas: &One, + Template: &api.PodTemplateSpec{ ObjectMeta: metav1.ObjectMeta{ - Labels: map[string]string{"name": "apparmor-loader"}, + Labels: map[string]string{loaderLabelKey: loaderLabelValue}, }, Spec: api.PodSpec{ Containers: []api.Container{{ @@ -191,5 +216,18 @@ func createAppArmorProfileLoader(f *framework.Framework) (*extensions.DaemonSet, }, }, } - return f.ClientSet.Extensions().DaemonSets(f.Namespace.Name).Create(loader) + _, err := f.ClientSet.Core().ReplicationControllers(f.Namespace.Name).Create(loader) + framework.ExpectNoError(err, "Failed to create apparmor-loader ReplicationController") + + // Wait for loader to be ready. + getRunningLoaderPod(f) +} + +func getRunningLoaderPod(f *framework.Framework) *api.Pod { + label := labels.SelectorFromSet(labels.Set(map[string]string{loaderLabelKey: loaderLabelValue})) + pods, err := framework.WaitForPodsWithLabelScheduled(f.ClientSet, f.Namespace.Name, label) + framework.ExpectNoError(err, "Failed to schedule apparmor-loader Pod") + pod := &pods.Items[0] + framework.ExpectNoError(framework.WaitForPodRunningInNamespace(f.ClientSet, pod), "Failed to run apparmor-loader Pod") + return pod }