From a976f1c23c31e8a15f9d5abdc39f87102868c8c3 Mon Sep 17 00:00:00 2001 From: Edison Su Date: Thu, 19 Jan 2012 20:02:17 -0800 Subject: [PATCH] bug 13145: update user data in domr when updatevmcmd is called status 13145: resolved fixed --- .../network/router/UpdateUserDataElement.java | 11 ++++ .../src/com/cloud/network/NetworkManager.java | 3 ++ .../com/cloud/network/NetworkManagerImpl.java | 41 ++++++++++++++ .../cloud/network/element/DhcpElement.java | 19 ++++++- .../network/element/VirtualRouterElement.java | 17 ++++++ .../VirtualNetworkApplianceManager.java | 6 +++ .../VirtualNetworkApplianceManagerImpl.java | 53 +++++++++++++------ .../src/com/cloud/vm/UserVmManagerImpl.java | 5 ++ 8 files changed, 139 insertions(+), 16 deletions(-) create mode 100644 api/src/com/cloud/network/router/UpdateUserDataElement.java diff --git a/api/src/com/cloud/network/router/UpdateUserDataElement.java b/api/src/com/cloud/network/router/UpdateUserDataElement.java new file mode 100644 index 00000000000..0dd02fd7f05 --- /dev/null +++ b/api/src/com/cloud/network/router/UpdateUserDataElement.java @@ -0,0 +1,11 @@ +package com.cloud.network.router; + +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.Network; +import com.cloud.vm.NicProfile; +import com.cloud.vm.VirtualMachine; +import com.cloud.vm.VirtualMachineProfile; + +public interface UpdateUserDataElement { + public boolean updateUserData(Network network, NicProfile nic, VirtualMachineProfile vm) throws ResourceUnavailableException; +} diff --git a/server/src/com/cloud/network/NetworkManager.java b/server/src/com/cloud/network/NetworkManager.java index 59be681a169..b6e1a4d2415 100644 --- a/server/src/com/cloud/network/NetworkManager.java +++ b/server/src/com/cloud/network/NetworkManager.java @@ -41,6 +41,7 @@ import com.cloud.network.vpn.RemoteAccessVpnElement; import com.cloud.offerings.NetworkOfferingVO; import com.cloud.user.Account; import com.cloud.user.AccountVO; +import com.cloud.uservm.UserVm; import com.cloud.utils.Pair; import com.cloud.vm.Nic; import com.cloud.vm.NicProfile; @@ -217,4 +218,6 @@ public interface NetworkManager extends NetworkService { String getIpInNetwork(long vmId, long networkId); String getIpInNetworkIncludingRemoved(long vmId, long networkId); + + boolean updateVmData(UserVm vm); } diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index c3bf61bcc8f..a471ccc909a 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -100,6 +100,7 @@ import com.cloud.network.dao.NetworkDomainDao; import com.cloud.network.element.NetworkElement; import com.cloud.network.guru.NetworkGuru; import com.cloud.network.lb.LoadBalancingRulesManager; +import com.cloud.network.router.UpdateUserDataElement; import com.cloud.network.rules.FirewallManager; import com.cloud.network.rules.FirewallRule; import com.cloud.network.rules.FirewallRule.Purpose; @@ -121,6 +122,7 @@ import com.cloud.user.User; import com.cloud.user.UserContext; import com.cloud.user.dao.AccountDao; import com.cloud.user.dao.UserStatisticsDao; +import com.cloud.uservm.UserVm; import com.cloud.utils.NumbersUtil; import com.cloud.utils.Pair; import com.cloud.utils.component.Adapters; @@ -147,6 +149,7 @@ import com.cloud.vm.ReservationContextImpl; import com.cloud.vm.UserVmVO; import com.cloud.vm.VMInstanceVO; import com.cloud.vm.VirtualMachine; +import com.cloud.vm.VirtualMachineProfileImpl; import com.cloud.vm.VirtualMachine.Type; import com.cloud.vm.VirtualMachineProfile; import com.cloud.vm.dao.DomainRouterDao; @@ -2801,6 +2804,44 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } return elements; } + + private List getUpdateUserDataElements() { + List elements = new ArrayList(); + for (NetworkElement element : _networkElements) { + if (element instanceof UpdateUserDataElement) { + elements.add((UpdateUserDataElement) element); + } + } + return elements; + } + + @Override + public boolean updateVmData(UserVm vm) { + Nic defaultNic = getDefaultNic(vm.getId()); + if (defaultNic == null) { + s_logger.error("Unable to update vm data for vm " + vm.getDisplayName() + " as the instance doesn't have default nic"); + return false; + } + + Network defaultNetwork = getNetwork(defaultNic.getNetworkId()); + NicProfile defaultNicProfile = new NicProfile(defaultNic, defaultNetwork, null, null, null); + VirtualMachineProfile vmProfile = new VirtualMachineProfileImpl((VMInstanceVO)vm); + + List elements = getUpdateUserDataElements(); + + boolean result = true; + try { + for (UpdateUserDataElement element : elements) { + if (!element.updateUserData(defaultNetwork, defaultNicProfile, vmProfile)) { + result = false; + } + } + } catch (ResourceUnavailableException e) { + + } + + return true; + } @Override public boolean zoneIsConfiguredForExternalNetworking(long zoneId) { diff --git a/server/src/com/cloud/network/element/DhcpElement.java b/server/src/com/cloud/network/element/DhcpElement.java index aaad390a607..1d8dfb30add 100644 --- a/server/src/com/cloud/network/element/DhcpElement.java +++ b/server/src/com/cloud/network/element/DhcpElement.java @@ -42,6 +42,7 @@ import com.cloud.network.NetworkManager; import com.cloud.network.Networks.TrafficType; import com.cloud.network.PublicIpAddress; import com.cloud.network.dao.NetworkDao; +import com.cloud.network.router.UpdateUserDataElement; import com.cloud.network.router.VirtualNetworkApplianceManager; import com.cloud.network.router.VirtualRouter; import com.cloud.network.router.VirtualRouter.Role; @@ -65,7 +66,7 @@ import com.cloud.vm.dao.UserVmDao; @Local(value=NetworkElement.class) -public class DhcpElement extends AdapterBase implements NetworkElement, PasswordResetElement{ +public class DhcpElement extends AdapterBase implements NetworkElement, PasswordResetElement, UpdateUserDataElement { private static final Logger s_logger = Logger.getLogger(DhcpElement.class); private static final Map> capabilities = setCapabilities(); @@ -258,4 +259,20 @@ public class DhcpElement extends AdapterBase implements NetworkElement, Password public boolean applyStaticNats(Network config, List rules) throws ResourceUnavailableException { return false; } + + @Override + public boolean updateUserData(Network network, NicProfile nic, + VirtualMachineProfile vm) + throws ResourceUnavailableException { + List routers = _routerDao.listByNetworkAndRole(network.getId(), Role.DHCP_USERDATA); + if (routers == null || routers.isEmpty()) { + s_logger.trace("Can't find dhcp element in network " + network.getId()); + return true; + } + + @SuppressWarnings("unchecked") + VirtualMachineProfile uservm = (VirtualMachineProfile)vm; + + return _routerMgr.updateVmData(network, nic, uservm, routers); + } } diff --git a/server/src/com/cloud/network/element/VirtualRouterElement.java b/server/src/com/cloud/network/element/VirtualRouterElement.java index 230b9f17b27..4512e69c5bd 100644 --- a/server/src/com/cloud/network/element/VirtualRouterElement.java +++ b/server/src/com/cloud/network/element/VirtualRouterElement.java @@ -45,6 +45,7 @@ import com.cloud.network.VpnUser; import com.cloud.network.dao.LoadBalancerDao; import com.cloud.network.dao.NetworkDao; import com.cloud.network.lb.LoadBalancingRulesManager; +import com.cloud.network.router.UpdateUserDataElement; import com.cloud.network.router.VirtualNetworkApplianceManager; import com.cloud.network.router.VirtualRouter; import com.cloud.network.router.VirtualRouter.Role; @@ -372,4 +373,20 @@ public class VirtualRouterElement extends DhcpElement implements NetworkElement, return _routerMgr.savePasswordToRouter(network, nic, uservm, routers); } + + @Override + public boolean updateUserData(Network network, NicProfile nic, + VirtualMachineProfile vm) + throws ResourceUnavailableException { + List routers = _routerDao.listByNetworkAndRole(network.getId(), Role.DHCP_FIREWALL_LB_PASSWD_USERDATA); + if (routers == null || routers.isEmpty()) { + s_logger.trace("Can't find virtual router element in network " + network.getId()); + return true; + } + + @SuppressWarnings("unchecked") + VirtualMachineProfile uservm = (VirtualMachineProfile)vm; + + return _routerMgr.updateVmData(network, nic, uservm, routers); + } } diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java index 4d68faece9a..923aec1234f 100644 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java @@ -38,6 +38,7 @@ import com.cloud.utils.component.Manager; import com.cloud.vm.DomainRouterVO; import com.cloud.vm.NicProfile; import com.cloud.vm.ReservationContext; +import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachineProfile; /** @@ -92,4 +93,9 @@ public interface VirtualNetworkApplianceManager extends Manager, VirtualNetworkA boolean applyStaticNats(Network network, List rules, List routers) throws ResourceUnavailableException; + boolean updateVmData(Network network, NicProfile nic, + VirtualMachineProfile profile, + List routers) + throws ResourceUnavailableException; + } diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index 1177339d9a0..713fcfdfe91 100755 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -2324,27 +2324,32 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian cmds.addCommand("users", addUsersCmd); cmds.addCommand("startVpn", startVpnCmd); } + + private void createvmDataCommand(DomainRouterVO router, UserVmVO userVM, DataCenterVO dc, Commands cmds) { + boolean createVmData = true; + long networkId = router.getNetworkId(); + if (dc.getNetworkType() == NetworkType.Basic && router.getPodIdToDeployIn().longValue() != userVM.getPodIdToDeployIn().longValue()) { + createVmData = false; + } + + if (createVmData) { + NicVO nic = _nicDao.findByInstanceIdAndNetworkId(networkId, userVM.getId()); + if (nic != null) { + s_logger.debug("Creating user data entry for vm " + userVM + " on domR " + router); + String serviceOffering = _serviceOfferingDao.findByIdIncludingRemoved(userVM.getServiceOfferingId()).getDisplayText(); + String zoneName = _dcDao.findById(router.getDataCenterIdToDeployIn()).getName(); + cmds.addCommand("vmdata", + generateVmDataCommand(router, nic.getIp4Address(), userVM.getUserData(), serviceOffering, zoneName, nic.getIp4Address(), userVM.getHostName(), userVM.getInstanceName(), userVM.getId(), null)); + } + } + } private void createVmDataCommands(DomainRouterVO router, Commands cmds) { long networkId = router.getNetworkId(); List vms = _userVmDao.listByNetworkIdAndStates(networkId, State.Running, State.Migrating, State.Stopping); DataCenterVO dc = _dcDao.findById(router.getDataCenterIdToDeployIn()); for (UserVmVO vm : vms) { - boolean createVmData = true; - if (dc.getNetworkType() == NetworkType.Basic && router.getPodIdToDeployIn().longValue() != vm.getPodIdToDeployIn().longValue()) { - createVmData = false; - } - - if (createVmData) { - NicVO nic = _nicDao.findByInstanceIdAndNetworkId(networkId, vm.getId()); - if (nic != null) { - s_logger.debug("Creating user data entry for vm " + vm + " on domR " + router); - String serviceOffering = _serviceOfferingDao.findByIdIncludingRemoved(vm.getServiceOfferingId()).getDisplayText(); - String zoneName = _dcDao.findById(router.getDataCenterIdToDeployIn()).getName(); - cmds.addCommand("vmdata", - generateVmDataCommand(router, nic.getIp4Address(), vm.getUserData(), serviceOffering, zoneName, nic.getIp4Address(), vm.getHostName(), vm.getInstanceName(), vm.getId(), null)); - } - } + createvmDataCommand(router, vm, dc, cmds); } } @@ -2509,6 +2514,24 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian } return result; } + + @Override + public boolean updateVmData(Network network, NicProfile nic, VirtualMachineProfile profile, List routers) throws ResourceUnavailableException { + if (routers == null || routers.isEmpty()) { + s_logger.warn("Unable save password, router doesn't exist in network " + network.getId()); + throw new CloudRuntimeException("Unable to save password to router"); + } + + boolean result = true; + UserVm userVm = profile.getVirtualMachine(); + DataCenterVO dc = _dcDao.findById(userVm.getDataCenterIdToDeployIn()); + for (VirtualRouter router : routers) { + Commands cmds = new Commands(OnError.Continue); + createvmDataCommand((DomainRouterVO)router, (UserVmVO)userVm, dc, cmds); + result = result && sendCommandsToRouter(router, cmds); + } + return result; + } @Override public boolean applyFirewallRules(Network network, List rules, List routers) throws ResourceUnavailableException { diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index 593ed7c3c0d..8b175d0191a 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -1818,9 +1818,11 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager throw new InvalidParameterValueException("Vm with id " + id + " is not in the right state"); } + boolean updateUserdata = false; if (userData != null) { validateUserData(userData); // update userData on domain router. + updateUserdata = true; } else { userData = vmInstance.getUserData(); } @@ -1852,6 +1854,9 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager _vmDao.updateVM(id, displayName, ha, osTypeId, userData); + if (updateUserdata) { + _networkMgr.updateVmData(vmInstance); + } return _vmDao.findById(id); }