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/08 01:23:07 UTC

[34/50] [abbrv] git commit: updated refs/heads/resize-root to 0eb9967

CLOUDSTACK-6047: Introduce Aggregated commands queue to VR


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/60dc2545
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/60dc2545
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/60dc2545

Branch: refs/heads/resize-root
Commit: 60dc25450a02f070c13a768d832a7a24d2b7b414
Parents: 7cb9132
Author: Sheng Yang <sh...@citrix.com>
Authored: Tue Mar 4 14:28:41 2014 -0800
Committer: Sheng Yang <sh...@citrix.com>
Committed: Thu Mar 6 16:22:01 2014 -0800

----------------------------------------------------------------------
 .../api/routing/FinishAggregationCommand.java   |  31 +++
 .../api/routing/StartAggregationCommand.java    |  31 +++
 .../virtualnetwork/VirtualRoutingResource.java  | 188 ++++++++++++++-----
 .../VirtualNetworkApplianceManagerImpl.java     |   8 +-
 .../debian/config/opt/cloud/bin/vr_cfg.sh       |  96 ++++++++++
 5 files changed, 302 insertions(+), 52 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/60dc2545/core/src/com/cloud/agent/api/routing/FinishAggregationCommand.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/agent/api/routing/FinishAggregationCommand.java b/core/src/com/cloud/agent/api/routing/FinishAggregationCommand.java
