diff --git a/pkg/virt-launcher/virtwrap/network/dhcp/dhcp.go b/pkg/virt-launcher/virtwrap/network/dhcp/dhcp.go
index 87068cafb432..22de3b877758 100644
--- a/pkg/virt-launcher/virtwrap/network/dhcp/dhcp.go
+++ b/pkg/virt-launcher/virtwrap/network/dhcp/dhcp.go
@@ -39,7 +39,7 @@ func SingleClientDHCPServer(
serverIface string,
serverIP net.IP,
routerIP net.IP,
- dnsIP net.IP) error {
+ dnsIP net.IP) {
log.Log.Info("Starting SingleClientDHCPServer")
@@ -57,14 +57,13 @@ func SingleClientDHCPServer(
l, err := dhcpConn.NewUDP4BoundListener(serverIface, ":67")
if err != nil {
- return err
+ panic(err)
}
defer l.Close()
err = dhcp.Serve(l, handler)
if err != nil {
- return err
+ panic(err)
}
- return nil
}
type DHCPHandler struct {
diff --git a/pkg/virt-launcher/virtwrap/network/generated_mock_network.go b/pkg/virt-launcher/virtwrap/network/generated_mock_network.go
index 208b8e4bcd64..d4416e2f35af 100644
--- a/pkg/virt-launcher/virtwrap/network/generated_mock_network.go
+++ b/pkg/virt-launcher/virtwrap/network/generated_mock_network.go
@@ -8,6 +8,8 @@ import (
gomock "github.com/golang/mock/gomock"
netlink "github.com/vishvananda/netlink"
+
+ v1 "kubevirt.io/kubevirt/pkg/api/v1"
)
// Mock of NetworkHandler interface
@@ -147,10 +149,10 @@ func (_mr *_MockNetworkHandlerRecorder) GetMacDetails(arg0 interface{}) *gomock.
return _mr.mock.ctrl.RecordCall(_mr.mock, "GetMacDetails", arg0)
}
-func (_m *MockNetworkHandler) StartDHCP(nic *VIF, serverAddr *netlink.Addr) {
- _m.ctrl.Call(_m, "StartDHCP", nic, serverAddr)
+func (_m *MockNetworkHandler) StartDHCP(vm *v1.VirtualMachine, nic *VIF, serverAddr *netlink.Addr) {
+ _m.ctrl.Call(_m, "StartDHCP", vm, nic, serverAddr)
}
-func (_mr *_MockNetworkHandlerRecorder) StartDHCP(arg0, arg1 interface{}) *gomock.Call {
- return _mr.mock.ctrl.RecordCall(_mr.mock, "StartDHCP", arg0, arg1)
+func (_mr *_MockNetworkHandlerRecorder) StartDHCP(arg0, arg1, arg2 interface{}) *gomock.Call {
+ return _mr.mock.ctrl.RecordCall(_mr.mock, "StartDHCP", arg0, arg1, arg2)
}
diff --git a/pkg/virt-launcher/virtwrap/network/network.go b/pkg/virt-launcher/virtwrap/network/network.go
index a977af18d095..1963efeba1e8 100644
--- a/pkg/virt-launcher/virtwrap/network/network.go
+++ b/pkg/virt-launcher/virtwrap/network/network.go
@@ -66,7 +66,7 @@ type NetworkHandler interface {
ParseAddr(s string) (*netlink.Addr, error)
ChangeMacAddr(iface string) (net.HardwareAddr, error)
GetMacDetails(iface string) (net.HardwareAddr, error)
- StartDHCP(nic *VIF, serverAddr *netlink.Addr)
+ StartDHCP(vm *v1.VirtualMachine, nic *VIF, serverAddr *netlink.Addr)
}
type NetworkUtilsHandler struct{}
@@ -136,10 +136,16 @@ func (h *NetworkUtilsHandler) ChangeMacAddr(iface string) (net.HardwareAddr, err
return currentMac, nil
}
-func (h *NetworkUtilsHandler) StartDHCP(nic *VIF, serverAddr *netlink.Addr) {
- // Start DHCP
- go func() {
- dhcp.SingleClientDHCPServer(
+func (h *NetworkUtilsHandler) StartDHCP(vm *v1.VirtualMachine, nic *VIF, serverAddr *netlink.Addr) {
+ func() {
+ defer func() {
+ if err := recover(); err != nil && !vm.IsFinal() {
+ log.Log.Errorf("failed to run DHCP: %v", err)
+ panic("err")
+ }
+ }()
+
+ DHCPServer(
nic.MAC,
nic.IP.IP,
nic.IP.Mask,
@@ -153,6 +159,7 @@ func (h *NetworkUtilsHandler) StartDHCP(nic *VIF, serverAddr *netlink.Addr) {
// Allow mocking for tests
var SetupPodNetwork = SetupDefaultPodNetwork
+var DHCPServer = dhcp.SingleClientDHCPServer
func initHandler() {
if Handler == nil {
@@ -273,7 +280,7 @@ func SetupDefaultPodNetwork(vm *v1.VirtualMachine, domain *api.Domain) error {
}
// Start DHCP Server
- Handler.StartDHCP(nic, fakeaddr)
+ go Handler.StartDHCP(vm, nic, fakeaddr)
if err := plugNetworkDevice(vm, domain, nic); err != nil {
return err
diff --git a/pkg/virt-launcher/virtwrap/network/network_test.go b/pkg/virt-launcher/virtwrap/network/network_test.go
index f3b3abc760ce..9e16a7161e17 100644
--- a/pkg/virt-launcher/virtwrap/network/network_test.go
+++ b/pkg/virt-launcher/virtwrap/network/network_test.go
@@ -36,12 +36,46 @@ import (
var _ = Describe("Network", func() {
var mockNetwork *MockNetworkHandler
var ctrl *gomock.Controller
-
+ var dummy *netlink.Dummy
+ var addrList []netlink.Addr
+ var routeList []netlink.Route
+ var routeAddr netlink.Route
+ var fakeMac net.HardwareAddr
+ var fakeAddr netlink.Addr
+ var updateFakeMac net.HardwareAddr
+ var macvlanTest *netlink.Macvlan
+ var macvlanAddr *netlink.Addr
+ var testNic *VIF
+ var interfaceXml []byte
log.Log.SetIOWriter(GinkgoWriter)
BeforeEach(func() {
ctrl = gomock.NewController(GinkgoT())
mockNetwork = NewMockNetworkHandler(ctrl)
+ testMac := "12:34:56:78:9A:BC"
+ updateTestMac := "AF:B3:1F:78:2A:CA"
+ dummy = &netlink.Dummy{LinkAttrs: netlink.LinkAttrs{Index: 1}}
+ address := &net.IPNet{IP: net.IPv4(10, 35, 0, 6), Mask: net.CIDRMask(24, 32)}
+ gw := net.IPv4(10, 35, 0, 1)
+ fakeMac, _ = net.ParseMAC(testMac)
+ updateFakeMac, _ = net.ParseMAC(updateTestMac)
+ fakeAddr = netlink.Addr{IPNet: address}
+ addrList = []netlink.Addr{fakeAddr}
+ routeAddr = netlink.Route{Gw: gw}
+ routeList = []netlink.Route{routeAddr}
+ macvlanTest = &netlink.Macvlan{
+ LinkAttrs: netlink.LinkAttrs{
+ Name: macVlanIfaceName,
+ ParentIndex: 1,
+ },
+ Mode: netlink.MACVLAN_MODE_BRIDGE,
+ }
+ macvlanAddr, _ = netlink.ParseAddr(macVlanFakeIP)
+ testNic = &VIF{Name: podInterface,
+ IP: fakeAddr,
+ MAC: fakeMac,
+ Gateway: gw}
+ interfaceXml = []byte(``)
})
Context("on successful Network setup", func() {
@@ -54,30 +88,6 @@ var _ = Describe("Network", func() {
}
api.SetObjectDefaults_Domain(domain)
- testMac := "12:34:56:78:9A:BC"
- updateTestMac := "AF:B3:1F:78:2A:CA"
- dummy := &netlink.Dummy{LinkAttrs: netlink.LinkAttrs{Index: 1}}
- address := &net.IPNet{IP: net.IPv4(10, 35, 0, 6), Mask: net.CIDRMask(24, 32)}
- gw := net.IPv4(10, 35, 0, 1)
- fakeMac, _ := net.ParseMAC(testMac)
- updateFakeMac, _ := net.ParseMAC(updateTestMac)
- fakeAddr := netlink.Addr{IPNet: address}
- addrList := []netlink.Addr{fakeAddr}
- routeAddr := netlink.Route{Gw: gw}
- routeList := []netlink.Route{routeAddr}
- macvlanTest := &netlink.Macvlan{
- LinkAttrs: netlink.LinkAttrs{
- Name: macVlanIfaceName,
- ParentIndex: 1,
- },
- Mode: netlink.MACVLAN_MODE_BRIDGE,
- }
- macvlanAddr, _ := netlink.ParseAddr(macVlanFakeIP)
- testNic := &VIF{Name: podInterface,
- IP: fakeAddr,
- MAC: fakeMac,
- Gateway: gw}
- var interfaceXml = []byte(``)
mockNetwork.EXPECT().LinkByName(podInterface).Return(dummy, nil)
mockNetwork.EXPECT().AddrList(dummy, netlink.FAMILY_V4).Return(addrList, nil)
@@ -92,7 +102,7 @@ var _ = Describe("Network", func() {
mockNetwork.EXPECT().LinkSetUp(macvlanTest).Return(nil)
mockNetwork.EXPECT().ParseAddr(macVlanFakeIP).Return(macvlanAddr, nil)
mockNetwork.EXPECT().AddrAdd(macvlanTest, macvlanAddr).Return(nil)
- mockNetwork.EXPECT().StartDHCP(testNic, macvlanAddr)
+ mockNetwork.EXPECT().StartDHCP(vm, testNic, macvlanAddr)
err := SetupPodNetwork(vm, domain)
Expect(err).To(BeNil())
@@ -108,8 +118,45 @@ var _ = Describe("Network", func() {
Expect(ifaceStaus.MAC).To(Equal(testNic.MAC.String()))
})
})
+ Context("on DHCP execution", func() {
+ It("should panic if vm is running", func() {
+ netInterface := &NetworkUtilsHandler{}
+ dhcpTestFunc := func() {
+ vm := &v1.VirtualMachine{
+ Status: v1.VirtualMachineStatus{Phase: v1.Running},
+ }
- AfterEach(func() {
- ctrl.Finish()
+ DHCPServer = func(clientMAC net.HardwareAddr,
+ clientIP net.IP,
+ clientMask net.IPMask,
+ serverIface string,
+ serverIP net.IP,
+ routerIP net.IP,
+ dnsIP net.IP) {
+ panic("DHCP exception: Running")
+ }
+ netInterface.StartDHCP(vm, testNic, &fakeAddr)
+ }
+ Expect(dhcpTestFunc).To(Panic())
+ })
+ It("should not panic if vm is shutting down", func() {
+ netInterface := &NetworkUtilsHandler{}
+ dhcpTestFunc := func() {
+ vm := &v1.VirtualMachine{
+ Status: v1.VirtualMachineStatus{Phase: v1.Succeeded},
+ }
+ DHCPServer = func(clientMAC net.HardwareAddr,
+ clientIP net.IP,
+ clientMask net.IPMask,
+ serverIface string,
+ serverIP net.IP,
+ routerIP net.IP,
+ dnsIP net.IP) {
+ panic("DHCP exception: Succeeded")
+ }
+ netInterface.StartDHCP(vm, testNic, &fakeAddr)
+ }
+ Expect(dhcpTestFunc).ShouldNot(Panic())
+ })
})
})