-
Notifications
You must be signed in to change notification settings - Fork 299
Resolve ovnkube node encap IP in startup script #2998
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -478,6 +478,18 @@ data: | |
| echo "$(date --iso-8601=seconds) [{$1}] ${2}" | ||
| } | ||
|
|
||
| # set-encap-ip-flag() sets --encap-ip from the OVN_ENCAP_IP environment | ||
| # variable when present. | ||
| set-encap-ip-flag() | ||
| { | ||
| ovn_encap_ip_flag= | ||
|
|
||
| if [[ -n "${OVN_ENCAP_IP}" ]]; then | ||
| log "encapip" "Using OVN_ENCAP_IP=${OVN_ENCAP_IP}" | ||
| ovn_encap_ip_flag="--encap-ip=${OVN_ENCAP_IP}" | ||
| fi | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
| } | ||
|
|
||
| # cni-bin-copy() detects the host OS and copies the correct shim binary to | ||
| # the CNI binary directory. | ||
| # | ||
|
|
@@ -688,6 +700,8 @@ data: | |
| enable_interconnect_flag="--enable-interconnect" | ||
| fi | ||
|
|
||
| set-encap-ip-flag | ||
|
|
||
| exec /usr/bin/ovnkube \ | ||
| ${init_ovnkube_controller} \ | ||
| --init-node "${K8S_NODE}" \ | ||
|
|
@@ -698,6 +712,7 @@ data: | |
| ${gateway_mode_flags} \ | ||
| ${node_mgmt_port_netdev_flags} \ | ||
| ${ovnkube_node_mode} \ | ||
| ${ovn_encap_ip_flag} \ | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is that it has to be a singe IP or comma of IPs is accepted for dualstack? what's the design for this config field upstream? I forget the details.. |
||
| --metrics-bind-address "127.0.0.1:${metrics_port}" \ | ||
| --ovn-metrics-bind-address "127.0.0.1:${ovn_metrics_port}" \ | ||
| --metrics-enable-pprof \ | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4402,6 +4402,113 @@ func TestRenderOVNKubernetes_OpenFlowProbeOverride(t *testing.T) { | |
| }) | ||
| } | ||
|
|
||
| // TestRenderOVNKubernetes_EncapIPEnvOverrideWiring verifies the rendered OVN | ||
| // script library sources per-node overrides and wires OVN_ENCAP_IP into the | ||
| // ovnkube-node command line. | ||
| func TestRenderOVNKubernetes_EncapIPEnvOverrideWiring(t *testing.T) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd drop this test, as it makes noise without giving too value |
||
| g := NewGomegaWithT(t) | ||
|
|
||
| crd := OVNKubernetesConfig.DeepCopy() | ||
| config := &crd.Spec | ||
| fillDefaults(config, nil) | ||
|
|
||
| bootstrapResult := fakeBootstrapResult() | ||
| bootstrapResult.OVN = bootstrap.OVNBootstrapResult{ | ||
| ControlPlaneReplicaCount: 3, | ||
| OVNKubernetesConfig: &bootstrap.OVNConfigBoostrapResult{ | ||
| DpuHostModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU_HOST, | ||
| DpuModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU, | ||
| SmartNicModeLabel: OVN_NODE_SELECTOR_DEFAULT_SMART_NIC, | ||
| MgmtPortResourceName: "", | ||
| DpuNodeLeaseRenewInterval: DPU_NODE_LEASE_RENEW_INTERVAL_DEFAULT, | ||
| DpuNodeLeaseDuration: DPU_NODE_LEASE_DURATION_DEFAULT, | ||
| HyperShiftConfig: &bootstrap.OVNHyperShiftBootstrapResult{ | ||
| Enabled: false, | ||
| }, | ||
| }, | ||
| } | ||
| featureGatesCNO := getDefaultFeatureGates() | ||
| fakeClient := cnofake.NewFakeClient() | ||
|
|
||
| objs, _, err := renderOVNKubernetes(config, bootstrapResult, manifestDirOvn, fakeClient, featureGatesCNO) | ||
| g.Expect(err).NotTo(HaveOccurred()) | ||
|
|
||
| ovnkubeScriptLib := extractOVNScriptLib(g, objs) | ||
| g.Expect(ovnkubeScriptLib).To(ContainSubstring(`if [[ -n "${K8S_NODE}" && -f "/env/${K8S_NODE}" ]]; then`)) | ||
| g.Expect(ovnkubeScriptLib).To(ContainSubstring(`source "/env/${K8S_NODE}"`)) | ||
| g.Expect(ovnkubeScriptLib).To(ContainSubstring(`if [[ -n "${OVN_ENCAP_IP}" ]]; then`)) | ||
| g.Expect(ovnkubeScriptLib).To(ContainSubstring(`ovn_encap_ip_flag="--encap-ip=${OVN_ENCAP_IP}"`)) | ||
| g.Expect(ovnkubeScriptLib).To(ContainSubstring(`${ovn_encap_ip_flag}`)) | ||
| } | ||
|
|
||
| // TestRenderOVNKubernetes_NodeDaemonSetEnvOverridesVolume verifies the | ||
| // ovnkube-node DaemonSet keeps the optional env-overrides ConfigMap mounted so | ||
| // node-specific OVN encapsulation overrides can be sourced at startup. | ||
| func TestRenderOVNKubernetes_NodeDaemonSetEnvOverridesVolume(t *testing.T) { | ||
| g := NewGomegaWithT(t) | ||
|
|
||
| crd := OVNKubernetesConfig.DeepCopy() | ||
| config := &crd.Spec | ||
| fillDefaults(config, nil) | ||
|
|
||
| bootstrapResult := fakeBootstrapResult() | ||
| bootstrapResult.OVN = bootstrap.OVNBootstrapResult{ | ||
| ControlPlaneReplicaCount: 3, | ||
| OVNKubernetesConfig: &bootstrap.OVNConfigBoostrapResult{ | ||
| DpuHostModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU_HOST, | ||
| DpuModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU, | ||
| SmartNicModeLabel: OVN_NODE_SELECTOR_DEFAULT_SMART_NIC, | ||
| MgmtPortResourceName: "", | ||
| DpuNodeLeaseRenewInterval: DPU_NODE_LEASE_RENEW_INTERVAL_DEFAULT, | ||
| DpuNodeLeaseDuration: DPU_NODE_LEASE_DURATION_DEFAULT, | ||
| HyperShiftConfig: &bootstrap.OVNHyperShiftBootstrapResult{ | ||
| Enabled: false, | ||
| }, | ||
| }, | ||
| } | ||
| featureGatesCNO := getDefaultFeatureGates() | ||
| fakeClient := cnofake.NewFakeClient() | ||
|
|
||
| objs, _, err := renderOVNKubernetes(config, bootstrapResult, manifestDirOvn, fakeClient, featureGatesCNO) | ||
| g.Expect(err).NotTo(HaveOccurred()) | ||
|
|
||
| nodeDS := findInObjs("apps", "DaemonSet", "ovnkube-node", "openshift-ovn-kubernetes", objs) | ||
| g.Expect(nodeDS).NotTo(BeNil()) | ||
|
|
||
| ds := appsv1.DaemonSet{} | ||
| g.Expect(convert(nodeDS, &ds)).To(Succeed()) | ||
|
|
||
| var envOverridesVolume *v1.Volume | ||
| for i := range ds.Spec.Template.Spec.Volumes { | ||
| volume := &ds.Spec.Template.Spec.Volumes[i] | ||
| if volume.Name == "env-overrides" { | ||
| envOverridesVolume = volume | ||
| break | ||
| } | ||
| } | ||
|
|
||
| g.Expect(envOverridesVolume).NotTo(BeNil()) | ||
| g.Expect(envOverridesVolume.ConfigMap).NotTo(BeNil()) | ||
| g.Expect(envOverridesVolume.ConfigMap.Name).To(Equal("env-overrides")) | ||
| g.Expect(envOverridesVolume.ConfigMap.Optional).NotTo(BeNil()) | ||
| g.Expect(*envOverridesVolume.ConfigMap.Optional).To(BeTrue()) | ||
|
|
||
| nodeContainer, ok := findContainer(ds.Spec.Template.Spec.Containers, "ovnkube-node") | ||
| if !ok { | ||
| nodeContainer, ok = findContainer(ds.Spec.Template.Spec.Containers, "ovnkube-controller") | ||
| } | ||
| g.Expect(ok).To(BeTrue(), "expecting container named ovnkube-node or ovnkube-controller in the DaemonSet") | ||
|
|
||
| hasEnvOverridesMount := false | ||
| for _, mount := range nodeContainer.VolumeMounts { | ||
| if mount.Name == "env-overrides" && mount.MountPath == "/env" { | ||
| hasEnvOverridesMount = true | ||
| break | ||
| } | ||
| } | ||
| g.Expect(hasEnvOverridesMount).To(BeTrue()) | ||
| } | ||
|
|
||
| func TestRenderOVNKubernetes_AllowICMPNetworkPolicyOverride(t *testing.T) { | ||
| g := NewGomegaWithT(t) | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Normalize
OVN_ENCAP_IPbefore building the flag.At Line 544,
OVN_ENCAP_IPis used verbatim. Accidental whitespace in env overrides can produce an invalid/split--encap-ipargument at runtime.Suggested patch
📝 Committable suggestion
🤖 Prompt for AI Agents