Return-Path: X-Original-To: apmail-cloudstack-commits-archive@www.apache.org Delivered-To: apmail-cloudstack-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 49EBA10A55 for ; Thu, 13 Mar 2014 18:07:20 +0000 (UTC) Received: (qmail 84063 invoked by uid 500); 13 Mar 2014 18:06:17 -0000 Delivered-To: apmail-cloudstack-commits-archive@cloudstack.apache.org Received: (qmail 83823 invoked by uid 500); 13 Mar 2014 18:06:13 -0000 Mailing-List: contact commits-help@cloudstack.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cloudstack.apache.org Delivered-To: mailing list commits@cloudstack.apache.org Received: (qmail 82760 invoked by uid 99); 13 Mar 2014 18:05:50 -0000 Received: from tyr.zones.apache.org (HELO tyr.zones.apache.org) (140.211.11.114) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 13 Mar 2014 18:05:50 +0000 Received: by tyr.zones.apache.org (Postfix, from userid 65534) id 8664C944BE5; Thu, 13 Mar 2014 18:05:48 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: mchen@apache.org To: commits@cloudstack.apache.org Date: Thu, 13 Mar 2014 18:06:11 -0000 Message-Id: <5a8e677b641346739520ae4576bb11d0@git.apache.org> In-Reply-To: <6b3a226c4d0c47e399cb8391b2c5754f@git.apache.org> References: <6b3a226c4d0c47e399cb8391b2c5754f@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [24/50] [abbrv] git commit: updated refs/heads/rbac to 99bdc8d CLOUDSTACK-6179 Execute VR commands on Virtual Resource when commands received to Hyper-V Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/540d020a Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/540d020a Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/540d020a Branch: refs/heads/rbac Commit: 540d020aa5c0cd5d3b4657973b1c8a852bdf6d58 Parents: 33a0dec Author: Rajesh Battala Authored: Tue Mar 11 13:09:18 2014 +0530 Committer: Rajesh Battala Committed: Tue Mar 11 13:10:13 2014 +0530 ---------------------------------------------------------------------- .../hypervisor/hyperv/guru/HypervGuru.java | 9 +- .../resource/HypervDirectConnectResource.java | 216 ++++++++++++++++++- .../debian/config/etc/init.d/cloud-early-config | 8 +- 3 files changed, 222 insertions(+), 11 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/540d020a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/guru/HypervGuru.java ---------------------------------------------------------------------- diff --git a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/guru/HypervGuru.java b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/guru/HypervGuru.java index 1d9e7f6..bf0795d 100644 --- a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/guru/HypervGuru.java +++ b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/guru/HypervGuru.java @@ -53,7 +53,7 @@ public class HypervGuru extends HypervisorGuruBase implements HypervisorGuru { @Inject HypervManager _hypervMgr; @Inject NetworkDao _networkDao; @Inject NetworkModel _networkMgr; - + int MaxNicSupported = 8; @Override public final HypervisorType getHypervisorType() { return HypervisorType.Hyperv; @@ -85,7 +85,7 @@ public class HypervGuru extends HypervisorGuruBase implements HypervisorGuru { NicTO[] nics = to.getNics(); // reserve extra NICs - NicTO[] expandedNics = new NicTO[nics.length + _hypervMgr.getRouterExtraPublicNics()]; + NicTO[] expandedNics = new NicTO[MaxNicSupported]; int i = 0; int deviceId = -1; for(i = 0; i < nics.length; i++) { @@ -97,8 +97,9 @@ public class HypervGuru extends HypervisorGuruBase implements HypervisorGuru { long networkId = publicNicProfile.getNetworkId(); NetworkVO network = _networkDao.findById(networkId); - - for(; i < nics.length + _hypervMgr.getRouterExtraPublicNics(); i++) { + // for Hyperv Hot Nic plug is not supported and it will support upto 8 nics. + // creating the VR with extra nics (actual nics(3) + extra nics) will be 8 + for(; i < MaxNicSupported; i++) { NicTO nicTo = new NicTO(); nicTo.setDeviceId(deviceId++); nicTo.setBroadcastType(publicNicProfile.getBroadcastType()); http://git-wip-us.apache.org/repos/asf/cloudstack/blob/540d020a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java ---------------------------------------------------------------------- diff --git a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java index 549f06d..a3ffa75 100644 --- a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java +++ b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java @@ -83,6 +83,7 @@ import com.cloud.agent.api.NetworkUsageCommand; import com.cloud.agent.api.PingCommand; import com.cloud.agent.api.PingRoutingCommand; import com.cloud.agent.api.PingTestCommand; +import com.cloud.agent.api.SetupGuestNetworkCommand; import com.cloud.agent.api.StartCommand; import com.cloud.agent.api.StartupCommand; import com.cloud.agent.api.StartupRoutingCommand; @@ -98,6 +99,7 @@ import com.cloud.agent.api.routing.DnsMasqConfigCommand; import com.cloud.agent.api.routing.IpAliasTO; import com.cloud.agent.api.routing.IpAssocAnswer; import com.cloud.agent.api.routing.IpAssocCommand; +import com.cloud.agent.api.routing.IpAssocVpcCommand; import com.cloud.agent.api.routing.LoadBalancerConfigCommand; import com.cloud.agent.api.routing.NetworkElementCommand; import com.cloud.agent.api.routing.RemoteAccessVpnCfgCommand; @@ -105,6 +107,7 @@ import com.cloud.agent.api.routing.SavePasswordCommand; import com.cloud.agent.api.routing.SetFirewallRulesAnswer; import com.cloud.agent.api.routing.SetFirewallRulesCommand; import com.cloud.agent.api.routing.SetMonitorServiceCommand; +import com.cloud.agent.api.routing.SetNetworkACLCommand; import com.cloud.agent.api.routing.SetPortForwardingRulesAnswer; import com.cloud.agent.api.routing.SetPortForwardingRulesCommand; import com.cloud.agent.api.routing.SetSourceNatAnswer; @@ -119,9 +122,12 @@ import com.cloud.agent.api.routing.VpnUsersCfgCommand; import com.cloud.agent.api.to.DhcpTO; import com.cloud.agent.api.to.FirewallRuleTO; import com.cloud.agent.api.to.IpAddressTO; +import com.cloud.agent.api.to.NicTO; import com.cloud.agent.api.to.PortForwardingRuleTO; import com.cloud.agent.api.to.StaticNatRuleTO; import com.cloud.agent.api.to.VirtualMachineTO; +import com.cloud.agent.resource.virtualnetwork.VirtualRouterDeployer; +import com.cloud.agent.resource.virtualnetwork.VirtualRoutingResource; import com.cloud.dc.DataCenter.NetworkType; import com.cloud.exception.InternalErrorException; import com.cloud.host.Host.Type; @@ -135,6 +141,7 @@ import com.cloud.network.rules.FirewallRule; import com.cloud.resource.ServerResource; import com.cloud.resource.ServerResourceBase; import com.cloud.serializer.GsonHelper; +import com.cloud.utils.ExecutionResult; import com.cloud.utils.Pair; import com.cloud.utils.StringUtils; import com.cloud.utils.net.NetUtils; @@ -148,7 +155,7 @@ import com.cloud.vm.VirtualMachineName; * Implementation of dummy resource to be returned from discoverer. **/ @Local(value = ServerResource.class) -public class HypervDirectConnectResource extends ServerResourceBase implements ServerResource { +public class HypervDirectConnectResource extends ServerResourceBase implements ServerResource, VirtualRouterDeployer { public static final int DEFAULT_AGENT_PORT = 8250; public static final String HOST_VM_STATE_REPORT_COMMAND = "org.apache.cloudstack.HostVmStateReportCommand"; private static final Logger s_logger = Logger.getLogger(HypervDirectConnectResource.class.getName()); @@ -178,6 +185,7 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S private static HypervManager s_hypervMgr; @Inject HypervManager _hypervMgr; + protected VirtualRoutingResource _vrResource; @PostConstruct void init() { @@ -421,8 +429,9 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S s_logger.error(errMsg, e); return null; } - - if (clazz == CheckSshCommand.class) { + if (cmd instanceof NetworkElementCommand) { + return _vrResource.executeRequest((NetworkElementCommand)cmd); + }if (clazz == CheckSshCommand.class) { answer = execute((CheckSshCommand)cmd); } else if (clazz == GetDomRVersionCmd.class) { answer = execute((GetDomRVersionCmd)cmd); @@ -499,6 +508,203 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S } return answer; } + + @Override + public ExecutionResult executeInVR(String routerIP, String script, String args) { + Pair result; + + //TODO: Password should be masked, cannot output to log directly + if (s_logger.isDebugEnabled()) { + s_logger.debug("Run command on VR: " + routerIP + ", script: " + script + " with args: " + args); + } + + try { + result = SshHelper.sshExecute(routerIP, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "/opt/cloud/bin/" + script + " " + args); + } catch (Exception e) { + String msg = "Command failed due to " + e ; + s_logger.error(msg); + result = new Pair(false, msg); + } + if (s_logger.isDebugEnabled()) { + s_logger.debug(script + " execution result: " + result.first().toString()); + } + return new ExecutionResult(result.first(), result.second()); + } + + @Override + public ExecutionResult createFileInVR(String routerIp, String filePath, String fileName, String content) { + File keyFile = getSystemVMKeyFile(); + try { + SshHelper.scpTo(routerIp, 3922, "root", keyFile, null, filePath, content.getBytes(), fileName, null); + } catch (Exception e) { + s_logger.warn("Fail to create file " + filePath + fileName + " in VR " + routerIp, e); + return new ExecutionResult(false, e.getMessage()); + } + return new ExecutionResult(true, null); + } + + @Override + public ExecutionResult prepareCommand(NetworkElementCommand cmd) { + //Update IP used to access router + cmd.setRouterAccessIp(getRouterSshControlIp(cmd)); + assert cmd.getRouterAccessIp() != null; + + if (cmd instanceof IpAssocVpcCommand) { + return prepareNetworkElementCommand((IpAssocVpcCommand)cmd); + } else if (cmd instanceof IpAssocCommand) { + return prepareNetworkElementCommand((IpAssocCommand)cmd); + } else if (cmd instanceof SetSourceNatCommand) { + return prepareNetworkElementCommand((SetSourceNatCommand)cmd); + } else if (cmd instanceof SetupGuestNetworkCommand) { + return prepareNetworkElementCommand((SetupGuestNetworkCommand)cmd); + } else if (cmd instanceof SetNetworkACLCommand) { + return prepareNetworkElementCommand((SetNetworkACLCommand)cmd); + } + return new ExecutionResult(true, null); + } + + private ExecutionResult prepareNetworkElementCommand(IpAssocCommand cmd) { + try { + + IpAddressTO[] ips = cmd.getIpAddresses(); + String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); + String controlIp = getRouterSshControlIp(cmd); + + for (IpAddressTO ip : ips) { + /** + * TODO support other networks + */ + URI broadcastUri = BroadcastDomainType.fromString(ip.getBroadcastUri()); + if (BroadcastDomainType.getSchemeValue(broadcastUri) != BroadcastDomainType.Vlan) { + throw new InternalErrorException("Unable to assign a public IP to a VIF on network " + ip.getBroadcastUri()); + } + int vlanId = Integer.parseInt(BroadcastDomainType.getValue(broadcastUri)); + int publicNicInfo = -1; + publicNicInfo = getVmNics(routerName, vlanId); + + boolean addVif = false; + if (ip.isAdd() && publicNicInfo == -1) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Plug new NIC to associate" + controlIp + " to " + ip.getPublicIp()); + } + addVif = true; + } + + if (addVif) { + Pair nicdevice = findRouterFreeEthDeviceIndex(controlIp); + publicNicInfo = nicdevice.first(); + if (publicNicInfo > 0) { + modifyNicVlan(routerName, vlanId, nicdevice.second()); + // After modifying the vnic on VR, check the VR VNics config in the host and get the device position + publicNicInfo = getVmNics(routerName, vlanId); + // As a new nic got activated in the VR. add the entry in the NIC's table. + networkUsage(controlIp, "addVif", "eth" + publicNicInfo); + } + else { + // we didn't find any eth device available in VR to configure the ip range with new VLAN + String msg = "No Nic is available on DomR VIF to associate/disassociate IP with."; + s_logger.error(msg); + throw new InternalErrorException(msg); + } + ip.setNicDevId(publicNicInfo); + ip.setNewNic(addVif); + } else { + ip.setNicDevId(publicNicInfo); + } + } + } catch (Throwable e) { + s_logger.error("Unexpected exception: " + e.toString() + " will shortcut rest of IPAssoc commands", e); + return new ExecutionResult(false, e.toString()); + } + return new ExecutionResult(true, null); + } + + protected ExecutionResult prepareNetworkElementCommand(SetupGuestNetworkCommand cmd) { + NicTO nic = cmd.getNic(); + String routerIp = getRouterSshControlIp(cmd); + String domrName = + cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); + + try { + int ethDeviceNum = findRouterEthDeviceIndex(domrName, routerIp, + nic.getMac()); + nic.setDeviceId(ethDeviceNum); + } catch (Exception e) { + String msg = "Prepare SetupGuestNetwork failed due to " + e.toString(); + s_logger.warn(msg, e); + return new ExecutionResult(false, msg); + } + return new ExecutionResult(true, null); + } + + + private ExecutionResult prepareNetworkElementCommand(IpAssocVpcCommand cmd) { + String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); + String routerIp = getRouterSshControlIp(cmd); + + try { + IpAddressTO[] ips = cmd.getIpAddresses(); + for (IpAddressTO ip : ips) { + + int ethDeviceNum = findRouterEthDeviceIndex(routerName, routerIp, ip.getVifMacAddress()); + if (ethDeviceNum < 0) { + if (ip.isAdd()) { + throw new InternalErrorException("Failed to find DomR VIF to associate/disassociate IP with."); + } else { + s_logger.debug("VIF to deassociate IP with does not exist, return success"); + continue; + } + } + + ip.setNicDevId(ethDeviceNum); + } + } catch (Exception e) { + s_logger.error("Prepare Ip Assoc failure on applying one ip due to exception: ", e); + return new ExecutionResult(false, e.toString()); + } + + return new ExecutionResult(true, null); + } + + protected ExecutionResult prepareNetworkElementCommand(SetSourceNatCommand cmd) { + String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); + String routerIp = getRouterSshControlIp(cmd); + IpAddressTO pubIp = cmd.getIpAddress(); + + try { + int ethDeviceNum = findRouterEthDeviceIndex(routerName, routerIp, pubIp.getVifMacAddress()); + pubIp.setNicDevId(ethDeviceNum); + } catch (Exception e) { + String msg = "Prepare Ip SNAT failure due to " + e.toString(); + s_logger.error(msg, e); + return new ExecutionResult(false, e.toString()); + } + return new ExecutionResult(true, null); + } + + private ExecutionResult prepareNetworkElementCommand(SetNetworkACLCommand cmd) { + NicTO nic = cmd.getNic(); + String routerName = + cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); + String routerIp = getRouterSshControlIp(cmd); + + try { + int ethDeviceNum = findRouterEthDeviceIndex(routerName, routerIp, + nic.getMac()); + nic.setDeviceId(ethDeviceNum); + } catch (Exception e) { + String msg = "Prepare SetNetworkACL failed due to " + e.toString(); + s_logger.error(msg, e); + return new ExecutionResult(false, msg); + } + return new ExecutionResult(true, null); + } + + @Override + public ExecutionResult cleanupCommand(NetworkElementCommand cmd) { + return new ExecutionResult(true, null); + } + protected Answer execute(final RemoteAccessVpnCfgCommand cmd) { String controlIp = getRouterSshControlIp(cmd); StringBuffer argsBuf = new StringBuffer(); @@ -1926,6 +2132,10 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S _configureCalled = true; } + _vrResource = new VirtualRoutingResource(this); + if (!_vrResource.configure(name, new HashMap())) { + throw new ConfigurationException("Unable to configure VirtualRoutingResource"); + } return true; } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/540d020a/systemvm/patches/debian/config/etc/init.d/cloud-early-config ---------------------------------------------------------------------- diff --git a/systemvm/patches/debian/config/etc/init.d/cloud-early-config b/systemvm/patches/debian/config/etc/init.d/cloud-early-config index fa95fda..c287d43 100755 --- a/systemvm/patches/debian/config/etc/init.d/cloud-early-config +++ b/systemvm/patches/debian/config/etc/init.d/cloud-early-config @@ -1221,10 +1221,6 @@ start() { patch_log4j parse_cmd_line change_password - if [ "$hyp" == "hyperv" ]; then - # eject the systemvm.iso - eject - fi case $TYPE in router) [ "$NAME" == "" ] && NAME=router @@ -1259,6 +1255,10 @@ start() { setup_default; ;; esac + if [ "$hyp" == "hyperv" ]; then + # eject the systemvm.iso + eject + fi return 0 }