Skip to content

Commit 75fdb07

Browse files
authored
vpc: fix ips on wrong interfaces after rebooting vpc vrs (#4467)
* vpc: fix ips on wrong interfaces after rebooting vpc vrs * #4467: Rename to updateNicWithDeviceId * CLSTACK-8923 vr: Force a restart of keepalived if conntrackd is not running or configuration has changed
1 parent d79d242 commit 75fdb07

File tree

7 files changed

+150
-3
lines changed

7 files changed

+150
-3
lines changed

server/src/main/java/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,7 @@ public boolean finalizeCommandsOnStart(final Commands cmds, final VirtualMachine
339339
vlanMacAddress.put(vlanTag, routerNic.getMacAddress());
340340
}
341341
}
342+
int deviceId = 1; //Public and Guest networks start from device_id = 1
342343

343344
final List<Command> usageCmds = new ArrayList<Command>();
344345

@@ -347,7 +348,8 @@ public boolean finalizeCommandsOnStart(final Commands cmds, final VirtualMachine
347348
// add VPC router to public networks
348349
final List<PublicIp> sourceNat = new ArrayList<PublicIp>(1);
349350
for (final Pair<Nic, Network> nicNtwk : publicNics) {
350-
final Nic publicNic = nicNtwk.first();
351+
final Nic publicNic = updateNicWithDeviceId(nicNtwk.first().getId(), deviceId);
352+
deviceId ++;
351353
final Network publicNtwk = nicNtwk.second();
352354
final IPAddressVO userIp = _ipAddressDao.findByIpAndSourceNetworkId(publicNtwk.getId(), publicNic.getIPv4Address());
353355

@@ -385,7 +387,8 @@ public boolean finalizeCommandsOnStart(final Commands cmds, final VirtualMachine
385387

386388
// add VPC router to guest networks
387389
for (final Pair<Nic, Network> nicNtwk : guestNics) {
388-
final Nic guestNic = nicNtwk.first();
390+
final Nic guestNic = updateNicWithDeviceId(nicNtwk.first().getId(), deviceId);
391+
deviceId ++;
389392
// plug guest nic
390393
final PlugNicCommand plugNicCmd = new PlugNicCommand(_nwHelper.getNicTO(domainRouterVO, guestNic.getNetworkId(), null), domainRouterVO.getInstanceName(), domainRouterVO.getType(), details);
391394
cmds.addCommand(plugNicCmd);
@@ -834,4 +837,11 @@ public boolean postStateTransitionEvent(final StateMachine2.Transition<State, Vi
834837
// once from VpcVirtualNetworkApplianceManagerImpl and once from VirtualNetworkApplianceManagerImpl itself
835838
return true;
836839
}
840+
841+
private Nic updateNicWithDeviceId(final long nicId, int deviceId) {
842+
NicVO nic = _nicDao.findById(nicId);
843+
nic.setDeviceId(deviceId);
844+
_nicDao.update(nic.getId(), nic);
845+
return nic;
846+
}
837847
}

systemvm/debian/opt/cloud/bin/cs/CsRedundant.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ def _redundant_on(self):
173173
force_keepalived_restart = False
174174
proc = CsProcess(['/etc/conntrackd/conntrackd.conf'])
175175

176-
if not proc.find() and not is_equals:
176+
if not proc.find() or not is_equals:
177177
CsHelper.copy(conntrackd_template_conf, self.CONNTRACKD_CONF)
178178
CsHelper.service("conntrackd", "restart")
179179
force_keepalived_restart = True

systemvm/debian/opt/cloud/bin/setup/bootstrap.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,9 @@ config_guest() {
104104
for i in {1..60}; do
105105
if [ -s $CMDLINE ]; then
106106
log_it "Received a new non-empty cmdline file from qemu-guest-agent"
107+
# Remove old configuration files in /etc/cloudstack if VR is booted from cloudstack
108+
rm -rf /etc/cloudstack/*.json
109+
log_it "Booting from cloudstack, remove old configuration files in /etc/cloudstack/"
107110
break
108111
fi
109112
sleep 1

test/integration/component/test_multiple_subnets_in_isolated_network.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
"""
2121

2222
from nose.plugins.attrib import attr
23+
from marvin.cloudstackAPI import rebootRouter
2324
from marvin.cloudstackTestCase import cloudstackTestCase, unittest
2425
from marvin.lib.utils import (validateList,
2526
get_host_credentials,
@@ -106,6 +107,23 @@ def tearDown(cls):
106107
raise Exception("Warning: Exception during cleanup : %s" % e)
107108
return
108109

110+
def get_router(self, router_id):
111+
routers = list_routers(
112+
self.apiclient,
113+
id=router_id,
114+
listall=True)
115+
self.assertEqual(
116+
isinstance(routers, list),
117+
True,
118+
"Check for list routers response return valid data"
119+
)
120+
self.assertNotEqual(
121+
len(routers),
122+
0,
123+
"Check list router response"
124+
)
125+
return routers[0]
126+
109127
def get_routers(self, network_id):
110128
routers = list_routers(
111129
self.apiclient,
@@ -672,6 +690,22 @@ def test_01_acquire_public_ips_in_isolated_network_with_single_vr(self):
672690
self.verify_ip_address_in_router(router, host, ipaddress_5.ipaddress.ipaddress, "eth4", False)
673691
self.verify_ip_address_in_router(router, host, ipaddress_6.ipaddress.ipaddress, "eth4", True)
674692

693+
# reboot router
694+
for router in routers:
695+
cmd = rebootRouter.rebootRouterCmd()
696+
cmd.id = router.id
697+
self.apiclient.rebootRouter(cmd)
698+
router = self.get_router(router.id)
699+
host = self.get_router_host(router)
700+
self.verify_network_interfaces_in_router(router, host, "eth0,eth1,eth2,eth3,")
701+
guestIp, controlIp, sourcenatIp = self.get_router_ips(router)
702+
self.verify_ip_address_in_router(router, host, guestIp, "eth0", True)
703+
self.verify_ip_address_in_router(router, host, controlIp, "eth1", True)
704+
self.verify_ip_address_in_router(router, host, sourcenatIp, "eth2", True)
705+
self.verify_ip_address_in_router(router, host, ipaddress_4.ipaddress.ipaddress, "eth3", False)
706+
self.verify_ip_address_in_router(router, host, ipaddress_5.ipaddress.ipaddress, "eth3", False)
707+
self.verify_ip_address_in_router(router, host, ipaddress_6.ipaddress.ipaddress, "eth3", True)
708+
675709
# 20. restart network with cleanup
676710
self.network1.restart(self.apiclient, cleanup=True)
677711
routers = self.get_routers(self.network1.id)

test/integration/component/test_multiple_subnets_in_isolated_network_rvr.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
"""
2121

2222
from nose.plugins.attrib import attr
23+
from marvin.cloudstackAPI import rebootRouter
2324
from marvin.cloudstackTestCase import cloudstackTestCase, unittest
2425
from marvin.lib.utils import (validateList,
2526
get_host_credentials,
@@ -106,6 +107,23 @@ def tearDown(cls):
106107
raise Exception("Warning: Exception during cleanup : %s" % e)
107108
return
108109

110+
def get_router(self, router_id):
111+
routers = list_routers(
112+
self.apiclient,
113+
id=router_id,
114+
listall=True)
115+
self.assertEqual(
116+
isinstance(routers, list),
117+
True,
118+
"Check for list routers response return valid data"
119+
)
120+
self.assertNotEqual(
121+
len(routers),
122+
0,
123+
"Check list router response"
124+
)
125+
return routers[0]
126+
109127
def get_routers(self, network_id):
110128
routers = list_routers(
111129
self.apiclient,
@@ -672,6 +690,22 @@ def test_02_acquire_public_ips_in_isolated_network_with_redundant_vrs(self):
672690
self.verify_ip_address_in_router(router, host, ipaddress_5.ipaddress.ipaddress, "eth4", False)
673691
self.verify_ip_address_in_router(router, host, ipaddress_6.ipaddress.ipaddress, "eth4", True)
674692

693+
# reboot router
694+
for router in routers:
695+
cmd = rebootRouter.rebootRouterCmd()
696+
cmd.id = router.id
697+
self.apiclient.rebootRouter(cmd)
698+
router = self.get_router(router.id)
699+
host = self.get_router_host(router)
700+
self.verify_network_interfaces_in_router(router, host, "eth0,eth1,eth2,eth3,")
701+
guestIp, controlIp, sourcenatIp = self.get_router_ips(router)
702+
self.verify_ip_address_in_router(router, host, guestIp, "eth0", True)
703+
self.verify_ip_address_in_router(router, host, controlIp, "eth1", True)
704+
self.verify_ip_address_in_router(router, host, sourcenatIp, "eth2", True)
705+
self.verify_ip_address_in_router(router, host, ipaddress_4.ipaddress.ipaddress, "eth3", False)
706+
self.verify_ip_address_in_router(router, host, ipaddress_5.ipaddress.ipaddress, "eth3", False)
707+
self.verify_ip_address_in_router(router, host, ipaddress_6.ipaddress.ipaddress, "eth3", True)
708+
675709
# 20. restart network with cleanup
676710
self.network1.restart(self.apiclient, cleanup=True)
677711
routers = self.get_routers(self.network1.id)

test/integration/component/test_multiple_subnets_in_vpc.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
"""
2121

2222
from nose.plugins.attrib import attr
23+
from marvin.cloudstackAPI import rebootRouter
2324
from marvin.cloudstackTestCase import cloudstackTestCase, unittest
2425
from marvin.lib.utils import (validateList,
2526
get_host_credentials,
@@ -106,6 +107,23 @@ def tearDown(cls):
106107
raise Exception("Warning: Exception during cleanup : %s" % e)
107108
return
108109

110+
def get_router(self, router_id):
111+
routers = list_routers(
112+
self.apiclient,
113+
id=router_id,
114+
listall=True)
115+
self.assertEqual(
116+
isinstance(routers, list),
117+
True,
118+
"Check for list routers response return valid data"
119+
)
120+
self.assertNotEqual(
121+
len(routers),
122+
0,
123+
"Check list router response"
124+
)
125+
return routers[0]
126+
109127
def get_routers(self, network_id):
110128
routers = list_routers(
111129
self.apiclient,
@@ -790,6 +808,21 @@ def test_03_acquire_public_ips_in_vpc_with_single_vr(self):
790808
self.verify_ip_address_in_router(router, host, tier2_Ip, "eth4", True)
791809
self.verify_ip_address_in_router(router, host, ipaddress_6.ipaddress.ipaddress, "eth5", True)
792810

811+
# reboot router
812+
for router in routers:
813+
cmd = rebootRouter.rebootRouterCmd()
814+
cmd.id = router.id
815+
self.apiclient.rebootRouter(cmd)
816+
router = self.get_router(router.id)
817+
host = self.get_router_host(router)
818+
self.verify_network_interfaces_in_router(router, host, "eth0,eth1,eth2,eth3,eth4,")
819+
controlIp, sourcenatIp, tier1_Ip, tier2_Ip = self.get_vpc_router_ips(router)
820+
self.verify_ip_address_in_router(router, host, controlIp, "eth0", True)
821+
self.verify_ip_address_in_router(router, host, sourcenatIp, "eth1", True)
822+
self.verify_ip_address_in_router(router, host, ipaddress_6.ipaddress.ipaddress, "eth2", True)
823+
self.verify_ip_address_in_router(router, host, tier1_Ip, "eth3", True)
824+
self.verify_ip_address_in_router(router, host, tier2_Ip, "eth4", True)
825+
793826
# 23. restart VPC with cleanup
794827
self.vpc1.restart(self.apiclient, cleanup=True)
795828
routers = self.get_vpc_routers(self.vpc1.id)

test/integration/component/test_multiple_subnets_in_vpc_rvr.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
"""
2121

2222
from nose.plugins.attrib import attr
23+
from marvin.cloudstackAPI import rebootRouter
2324
from marvin.cloudstackTestCase import cloudstackTestCase, unittest
2425
from marvin.lib.utils import (validateList,
2526
get_host_credentials,
@@ -106,6 +107,23 @@ def tearDown(cls):
106107
raise Exception("Warning: Exception during cleanup : %s" % e)
107108
return
108109

110+
def get_router(self, router_id):
111+
routers = list_routers(
112+
self.apiclient,
113+
id=router_id,
114+
listall=True)
115+
self.assertEqual(
116+
isinstance(routers, list),
117+
True,
118+
"Check for list routers response return valid data"
119+
)
120+
self.assertNotEqual(
121+
len(routers),
122+
0,
123+
"Check list router response"
124+
)
125+
return routers[0]
126+
109127
def get_routers(self, network_id):
110128
routers = list_routers(
111129
self.apiclient,
@@ -790,6 +808,21 @@ def test_04_acquire_public_ips_in_vpc_with_redundant_vrs(self):
790808
self.verify_ip_address_in_router(router, host, tier2_Ip, "eth4", True)
791809
self.verify_ip_address_in_router(router, host, ipaddress_6.ipaddress.ipaddress, "eth5", True)
792810

811+
# reboot router
812+
for router in routers:
813+
cmd = rebootRouter.rebootRouterCmd()
814+
cmd.id = router.id
815+
self.apiclient.rebootRouter(cmd)
816+
router = self.get_router(router.id)
817+
host = self.get_router_host(router)
818+
self.verify_network_interfaces_in_router(router, host, "eth0,eth1,eth2,eth3,eth4,")
819+
controlIp, sourcenatIp, tier1_Ip, tier2_Ip = self.get_vpc_router_ips(router)
820+
self.verify_ip_address_in_router(router, host, controlIp, "eth0", True)
821+
self.verify_ip_address_in_router(router, host, sourcenatIp, "eth1", True)
822+
self.verify_ip_address_in_router(router, host, ipaddress_6.ipaddress.ipaddress, "eth2", True)
823+
self.verify_ip_address_in_router(router, host, tier1_Ip, "eth3", True)
824+
self.verify_ip_address_in_router(router, host, tier2_Ip, "eth4", True)
825+
793826
# 23. restart VPC with cleanup
794827
self.vpc1.restart(self.apiclient, cleanup=True)
795828
routers = self.get_vpc_routers(self.vpc1.id)

0 commit comments

Comments
 (0)