You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ap...@apache.org on 2013/07/25 13:57:08 UTC

[30/50] git commit: updated refs/heads/ldapplugin to 1f64354

Summary: Get away from dozens of ssh/scp calls for KVM vm_data push

Detail: userdata and vm metadata take a long time to program on KVM routers.
This does it all in one go, processed on the router.

BUG-ID: CLOUDSTACK-3163
Tested-by: Wido
Signed-off-by: Marcus Sorensen <ma...@betterservers.com> 1374695897 -0600


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

Branch: refs/heads/ldapplugin
Commit: 28855b4987c9274d15a539b9d7ae26c0073b0651
Parents: 11dce48
Author: Marcus Sorensen <ma...@betterservers.com>
Authored: Wed Jul 24 13:58:17 2013 -0600
Committer: Marcus Sorensen <ma...@betterservers.com>
Committed: Wed Jul 24 14:01:02 2013 -0600

----------------------------------------------------------------------
 .../virtualnetwork/VirtualRoutingResource.java  |  70 ++-------
 .../debian/config/opt/cloud/bin/vmdata_kvm.py   | 140 ++++++++++++++++++
 scripts/network/domr/vm_data.sh                 | 147 -------------------
 3 files changed, 154 insertions(+), 203 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/28855b49/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 0b26220..b1532a8 100755
--- a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java
+++ b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java
@@ -16,6 +16,8 @@
 // under the License.
 package com.cloud.agent.resource.virtualnetwork;
 
+import com.google.gson.Gson;
+
 import com.cloud.agent.api.Answer;
 import com.cloud.agent.api.BumpUpPriorityCommand;
 import com.cloud.agent.api.CheckRouterAnswer;
