Skip to content

Commit 937fc9d

Browse files
authored
Bundle internal binaries when available and add IT cases (#3627)
* Update flag to bundle internal binarues and add IT cases * fix format * update COPY_INTERNAL_PLUGINS default to false * re-arrange imports * Remove docker wildcard as it has caused issues with packaging binaries * fix trailing space * update test to annotate the pod with bw limits * remove flag dependency in image build * Add core plugins test to cni release test suite
1 parent 1447502 commit 937fc9d

File tree

5 files changed

+190
-2
lines changed

5 files changed

+190
-2
lines changed

scripts/dockerfiles/Dockerfile.init

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ FROM $base_image
1818
WORKDIR /init
1919

2020
COPY --from=builder \
21-
/go/src/github.com/aws/amazon-vpc-cni-k8s/core-plugins/* \
21+
/go/src/github.com/aws/amazon-vpc-cni-k8s/core-plugins/ \
2222
/go/src/github.com/aws/amazon-vpc-cni-k8s/aws-cni-support.sh \
2323
/go/src/github.com/aws/amazon-vpc-cni-k8s/aws-vpc-cni-init /init/
2424

scripts/run-cni-release-tests.sh

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,12 @@ function run_integration_test() {
4949
START=$SECONDS
5050
cd $INTEGRATION_TEST_DIR/metrics-helper && CGO_ENABLED=0 ginkgo $EXTRA_GINKGO_FLAGS -v -timeout 15m --no-color --fail-on-pending -- --cluster-kubeconfig="$KUBECONFIG" --cluster-name="$CLUSTER_NAME" --aws-region="$REGION" --aws-vpc-id="$VPC_ID" --ng-name-label-key="$NG_LABEL_KEY" --ng-name-label-val="$NG_LABEL_VAL" --cni-metrics-helper-image-repo=$REPO_NAME --cni-metrics-helper-image-tag=$TAG --test-image-registry=$TEST_IMAGE_REGISTRY || TEST_RESULT=fail
5151
echo "cni-metrics-helper test took $((SECONDS - START)) seconds."
52+
53+
echo "Running core plugins integration tests"
54+
START=$SECONDS
55+
cd $INTEGRATION_TEST_DIR/core-plugins && CGO_ENABLED=0 ginkgo $EXTRA_GINKGO_FLAGS -v -timeout 60m --no-color --fail-on-pending -- --cluster-kubeconfig="$KUBECONFIG" --cluster-name="$CLUSTER_NAME" --aws-region="$REGION" --aws-vpc-id="$VPC_ID" --ng-name-label-key="$NG_LABEL_KEY" --ng-name-label-val="$NG_LABEL_VAL" --test-image-registry=$TEST_IMAGE_REGISTRY || TEST_RESULT=fail
56+
echo "core plugins test took $((SECONDS - START)) seconds."
57+
5258
if [[ "$TEST_RESULT" == fail ]]; then
5359
echo "Integration test failed."
5460
exit 1

test/framework/resources/k8s/manifest/deployment.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ type DeploymentBuilder struct {
2828
replicas int
2929
container corev1.Container
3030
labels map[string]string
31+
annotations map[string]string
3132
nodeSelector map[string]string
3233
terminationGracePeriod int
3334
nodeName string
@@ -111,6 +112,14 @@ func (d *DeploymentBuilder) PodLabel(labelKey string, labelValue string) *Deploy
111112
return d
112113
}
113114

115+
func (d *DeploymentBuilder) PodAnnotation(key string, value string) *DeploymentBuilder {
116+
if d.annotations == nil {
117+
d.annotations = map[string]string{}
118+
}
119+
d.annotations[key] = value
120+
return d
121+
}
122+
114123
func (d *DeploymentBuilder) HostNetwork(hostNetwork bool) *DeploymentBuilder {
115124
d.hostNetwork = hostNetwork
116125
return d
@@ -136,7 +145,8 @@ func (d *DeploymentBuilder) Build() *v1.Deployment {
136145
},
137146
Template: corev1.PodTemplateSpec{
138147
ObjectMeta: metav1.ObjectMeta{
139-
Labels: d.labels,
148+
Labels: d.labels,
149+
Annotations: d.annotations,
140150
},
141151
Spec: corev1.PodSpec{
142152
HostNetwork: d.hostNetwork,
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License"). You may
4+
// not use this file except in compliance with the License. A copy of the
5+
// License is located at
6+
//
7+
// http://aws.amazon.com/apache2.0/
8+
//
9+
// or in the "license" file accompanying this file. This file is distributed
10+
// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11+
// express or implied. See the License for the specific language governing
12+
// permissions and limitations under the License.
13+
14+
package core_plugins
15+
16+
import (
17+
"testing"
18+
19+
"github.com/aws/amazon-vpc-cni-k8s/test/framework"
20+
"github.com/aws/amazon-vpc-cni-k8s/test/framework/utils"
21+
22+
. "github.com/onsi/ginkgo/v2"
23+
. "github.com/onsi/gomega"
24+
)
25+
26+
var f *framework.Framework
27+
28+
func TestCorePlugins(t *testing.T) {
29+
RegisterFailHandler(Fail)
30+
RunSpecs(t, "CNI Init Container Core Plugins Suite")
31+
}
32+
33+
var _ = BeforeSuite(func() {
34+
f = framework.New(framework.GlobalOptions)
35+
36+
By("creating test namespace")
37+
f.K8sResourceManagers.NamespaceManager().CreateNamespace(utils.DefaultTestNamespace)
38+
})
39+
40+
var _ = AfterSuite(func() {
41+
By("deleting test namespace")
42+
f.K8sResourceManagers.NamespaceManager().
43+
DeleteAndWaitTillNamespaceDeleted(utils.DefaultTestNamespace)
44+
})
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License"). You may
4+
// not use this file except in compliance with the License. A copy of the
5+
// License is located at
6+
//
7+
// http://aws.amazon.com/apache2.0/
8+
//
9+
// or in the "license" file accompanying this file. This file is distributed
10+
// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11+
// express or implied. See the License for the specific language governing
12+
// permissions and limitations under the License.
13+
14+
package core_plugins
15+
16+
import (
17+
"fmt"
18+
"strings"
19+
20+
"github.com/aws/amazon-vpc-cni-k8s/test/framework/resources/k8s/manifest"
21+
k8sUtils "github.com/aws/amazon-vpc-cni-k8s/test/framework/resources/k8s/utils"
22+
"github.com/aws/amazon-vpc-cni-k8s/test/framework/utils"
23+
24+
. "github.com/onsi/ginkgo/v2"
25+
. "github.com/onsi/gomega"
26+
)
27+
28+
const (
29+
awsNodeLabelKey = "k8s-app"
30+
cniBinPath = "/host/opt/cni/bin"
31+
)
32+
33+
// expectedCorePlugins lists all containernetworking/plugins binaries shipped
34+
// in the amazon-k8s-cni-init image via core-plugins/binaries/.
35+
var expectedCorePlugins = []string{
36+
"bandwidth",
37+
"bridge",
38+
"dhcp",
39+
"dummy",
40+
"firewall",
41+
"host-device",
42+
"host-local",
43+
"ipvlan",
44+
"loopback",
45+
"macvlan",
46+
"portmap",
47+
"ptp",
48+
"sbr",
49+
"static",
50+
"tap",
51+
"tuning",
52+
"vlan",
53+
"vrf",
54+
}
55+
56+
var _ = Describe("CNI init container core plugins", func() {
57+
It("all core plugins should be present with executable permissions", func() {
58+
By("getting an aws-node pod")
59+
podList, err := f.K8sResourceManagers.PodManager().
60+
GetPodsWithLabelSelector(awsNodeLabelKey, utils.AwsNodeName)
61+
Expect(err).ToNot(HaveOccurred())
62+
Expect(podList.Items).ToNot(BeEmpty(), "expected at least one aws-node pod")
63+
64+
pod := podList.Items[0]
65+
By(fmt.Sprintf("checking core plugin executability on node %s via pod %s", pod.Spec.NodeName, pod.Name))
66+
67+
var failures []string
68+
for _, plugin := range expectedCorePlugins {
69+
p := fmt.Sprintf("%s/%s", cniBinPath, plugin)
70+
// Invoke the binary directly; CNI plugins print version info on
71+
// stdin-EOF and exit 0 or 1, but the exec itself will fail with a
72+
// clear error if the file is missing or not executable.
73+
cmd := []string{p}
74+
_, _, err := f.K8sResourceManagers.PodManager().
75+
PodExecWithContainer(pod.Namespace, pod.Name, "aws-node", cmd)
76+
if err != nil {
77+
errMsg := err.Error()
78+
if strings.Contains(errMsg, "not found") || strings.Contains(errMsg, "no such file") {
79+
failures = append(failures, fmt.Sprintf("MISSING: %s", plugin))
80+
} else if strings.Contains(errMsg, "permission denied") {
81+
failures = append(failures, fmt.Sprintf("NOT_EXEC: %s", plugin))
82+
}
83+
// Other errors (e.g. non-zero exit) are expected — the binary
84+
// exists and is executable but needs CNI_COMMAND env, so ignore.
85+
}
86+
}
87+
Expect(failures).To(BeEmpty(),
88+
fmt.Sprintf("core plugin issues found:\n%s", strings.Join(failures, "\n")))
89+
})
90+
91+
Context("when ENABLE_BANDWIDTH_PLUGIN is enabled", func() {
92+
AfterEach(func() {
93+
By("disabling ENABLE_BANDWIDTH_PLUGIN")
94+
k8sUtils.RemoveVarFromDaemonSetAndWaitTillUpdated(f,
95+
utils.AwsNodeName, utils.AwsNodeNamespace, utils.AwsNodeName,
96+
map[string]struct{}{
97+
"ENABLE_BANDWIDTH_PLUGIN": {},
98+
})
99+
})
100+
101+
It("pods should reach Running state", func() {
102+
By("enabling ENABLE_BANDWIDTH_PLUGIN on aws-node daemonset")
103+
k8sUtils.AddEnvVarToDaemonSetAndWaitTillUpdated(f,
104+
utils.AwsNodeName, utils.AwsNodeNamespace, utils.AwsNodeName,
105+
map[string]string{
106+
"ENABLE_BANDWIDTH_PLUGIN": "true",
107+
})
108+
109+
By("creating a deployment to verify pods can start")
110+
deployment := manifest.NewBusyBoxDeploymentBuilder(f.Options.TestImageRegistry).
111+
Replicas(3).
112+
PodLabel("app", "bandwidth-test").
113+
PodAnnotation("kubernetes.io/ingress-bandwidth", "10M").
114+
PodAnnotation("kubernetes.io/egress-bandwidth", "10M").
115+
Build()
116+
117+
deployment, err := f.K8sResourceManagers.DeploymentManager().
118+
CreateAndWaitTillDeploymentIsReady(deployment, utils.DefaultDeploymentReadyTimeout)
119+
Expect(err).ToNot(HaveOccurred(),
120+
"pods failed to reach Running state with ENABLE_BANDWIDTH_PLUGIN=true")
121+
122+
By("deleting the test deployment")
123+
err = f.K8sResourceManagers.DeploymentManager().
124+
DeleteAndWaitTillDeploymentIsDeleted(deployment)
125+
Expect(err).ToNot(HaveOccurred())
126+
})
127+
})
128+
})

0 commit comments

Comments
 (0)