new file mode 100644
index 0000000..bfafccd
--- /dev/null
+++ b/core/src/com/cloud/agent/api/routing/FinishAggregationCommand.java
@@ -0,0 +1,31 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package com.cloud.agent.api.routing;
+
+public class FinishAggregationCommand extends NetworkElementCommand{
+    protected FinishAggregationCommand() {
+        super();
+    }
+
+    public FinishAggregationCommand(String name, String ip, String guestIp) {
+        super();
+        this.setAccessDetail(NetworkElementCommand.ROUTER_NAME, name);
+        this.setAccessDetail(NetworkElementCommand.ROUTER_IP, ip);
+        this.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, guestIp);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/60dc2545/core/src/com/cloud/agent/api/routing/StartAggregationCommand.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/agent/api/routing/StartAggregationCommand.java b/core/src/com/cloud/agent/api/routing/StartAggregationCommand.java
new file mode 100644
index 0000000..fbf97a8
--- /dev/null
+++ b/core/src/com/cloud/agent/api/routing/StartAggregationCommand.java
@@ -0,0 +1,31 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package com.cloud.agent.api.routing;
+
+public class StartAggregationCommand extends NetworkElementCommand{
+    protected StartAggregationCommand() {
+        super();
+    }
+
+    public StartAggregationCommand(String name, String ip, String guestIp) {
+        super();
+        this.setAccessDetail(NetworkElementCommand.ROUTER_NAME, name);
+        this.setAccessDetail(NetworkElementCommand.ROUTER_IP, ip);
+        this.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, guestIp);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/60dc2545/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java
index 9bebd4c..49e6812 100755
--- a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java
+++ b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java
@@ -29,6 +29,7 @@ import com.cloud.agent.api.routing.CreateIpAliasCommand;
 import com.cloud.agent.api.routing.DeleteIpAliasCommand;
 import com.cloud.agent.api.routing.DhcpEntryCommand;
 import com.cloud.agent.api.routing.DnsMasqConfigCommand;
+import com.cloud.agent.api.routing.FinishAggregationCommand;
 import com.cloud.agent.api.routing.GroupAnswer;
 import com.cloud.agent.api.routing.IpAliasTO;
 import com.cloud.agent.api.routing.IpAssocCommand;
@@ -46,6 +47,7 @@ import com.cloud.agent.api.routing.SetSourceNatCommand;
 import com.cloud.agent.api.routing.SetStaticNatRulesCommand;
 import com.cloud.agent.api.routing.SetStaticRouteCommand;
 import com.cloud.agent.api.routing.Site2SiteVpnCfgCommand;
+import com.cloud.agent.api.routing.StartAggregationCommand;
 import com.cloud.agent.api.routing.VmDataCommand;
 import com.cloud.agent.api.routing.VpnUsersCfgCommand;
 import com.cloud.agent.api.to.DhcpTO;
@@ -72,6 +74,9 @@ import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
+import java.util.Queue;
+import java.util.UUID;
+import java.util.concurrent.LinkedBlockingQueue;
 
 /**
  * VirtualNetworkResource controls and configures virtual networking
@@ -111,27 +116,34 @@ public class VirtualRoutingResource {
         protected static final String VPC_STATIC_NAT = "vpc_staticnat.sh";
         protected static final String VPC_STATIC_ROUTE = "vpc_staticroute.sh";
         protected static final String VPN_L2TP = "vpn_l2tp.sh";
+
+        protected static final String VR_CFG = "vr_cfg.sh";
     }
 
     private static final Logger s_logger = Logger.getLogger(VirtualRoutingResource.class);
     private VirtualRouterDeployer _vrDeployer;
+    private Map <String, Queue> _vrAggregateCommandsSet;
 
     private String _name;
     private int _sleep;
     private int _retry;
     private int _port;
 
+    private String _cfgVersion = "1.0";
+
     public VirtualRoutingResource(VirtualRouterDeployer deployer) {
         this._vrDeployer = deployer;
     }
 
     public Answer executeRequest(final NetworkElementCommand cmd) {
+        boolean aggregated = false;
         try {
             ExecutionResult rc = _vrDeployer.prepareCommand(cmd);
             if (!rc.isSuccess()) {
                 s_logger.error("Failed to prepare VR command due to " + rc.getDetails());
                 return new Answer(cmd, false, rc.getDetails());
             }
+            String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
 
             assert cmd.getRouterAccessIp() != null : "Why there is no access IP for VR?";
 
@@ -139,50 +151,22 @@ public class VirtualRoutingResource {
                 return executeQueryCommand(cmd);
             }
 
-            List<ConfigItem> cfg;
-            if (cmd instanceof SetPortForwardingRulesVpcCommand) {
-                cfg = generateConfig((SetPortForwardingRulesVpcCommand)cmd);
-            } else if (cmd instanceof SetPortForwardingRulesCommand) {
-                cfg = generateConfig((SetPortForwardingRulesCommand)cmd);
-            } else if (cmd instanceof SetStaticRouteCommand) {
-                cfg = generateConfig((SetStaticRouteCommand)cmd);
-            } else if (cmd instanceof SetStaticNatRulesCommand) {
-                cfg = generateConfig((SetStaticNatRulesCommand)cmd);
-            } else if (cmd instanceof LoadBalancerConfigCommand) {
-                cfg = generateConfig((LoadBalancerConfigCommand)cmd);
-            } else if (cmd instanceof SavePasswordCommand) {
-                cfg = generateConfig((SavePasswordCommand)cmd);
-            } else if (cmd instanceof DhcpEntryCommand) {
-                cfg = generateConfig((DhcpEntryCommand)cmd);
-            } else if (cmd instanceof CreateIpAliasCommand) {
-                cfg = generateConfig((CreateIpAliasCommand)cmd);
-            } else if (cmd instanceof DnsMasqConfigCommand) {
-                cfg = generateConfig((DnsMasqConfigCommand)cmd);
-            } else if (cmd instanceof DeleteIpAliasCommand) {
-                cfg = generateConfig((DeleteIpAliasCommand)cmd);
-            } else if (cmd instanceof VmDataCommand) {
-                cfg = generateConfig((VmDataCommand)cmd);
-            } else if (cmd instanceof SetFirewallRulesCommand) {
-                cfg = generateConfig((SetFirewallRulesCommand)cmd);
-            } else if (cmd instanceof BumpUpPriorityCommand) {
-                cfg = generateConfig((BumpUpPriorityCommand)cmd);
-            } else if (cmd instanceof RemoteAccessVpnCfgCommand) {
-                cfg = generateConfig((RemoteAccessVpnCfgCommand)cmd);
-            } else if (cmd instanceof VpnUsersCfgCommand) {
-                cfg = generateConfig((VpnUsersCfgCommand)cmd);
-            } else if (cmd instanceof Site2SiteVpnCfgCommand) {
-                cfg = generateConfig((Site2SiteVpnCfgCommand)cmd);
-            } else if (cmd instanceof SetMonitorServiceCommand) {
-                cfg = generateConfig((SetMonitorServiceCommand)cmd);
-            } else if (cmd instanceof SetupGuestNetworkCommand) {
-                cfg = generateConfig((SetupGuestNetworkCommand)cmd);
-            } else if (cmd instanceof SetNetworkACLCommand) {
-                cfg = generateConfig((SetNetworkACLCommand)cmd);
-            } else if (cmd instanceof SetSourceNatCommand) {
-                cfg = generateConfig((SetSourceNatCommand)cmd);
-            } else if (cmd instanceof IpAssocCommand) {
-                cfg = generateConfig((IpAssocCommand)cmd);
-            } else {
+            if (cmd instanceof StartAggregationCommand) {
+                return execute((StartAggregationCommand)cmd);
+            } else if (cmd instanceof FinishAggregationCommand) {
+                return execute((FinishAggregationCommand)cmd);
+            }
+
+            if (_vrAggregateCommandsSet.containsKey(routerName)) {
+                _vrAggregateCommandsSet.get(routerName).add(cmd);
+                aggregated = true;
+                // Clean up would be done after command has been executed
+                //TODO: Deal with group answer as well
+                return new Answer(cmd);
+            }
+
+            List<ConfigItem> cfg = generateCommandCfg(cmd);
+            if (cfg == null) {
                 return Answer.createUnsupportedCommandAnswer(cmd);
             }
 
@@ -190,9 +174,11 @@ public class VirtualRoutingResource {
         } catch (final IllegalArgumentException e) {
             return new Answer(cmd, false, e.getMessage());
         } finally {
-            ExecutionResult rc = _vrDeployer.cleanupCommand(cmd);
-            if (!rc.isSuccess()) {
-                s_logger.error("Failed to cleanup VR command due to " + rc.getDetails());
+            if (!aggregated) {
+                ExecutionResult rc = _vrDeployer.cleanupCommand(cmd);
+                if (!rc.isSuccess()) {
+                    s_logger.error("Failed to cleanup VR command due to " + rc.getDetails());
+                }
             }
         }
     }
@@ -952,6 +938,8 @@ public class VirtualRoutingResource {
         if (_vrDeployer == null) {
             throw new ConfigurationException("Unable to find the resource for VirtualRouterDeployer!");
         }
+
+        _vrAggregateCommandsSet = new HashMap<>();
         return true;
     }
 
@@ -1030,4 +1018,110 @@ public class VirtualRoutingResource {
 
         return false;
     }
+
+    private Answer execute(StartAggregationCommand cmd) {
+        // Access IP would be used as ID for router
+        String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
+        assert routerName != null;
+        Queue<NetworkElementCommand> queue = new LinkedBlockingQueue<>();
+        _vrAggregateCommandsSet.put(routerName, queue);
+        return new Answer(cmd);
+    }
+
+    private List<ConfigItem> generateCommandCfg(NetworkElementCommand cmd) {
+        List<ConfigItem> cfg;
+        if (cmd instanceof SetPortForwardingRulesVpcCommand) {
+            cfg = generateConfig((SetPortForwardingRulesVpcCommand)cmd);
+        } else if (cmd instanceof SetPortForwardingRulesCommand) {
+            cfg = generateConfig((SetPortForwardingRulesCommand)cmd);
+        } else if (cmd instanceof SetStaticRouteCommand) {
+            cfg = generateConfig((SetStaticRouteCommand)cmd);
+        } else if (cmd instanceof SetStaticNatRulesCommand) {
+            cfg = generateConfig((SetStaticNatRulesCommand)cmd);
+        } else if (cmd instanceof LoadBalancerConfigCommand) {
+            cfg = generateConfig((LoadBalancerConfigCommand)cmd);
+        } else if (cmd instanceof SavePasswordCommand) {
+            cfg = generateConfig((SavePasswordCommand)cmd);
+        } else if (cmd instanceof DhcpEntryCommand) {
+            cfg = generateConfig((DhcpEntryCommand)cmd);
+        } else if (cmd instanceof CreateIpAliasCommand) {
+            cfg = generateConfig((CreateIpAliasCommand)cmd);
+        } else if (cmd instanceof DnsMasqConfigCommand) {
+            cfg = generateConfig((DnsMasqConfigCommand)cmd);
+        } else if (cmd instanceof DeleteIpAliasCommand) {
+            cfg = generateConfig((DeleteIpAliasCommand)cmd);
+        } else if (cmd instanceof VmDataCommand) {
+            cfg = generateConfig((VmDataCommand)cmd);
+        } else if (cmd instanceof SetFirewallRulesCommand) {
+            cfg = generateConfig((SetFirewallRulesCommand)cmd);
+        } else if (cmd instanceof BumpUpPriorityCommand) {
+            cfg = generateConfig((BumpUpPriorityCommand)cmd);
+        } else if (cmd instanceof RemoteAccessVpnCfgCommand) {
+            cfg = generateConfig((RemoteAccessVpnCfgCommand)cmd);
+        } else if (cmd instanceof VpnUsersCfgCommand) {
+            cfg = generateConfig((VpnUsersCfgCommand)cmd);
+        } else if (cmd instanceof Site2SiteVpnCfgCommand) {
+            cfg = generateConfig((Site2SiteVpnCfgCommand)cmd);
+        } else if (cmd instanceof SetMonitorServiceCommand) {
+            cfg = generateConfig((SetMonitorServiceCommand)cmd);
+        } else if (cmd instanceof SetupGuestNetworkCommand) {
+            cfg = generateConfig((SetupGuestNetworkCommand)cmd);
+        } else if (cmd instanceof SetNetworkACLCommand) {
+            cfg = generateConfig((SetNetworkACLCommand)cmd);
+        } else if (cmd instanceof SetSourceNatCommand) {
+            cfg = generateConfig((SetSourceNatCommand)cmd);
+        } else if (cmd instanceof IpAssocCommand) {
+            cfg = generateConfig((IpAssocCommand)cmd);
+        } else {
+            return null;
+        }
+        return cfg;
+    }
+
+    private Answer execute(FinishAggregationCommand cmd) {
+        String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
+        assert routerName != null;
+        assert cmd.getRouterAccessIp() != null;
+        Queue<NetworkElementCommand> queue = _vrAggregateCommandsSet.get(routerName);
+        try {
+            StringBuilder sb = new StringBuilder();
+            sb.append("#Apache CloudStack Virtual Router Config File\n");
+            sb.append("<version>\n" + _cfgVersion + "\n</version>\n");
+            for (NetworkElementCommand command : queue) {
+                List<ConfigItem> cfg = generateCommandCfg(command);
+                if (cfg == null) {
+                    s_logger.warn("Unknown commands for VirtualRoutingResource, but continue: " + cmd.toString());
+                }
+
+                for (ConfigItem c : cfg) {
+                    if (c.isFile()) {
+                        sb.append("<file>\n");
+                        sb.append(c.getFilePath() + c.getFileName() + "\n");
+                        sb.append(c.getFileContents() + "\n");
+                        sb.append("</file>\n");
+                    } else {
+                        sb.append("<script>\n");
+                        sb.append("/opt/cloud/bin/" + c.getScript() + " " + c.getArgs() + "\n");
+                        sb.append("</script>\n");
+                    }
+                }
+            }
+            String cfgFilePath = "/var/cache/cloud/";
+            String cfgFileName = "VR-"+ UUID.randomUUID().toString() + ".cfg";
+            ExecutionResult result = _vrDeployer.createFileInVR(cmd.getRouterAccessIp(), cfgFilePath, cfgFileName, sb.toString());
+            if (!result.isSuccess()) {
+                return new Answer(cmd, false, result.getDetails());
+            }
+
+            result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), VRScripts.VR_CFG, "-c " + cfgFilePath + cfgFileName);
+            if (!result.isSuccess()) {
+                return new Answer(cmd, false, result.getDetails());
+            }
+            return new Answer(cmd);
+        } finally {
+            queue.clear();
+            _vrAggregateCommandsSet.remove(routerName);
+        }
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/60dc2545/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
index 37171f5..8486f06 100755
--- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
+++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
@@ -2736,12 +2736,10 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V
             final Commands cmds = new Commands(Command.OnError.Stop);
             createApplyVpnCommands(true, vpn, router, cmds);
 
-            try {
-                _agentMgr.send(router.getHostId(), cmds);
-            } catch (final OperationTimedoutException e) {
-                s_logger.debug("Failed to start remote access VPN: ", e);
-                throw new AgentUnavailableException("Unable to send commands to virtual router ", router.getHostId(), e);
+            if (!sendCommandsToRouter(router, cmds)) {
+                throw new AgentUnavailableException("Unable to send commands to virtual router ", router.getHostId());
             }
+
             Answer answer = cmds.getAnswer("users");
             if (!answer.getResult()) {
                 s_logger.error("Unable to start vpn: unable add users to vpn in zone " + router.getDataCenterId() + " for account " + vpn.getAccountId() + " on domR: " +

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/60dc2545/systemvm/patches/debian/config/opt/cloud/bin/vr_cfg.sh
----------------------------------------------------------------------
diff --git a/systemvm/patches/debian/config/opt/cloud/bin/vr_cfg.sh b/systemvm/patches/debian/config/opt/cloud/bin/vr_cfg.sh
new file mode 100755
index 0000000..8994a06
--- /dev/null
+++ b/systemvm/patches/debian/config/opt/cloud/bin/vr_cfg.sh
@@ -0,0 +1,96 @@
+#!/bin/bash
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+#set -x
+
+cfg=
+version=
+log=/var/log/cloud.log
+
+log_it() {
+    logger -t cloud "$*"
+    echo "$(date) : $*" >> $log
+}
+
+while getopts 'c:' OPTION
+do
+  case $OPTION in
+      c) cfg="$OPTARG"
+          ;;
+  esac
+done
+
+while read line
+do
+    #comment
+    if [[ $line == \#* ]]
+    then
+	    continue
+    fi
+
+    if [ "$line" == "<version>" ]
+    then
+        read line
+        version=$line
+        log_it "VR config: configuation format version $version"
+        #skip </version>
+        read line
+        continue
+    fi
+
+    if [ "$line" == "<script>" ]
+    then
+        read line
+        log_it "VR config: executing: $line"
+        eval $line >> $log 2>&1
+        if [ $? -ne 0 ]
+        then
+            log_it "VR config: executing failed: $line"
+            # expose error info to mgmt server
+            echo "VR config: execution failed: \"$line\", check $log in VR for details "
+            exit 1
+        fi
+        #skip </script>
+        read line
+        log_it "VR config: execution success "
+        continue
+    fi
+
+    if [ "$line" == "<file>" ]
+    then
+        read line
+        file=$line
+        log_it "VR config: creating file: $file"
+        rm -f $file
+        while read line
+        do
+            if [ "$line" == "</file>" ]
+            then
+                break
+            fi
+            echo $line >> $file
+        done
+        log_it "VR config: create file success"
+        continue
+    fi
+done < $cfg
+
+#remove the configuration file, log file should have all the records as well
+rm -f $cfg
+
+exit 0