@@ -85,6 +87,7 @@ import java.net.InetSocketAddress;
 import java.net.URL;
 import java.net.URLConnection;
 import java.nio.channels.SocketChannel;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -463,61 +466,21 @@ public class VirtualRoutingResource implements Manager {
 
     protected Answer execute(VmDataCommand cmd) {
         List<String[]> vmData = cmd.getVmData();
+        String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
+        Map<String, List<String[]>> data = new HashMap<String, List<String[]>>();
+        data.put(cmd.getVmIpAddress(), cmd.getVmData());
+ 
+        String json = new Gson().toJson(data);
+        s_logger.debug("JSON IS:" + json);
 
-        for (String[] vmDataEntry : vmData) {
-            String folder = vmDataEntry[0];
-            String file = vmDataEntry[1];
-            String data = vmDataEntry[2];
-            File tmpFile = null;
-
-            byte[] dataBytes = null;
-            if (data != null) {
-                if (folder.equals("userdata")) {
-                    dataBytes = Base64.decodeBase64(data);//userdata is supplied in url-safe unchunked mode
-                } else {
-                    dataBytes = data.getBytes();
-                }
-            }
-
-            try {
-                tmpFile = File.createTempFile("vmdata_", null);
-                FileOutputStream outStream = new FileOutputStream(tmpFile);
-                if (dataBytes != null)
-                    outStream.write(dataBytes); 
-                outStream.close();
-            } catch (IOException e) {
-                String tmpDir = System.getProperty("java.io.tmpdir");
-                s_logger.warn("Failed to create temporary file: is " + tmpDir + " full?", e);
-                return new Answer(cmd, false, "Failed to create or write to temporary file: is " + tmpDir + " full? " + e.getMessage() );
-            }
-       
-
-            final Script command  = new Script(_vmDataPath, _timeout, s_logger);
-            command.add("-r", cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP));
-            command.add("-v", cmd.getVmIpAddress());
-            command.add("-F", folder);
-            command.add("-f", file);
-
-            if (tmpFile != null) {
-                command.add("-d", tmpFile.getAbsolutePath());
-            }
-
-            final String result = command.execute();
-
-            if (tmpFile != null) {
-                boolean deleted = tmpFile.delete();
-                if (!deleted) {
-                    s_logger.warn("Failed to clean up temp file after sending vmdata");
-                    tmpFile.deleteOnExit();
-                }
-            }
+        json = Base64.encodeBase64String(json.getBytes());
 
-            if (result != null) {
-                return new Answer(cmd, false, result);        	
-            }        	
+        String args = "-d " + json;
 
+        final String result = routerProxy("vmdata_kvm.py", routerIp, args);
+        if (result != null) {
+            return new Answer(cmd, false, "VmDataCommand failed, check agent logs");
         }
-
         return new Answer(cmd);
     }
 
@@ -1192,11 +1155,6 @@ public class VirtualRoutingResource implements Manager {
             throw new ConfigurationException("Unable to find dhcp_entry.sh");
         }
 
-        _vmDataPath = findScript("vm_data.sh");
-        if(_vmDataPath == null) {
-            throw new ConfigurationException("Unable to find user_data.sh");
-        }
-
         _publicEthIf = (String)params.get("public.network.device");
         if (_publicEthIf == null) {
             _publicEthIf = "xenbr1";

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/28855b49/patches/systemvm/debian/config/opt/cloud/bin/vmdata_kvm.py
----------------------------------------------------------------------
diff --git a/patches/systemvm/debian/config/opt/cloud/bin/vmdata_kvm.py b/patches/systemvm/debian/config/opt/cloud/bin/vmdata_kvm.py
new file mode 100644
index 0000000..bf8baac
--- /dev/null
+++ b/patches/systemvm/debian/config/opt/cloud/bin/vmdata_kvm.py
@@ -0,0 +1,140 @@
+#!/usr/bin/python
+# 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.
+
+import sys, getopt, json, os, base64
+
+def main(argv):
+    fpath =  ''
+    b64data = ''
+
+    try:
+        opts, args = getopt.getopt(argv,"f:d:")
+    except getopt.GetoptError:
+        print 'params: -f <filename> -d <b64jsondata>'
+        sys.exit(2)
+    for opt, arg in opts:
+        if opt == '-f':
+            fpath = arg
+        elif opt == '-d':
+            b64data = arg
+
+    json_data = ''
+    if fpath != '':
+        fh = open(fpath, 'r')
+        json_data = json.loads(fh.read())
+    elif b64data != '':
+        json_data = json.loads(base64.b64decode(b64data))
+    else:
+        print '-f <filename> or -d <b64jsondata> required'
+        sys.exit(2)
+
+    for ip in json_data:
+        for item in json_data[ip]:
+            folder = item[0]
+            file   = item[1]
+            data   = item[2]
+
+            # process only valid data
+            if folder != "userdata" and folder != "metadata":
+                continue
+
+            if file == "":
+                continue
+
+            htaccess(ip, folder, file)
+
+            if data == "":
+                deletefile(ip, folder, file)
+            else:
+                createfile(ip, folder, file, data)
+    
+    if fpath != '':
+        fh.close()
+        os.remove(fpath)
+
+def deletefile(ip, folder, file):
+    datafile = "/var/www/html/" + folder + "/" + ip + "/" + file
+
+    if os.path.exists(datafile):
+        os.remove(datafile)
+
+def createfile(ip, folder, file, data):
+    dest = "/var/www/html/" + folder + "/" + ip + "/" + file
+    metamanifestdir = "/var/www/html/" + folder + "/" + ip 
+    metamanifest =  metamanifestdir + "/meta-data"
+
+    # base64 decode userdata
+    if folder == "userdata" or folder == "user-data":
+        if data is not None:
+            data = base64.b64decode(data)
+
+    if data is not None:
+        open(dest, "w").write(data)
+    else:
+        open(dest, "w").write("")
+    os.chmod(dest, 0644)
+
+    if folder == "metadata" or folder == "meta-data":
+        if not os.path.exists(metamanifestdir):
+            os.makedirs(metamanifestdir, 0755)
+        if os.path.exists(metamanifest):
+            if not file in open(metamanifest).read():
+                open(metamanifest, "a").write(file + '\n')
+        else:
+            open(metamanifest, "w").write(file + '\n')
+
+    if os.path.exists(metamanifest):
+        os.chmod(metamanifest, 0644)
+
+def htaccess(ip, folder, file):
+    entry = "RewriteRule ^" + file + "$  ../" + folder + "/%{REMOTE_ADDR}/" + file + " [L,NC,QSA]"
+    htaccessFolder = "/var/www/html/latest"
+    htaccessFile = htaccessFolder + "/.htaccess"
+
+    if not os.path.exists(htaccessFolder):
+        os.mkdir(htaccessFolder,0755)
+
+    if os.path.exists(htaccessFile):
+        if not entry in open(htaccessFile).read():
+            open(htaccessFile, "a").write(entry + '\n')
+
+    entry="Options -Indexes\nOrder Deny,Allow\nDeny from all\nAllow from " + ip
+    htaccessFolder = "/var/www/html/" + folder + "/" + ip
+    htaccessFile = htaccessFolder+"/.htaccess"
+
+    if not os.path.exists(htaccessFolder):
+        os.makedirs(htaccessFolder,0755)
+
+    open(htaccessFile, "w").write(entry + '\n')
+
+    if folder == "metadata" or folder == "meta-data":
+        entry="RewriteRule ^meta-data/(.+)$  ../" + folder + "/%{REMOTE_ADDR}/$1 [L,NC,QSA]"
+        htaccessFolder = "/var/www/html/latest"
+        htaccessFile = htaccessFolder + "/.htaccess"
+
+        if not entry in open(htaccessFile).read():
+            open(htaccessFile, "a").write(entry + '\n')
+
+        entry="RewriteRule ^meta-data/$  ../" + folder + "/%{REMOTE_ADDR}/meta-data [L,NC,QSA]"
+
+        if not entry in open(htaccessFile).read():
+            open(htaccessFile, "a").write(entry + '\n')
+
+
+if __name__ == "__main__":
+    main(sys.argv[1:])

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/28855b49/scripts/network/domr/vm_data.sh
----------------------------------------------------------------------
diff --git a/scripts/network/domr/vm_data.sh b/scripts/network/domr/vm_data.sh
deleted file mode 100755
index c861723..0000000
--- a/scripts/network/domr/vm_data.sh
+++ /dev/null
@@ -1,147 +0,0 @@
-#!/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.
-
-
-# $Id: vm_data.sh 9307 2010-06-08 00:43:08Z chiradeep $ $HeadURL: svn://svn.lab.vmops.com/repos/vmdev/java/scripts/vm/hypervisor/xenserver/patch/vm_data.sh $
-# @VERSION@
-
-usage() {
-  printf "Usage: %s: -r <domr-ip> -v <vm ip> -F <vm data folder> -f <vm data file> -d <data to put in file> \n" $(basename $0) >&2
-  exit 2
-}
-
-set -x
-cert="/root/.ssh/id_rsa.cloud"
-PORT=3922
-
-create_htaccess() {
-  local domrIp=$1
-  local vmIp=$2
-  local folder=$3
-  local file=$4
-  
-  local result=0
-  #rewrite rule in top level /latest folder to redirect 
-  #to vm specific folder based on source ip
-  entry="RewriteRule ^$file$  ../$folder/%{REMOTE_ADDR}/$file [L,NC,QSA]"
-  htaccessFolder="/var/www/html/latest"
-  htaccessFile=$htaccessFolder/.htaccess
-  ssh -p $PORT -o StrictHostKeyChecking=no -i $cert root@$domrIp "mkdir -p $htaccessFolder; touch $htaccessFile; grep -F \"$entry\" $htaccessFile; if [ \$? -gt 0 ]; then echo -e \"$entry\" >> $htaccessFile; fi" >/dev/null
-  result=$?
-  
-  if [ $result -eq 0 ]
-  then
-    #ensure that vm specific folder cannot be listed and that only 
-    #the vm that owns the data can access the items in this directory
-    entry="Options -Indexes\\nOrder Deny,Allow\\nDeny from all\\nAllow from $vmIp"
-    htaccessFolder="/var/www/html/$folder/$vmIp"
-    htaccessFile=$htaccessFolder/.htaccess
-    ssh -p $PORT -o StrictHostKeyChecking=no -i $cert root@$domrIp "mkdir -p $htaccessFolder; echo -e \"$entry\" > $htaccessFile" >/dev/null
-    result=$?
-  fi
-  
-  #support access by http://<dhcp server>/latest/<metadata key> (legacy, see above) also
-  # http://<dhcp server>/latest/meta-data/<metadata key> (correct)
-  if [ "$folder" == "metadata" ] || [ "$folder" == "meta-data" ]
-  then
-    entry="RewriteRule ^meta-data/(.+)$  ../$folder/%{REMOTE_ADDR}/\\\$1 [L,NC,QSA]"
-    htaccessFolder="/var/www/html/latest"
-    htaccessFile=$htaccessFolder/.htaccess
-    ssh -p $PORT -o StrictHostKeyChecking=no -i $cert root@$domrIp "grep -F \"$entry\" $htaccessFile; if [ \$? -gt 0 ]; then echo -e \"$entry\" >> $htaccessFile; fi" >/dev/null
-    entry="RewriteRule ^meta-data/$  ../$folder/%{REMOTE_ADDR}/meta-data [L,NC,QSA]"
-    ssh -p $PORT -o StrictHostKeyChecking=no -i $cert root@$domrIp "grep -F \"$entry\" $htaccessFile; if [ \$? -gt 0 ]; then echo -e \"$entry\" >> $htaccessFile; fi" >/dev/null
-    result=$?
-  fi
-  
-  return $result  
-}
-
-copy_vm_data_file() {
-  local domrIp=$1
-  local vmIp=$2
-  local folder=$3
-  local file=$4
-  local dataFile=$5        
-  
-  dest=/var/www/html/$folder/$vmIp/$file
-  metamanifest=/var/www/html/$folder/$vmIp/meta-data
-  scp -P $PORT -o StrictHostKeyChecking=no -i $cert $dataFile root@$domrIp:$dest >/dev/null
-  ssh -p $PORT -o StrictHostKeyChecking=no -i $cert root@$domrIp "chmod 644 $dest" > /dev/null
-  ssh -p $PORT -o StrictHostKeyChecking=no -i $cert root@$domrIp "touch $metamanifest; chmod 644 $metamanifest" > /dev/null
-  if [ "$folder" == "metadata" ] || [ "$folder" == "meta-data" ]
-  then
-    ssh -p $PORT -o StrictHostKeyChecking=no -i $cert root@$domrIp "sed -i '/$file/d' $metamanifest; echo $file >> $metamanifest" > /dev/null
-  fi
-  
-  return $?
-}
-
-delete_vm_data_file() {
-  local domrIp=$1
-  local vmIp=$2
-  local folder=$3
-  local file=$4
-  
-  vmDataFilePath="/var/www/html/$folder/$vmIp/$file"
-  ssh -p $PORT -o StrictHostKeyChecking=no -i $cert root@$domrIp "if [ -f $vmDataFilePath ]; then rm -rf $vmDataFilePath; fi" >/dev/null
-  return $?
-}
-
-domrIp=
-vmIp=
-folder=
-file=
-dataFile=
-
-while getopts 'r:v:F:f:d:' OPTION
-do
-  case $OPTION in
-  r)	domrIp="$OPTARG"
-		;;
-  v)	vmIp="$OPTARG"
-		;;
-  F)	folder="$OPTARG"
-  		;;
-  f)	file="$OPTARG"
-  		;;
-  d)	dataFile="$OPTARG"
-  		;;
-  ?)    usage
-		exit 1
-		;;
-  esac
-done
-
-[ "$domrIp" == "" ] || [ "$vmIp" == "" ]  || [ "$folder" == "" ] || [ "$file" == "" ] && usage 
-[ "$folder" != "userdata" ] && [ "$folder" != "metadata" ] && usage
-
-if [ "$dataFile" != "" ]
-then
-  create_htaccess $domrIp $vmIp $folder $file
-  
-  if [ $? -gt 0 ]
-  then
-    exit 1
-  fi
-  
-  copy_vm_data_file $domrIp $vmIp $folder $file $dataFile
-else
-  delete_vm_data_file $domrIp $vmIp $folder $file
-fi
-
-exit $?