Skip to content

Commit

Permalink
fix vm not running after changing the subnet
Browse files Browse the repository at this point in the history
Signed-off-by: zhangzujian <zhangzujian.7@gmail.com>
  • Loading branch information
zhangzujian committed Jun 20, 2024
1 parent e16f380 commit 24ab82b
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 3 deletions.
4 changes: 2 additions & 2 deletions pkg/ovs/ovn-nb-logical_switch_port.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,14 +98,14 @@ func (c *OVNNbClient) CreateLogicalSwitchPort(lsName, lspName, ip, mac, podName,
var ops []ovsdb.Operation
lsp := buildLogicalSwitchPort(lspName, lsName, ip, mac, podName, namespace, portSecurity, securityGroups, vips, enableDHCP, dhcpOptions, vpc)
if existingLsp != nil {
if lsp.ExternalIDs[logicalSwitchKey] == lsName {
if existingLsp.ExternalIDs[logicalSwitchKey] == lsName {
if err := c.UpdateLogicalSwitchPort(lsp, &lsp.Addresses, &lsp.Dhcpv4Options, &lsp.Dhcpv6Options, &lsp.PortSecurity, &lsp.ExternalIDs); err != nil {
klog.Error(err)
return fmt.Errorf("failed to update logical switch port %s: %v", lspName, err)
}
return nil
}
if ops, err = c.LogicalSwitchUpdatePortOp(lsp.ExternalIDs[logicalSwitchKey], existingLsp.UUID, ovsdb.MutateOperationDelete); err != nil {
if ops, err = c.LogicalSwitchUpdatePortOp(existingLsp.ExternalIDs[logicalSwitchKey], existingLsp.UUID, ovsdb.MutateOperationDelete); err != nil {
klog.Error(err)
return err
}
Expand Down
63 changes: 62 additions & 1 deletion test/e2e/kubevirt/e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ var _ = framework.Describe("[group:kubevirt]", func() {
framework.ExpectEqual(ips, pod.Status.PodIPs)
})

framework.ConformanceIt("restart vm should be able to handle subnet change after the namespace has its first subnet", func() {
framework.ConformanceIt("should be able to handle vm restart when subnet changes before the vm is stopped", func() {
// create a vm within a namespace, the namespace has no subnet, so the vm use ovn-default subnet
// create a subnet in the namespace later, the vm should use its own subnet
// stop the vm, the vm should delete the vm ip, because of the namespace only has one subnet but not ovn-default
Expand Down Expand Up @@ -227,6 +227,67 @@ var _ = framework.Describe("[group:kubevirt]", func() {
framework.ExpectContainSubstring(string(output), subnetName)
})

framework.ConformanceIt("should be able to handle vm restart when subnet changes after the vm is stopped", func() {
ginkgo.By("Getting pod of vm " + vmName)
labelSelector := fmt.Sprintf("%s=%s", v1.VirtualMachineNameLabel, vmName)
podList, err := podClient.List(context.TODO(), metav1.ListOptions{
LabelSelector: labelSelector,
})
framework.ExpectNoError(err)
framework.ExpectHaveLen(podList.Items, 1)

ginkgo.By("Validating pod annotations")
pod := &podList.Items[0]
framework.ExpectHaveKeyWithValue(pod.Annotations, util.AllocatedAnnotation, "true")
framework.ExpectHaveKeyWithValue(pod.Annotations, util.RoutedAnnotation, "true")
framework.ExpectHaveKeyWithValue(pod.Annotations, util.VMAnnotation, vmName)
ips := pod.Status.PodIPs

ginkgo.By("Checking old lsp ExternalIDs contains should contains default subnet " + util.DefaultSubnet)
portName := ovs.PodNameToPortName(vmName, namespaceName, util.OvnProvider)
conditions := fmt.Sprintf("name=%s", portName)
execCmd := "kubectl ko nbctl --format=list --data=bare --no-heading --columns=external_ids find logical-switch-port " + conditions
framework.Logf("exec cmd %s", execCmd)
output, err := exec.Command("bash", "-c", execCmd).CombinedOutput()
framework.ExpectNoError(err)
framework.ExpectContainSubstring(string(output), util.DefaultSubnet)

ginkgo.By("Stopping vm " + vmName)
vmClient.StopSync(vmName)

ginkgo.By("Creating subnet " + subnetName)
cidr := framework.RandomCIDR(f.ClusterIPFamily)
subnet := framework.MakeSubnet(subnetName, "", cidr, "", "", "", nil, nil, []string{namespaceName})
_ = subnetClient.CreateSync(subnet)

ginkgo.By("Starting vm " + vmName)
vmClient.StartSync(vmName)

ginkgo.By("Getting pod of vm " + vmName)
podList, err = podClient.List(context.TODO(), metav1.ListOptions{
LabelSelector: labelSelector,
})
framework.ExpectNoError(err)
framework.ExpectHaveLen(podList.Items, 1)

ginkgo.By("Validating new pod annotations")
pod = &podList.Items[0]
framework.ExpectHaveKeyWithValue(pod.Annotations, util.AllocatedAnnotation, "true")
framework.ExpectHaveKeyWithValue(pod.Annotations, util.RoutedAnnotation, "true")
framework.ExpectHaveKeyWithValue(pod.Annotations, util.VMAnnotation, vmName)

ginkgo.By("Checking whether pod ips are changed")
framework.ExpectNotEqual(ips, pod.Status.PodIPs)

ginkgo.By("Checking new lsp ExternalIDs should contains new subnet " + subnetName)
conditions = fmt.Sprintf("name=%s", portName)
execCmd = "kubectl ko nbctl --format=list --data=bare --no-heading --columns=external_ids find logical-switch-port " + conditions
framework.Logf("exec cmd %s", execCmd)
output, err = exec.Command("bash", "-c", execCmd).CombinedOutput()
framework.ExpectNoError(err)
framework.ExpectContainSubstring(string(output), subnetName)
})

framework.ConformanceIt("restart vm should be able to change vm subnet after deleting the old ip", func() {
// case: test change vm subnet after stop vm and delete old ip
// stop vm, delete the ip.
Expand Down

0 comments on commit 24ab82b

Please sign in to comment.