You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by pr...@apache.org on 2013/04/11 00:25:44 UTC

[03/54] [abbrv] QuickCloud: Enable secondary storage daemon to run outside the system vm

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/services/secondary-storage/scripts/_run.sh
----------------------------------------------------------------------
diff --git a/services/secondary-storage/scripts/_run.sh b/services/secondary-storage/scripts/_run.sh
new file mode 100755
index 0000000..e408378
--- /dev/null
+++ b/services/secondary-storage/scripts/_run.sh
@@ -0,0 +1,63 @@
+#!/usr/bin/env 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.
+
+
+
+ 
+
+#run.sh runs the console proxy.
+
+# make sure we delete the old files from the original template 
+rm console-proxy.jar
+rm console-common.jar
+rm conf/cloud.properties
+
+set -x
+
+CP=./:./conf
+for file in *.jar
+do
+  CP=${CP}:$file
+done
+keyvalues=
+
+CMDLINE=$(cat /var/cache/cloud/cmdline)
+
+#CMDLINE="graphical utf8 eth0ip=0.0.0.0 eth0mask=255.255.255.0 eth1ip=192.168.140.40 eth1mask=255.255.255.0 eth2ip=172.24.0.50 eth2mask=255.255.0.0 gateway=172.24.0.1 dns1=72.52.126.11 template=domP dns2=72.52.126.12 host=192.168.1.142 port=8250 mgmtcidr=192.168.1.0/24 localgw=192.168.140.1 zone=5 pod=5"
+for i in $CMDLINE
+  do
+     KEY=$(echo $i | cut -s -d= -f1)
+     VALUE=$(echo $i | cut -s -d= -f2)
+     [ "$KEY" == "" ] && continue
+     case $KEY in
+        *)
+          keyvalues="${keyvalues} $KEY=$VALUE"
+     esac
+  done
+   
+tot_mem_k=$(cat /proc/meminfo | grep MemTotal | awk '{print $2}')
+let "tot_mem_m=tot_mem_k>>10"
+let "eightypcnt=$tot_mem_m*8/10"
+let "maxmem=$tot_mem_m-80"
+
+if [ $maxmem -gt $eightypcnt ]
+then
+  maxmem=$eightypcnt
+fi
+
+java -Djavax.net.ssl.trustStore=./certs/realhostip.keystore -mx${maxmem}m -cp $CP com.cloud.agent.AgentShell $keyvalues $@

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/services/secondary-storage/scripts/config_auth.sh
----------------------------------------------------------------------
diff --git a/services/secondary-storage/scripts/config_auth.sh b/services/secondary-storage/scripts/config_auth.sh
new file mode 100755
index 0000000..4b74f8e
--- /dev/null
+++ b/services/secondary-storage/scripts/config_auth.sh
@@ -0,0 +1,69 @@
+#!/usr/bin/env 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.
+
+
+
+ 
+
+
+BASE_DIR="/var/www/html/copy/template/"
+HTACCESS="$BASE_DIR/.htaccess"
+
+PASSWDFILE="/etc/httpd/.htpasswd"
+if [ -d /etc/apache2 ]
+then
+  PASSWDFILE="/etc/apache2/.htpasswd"
+fi
+
+config_htaccess() {
+  mkdir -p $BASE_DIR
+  result=$?
+  echo "Options -Indexes" > $HTACCESS
+  let "result=$result+$?"
+  echo "AuthType Basic" >> $HTACCESS
+  let "result=$result+$?"
+  echo "AuthName \"Authentication Required\"" >> $HTACCESS
+  let "result=$result+$?"
+  echo "AuthUserFile  \"$PASSWDFILE\"" >> $HTACCESS
+  let "result=$result+$?"
+  echo "Require valid-user" >> $HTACCESS
+  let "result=$result+$?"
+  return $result 
+}
+
+write_passwd() {
+  local user=$1
+  local passwd=$2
+  htpasswd -bc $PASSWDFILE $user $passwd
+  return $?
+}
+
+if [ $# -ne 2 ] ; then
+	echo $"Usage: `basename $0` username password "
+	exit 0
+fi
+
+write_passwd $1 $2
+if [ $? -ne 0 ]
+then
+  echo "Failed to update password"
+  exit 2
+fi
+
+config_htaccess 
+exit $?

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/services/secondary-storage/scripts/config_ssl.sh
----------------------------------------------------------------------
diff --git a/services/secondary-storage/scripts/config_ssl.sh b/services/secondary-storage/scripts/config_ssl.sh
new file mode 100755
index 0000000..8d80c47
--- /dev/null
+++ b/services/secondary-storage/scripts/config_ssl.sh
@@ -0,0 +1,174 @@
+#!/usr/bin/env 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.
+
+
+
+ 
+help() {
+   printf " -c use customized key/cert\n"
+   printf " -k path of private key\n"
+   printf " -p path of certificate of public key\n"
+   printf " -t path of certificate chain\n"
+}
+
+
+config_httpd_conf() {
+  local ip=$1
+  local srvr=$2
+  cp -f /etc/httpd/conf/httpd.conf.orig /etc/httpd/conf/httpd.conf
+  sed -i -e "s/Listen.*:80$/Listen $ip:80/" /etc/httpd/conf/httpd.conf
+  echo "<VirtualHost $ip:443> " >> /etc/httpd/conf/httpd.conf
+  echo "  DocumentRoot /var/www/html/" >> /etc/httpd/conf/httpd.conf
+  echo "  ServerName $srvr" >> /etc/httpd/conf/httpd.conf
+  echo "  SSLEngine on" >>  /etc/httpd/conf/httpd.conf
+  echo "  SSLCertificateFile /etc/httpd/ssl/certs/realhostip.crt" >>  /etc/httpd/conf/httpd.conf
+  echo "  SSLCertificateKeyFile /etc/httpd/ssl/keys/realhostip.key" >> /etc/httpd/conf/httpd.conf
+  echo "</VirtualHost>" >> /etc/httpd/conf/httpd.conf
+}
+
+config_apache2_conf() {
+  local ip=$1
+  local srvr=$2
+  cp -f /etc/apache2/sites-available/default.orig /etc/apache2/sites-available/default
+  cp -f /etc/apache2/sites-available/default-ssl.orig /etc/apache2/sites-available/default-ssl
+  sed -i -e "s/<VirtualHost.*>/<VirtualHost $ip:80>/" /etc/apache2/sites-available/default
+  sed -i -e "s/<VirtualHost.*>/<VirtualHost $ip:443>/" /etc/apache2/sites-available/default-ssl
+  sed -i -e "s/Listen .*:80/Listen $ip:80/g" /etc/apache2/ports.conf
+  sed -i -e "s/Listen .*:443/Listen $ip:443/g" /etc/apache2/ports.conf
+  sed -i -e "s/NameVirtualHost .*:80/NameVirtualHost $ip:80/g" /etc/apache2/ports.conf
+  sed -i  's/ssl-cert-snakeoil.key/cert_apache.key/' /etc/apache2/sites-available/default-ssl
+  sed -i  's/ssl-cert-snakeoil.pem/cert_apache.crt/' /etc/apache2/sites-available/default-ssl
+}
+
+copy_certs() {
+  local certdir=$(dirname $0)/certs
+  local mydir=$(dirname $0)
+  if [ -d $certdir ] && [ -f $customPrivKey ] &&  [ -f $customPrivCert ] ; then
+       mkdir -p /etc/httpd/ssl/keys  &&  mkdir -p /etc/httpd/ssl/certs  &&  cp $customprivKey /etc/httpd/ssl/keys   &&  cp $customPrivCert /etc/httpd/ssl/certs
+      return $?
+  fi
+  if [ ! -z customCertChain ] && [ -f $customCertChain ] ; then
+     cp $customCertChain /etc/httpd/ssl/certs  
+  fi
+  return 1
+}
+
+copy_certs_apache2() {
+  local certdir=$(dirname $0)/certs
+  local mydir=$(dirname $0)
+  if [ -f $customPrivKey ] &&  [ -f $customPrivCert ] ; then
+      cp $customPrivKey /etc/ssl/private/cert_apache.key   &&  cp $customPrivCert /etc/ssl/certs/cert_apache.crt
+  fi
+  if [ ! -z "$customCertChain" ] && [ -f "$customCertChain" ] ; then
+     cp $customCertChain /etc/ssl/certs/cert_apache_chain.crt
+  fi
+  return 0
+}
+
+
+cflag=
+cpkflag=
+cpcflag=
+cccflag=
+customPrivKey=$(dirname $0)/certs/realhostip.key
+customPrivCert=$(dirname $0)/certs/realhostip.crt
+customCertChain=
+publicIp=
+hostName=
+while getopts 'i:h:k:p:t:c' OPTION
+do
+  case $OPTION in
+     c) cflag=1
+        ;;
+     k) cpkflag=1
+        customPrivKey="$OPTARG"
+        ;;
+     p) cpcflag=1
+        customPrivCert="$OPTARG"
+        ;;
+     t) cccflag=1
+        customCertChain="$OPTARG"
+        ;;
+     i) publicIp="$OPTARG"
+        ;;
+     h) hostName="$OPTARG"
+        ;;
+     ?) help
+        ;;
+   esac
+done
+
+
+if [ -z "$publicIp" ] || [ -z "$hostName" ]
+then
+   help
+   exit 1
+fi
+
+if [ "$cflag" == "1" ]
+then
+  if [ "$cpkflag$cpcflag" != "11" ] 
+  then
+     help
+     exit 1
+  fi
+  if [ ! -f "$customPrivKey" ]
+  then
+     printf "priviate key file is not exist\n"
+     exit 2
+  fi
+
+  if [ ! -f "$customPrivCert" ]
+  then
+     printf "public certificate is not exist\n"
+     exit 3
+  fi
+
+  if [ "$cccflag" == "1" ] 
+  then
+     if [ ! -f "$customCertChain" ]
+     then
+        printf "certificate chain is not exist\n"
+        exit 4
+     fi
+  fi
+fi
+
+if [ -d /etc/apache2 ]
+then
+  copy_certs_apache2
+else
+  copy_certs
+fi
+
+if [ $? -ne 0 ]
+then
+  echo "Failed to copy certificates"
+  exit 2
+fi
+
+if [ -d /etc/apache2 ]
+then
+  config_apache2_conf $publicIp $hostName
+  /etc/init.d/apache2 stop
+  /etc/init.d/apache2 start
+else
+  config_httpd_conf $publicIp $hostName
+fi
+
+

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/services/secondary-storage/scripts/ipfirewall.sh
----------------------------------------------------------------------
diff --git a/services/secondary-storage/scripts/ipfirewall.sh b/services/secondary-storage/scripts/ipfirewall.sh
new file mode 100755
index 0000000..4711b8a
--- /dev/null
+++ b/services/secondary-storage/scripts/ipfirewall.sh
@@ -0,0 +1,50 @@
+#!/usr/bin/env 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.
+
+BASE_DIR="/var/www/html/copy/"
+HTACCESS="$BASE_DIR/.htaccess"
+
+config_htaccess() {
+  mkdir -p $BASE_DIR
+  result=$?
+  echo "Options -Indexes" > $HTACCESS
+  let "result=$result+$?"
+  echo "order deny,allow" >> $HTACCESS
+  let "result=$result+$?"
+  echo "deny from all" >> $HTACCESS
+  let "result=$result+$?"
+  return $result
+}
+
+ips(){
+  echo "allow from $1" >> $HTACCESS
+  result=$?
+  return $result
+}
+
+is_append="$1"
+shift
+if [ $is_append != "true" ]; then
+	config_htaccess
+fi
+for i in $@
+do
+        ips "$i"
+done
+exit $?
+

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/services/secondary-storage/scripts/run-proxy.sh
----------------------------------------------------------------------
diff --git a/services/secondary-storage/scripts/run-proxy.sh b/services/secondary-storage/scripts/run-proxy.sh
new file mode 100644
index 0000000..d6ccf7c
--- /dev/null
+++ b/services/secondary-storage/scripts/run-proxy.sh
@@ -0,0 +1,48 @@
+#!/usr/bin/env 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.
+
+
+
+ 
+
+#run.sh runs the console proxy.
+
+# make sure we delete the old files from the original template 
+rm console-proxy.jar
+rm console-common.jar
+rm conf/cloud.properties
+
+CP=./:./conf
+for file in *.jar
+do
+  CP=${CP}:$file
+done
+
+#CMDLINE=$(cat /proc/cmdline)
+#for i in $CMDLINE
+#  do
+#     KEY=$(echo $i | cut -d= -f1)
+#     VALUE=$(echo $i | cut -d= -f2)
+#     case $KEY in
+#       mgmt_host)
+#          MGMT_HOST=$VALUE
+#          ;;
+#     esac
+#  done
+   
+java -mx700m -cp $CP:./conf com.cloud.consoleproxy.ConsoleProxy $@

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/services/secondary-storage/scripts/run.bat
----------------------------------------------------------------------
diff --git a/services/secondary-storage/scripts/run.bat b/services/secondary-storage/scripts/run.bat
new file mode 100644
index 0000000..ce6dc40
--- /dev/null
+++ b/services/secondary-storage/scripts/run.bat
@@ -0,0 +1,18 @@
+rem  Licensed to the Apache Software Foundation (ASF) under one
+rem  or more contributor license agreements.  See the NOTICE file
+rem  distributed with this work for additional information
+rem  regarding copyright ownership.  The ASF licenses this file
+rem  to you under the Apache License, Version 2.0 (the
+rem  "License"); you may not use this file except in compliance
+rem  with the License.  You may obtain a copy of the License at
+rem  
+rem    http://www.apache.org/licenses/LICENSE-2.0
+rem  
+rem  Unless required by applicable law or agreed to in writing,
+rem  software distributed under the License is distributed on an
+rem  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+rem  KIND, either express or implied.  See the License for the
+rem  specific language governing permissions and limitations
+rem  under the License.
+
+java -mx700m -cp cloud-console-proxy.jar;;cloud-console-common.jar;log4j-1.2.15.jar;apache-log4j-extras-1.0.jar;gson-1.3.jar;commons-logging-1.1.1.jar;.;.\conf; com.cloud.consoleproxy.ConsoleProxy %*

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/services/secondary-storage/scripts/run.sh
----------------------------------------------------------------------
diff --git a/services/secondary-storage/scripts/run.sh b/services/secondary-storage/scripts/run.sh
new file mode 100755
index 0000000..146d96f
--- /dev/null
+++ b/services/secondary-storage/scripts/run.sh
@@ -0,0 +1,45 @@
+#!/usr/bin/env 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.
+
+
+
+ 
+
+#_run.sh runs the agent client.
+
+# set -x
+ 
+while true
+do
+  ./_run.sh "$@" &
+  wait
+  ex=$?
+  if [ $ex -eq 0 ] || [ $ex -eq 1 ] || [ $ex -eq 66 ] || [ $ex -gt 128 ]; then
+      # permanent errors
+      sleep 5
+  fi
+
+  # user stop agent by service cloud stop
+  grep 'stop' /usr/local/cloud/systemvm/user_request &>/dev/null
+  if [ $? -eq 0 ]; then
+      timestamp=$(date)
+      echo "$timestamp User stops cloud.com service" >> /var/log/cloud.log
+      exit 0
+  fi
+  sleep 5
+done

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/services/secondary-storage/scripts/ssvm-check.sh
----------------------------------------------------------------------
diff --git a/services/secondary-storage/scripts/ssvm-check.sh b/services/secondary-storage/scripts/ssvm-check.sh
new file mode 100644
index 0000000..a401164
--- /dev/null
+++ b/services/secondary-storage/scripts/ssvm-check.sh
@@ -0,0 +1,136 @@
+#!/usr/bin/env 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.
+ 
+
+# Health check script for the Secondary Storage VM
+
+# DNS server is specified.
+
+
+CMDLINE=/var/cache/cloud/cmdline
+for i in `cat $CMDLINE`
+do
+   key=`echo $i | cut -d= -f1`
+   value=`echo $i | cut -d= -f2`
+   case $key in
+      host)
+         MGMTSERVER=$value       
+         ;;
+   esac
+done
+
+
+# ping dns server
+echo ================================================
+DNSSERVER=`egrep '^nameserver' /etc/resolv.conf  | awk '{print $2}'| head -1`
+echo "First DNS server is " $DNSSERVER
+ping -c 2  $DNSSERVER
+if [ $? -eq 0 ]
+then
+    echo "Good: Can ping DNS server"
+else
+    echo "WARNING: cannot ping DNS server"
+    echo "route follows"
+    route -n
+fi
+
+
+# check dns resolve
+echo ================================================
+nslookup download.cloud.com 1> /tmp/dns 2>&1
+grep 'no servers could' /tmp/dns 1> /dev/null 2>&1
+if [ $? -eq 0 ]
+then
+    echo "ERROR: DNS not resolving download.cloud.com"
+    echo resolv.conf follows
+    cat /etc/resolv.conf
+    exit 2
+else
+    echo "Good: DNS resolves download.cloud.com"
+fi
+
+
+# check to see if we have the NFS volume mounted
+echo ================================================
+mount|grep -v sunrpc|grep nfs 1> /dev/null 2>&1
+if [ $? -eq 0 ]
+then
+    echo "NFS is currently mounted"
+    # check for write access
+    for MOUNTPT in `mount|grep -v sunrpc|grep nfs| awk '{print $3}'`
+    do
+        if [ $MOUNTPT != "/proc/xen" ] # mounted by xen
+        then
+            echo Mount point is $MOUNTPT
+            touch $MOUNTPT/foo
+            if [ $? -eq 0 ]
+            then
+                echo "Good: Can write to mount point"
+                rm $MOUNTPT/foo
+            else
+                echo "ERROR: Cannot write to mount point"
+                echo "You need to export with norootsquash"
+            fi
+        fi
+     done
+else
+    echo "ERROR: NFS is not currently mounted"
+    echo "Try manually mounting from inside the VM"
+    NFSSERVER=`awk '{print $17}' $CMDLINE|awk -F= '{print $2}'|awk -F: '{print $1}'`
+    echo "NFS server is " $NFSSERVER
+    ping -c 2  $NFSSERVER
+    if [ $? -eq 0 ]
+    then
+	echo "Good: Can ping NFS server"
+    else
+	echo "WARNING: cannot ping NFS server"
+	echo routing table follows
+	route -n
+    fi
+fi
+
+
+# check for connectivity to the management server
+echo ================================================
+echo Management server is $MGMTSERVER.  Checking connectivity.
+socatout=$(echo | socat - TCP:$MGMTSERVER:8250,connect-timeout=3 2>&1)
+if [ $? -eq 0 ]
+then
+    echo "Good: Can connect to management server port 8250"
+else
+    echo "ERROR: Cannot connect to $MGMTSERVER port 8250"
+    echo $socatout
+    exit 4
+fi
+
+
+# check for the java process running
+echo ================================================
+ps -eaf|grep -v grep|grep java 1> /dev/null 2>&1
+if [ $? -eq 0 ]
+then
+    echo "Good: Java process is running"
+else
+    echo "ERROR: Java process not running.  Try restarting the SSVM."
+    exit 3
+fi
+
+echo ================================================
+echo Tests Complete.  Look for ERROR or WARNING above.  
+
+exit 0

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/services/secondary-storage/src/org/apache/cloudstack/storage/resource/CifsSecondaryStorageResource.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/CifsSecondaryStorageResource.java b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/CifsSecondaryStorageResource.java
new file mode 100755
index 0000000..de4cfe0
--- /dev/null
+++ b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/CifsSecondaryStorageResource.java
@@ -0,0 +1,755 @@
+// 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 org.apache.cloudstack.storage.resource;
+
+import java.io.File;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+
+import javax.naming.ConfigurationException;
+
+import org.apache.cloudstack.storage.template.DownloadManager;
+import org.apache.cloudstack.storage.template.DownloadManagerImpl;
+import org.apache.cloudstack.storage.template.UploadManager;
+import org.apache.cloudstack.storage.template.UploadManagerImpl;
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.CheckHealthAnswer;
+import com.cloud.agent.api.CheckHealthCommand;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.GetStorageStatsAnswer;
+import com.cloud.agent.api.GetStorageStatsCommand;
+import com.cloud.agent.api.PingCommand;
+import com.cloud.agent.api.PingStorageCommand;
+import com.cloud.agent.api.ReadyAnswer;
+import com.cloud.agent.api.ReadyCommand;
+import com.cloud.agent.api.SecStorageFirewallCfgCommand;
+import com.cloud.agent.api.SecStorageFirewallCfgCommand.PortConfig;
+import com.cloud.agent.api.SecStorageSetupCommand;
+import com.cloud.agent.api.SecStorageVMSetupCommand;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.StartupStorageCommand;
+import com.cloud.agent.api.storage.CreateEntityDownloadURLCommand;
+import com.cloud.agent.api.storage.DeleteEntityDownloadURLCommand;
+import com.cloud.agent.api.storage.DeleteTemplateCommand;
+import com.cloud.agent.api.storage.DownloadCommand;
+import com.cloud.agent.api.storage.DownloadProgressCommand;
+import com.cloud.agent.api.storage.UploadCommand;
+import com.cloud.agent.api.storage.ssCommand;
+import com.cloud.host.Host;
+import com.cloud.host.Host.Type;
+import com.cloud.resource.ServerResourceBase;
+import com.cloud.storage.Storage;
+import com.cloud.storage.Storage.StoragePoolType;
+import com.cloud.storage.StorageLayer;
+import com.cloud.storage.template.TemplateInfo;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.component.ComponentContext;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.utils.net.NfsUtils;
+import com.cloud.utils.script.Script;
+
+/**
+ * Implementation of Secondary Storage Resource to handle CIFS share
+ * 
+ * TODOD: After mount rest of the functionality should be similar to NfsSecondaryStroage.
+ * Move common functionality of NFS and CIFS secondary storage resource class to base class
+ **/
+
+public class CifsSecondaryStorageResource extends ServerResourceBase implements SecondaryStorageResource {
+    private static final Logger s_logger = Logger.getLogger(CifsSecondaryStorageResource.class);
+    int _timeout;
+
+    String _instance;
+    String _parent;
+
+    String _dc;
+    String _pod;
+    String _guid;
+    String _nfsPath;
+    String _mountParent;
+    Map<String, Object> _params;
+    StorageLayer _storage;
+    boolean _inSystemVM = false;
+    boolean _sslCopy = false;
+
+    Random _rand = new Random(System.currentTimeMillis());
+
+    DownloadManager _dlMgr;
+    UploadManager _upldMgr;
+    private String _configSslScr;
+    private String _configAuthScr;
+    private String _configIpFirewallScr;
+    private String _publicIp;
+    private String _hostname;
+    private String _localgw;
+    private String _eth1mask;
+    private String _eth1ip;
+
+    @Override
+    public void disconnected() {
+        if (_parent != null && !_inSystemVM) {
+            Script script = new Script(!_inSystemVM, "umount", _timeout, s_logger);
+            script.add(_parent);
+            script.execute();
+
+            File file = new File(_parent);
+            file.delete();
+        }
+    }
+
+    @Override
+    public Answer executeRequest(Command cmd) {
+        if (cmd instanceof DownloadProgressCommand) {
+            return _dlMgr.handleDownloadCommand(this, (DownloadProgressCommand)cmd);
+        } else if (cmd instanceof DownloadCommand) {
+            return _dlMgr.handleDownloadCommand(this, (DownloadCommand)cmd);
+        } else if (cmd instanceof UploadCommand) {        	
+            return _upldMgr.handleUploadCommand(this, (UploadCommand)cmd);
+        } else if (cmd instanceof CreateEntityDownloadURLCommand){
+            return _upldMgr.handleCreateEntityURLCommand((CreateEntityDownloadURLCommand)cmd);
+        } else if(cmd instanceof DeleteEntityDownloadURLCommand){
+            return _upldMgr.handleDeleteEntityDownloadURLCommand((DeleteEntityDownloadURLCommand)cmd);
+        } else if (cmd instanceof GetStorageStatsCommand) {
+            return execute((GetStorageStatsCommand)cmd);
+        } else if (cmd instanceof CheckHealthCommand) {
+            return new CheckHealthAnswer((CheckHealthCommand)cmd, true);
+        } else if (cmd instanceof DeleteTemplateCommand) {
+            return execute((DeleteTemplateCommand) cmd);
+        } else if (cmd instanceof ReadyCommand) {
+            return new ReadyAnswer((ReadyCommand)cmd);
+        } else if (cmd instanceof SecStorageFirewallCfgCommand){
+            return execute((SecStorageFirewallCfgCommand)cmd);
+        } else if (cmd instanceof SecStorageVMSetupCommand){
+            return execute((SecStorageVMSetupCommand)cmd);
+        } else if (cmd instanceof SecStorageSetupCommand){
+            return new Answer(cmd, true, "success");
+        } else {
+            return Answer.createUnsupportedCommandAnswer(cmd);
+        }
+    }
+
+    private Answer execute(SecStorageVMSetupCommand cmd) {
+        if (!_inSystemVM){
+            return new Answer(cmd, true, null);
+        }
+        boolean success = true;
+        StringBuilder result = new StringBuilder();
+        for (String cidr: cmd.getAllowedInternalSites()) {
+            String tmpresult = allowOutgoingOnPrivate(cidr);
+            if (tmpresult != null) {
+                result.append(", ").append(tmpresult);
+                success = false;
+            }
+        }
+        if (success) {
+            if (cmd.getCopyPassword() != null && cmd.getCopyUserName() != null) {
+                String tmpresult = configureAuth(cmd.getCopyUserName(), cmd.getCopyPassword());
+                if (tmpresult != null) {
+                    result.append("Failed to configure auth for copy ").append(tmpresult);
+                    success = false;
+                }
+            }
+        }
+        return new Answer(cmd, success, result.toString());
+
+    }
+
+    private String allowOutgoingOnPrivate(String destCidr) {
+
+        Script command = new Script("/bin/bash", s_logger);
+        String intf = "eth1";
+        command.add("-c");
+        command.add("iptables -I OUTPUT -o " + intf + " -d " + destCidr + " -p tcp -m state --state NEW -m tcp  -j ACCEPT");
+
+        String result = command.execute();
+        if (result != null) {
+            s_logger.warn("Error in allowing outgoing to " + destCidr + ", err=" + result );
+            return "Error in allowing outgoing to " + destCidr + ", err=" + result;
+        }
+        addRouteToInternalIpOrCidr(_localgw, _eth1ip, _eth1mask, destCidr);
+        return null;
+    }
+
+
+
+    private Answer execute(SecStorageFirewallCfgCommand cmd) {
+        if (!_inSystemVM){
+            return new Answer(cmd, true, null);
+        }
+
+        List<String> ipList = new ArrayList<String>();
+
+        for (PortConfig pCfg:cmd.getPortConfigs()){
+            if (pCfg.isAdd()) {
+                ipList.add(pCfg.getSourceIp());		
+            }
+        }
+        boolean success = true;
+        String result;
+        result = configureIpFirewall(ipList);
+        if (result !=null)
+            success = false;
+
+        return new Answer(cmd, success, result);
+    }
+
+    protected GetStorageStatsAnswer execute(final GetStorageStatsCommand cmd) {
+        final long usedSize = getUsedSize();
+        final long totalSize = getTotalSize();
+        if (usedSize == -1 || totalSize == -1) {
+            return new GetStorageStatsAnswer(cmd, "Unable to get storage stats");
+        } else {
+            return new GetStorageStatsAnswer(cmd, totalSize, usedSize) ;
+        }
+    }
+
+    @Override
+    public String getRootDir(ssCommand cmd){
+        return null;
+    }
+
+    protected Answer execute(final DeleteTemplateCommand cmd) {
+        String relativeTemplatePath = cmd.getTemplatePath();
+        String parent = _parent;
+
+        if (relativeTemplatePath.startsWith(File.separator)) {
+            relativeTemplatePath = relativeTemplatePath.substring(1);
+        }
+
+        if (!parent.endsWith(File.separator)) {
+            parent += File.separator;
+        }
+        String absoluteTemplatePath = parent + relativeTemplatePath;
+        File tmpltParent = new File(absoluteTemplatePath).getParentFile();
+        String details = null;
+        if (!tmpltParent.exists()) {
+            details = "template parent directory " + tmpltParent.getName() + " doesn't exist";
+            s_logger.debug(details);
+            return new Answer(cmd, true, details);
+        }
+        File[] tmpltFiles = tmpltParent.listFiles();
+        if (tmpltFiles == null || tmpltFiles.length == 0) {
+            details = "No files under template parent directory " + tmpltParent.getName();
+            s_logger.debug(details);
+        } else {
+            boolean found = false;
+            for (File f : tmpltFiles) {
+                if (!found && f.getName().equals("template.properties")) {
+                    found = true;
+                }
+                if (!f.delete()) {
+                    return new Answer(cmd, false, "Unable to delete file " + f.getName() + " under Template path "
+                            + relativeTemplatePath);
+                }
+            }
+            if (!found) {
+                details = "Can not find template.properties under " + tmpltParent.getName();
+                s_logger.debug(details);
+            }
+        }
+        if (!tmpltParent.delete()) {
+            details = "Unable to delete directory " + tmpltParent.getName() + " under Template path "
+                    + relativeTemplatePath;
+            s_logger.debug(details);
+            return new Answer(cmd, false, details);
+        }
+        return new Answer(cmd, true, null);
+    }
+
+    protected long getUsedSize() {
+        return _storage.getUsedSpace(_parent);
+    }
+
+    protected long getTotalSize() {
+        return _storage.getTotalSpace(_parent);
+    }
+
+    protected long convertFilesystemSize(final String size) {
+        if (size == null || size.isEmpty()) {
+            return -1;
+        }
+
+        long multiplier = 1;
+        if (size.endsWith("T")) {
+            multiplier = 1024l * 1024l * 1024l * 1024l;
+        } else if (size.endsWith("G")) {
+            multiplier = 1024l * 1024l * 1024l;
+        } else if (size.endsWith("M")) {
+            multiplier = 1024l * 1024l;
+        } else {
+            assert (false) : "Well, I have no idea what this is: " + size;
+        }
+
+        return (long)(Double.parseDouble(size.substring(0, size.length() - 1)) * multiplier);
+    }
+
+
+    @Override
+    public Type getType() {
+        return Host.Type.SecondaryStorage;
+    }
+
+    @Override
+    public PingCommand getCurrentStatus(final long id) {
+        return new PingStorageCommand(Host.Type.Storage, id, new HashMap<String, Boolean>());
+    }
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+        _eth1ip = (String)params.get("eth1ip");
+        if (_eth1ip != null) { //can only happen inside service vm
+            params.put("private.network.device", "eth1");
+        } else {
+            s_logger.warn("Wait, what's going on? eth1ip is null!!");
+        }
+        String eth2ip = (String) params.get("eth2ip");
+        if (eth2ip != null) {
+            params.put("public.network.device", "eth2");
+        }         
+        _publicIp = (String) params.get("eth2ip");
+        _hostname = (String) params.get("name");
+
+        super.configure(name, params);
+
+        _params = params;
+        String value = (String)params.get("scripts.timeout");
+        _timeout = NumbersUtil.parseInt(value, 1440) * 1000;
+
+        _storage = (StorageLayer)params.get(StorageLayer.InstanceConfigKey);
+        if (_storage == null) {
+            value = (String)params.get(StorageLayer.ClassConfigKey);
+            if (value == null) {
+                value = "com.cloud.storage.JavaStorageLayer";
+            }
+
+            try {
+                Class<?> clazz = Class.forName(value);
+                _storage = (StorageLayer)ComponentContext.inject(clazz);
+                _storage.configure("StorageLayer", params);
+            } catch (ClassNotFoundException e) {
+                throw new ConfigurationException("Unable to find class " + value);
+            }
+        }
+        _configSslScr = Script.findScript(getDefaultScriptsDir(), "config_ssl.sh");
+        if (_configSslScr != null) {
+            s_logger.info("config_ssl.sh found in " + _configSslScr);
+        }
+
+        _configAuthScr = Script.findScript(getDefaultScriptsDir(), "config_auth.sh");
+        if (_configSslScr != null) {
+            s_logger.info("config_auth.sh found in " + _configAuthScr);
+        }
+
+        _configIpFirewallScr = Script.findScript(getDefaultScriptsDir(), "ipfirewall.sh");
+        if (_configIpFirewallScr != null) {
+            s_logger.info("_configIpFirewallScr found in " + _configIpFirewallScr);
+        }
+
+        _guid = (String)params.get("guid");
+        if (_guid == null) {
+            throw new ConfigurationException("Unable to find the guid");
+        }
+
+        _dc = (String)params.get("zone");
+        if (_dc == null) {
+            throw new ConfigurationException("Unable to find the zone");
+        }
+        _pod = (String)params.get("pod");
+
+        _instance = (String)params.get("instance");
+
+        _mountParent = (String)params.get("mount.parent");
+        if (_mountParent == null) {
+            _mountParent = File.separator + "mnt";
+        }
+
+        if (_instance != null) {
+            _mountParent = _mountParent + File.separator + _instance;
+        }
+
+        _nfsPath = (String)params.get("mount.path");
+        if (_nfsPath == null) {
+            throw new ConfigurationException("Unable to find mount.path");
+        }
+
+
+
+        String inSystemVM = (String)params.get("secondary.storage.vm");
+        if (inSystemVM == null || "true".equalsIgnoreCase(inSystemVM)) {
+            _inSystemVM = true;
+            _localgw = (String)params.get("localgw");
+            if (_localgw != null) { //can only happen inside service vm
+                _eth1mask = (String)params.get("eth1mask");
+                String internalDns1 = (String)params.get("dns1");
+                String internalDns2 = (String)params.get("dns2");
+
+                if (internalDns1 == null) {
+                    s_logger.warn("No DNS entry found during configuration of NfsSecondaryStorage");
+                } else {
+                    addRouteToInternalIpOrCidr(_localgw, _eth1ip, _eth1mask, internalDns1);
+                }
+
+                String mgmtHost = (String)params.get("host");
+                String nfsHost = NfsUtils.getHostPart(_nfsPath);
+                if (nfsHost == null) {
+                    s_logger.error("Invalid or corrupt nfs url " + _nfsPath);
+                    throw new CloudRuntimeException("Unable to determine host part of nfs path");
+                }
+                try {
+                    InetAddress nfsHostAddr = InetAddress.getByName(nfsHost);
+                    nfsHost = nfsHostAddr.getHostAddress();
+                } catch (UnknownHostException uhe) {
+                    s_logger.error("Unable to resolve nfs host " + nfsHost);
+                    throw new CloudRuntimeException("Unable to resolve nfs host to an ip address " + nfsHost);
+                }
+                addRouteToInternalIpOrCidr(_localgw, _eth1ip, _eth1mask, nfsHost);
+                addRouteToInternalIpOrCidr(_localgw, _eth1ip, _eth1mask, mgmtHost);
+                if (internalDns2 != null) {
+                    addRouteToInternalIpOrCidr(_localgw, _eth1ip, _eth1mask, internalDns2);
+                }
+
+            }
+            String useSsl = (String)params.get("sslcopy");
+            if (useSsl != null) {
+                _sslCopy = Boolean.parseBoolean(useSsl);
+                if (_sslCopy) {
+                    configureSSL();
+                }
+            }
+            startAdditionalServices();
+            _params.put("install.numthreads", "50");
+            _params.put("secondary.storage.vm", "true");
+        }
+        _parent = mount(_nfsPath, _mountParent);
+        if (_parent == null) {
+            throw new ConfigurationException("Unable to create mount point");
+        }
+
+
+        s_logger.info("Mount point established at " + _parent);
+
+        try {
+            _params.put("template.parent", _parent);
+            _params.put(StorageLayer.InstanceConfigKey, _storage);
+            _dlMgr = new DownloadManagerImpl();
+            _dlMgr.configure("DownloadManager", _params);
+            _upldMgr = new UploadManagerImpl();
+            _upldMgr.configure("UploadManager", params);
+        } catch (ConfigurationException e) {
+            s_logger.warn("Caught problem while configuring DownloadManager", e);
+            return false;
+        }
+        return true;
+    }
+
+    private void startAdditionalServices() {
+        Script command = new Script("/bin/bash", s_logger);
+        command.add("-c");
+        command.add("if [ -f /etc/init.d/ssh ]; then service ssh restart; else service sshd restart; fi ");
+        String result = command.execute();
+        if (result != null) {
+            s_logger.warn("Error in starting sshd service err=" + result );
+        }
+        command = new Script("/bin/bash", s_logger);
+        command.add("-c");
+        command.add("iptables -I INPUT -i eth1 -p tcp -m state --state NEW -m tcp --dport 3922 -j ACCEPT");
+        result = command.execute();
+        if (result != null) {
+            s_logger.warn("Error in opening up ssh port err=" + result );
+        }
+    }
+
+    private void addRouteToInternalIpOrCidr(String localgw, String eth1ip, String eth1mask, String destIpOrCidr) {
+        s_logger.debug("addRouteToInternalIp: localgw=" + localgw + ", eth1ip=" + eth1ip + ", eth1mask=" + eth1mask + ",destIp=" + destIpOrCidr);
+        if (destIpOrCidr == null) {
+            s_logger.debug("addRouteToInternalIp: destIp is null");
+            return;
+        }
+        if (!NetUtils.isValidIp(destIpOrCidr) && !NetUtils.isValidCIDR(destIpOrCidr)){
+            s_logger.warn(" destIp is not a valid ip address or cidr destIp=" + destIpOrCidr);
+            return;
+        }
+        boolean inSameSubnet = false;
+        if (NetUtils.isValidIp(destIpOrCidr)) {
+            if (eth1ip != null && eth1mask != null) {
+                inSameSubnet = NetUtils.sameSubnet(eth1ip, destIpOrCidr, eth1mask);
+            } else {
+                s_logger.warn("addRouteToInternalIp: unable to determine same subnet: _eth1ip=" + eth1ip + ", dest ip=" + destIpOrCidr + ", _eth1mask=" + eth1mask);
+            }
+        } else {
+            inSameSubnet = NetUtils.isNetworkAWithinNetworkB(destIpOrCidr, NetUtils.ipAndNetMaskToCidr(eth1ip, eth1mask));
+        }
+        if (inSameSubnet) {
+            s_logger.debug("addRouteToInternalIp: dest ip " + destIpOrCidr + " is in the same subnet as eth1 ip " + eth1ip);
+            return;
+        }
+        Script command = new Script("/bin/bash", s_logger);
+        command.add("-c");
+        command.add("ip route delete " + destIpOrCidr);
+        command.execute();
+        command = new Script("/bin/bash", s_logger);
+        command.add("-c");
+        command.add("ip route add " + destIpOrCidr + " via " + localgw);
+        String result = command.execute();
+        if (result != null) {
+            s_logger.warn("Error in configuring route to internal ip err=" + result );
+        } else {
+            s_logger.debug("addRouteToInternalIp: added route to internal ip=" + destIpOrCidr + " via " + localgw);
+        }
+    }
+
+    private void configureSSL() {
+        Script command = new Script(_configSslScr);
+        command.add(_publicIp);
+        command.add(_hostname);
+        String result = command.execute();
+        if (result != null) {
+            s_logger.warn("Unable to configure httpd to use ssl");
+        }
+    }
+
+    private String configureAuth(String user, String passwd) {
+        Script command = new Script(_configAuthScr);
+        command.add(user);
+        command.add(passwd);
+        String result = command.execute();
+        if (result != null) {
+            s_logger.warn("Unable to configure httpd to use auth");
+        }
+        return result;
+    }
+
+    private String configureIpFirewall(List<String> ipList){
+        Script command = new Script(_configIpFirewallScr);		
+        for (String ip : ipList){
+            command.add(ip);
+        }		
+
+        String result = command.execute();
+        if (result != null) {
+            s_logger.warn("Unable to configure firewall for command : " +command);
+        }
+        return result;
+    }
+
+    protected String mount(String path, String parent) {
+        String mountPoint = null;
+        for (int i = 0; i < 10; i++) {
+            String mntPt = parent + File.separator + Integer.toHexString(_rand.nextInt(Integer.MAX_VALUE));
+            File file = new File(mntPt);
+            if (!file.exists()) {
+                if (_storage.mkdir(mntPt)) {
+                    mountPoint = mntPt;
+                    break;
+                }
+            }
+            s_logger.debug("Unable to create mount: " + mntPt);
+        }
+
+        if (mountPoint == null) {
+            s_logger.warn("Unable to create a mount point");
+            return null;
+        }
+
+        Script script = null;
+        String result = null;
+        script = new Script(!_inSystemVM, "umount", _timeout, s_logger);
+        script.add(path);
+        result = script.execute();
+
+        if( _parent != null ) {
+            script = new Script("rmdir", _timeout, s_logger);
+            script.add(_parent);
+            result = script.execute();
+        }
+
+        Script command = new Script(!_inSystemVM, "mount", _timeout, s_logger);
+        command.add("-t", "cifs");
+        if (_inSystemVM) {
+            //Fedora Core 12 errors out with any -o option executed from java
+            //command.add("-o", "soft,timeo=133,retrans=2147483647,tcp,acdirmax=0,acdirmin=0");
+        }
+        String tok[] = path.split(":");
+        //command.add(path);
+        command.add("//"+tok[0]+tok[1]);
+        command.add(mountPoint);
+        result = command.execute();
+        if (result != null) {
+            s_logger.warn("Unable to mount " + path + " due to " + result);
+            File file = new File(mountPoint);
+            if (file.exists())
+                file.delete();
+            return null;
+        }
+
+
+
+        // XXX: Adding the check for creation of snapshots dir here. Might have to move it somewhere more logical later.
+        if (!checkForSnapshotsDir(mountPoint)) {
+            return null;
+        }
+
+        // Create the volumes dir
+        if (!checkForVolumesDir(mountPoint)) {
+            return null;
+        }
+
+        return mountPoint;
+    }
+
+    @Override
+    public boolean start() {
+        return true;
+    }
+
+    @Override
+    public boolean stop() {
+        return true;
+    }
+
+    @Override
+    public StartupCommand[] initialize() {
+        /*disconnected();
+
+        _parent = mount(_nfsPath, _mountParent);
+
+        if( _parent == null ) {
+            s_logger.warn("Unable to mount the nfs server");
+            return null;
+        }
+
+        try {
+            _params.put("template.parent", _parent);
+            _params.put(StorageLayer.InstanceConfigKey, _storage);
+            _dlMgr = new DownloadManagerImpl();
+            _dlMgr.configure("DownloadManager", _params);
+        } catch (ConfigurationException e) {
+            s_logger.warn("Caught problem while configuring folers", e);
+            return null;
+        }*/
+
+        final StartupStorageCommand cmd = new StartupStorageCommand(_parent, StoragePoolType.NetworkFilesystem, getTotalSize(), new HashMap<String, TemplateInfo>());
+
+        cmd.setResourceType(Storage.StorageResourceType.SECONDARY_STORAGE);
+        cmd.setIqn(null);
+
+        fillNetworkInformation(cmd);
+        cmd.setDataCenter(_dc);
+        cmd.setPod(_pod);
+        cmd.setGuid(_guid);
+        cmd.setName(_guid);
+        cmd.setVersion(NfsSecondaryStorageResource.class.getPackage().getImplementationVersion());
+        cmd.getHostDetails().put("mount.parent", _mountParent);
+        cmd.getHostDetails().put("mount.path", _nfsPath);
+        String tok[] = _nfsPath.split(":");
+        cmd.setNfsShare("nfs://" + tok[0] + tok[1]);
+        if (cmd.getHostDetails().get("orig.url") == null) {
+            if (tok.length != 2) {
+                throw new CloudRuntimeException("Not valid NFS path" + _nfsPath);
+            }
+            String nfsUrl = "nfs://" + tok[0] + tok[1];
+            cmd.getHostDetails().put("orig.url", nfsUrl);
+        }
+        InetAddress addr;
+        try {
+            addr = InetAddress.getByName(tok[0]);
+            cmd.setPrivateIpAddress(addr.getHostAddress());
+        } catch (UnknownHostException e) {
+            cmd.setPrivateIpAddress(tok[0]);
+        }
+        return new StartupCommand [] {cmd};
+    }
+
+    protected boolean checkForSnapshotsDir(String mountPoint) {
+        String snapshotsDirLocation = mountPoint + File.separator + "snapshots";
+        return createDir("snapshots", snapshotsDirLocation, mountPoint);
+    }
+
+    protected boolean checkForVolumesDir(String mountPoint) {
+        String volumesDirLocation = mountPoint + "/" + "volumes";
+        return createDir("volumes", volumesDirLocation, mountPoint);
+    }
+
+    protected boolean createDir(String dirName, String dirLocation, String mountPoint) {
+        boolean dirExists = false;
+
+        File dir = new File(dirLocation);
+        if (dir.exists()) {
+            if (dir.isDirectory()) {
+                s_logger.debug(dirName + " already exists on secondary storage, and is mounted at " + mountPoint);
+                dirExists = true;
+            } else {
+                if (dir.delete() && _storage.mkdir(dirLocation)) {
+                    dirExists = true;
+                }
+            }
+        } else if (_storage.mkdir(dirLocation)) {
+            dirExists = true;
+        }
+
+        if (dirExists) {
+            s_logger.info(dirName  + " directory created/exists on Secondary Storage.");
+        } else {
+            s_logger.info(dirName + " directory does not exist on Secondary Storage.");
+        }
+
+        return dirExists;
+    }
+
+    @Override
+    protected String getDefaultScriptsDir() {
+        return "./scripts/storage/secondary";
+    }
+
+	@Override
+	public void setName(String name) {
+		// TODO Auto-generated method stub
+		
+	}
+
+	@Override
+	public void setConfigParams(Map<String, Object> params) {
+		// TODO Auto-generated method stub
+		
+	}
+
+	@Override
+	public Map<String, Object> getConfigParams() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public int getRunLevel() {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	@Override
+	public void setRunLevel(int level) {
+		// TODO Auto-generated method stub
+		
+	}
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/services/secondary-storage/src/org/apache/cloudstack/storage/resource/LocalSecondaryStorageResource.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/LocalSecondaryStorageResource.java b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/LocalSecondaryStorageResource.java
new file mode 100644
index 0000000..b904254
--- /dev/null
+++ b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/LocalSecondaryStorageResource.java
@@ -0,0 +1,246 @@
+// 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 org.apache.cloudstack.storage.resource;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.naming.ConfigurationException;
+
+import org.apache.cloudstack.storage.template.DownloadManager;
+import org.apache.cloudstack.storage.template.DownloadManagerImpl;
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.CheckHealthAnswer;
+import com.cloud.agent.api.CheckHealthCommand;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.ComputeChecksumCommand;
+import com.cloud.agent.api.PingCommand;
+import com.cloud.agent.api.PingStorageCommand;
+import com.cloud.agent.api.ReadyAnswer;
+import com.cloud.agent.api.ReadyCommand;
+import com.cloud.agent.api.SecStorageSetupCommand;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.StartupStorageCommand;
+import com.cloud.agent.api.storage.DownloadCommand;
+import com.cloud.agent.api.storage.DownloadProgressCommand;
+import com.cloud.agent.api.storage.ListTemplateAnswer;
+import com.cloud.agent.api.storage.ListTemplateCommand;
+import com.cloud.agent.api.storage.ssCommand;
+import com.cloud.host.Host;
+import com.cloud.host.Host.Type;
+import com.cloud.resource.ServerResourceBase;
+import com.cloud.storage.Storage;
+import com.cloud.storage.Storage.StoragePoolType;
+import com.cloud.storage.StorageLayer;
+import com.cloud.storage.template.TemplateInfo;
+import com.cloud.utils.component.ComponentContext;
+
+public class LocalSecondaryStorageResource extends ServerResourceBase implements SecondaryStorageResource {
+    private static final Logger s_logger = Logger.getLogger(LocalSecondaryStorageResource.class);
+    int _timeout;
+
+    String _instance;
+    String _parent;
+
+    String _dc;
+    String _pod;
+    String _guid;
+
+    StorageLayer _storage;
+
+    DownloadManager _dlMgr;
+
+    @Override
+    public void disconnected() {
+    }
+
+
+    @Override
+    public String getRootDir(ssCommand cmd){
+        return getRootDir();
+
+    }
+
+    public String getRootDir() {
+        return _parent;
+    }
+
+    @Override
+    public Answer executeRequest(Command cmd) {
+        if (cmd instanceof DownloadProgressCommand) {
+            return _dlMgr.handleDownloadCommand(this, (DownloadProgressCommand)cmd);
+        } else if (cmd instanceof DownloadCommand) {
+            return _dlMgr.handleDownloadCommand(this, (DownloadCommand)cmd);
+        } else if (cmd instanceof CheckHealthCommand) {
+            return new CheckHealthAnswer((CheckHealthCommand)cmd, true);
+        } else if (cmd instanceof SecStorageSetupCommand){
+            return new Answer(cmd, true, "success");
+        } else if (cmd instanceof ReadyCommand) {
+            return new ReadyAnswer((ReadyCommand)cmd);
+        } else if (cmd instanceof ListTemplateCommand){
+            return execute((ListTemplateCommand)cmd);   
+        } else if (cmd instanceof ComputeChecksumCommand){
+            return execute((ComputeChecksumCommand)cmd);
+        } else {
+            return Answer.createUnsupportedCommandAnswer(cmd);
+        }
+    }
+
+    private Answer execute(ComputeChecksumCommand cmd) {
+        return new Answer(cmd, false, null);   
+    }
+
+
+    private Answer execute(ListTemplateCommand cmd) {
+        String root = getRootDir();
+        Map<String, TemplateInfo> templateInfos = _dlMgr.gatherTemplateInfo(root);
+        return new ListTemplateAnswer(cmd.getSecUrl(), templateInfos);
+    }
+
+    @Override
+    public Type getType() {
+        return Host.Type.LocalSecondaryStorage;
+    }
+
+    @Override
+    public PingCommand getCurrentStatus(final long id) {
+        return new PingStorageCommand(Host.Type.Storage, id, new HashMap<String, Boolean>());
+    }
+
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+        super.configure(name, params);
+
+        _guid = (String)params.get("guid");
+        if (_guid == null) {
+            throw new ConfigurationException("Unable to find the guid");
+        }
+
+        _dc = (String)params.get("zone");
+        if (_dc == null) {
+            throw new ConfigurationException("Unable to find the zone");
+        }
+        _pod = (String)params.get("pod");
+
+        _instance = (String)params.get("instance");
+
+        _parent = (String)params.get("mount.path");
+        if (_parent == null) {
+            throw new ConfigurationException("No directory specified.");
+        }
+
+        _storage = (StorageLayer)params.get(StorageLayer.InstanceConfigKey);
+        if (_storage == null) {
+            String value = (String)params.get(StorageLayer.ClassConfigKey);
+            if (value == null) {
+                value = "com.cloud.storage.JavaStorageLayer";
+            }
+
+            try {
+                Class<StorageLayer> clazz = (Class<StorageLayer>)Class.forName(value);
+                _storage = ComponentContext.inject(clazz);
+            } catch (ClassNotFoundException e) {
+                throw new ConfigurationException("Unable to find class " + value);
+            }
+        }
+
+        if (!_storage.mkdirs(_parent)) {
+            s_logger.warn("Unable to create the directory " + _parent);
+            throw new ConfigurationException("Unable to create the directory " + _parent);
+        }
+
+        s_logger.info("Mount point established at " + _parent);
+
+        params.put("template.parent", _parent);
+        params.put(StorageLayer.InstanceConfigKey, _storage);
+
+        _dlMgr = new DownloadManagerImpl();
+        _dlMgr.configure("DownloadManager", params);
+
+        return true;
+    }
+
+    @Override
+    public boolean start() {
+        return true;
+    }
+
+    @Override
+    public boolean stop() {
+        return true;
+    }
+
+    @Override
+    public StartupCommand[] initialize() {
+
+        final StartupStorageCommand cmd = new StartupStorageCommand(_parent, StoragePoolType.Filesystem, 1024l*1024l*1024l*1024l, _dlMgr.gatherTemplateInfo(_parent));
+        cmd.setResourceType(Storage.StorageResourceType.LOCAL_SECONDARY_STORAGE);
+        cmd.setIqn("local://");
+        fillNetworkInformation(cmd);
+        cmd.setDataCenter(_dc);
+        cmd.setPod(_pod);
+        cmd.setGuid(_guid);
+        cmd.setName(_guid);
+        cmd.setVersion(LocalSecondaryStorageResource.class.getPackage().getImplementationVersion());
+
+        return new StartupCommand [] {cmd};
+    }
+
+    @Override
+    protected String getDefaultScriptsDir() {
+        return "scripts/storage/secondary";
+    }
+
+
+	@Override
+	public void setName(String name) {
+		// TODO Auto-generated method stub
+		
+	}
+
+
+	@Override
+	public void setConfigParams(Map<String, Object> params) {
+		// TODO Auto-generated method stub
+		
+	}
+
+
+	@Override
+	public Map<String, Object> getConfigParams() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+
+	@Override
+	public int getRunLevel() {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+
+	@Override
+	public void setRunLevel(int level) {
+		// TODO Auto-generated method stub
+		
+	}
+}