You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ml...@apache.org on 2014/03/11 20:05:44 UTC

[05/13] git commit: updated refs/heads/resize-root to dd4f6bf

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/resize-root
Commit: 540d020aa5c0cd5d3b4657973b1c8a852bdf6d58
Parents: 33a0dec
Author: Rajesh Battala <ra...@citrix.com>
Authored: Tue Mar 11 13:09:18 2014 +0530
Committer: Rajesh Battala <ra...@citrix.com>
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<Boolean, String> 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<Boolean, String>(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<Integer, String> 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<String, Object>())) {
+            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
 }