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

[01/19] git commit: updated refs/heads/master to bf56403

Updated Branches:
  refs/heads/master 4fd3fca84 -> bf56403d8


QuickCloud: start console proxy service from mvn exec:java


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

Branch: refs/heads/master
Commit: 16790446e51645dc3e2623ebf57f88e0cfe2c89c
Parents: e7983b2
Author: Chiradeep Vittal <ch...@apache.org>
Authored: Mon Mar 25 12:15:14 2013 -0700
Committer: Chiradeep Vittal <ch...@apache.org>
Committed: Tue Apr 9 14:45:25 2013 -0700

----------------------------------------------------------------------
 services/console-proxy/server/conf/log4j-cloud.xml |    2 +-
 services/console-proxy/server/pom.xml              |   38 +++++++++++++++
 2 files changed, 39 insertions(+), 1 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/16790446/services/console-proxy/server/conf/log4j-cloud.xml
----------------------------------------------------------------------
diff --git a/services/console-proxy/server/conf/log4j-cloud.xml b/services/console-proxy/server/conf/log4j-cloud.xml
index 5b31c9d..2d1d361 100644
--- a/services/console-proxy/server/conf/log4j-cloud.xml
+++ b/services/console-proxy/server/conf/log4j-cloud.xml
@@ -27,7 +27,7 @@ under the License.
 
    <!-- A time/date based rolling appender -->
    <appender name="FILE" class="org.apache.log4j.DailyRollingFileAppender">
-      <param name="File" value="/var/log/cloud/systemvm.log"/>
+      <param name="File" value="${log.home}systemvm.log"/>
       <param name="Append" value="true"/>
       <param name="Threshold" value="DEBUG"/>
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/16790446/services/console-proxy/server/pom.xml
----------------------------------------------------------------------
diff --git a/services/console-proxy/server/pom.xml b/services/console-proxy/server/pom.xml
index f57b4ca..fd7b964 100644
--- a/services/console-proxy/server/pom.xml
+++ b/services/console-proxy/server/pom.xml
@@ -254,6 +254,44 @@
       </plugins>
       </build>
     </profile>
+    <profile>
+      <id>quickcloud</id>
+      <activation>
+        <property>
+          <name>quickcloud</name>
+        </property>
+      </activation>
+      <build>
+      <plugins>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>exec-maven-plugin</artifactId>
+        <version>1.2.1</version>
+        <executions>
+          <execution>
+            <goals>
+              <goal>java</goal>
+            </goals>
+          </execution>
+        </executions>
+        <configuration>
+          <mainClass>com.cloud.agent.AgentShell</mainClass>
+          <arguments>
+            <argument>zone=1</argument>
+            <argument>pod=1</argument>
+            <argument>host=192.168.56.1</argument>
+          </arguments>
+          <systemProperties>
+            <systemProperty>
+              <key>javax.net.ssl.trustStore</key>
+              <value>certs/realhostip.keystore</value>
+            </systemProperty>
+          </systemProperties>
+        </configuration>
+      </plugin>
+      </plugins>
+    </build>
+  </profile>
   </profiles>
 
 </project>


[18/19] git commit: updated refs/heads/master to bf56403

Posted by ch...@apache.org.
QuickCloud: default to enabled if not specified in datacenter config


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

Branch: refs/heads/master
Commit: bf56403d828aa50c0650cc41cdc51aae79b1c19e
Parents: 2e6c65f
Author: Chiradeep Vittal <ch...@apache.org>
Authored: Tue Apr 9 14:45:12 2013 -0700
Committer: Chiradeep Vittal <ch...@apache.org>
Committed: Tue Apr 9 14:45:27 2013 -0700

----------------------------------------------------------------------
 tools/marvin/marvin/deployDataCenter.py |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bf56403d/tools/marvin/marvin/deployDataCenter.py
----------------------------------------------------------------------
diff --git a/tools/marvin/marvin/deployDataCenter.py b/tools/marvin/marvin/deployDataCenter.py
index d365395..2e270a7 100644
--- a/tools/marvin/marvin/deployDataCenter.py
+++ b/tools/marvin/marvin/deployDataCenter.py
@@ -329,7 +329,7 @@ class deployDataCenters():
             self.createSecondaryStorages(zone.secondaryStorages, zoneId)
             
             enabled = getattr(zone, 'enabled', 'True')
-            if enabled == 'True' or enabled == 'None':
+            if enabled == 'True' or enabled is None:
                 self.enableZone(zoneId, "Enabled")
             details = getattr(zone, 'details')
             if details is not None:


[15/19] git commit: updated refs/heads/master to bf56403

Posted by ch...@apache.org.
QuickCloud: also look for consoleproxy.properties using PropertiesUtil.
When executed with mvn exec:java, the path 'conf' is not on the classpath


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

Branch: refs/heads/master
Commit: 21b4635948152710935ba420cee50b823fd7a2b4
Parents: 3d78019
Author: Chiradeep Vittal <ch...@apache.org>
Authored: Tue Mar 26 10:06:46 2013 -0700
Committer: Chiradeep Vittal <ch...@apache.org>
Committed: Tue Apr 9 14:45:26 2013 -0700

----------------------------------------------------------------------
 .../src/com/cloud/consoleproxy/ConsoleProxy.java   |   16 +++++++++++++-
 1 files changed, 14 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/21b46359/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxy.java
----------------------------------------------------------------------
diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxy.java b/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxy.java
index b5c2989..2abce56 100644
--- a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxy.java
+++ b/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxy.java
@@ -17,6 +17,8 @@
 package com.cloud.consoleproxy;
 
 import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
 import java.io.InputStream;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
@@ -34,6 +36,7 @@ import org.apache.commons.codec.binary.Base64;
 import org.apache.log4j.xml.DOMConfigurator;
 
 import com.cloud.consoleproxy.util.Logger;
+import com.cloud.utils.PropertiesUtil;
 import com.google.gson.Gson;
 import com.sun.net.httpserver.HttpServer;
 
@@ -282,8 +285,17 @@ public class ConsoleProxy {
         InputStream confs = ConsoleProxy.class.getResourceAsStream("/conf/consoleproxy.properties");
         Properties props = new Properties();
         if (confs == null) {
-            s_logger.info("Can't load consoleproxy.properties from classpath, will use default configuration");
-        } else {
+            final File file = PropertiesUtil.findConfigFile("consoleproxy.properties");
+            if (file == null)
+                s_logger.info("Can't load consoleproxy.properties from classpath, will use default configuration");
+            else
+                try {
+                    confs = new FileInputStream(file);
+                } catch (FileNotFoundException e) {
+                    s_logger.info("Ignoring file not found exception and using defaults");
+                }
+        } 
+        if (confs != null) {
             try {
                 props.load(confs);
                 


[17/19] git commit: updated refs/heads/master to bf56403

Posted by ch...@apache.org.
QuickCloud: we moved the SecondaryStorageDiscoverer from the com.cloud package to the org.apache.cloudstack package
QuickCloud: fix license issue
QuickCloud: use a different activation for deploying quickcloud
Otherwise marvin gets invoked during mvn install -Dquickcloud


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

Branch: refs/heads/master
Commit: 271d232d620f27c6b8b10bc85f849563c528e3ae
Parents: 778a59f
Author: Chiradeep Vittal <ch...@apache.org>
Authored: Fri Apr 5 11:52:52 2013 -0700
Committer: Chiradeep Vittal <ch...@apache.org>
Committed: Tue Apr 9 14:45:27 2013 -0700

----------------------------------------------------------------------
 client/tomcatconf/applicationContext.xml.in        |    2 +-
 .../cloud/consoleproxy/ConsoleProxyService.java    |   16 +++++++++++++++
 tools/devcloud/pom.xml                             |    4 +-
 3 files changed, 19 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/271d232d/client/tomcatconf/applicationContext.xml.in
----------------------------------------------------------------------
diff --git a/client/tomcatconf/applicationContext.xml.in b/client/tomcatconf/applicationContext.xml.in
index 3b51a83..67b1286 100644
--- a/client/tomcatconf/applicationContext.xml.in
+++ b/client/tomcatconf/applicationContext.xml.in
@@ -503,7 +503,7 @@
     <property name="name" value="XCP Agent"/>
   </bean>
 
-  <bean id="SecondaryStorageDiscoverer" class="com.cloud.storage.secondary.SecondaryStorageDiscoverer">
+  <bean id="SecondaryStorageDiscoverer" class="org.apache.cloudstack.storage.resource.SecondaryStorageDiscoverer">
     <property name="name" value="SecondaryStorage"/>
   </bean>
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/271d232d/server/src/com/cloud/consoleproxy/ConsoleProxyService.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyService.java b/server/src/com/cloud/consoleproxy/ConsoleProxyService.java
index e43e5c3..fd00f56 100644
--- a/server/src/com/cloud/consoleproxy/ConsoleProxyService.java
+++ b/server/src/com/cloud/consoleproxy/ConsoleProxyService.java
@@ -1,3 +1,19 @@
+// 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.consoleproxy;
 
 import com.cloud.info.ConsoleProxyInfo;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/271d232d/tools/devcloud/pom.xml
----------------------------------------------------------------------
diff --git a/tools/devcloud/pom.xml b/tools/devcloud/pom.xml
index 93029e1..ba4cc46 100644
--- a/tools/devcloud/pom.xml
+++ b/tools/devcloud/pom.xml
@@ -146,7 +146,7 @@
       <id>quickcloud</id>
       <activation>
         <property>
-          <name>quickcloud</name>
+          <name>deployquick</name>
         </property>
       </activation>
       <build> 
@@ -157,7 +157,7 @@
         <version>1.2.1</version>
         <executions>
           <execution>
-            <phase>package</phase>
+            <phase>integration-test</phase>
             <goals>
               <goal>exec</goal>
             </goals>


[05/19] QuickCloud: Enable secondary storage daemon to run outside the system vm

Posted by ch...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/core/src/com/cloud/storage/template/DownloadManagerImpl.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/storage/template/DownloadManagerImpl.java b/core/src/com/cloud/storage/template/DownloadManagerImpl.java
deleted file mode 100755
index 22e78a0..0000000
--- a/core/src/com/cloud/storage/template/DownloadManagerImpl.java
+++ /dev/null
@@ -1,1049 +0,0 @@
-// 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.storage.template;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.math.BigInteger;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-
-import javax.ejb.Local;
-import javax.naming.ConfigurationException;
-
-import org.apache.log4j.Logger;
-
-import com.cloud.agent.api.storage.DownloadAnswer;
-import com.cloud.agent.api.storage.DownloadCommand;
-import com.cloud.agent.api.storage.DownloadCommand.Proxy;
-import com.cloud.agent.api.storage.DownloadCommand.ResourceType;
-import com.cloud.agent.api.storage.DownloadProgressCommand;
-import com.cloud.agent.api.storage.DownloadProgressCommand.RequestType;
-import com.cloud.exception.InternalErrorException;
-import com.cloud.storage.Storage.ImageFormat;
-import com.cloud.storage.StorageLayer;
-import com.cloud.storage.VMTemplateHostVO;
-import com.cloud.storage.VMTemplateStorageResourceAssoc;
-import com.cloud.storage.resource.SecondaryStorageResource;
-import com.cloud.storage.template.Processor.FormatInfo;
-import com.cloud.storage.template.TemplateDownloader.DownloadCompleteCallback;
-import com.cloud.storage.template.TemplateDownloader.Status;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.script.OutputInterpreter;
-import com.cloud.utils.script.Script;
-
-@Local(value = DownloadManager.class)
-public class DownloadManagerImpl extends ManagerBase implements DownloadManager {
-    private String _name;
-    StorageLayer _storage;
-    Map<String, Processor> _processors;
-
-    public class Completion implements DownloadCompleteCallback {
-        private final String jobId;
-
-        public Completion(String jobId) {
-            this.jobId = jobId;
-        }
-
-        @Override
-        public void downloadComplete(Status status) {
-            setDownloadStatus(jobId, status);
-        }
-    }
-
-    private static class DownloadJob {
-        private final TemplateDownloader td;
-        private final String jobId;
-        private final String tmpltName;
-        private final boolean hvm;
-        private final ImageFormat format;
-        private String tmpltPath;
-        private final String description;
-        private String checksum;
-        private final Long accountId;
-        private final String installPathPrefix;
-        private long templatesize;
-        private long templatePhysicalSize;
-        private final long id;
-        private final ResourceType resourceType;
-
-        public DownloadJob(TemplateDownloader td, String jobId, long id, String tmpltName, ImageFormat format, boolean hvm, Long accountId, String descr, String cksum, String installPathPrefix, ResourceType resourceType) {
-            super();
-            this.td = td;
-            this.jobId = jobId;
-            this.tmpltName = tmpltName;
-            this.format = format;
-            this.hvm = hvm;
-            this.accountId = accountId;
-            this.description = descr;
-            this.checksum = cksum;
-            this.installPathPrefix = installPathPrefix;
-            this.templatesize = 0;
-            this.id = id;
-            this.resourceType = resourceType;
-        }
-
-        public TemplateDownloader getTd() {
-            return td;
-        }
-
-        public String getDescription() {
-            return description;
-        }
-
-        public String getChecksum() {
-            return checksum;
-        }
-
-        public TemplateDownloader getTemplateDownloader() {
-            return td;
-        }
-
-        public String getJobId() {
-            return jobId;
-        }
-
-        public String getTmpltName() {
-            return tmpltName;
-        }
-
-        public ImageFormat getFormat() {
-            return format;
-        }
-
-        public boolean isHvm() {
-            return hvm;
-        }
-
-        public Long getAccountId() {
-            return accountId;
-        }
-
-        public long getId() {
-            return id;
-        }
-
-        public ResourceType getResourceType() {
-            return resourceType;
-        }
-
-        public void setTmpltPath(String tmpltPath) {
-            this.tmpltPath = tmpltPath;
-        }
-
-        public String getTmpltPath() {
-            return tmpltPath;
-        }
-
-        public String getInstallPathPrefix() {
-            return installPathPrefix;
-        }
-
-        public void cleanup() {
-            if (td != null) {
-                String dnldPath = td.getDownloadLocalPath();
-                if (dnldPath != null) {
-                    File f = new File(dnldPath);
-                    File dir = f.getParentFile();
-                    f.delete();
-                    if (dir != null) {
-                        dir.delete();
-                    }
-                }
-            }
-
-        }
-
-        public void setTemplatesize(long templatesize) {
-            this.templatesize = templatesize;
-        }
-
-        public long getTemplatesize() {
-            return templatesize;
-        }
-
-        public void setTemplatePhysicalSize(long templatePhysicalSize) {
-            this.templatePhysicalSize = templatePhysicalSize;
-        }
-
-        public long getTemplatePhysicalSize() {
-            return templatePhysicalSize;
-        }
-
-        public void setCheckSum(String checksum) {
-            this.checksum = checksum;
-        }
-    }
-
-    public static final Logger s_logger = Logger.getLogger(DownloadManagerImpl.class);
-    private String _templateDir;
-    private String _volumeDir;
-    private String createTmpltScr;
-    private String createVolScr;
-    private List<Processor> processors;
-
-    private ExecutorService threadPool;
-
-    private final Map<String, DownloadJob> jobs = new ConcurrentHashMap<String, DownloadJob>();
-    private String listTmpltScr;
-    private String listVolScr;
-    private int installTimeoutPerGig = 180 * 60 * 1000;
-    private boolean _sslCopy;
-
-    /**
-     * Get notified of change of job status. Executed in context of downloader thread
-     * 
-     * @param jobId
-     *            the id of the job
-     * @param status
-     *            the status of the job
-     */
-    public void setDownloadStatus(String jobId, Status status) {
-        DownloadJob dj = jobs.get(jobId);
-        if (dj == null) {
-            s_logger.warn("setDownloadStatus for jobId: " + jobId + ", status=" + status + " no job found");
-            return;
-        }
-        TemplateDownloader td = dj.getTemplateDownloader();
-        s_logger.info("Download Completion for jobId: " + jobId + ", status=" + status);
-        s_logger.info("local: " + td.getDownloadLocalPath() + ", bytes=" + td.getDownloadedBytes() + ", error=" + td.getDownloadError() + ", pct=" + td.getDownloadPercent());
-
-        switch (status) {
-        case ABORTED:
-        case NOT_STARTED:
-        case UNRECOVERABLE_ERROR:
-            // TODO
-            dj.cleanup();
-            break;
-        case UNKNOWN:
-            return;
-        case IN_PROGRESS:
-            s_logger.info("Resuming jobId: " + jobId + ", status=" + status);
-            td.setResume(true);
-            threadPool.execute(td);
-            break;
-        case RECOVERABLE_ERROR:
-            threadPool.execute(td);
-            break;
-        case DOWNLOAD_FINISHED:
-            td.setDownloadError("Download success, starting install ");
-            String result = postDownload(jobId);
-            if (result != null) {
-                s_logger.error("Failed post download script: " + result);
-                td.setStatus(Status.UNRECOVERABLE_ERROR);
-                td.setDownloadError("Failed post download script: " + result);
-            } else {
-                td.setStatus(Status.POST_DOWNLOAD_FINISHED);
-                td.setDownloadError("Install completed successfully at " + new SimpleDateFormat().format(new Date()));
-            }
-            dj.cleanup();
-            break;
-        default:
-            break;
-        }
-    }
-
-    private String computeCheckSum(File f) {
-        byte[] buffer = new byte[8192];
-        int read = 0;
-        MessageDigest digest;
-        String checksum = null;        
-        InputStream is = null;
-        try {
-            digest = MessageDigest.getInstance("MD5");           
-            is = new FileInputStream(f);     
-            while( (read = is.read(buffer)) > 0) {
-                digest.update(buffer, 0, read);
-            }       
-            byte[] md5sum = digest.digest();
-            BigInteger bigInt = new BigInteger(1, md5sum);
-            checksum = String.format("%032x",bigInt);
-            return checksum;
-        }catch(IOException e) {
-            return null;
-        }catch (NoSuchAlgorithmException e) {         
-            return null;
-        }
-        finally {
-            try {
-                if(is != null)
-                    is.close();
-            } catch (IOException e) {
-                return null;
-            }                        
-        }
-    }
-
-    /**
-     * Post download activity (install and cleanup). Executed in context of downloader thread
-     * 
-     * @throws IOException
-     */
-    private String postDownload(String jobId) {
-        DownloadJob dnld = jobs.get(jobId);
-        TemplateDownloader td = dnld.getTemplateDownloader();
-        String resourcePath = null;               
-        ResourceType resourceType = dnld.getResourceType();
-
-        // once template path is set, remove the parent dir so that the template is installed with a relative path
-        String finalResourcePath = "";
-        if (resourceType == ResourceType.TEMPLATE){
-            finalResourcePath += _templateDir + File.separator + dnld.getAccountId() + File.separator + dnld.getId() + File.separator;
-            resourcePath = dnld.getInstallPathPrefix() + dnld.getAccountId() + File.separator + dnld.getId() + File.separator;// dnld.getTmpltName();
-        }else {
-            finalResourcePath += _volumeDir + File.separator + dnld.getId() + File.separator;
-            resourcePath = dnld.getInstallPathPrefix() + dnld.getId() + File.separator;// dnld.getTmpltName();
-        }
-
-        _storage.mkdirs(resourcePath);
-        dnld.setTmpltPath(finalResourcePath);
-
-        File originalTemplate = new File(td.getDownloadLocalPath());
-        String checkSum = computeCheckSum(originalTemplate);
-        if (checkSum == null) {
-            s_logger.warn("Something wrong happened when try to calculate the checksum of downloaded template!");
-        }
-        dnld.setCheckSum(checkSum);
-
-        int imgSizeGigs = (int) Math.ceil(_storage.getSize(td.getDownloadLocalPath()) * 1.0d / (1024 * 1024 * 1024));
-        imgSizeGigs++; // add one just in case
-        long timeout = imgSizeGigs * installTimeoutPerGig;
-        Script scr = null;
-        String script = resourceType == ResourceType.TEMPLATE ? createTmpltScr : createVolScr;
-        scr = new Script(script, timeout, s_logger);
-        scr.add("-s", Integer.toString(imgSizeGigs));
-        scr.add("-S", Long.toString(td.getMaxTemplateSizeInBytes()));
-        if (dnld.getDescription() != null && dnld.getDescription().length() > 1) {
-            scr.add("-d", dnld.getDescription());
-        }
-        if (dnld.isHvm()) {
-            scr.add("-h");
-        }
-
-        // add options common to ISO and template
-        String extension = dnld.getFormat().getFileExtension();
-        String templateName = "";
-        if( extension.equals("iso")) {
-            templateName = jobs.get(jobId).getTmpltName().trim().replace(" ", "_");
-        } else {
-            templateName = java.util.UUID.nameUUIDFromBytes((jobs.get(jobId).getTmpltName() + System.currentTimeMillis()).getBytes()).toString();
-        }
-
-        String templateFilename = templateName + "." + extension;
-        dnld.setTmpltPath(finalResourcePath + "/" + templateFilename);
-        scr.add("-n", templateFilename);
-
-        scr.add("-t", resourcePath);
-        scr.add("-f", td.getDownloadLocalPath());
-        if (dnld.getChecksum() != null && dnld.getChecksum().length() > 1) {
-            scr.add("-c", dnld.getChecksum());
-        }
-        scr.add("-u"); // cleanup
-        String result;
-        result = scr.execute();
-
-        if (result != null) {
-            return result;
-        }
-
-        // Set permissions for the downloaded template
-        File downloadedTemplate = new File(resourcePath + "/" + templateFilename);
-        _storage.setWorldReadableAndWriteable(downloadedTemplate);
-
-        // Set permissions for template/volume.properties
-        String propertiesFile = resourcePath;
-        if (resourceType == ResourceType.TEMPLATE){
-            propertiesFile += "/template.properties";
-        }else{
-            propertiesFile += "/volume.properties";
-        }
-        File templateProperties = new File(propertiesFile);
-        _storage.setWorldReadableAndWriteable(templateProperties);
-
-        TemplateLocation loc = new TemplateLocation(_storage, resourcePath);
-        try {
-            loc.create(dnld.getId(), true, dnld.getTmpltName());
-        } catch (IOException e) {
-            s_logger.warn("Something is wrong with template location " + resourcePath, e);
-            loc.purge();
-            return "Unable to download due to " + e.getMessage();
-        }
-
-        Iterator<Processor> en = _processors.values().iterator();
-        while (en.hasNext()) {
-            Processor processor = en.next();
-
-            FormatInfo info = null;
-            try {
-                info = processor.process(resourcePath, null, templateName);
-            } catch (InternalErrorException e) {
-                s_logger.error("Template process exception ", e);
-                return e.toString();
-            }
-            if (info != null) {
-                loc.addFormat(info);
-                dnld.setTemplatesize(info.virtualSize);
-                dnld.setTemplatePhysicalSize(info.size);
-                break;
-            }
-        }
-
-        if (!loc.save()) {
-            s_logger.warn("Cleaning up because we're unable to save the formats");
-            loc.purge();
-        }
-
-        return null;
-    }
-
-    @Override
-    public Status getDownloadStatus(String jobId) {
-        DownloadJob job = jobs.get(jobId);
-        if (job != null) {
-            TemplateDownloader td = job.getTemplateDownloader();
-            if (td != null) {
-                return td.getStatus();
-            }
-        }
-        return Status.UNKNOWN;
-    }
-
-    @Override
-    public String downloadPublicTemplate(long id, String url, String name, ImageFormat format, boolean hvm, Long accountId, String descr, String cksum, String installPathPrefix, String user, String password, long maxTemplateSizeInBytes, Proxy proxy, ResourceType resourceType) {
-        UUID uuid = UUID.randomUUID();
-        String jobId = uuid.toString();
-        String tmpDir = "";
-        if(resourceType == ResourceType.TEMPLATE){
-            tmpDir = installPathPrefix + File.separator + accountId + File.separator + id;
-        }else {
-            tmpDir = installPathPrefix + File.separator + id;
-        }
-
-        try {
-
-            if (!_storage.mkdirs(tmpDir)) {
-                s_logger.warn("Unable to create " + tmpDir);
-                return "Unable to create " + tmpDir;
-            }
-            //	TO DO - define constant for volume properties.
-            File file = ResourceType.TEMPLATE == resourceType ? _storage.getFile(tmpDir + File.separator + TemplateLocation.Filename) : 
-                _storage.getFile(tmpDir + File.separator + "volume.properties");
-            if ( file.exists() ) {
-                file.delete();
-            }
-
-            if (!file.createNewFile()) {
-                s_logger.warn("Unable to create new file: " + file.getAbsolutePath());
-                return "Unable to create new file: " + file.getAbsolutePath();
-            }
-
-            URI uri;
-            try {
-                uri = new URI(url);
-            } catch (URISyntaxException e) {
-                throw new CloudRuntimeException("URI is incorrect: " + url);
-            }
-            TemplateDownloader td;
-            if ((uri != null) && (uri.getScheme() != null)) {
-                if (uri.getScheme().equalsIgnoreCase("http") || uri.getScheme().equalsIgnoreCase("https")) {
-                    td = new HttpTemplateDownloader(_storage, url, tmpDir, new Completion(jobId), maxTemplateSizeInBytes, user, password, proxy, resourceType);
-                } else if (uri.getScheme().equalsIgnoreCase("file")) {
-                    td = new LocalTemplateDownloader(_storage, url, tmpDir, maxTemplateSizeInBytes, new Completion(jobId));
-                } else if (uri.getScheme().equalsIgnoreCase("scp")) {
-                    td = new ScpTemplateDownloader(_storage, url, tmpDir, maxTemplateSizeInBytes, new Completion(jobId));
-                } else if (uri.getScheme().equalsIgnoreCase("nfs")) {
-                    td = null;
-                    // TODO: implement this.
-                    throw new CloudRuntimeException("Scheme is not supported " + url);
-                } else {
-                    throw new CloudRuntimeException("Scheme is not supported " + url);
-                }
-            } else {
-                throw new CloudRuntimeException("Unable to download from URL: " + url);
-            }
-            DownloadJob dj = new DownloadJob(td, jobId, id, name, format, hvm, accountId, descr, cksum, installPathPrefix, resourceType);
-            jobs.put(jobId, dj);
-            threadPool.execute(td);
-
-            return jobId;
-        } catch (IOException e) {
-            s_logger.warn("Unable to download to " + tmpDir, e);
-            return null;
-        }
-    }
-
-    @Override
-    public String getDownloadError(String jobId) {
-        DownloadJob dj = jobs.get(jobId);
-        if (dj != null) {
-            return dj.getTemplateDownloader().getDownloadError();
-        }
-        return null;
-    }
-
-    public long getDownloadTemplateSize(String jobId) {
-        DownloadJob dj = jobs.get(jobId);
-        if (dj != null) {
-            return dj.getTemplatesize();
-        }
-        return 0;
-    }
-
-    public String getDownloadCheckSum(String jobId) {
-        DownloadJob dj = jobs.get(jobId);
-        if (dj != null) {
-            return dj.getChecksum();
-        }
-        return null;
-    }
-
-    public long getDownloadTemplatePhysicalSize(String jobId) {
-        DownloadJob dj = jobs.get(jobId);
-        if (dj != null) {
-            return dj.getTemplatePhysicalSize();
-        }
-        return 0;
-    }
-
-    // @Override
-    public String getDownloadLocalPath(String jobId) {
-        DownloadJob dj = jobs.get(jobId);
-        if (dj != null) {
-            return dj.getTemplateDownloader().getDownloadLocalPath();
-        }
-        return null;
-    }
-
-    @Override
-    public int getDownloadPct(String jobId) {
-        DownloadJob dj = jobs.get(jobId);
-        if (dj != null) {
-            return dj.getTemplateDownloader().getDownloadPercent();
-        }
-        return 0;
-    }
-
-    public static VMTemplateHostVO.Status convertStatus(Status tds) {
-        switch (tds) {
-        case ABORTED:
-            return VMTemplateHostVO.Status.NOT_DOWNLOADED;
-        case DOWNLOAD_FINISHED:
-            return VMTemplateHostVO.Status.DOWNLOAD_IN_PROGRESS;
-        case IN_PROGRESS:
-            return VMTemplateHostVO.Status.DOWNLOAD_IN_PROGRESS;
-        case NOT_STARTED:
-            return VMTemplateHostVO.Status.NOT_DOWNLOADED;
-        case RECOVERABLE_ERROR:
-            return VMTemplateHostVO.Status.NOT_DOWNLOADED;
-        case UNKNOWN:
-            return VMTemplateHostVO.Status.UNKNOWN;
-        case UNRECOVERABLE_ERROR:
-            return VMTemplateHostVO.Status.DOWNLOAD_ERROR;
-        case POST_DOWNLOAD_FINISHED:
-            return VMTemplateHostVO.Status.DOWNLOADED;
-        default:
-            return VMTemplateHostVO.Status.UNKNOWN;
-        }
-    }
-
-    @Override
-    public com.cloud.storage.VMTemplateHostVO.Status getDownloadStatus2(String jobId) {
-        return convertStatus(getDownloadStatus(jobId));
-    }
-
-    @Override
-    public DownloadAnswer handleDownloadCommand(SecondaryStorageResource resource, DownloadCommand cmd) {
-        ResourceType resourceType = cmd.getResourceType();
-        if (cmd instanceof DownloadProgressCommand) {
-            return handleDownloadProgressCmd( resource, (DownloadProgressCommand) cmd);
-        }
-
-        if (cmd.getUrl() == null) {
-            return new DownloadAnswer(resourceType.toString() + " is corrupted on storage due to an invalid url , cannot download", VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR);
-        }
-
-        if (cmd.getName() == null) {
-            return new DownloadAnswer("Invalid Name", VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR);
-        }
-
-        String installPathPrefix = null;
-        if (ResourceType.TEMPLATE == resourceType){
-            installPathPrefix = resource.getRootDir(cmd) + File.separator + _templateDir;
-        }else {
-            installPathPrefix = resource.getRootDir(cmd) + File.separator + _volumeDir;
-        }
-
-        String user = null;
-        String password = null;
-        if (cmd.getAuth() != null) {
-            user = cmd.getAuth().getUserName();
-            password = new String(cmd.getAuth().getPassword());
-        }
-        //TO DO - Define Volume max size as well
-        long maxDownloadSizeInBytes = (cmd.getMaxDownloadSizeInBytes() == null) ? TemplateDownloader.DEFAULT_MAX_TEMPLATE_SIZE_IN_BYTES : (cmd.getMaxDownloadSizeInBytes());
-        String jobId = downloadPublicTemplate(cmd.getId(), cmd.getUrl(), cmd.getName(), cmd.getFormat(), cmd.isHvm(), cmd.getAccountId(), cmd.getDescription(), cmd.getChecksum(), installPathPrefix, user, password, maxDownloadSizeInBytes, cmd.getProxy(), resourceType);
-        sleep();
-        if (jobId == null) {
-            return new DownloadAnswer("Internal Error", VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR);
-        }
-        return new DownloadAnswer(jobId, getDownloadPct(jobId), getDownloadError(jobId), getDownloadStatus2(jobId), getDownloadLocalPath(jobId), getInstallPath(jobId),
-                getDownloadTemplateSize(jobId), getDownloadTemplateSize(jobId), getDownloadCheckSum(jobId));
-    }
-
-    private void sleep() {
-        try {
-            Thread.sleep(3000);
-        } catch (InterruptedException e) {
-            // ignore
-        }
-    }
-
-    private DownloadAnswer handleDownloadProgressCmd(SecondaryStorageResource resource, DownloadProgressCommand cmd) {
-        String jobId = cmd.getJobId();
-        DownloadAnswer answer;
-        DownloadJob dj = null;
-        if (jobId != null) {
-            dj = jobs.get(jobId);
-        }
-        if (dj == null) {
-            if (cmd.getRequest() == RequestType.GET_OR_RESTART) {
-                DownloadCommand dcmd = new DownloadCommand(cmd);
-                return handleDownloadCommand(resource, dcmd);
-            } else {
-                return new DownloadAnswer("Cannot find job", VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR.UNKNOWN);
-            }
-        }
-        TemplateDownloader td = dj.getTemplateDownloader();
-        switch (cmd.getRequest()) {
-        case GET_STATUS:
-            break;
-        case ABORT:
-            td.stopDownload();
-            sleep();
-            break;
-        case RESTART:
-            td.stopDownload();
-            sleep();
-            threadPool.execute(td);
-            break;
-        case PURGE:
-            td.stopDownload();
-            answer = new DownloadAnswer(jobId, getDownloadPct(jobId), getDownloadError(jobId), getDownloadStatus2(jobId), getDownloadLocalPath(jobId),
-                    getInstallPath(jobId), getDownloadTemplateSize(jobId), getDownloadTemplatePhysicalSize(jobId), getDownloadCheckSum(jobId));
-            jobs.remove(jobId);
-            return answer;
-        default:
-            break; // TODO
-        }
-        return new DownloadAnswer(jobId, getDownloadPct(jobId), getDownloadError(jobId), getDownloadStatus2(jobId), getDownloadLocalPath(jobId),
-                getInstallPath(jobId), getDownloadTemplateSize(jobId), getDownloadTemplatePhysicalSize(jobId), getDownloadCheckSum(jobId));
-    }
-
-    private String getInstallPath(String jobId) {
-        DownloadJob dj = jobs.get(jobId);
-        if (dj != null) {
-            return dj.getTmpltPath();
-        }
-        return null;
-    }
-
-    private String createTempDir(File rootDir, String name) throws IOException {
-
-        File f = File.createTempFile(name, "", rootDir);
-        f.delete();
-        f.mkdir();
-        _storage.setWorldReadableAndWriteable(f);
-        return f.getAbsolutePath();
-
-    }
-
-
-    private List<String> listVolumes(String rootdir) {
-        List<String> result = new ArrayList<String>();
-
-        Script script = new Script(listVolScr, s_logger);
-        script.add("-r", rootdir);
-        ZfsPathParser zpp = new ZfsPathParser(rootdir);
-        script.execute(zpp);
-        result.addAll(zpp.getPaths());
-        s_logger.info("found " + zpp.getPaths().size() + " volumes" + zpp.getPaths());
-        return result;
-    }
-
-
-
-    private List<String> listTemplates(String rootdir) {
-        List<String> result = new ArrayList<String>();
-
-        Script script = new Script(listTmpltScr, s_logger);
-        script.add("-r", rootdir);
-        ZfsPathParser zpp = new ZfsPathParser(rootdir);
-        script.execute(zpp);
-        result.addAll(zpp.getPaths());
-        s_logger.info("found " + zpp.getPaths().size() + " templates" + zpp.getPaths());
-        return result;
-    }
-
-    @Override
-    public Map<String, TemplateInfo> gatherTemplateInfo(String rootDir) {
-        Map<String, TemplateInfo> result = new HashMap<String, TemplateInfo>();
-        String templateDir = rootDir + File.separator + _templateDir;
-
-        if (! _storage.exists(templateDir)) {
-            _storage.mkdirs(templateDir);
-        }
-
-        List<String> publicTmplts = listTemplates(templateDir);
-        for (String tmplt : publicTmplts) {
-            String path = tmplt.substring(0, tmplt.lastIndexOf(File.separator));
-            TemplateLocation loc = new TemplateLocation(_storage, path);
-            try {
-                if (!loc.load()) {
-                    s_logger.warn("Post download installation was not completed for " + path);
-                    //loc.purge();
-                    _storage.cleanup(path, templateDir);
-                    continue;
-                }
-            } catch (IOException e) {
-                s_logger.warn("Unable to load template location " + path, e);
-                continue;
-            }
-
-            TemplateInfo tInfo = loc.getTemplateInfo();
-
-            if ((tInfo.size == tInfo.physicalSize) && (tInfo.installPath.endsWith(ImageFormat.OVA.getFileExtension()))) {
-                try {
-                    Processor processor = _processors.get("VMDK Processor");
-                    VmdkProcessor vmdkProcessor = (VmdkProcessor)processor;
-                    long vSize = vmdkProcessor.getTemplateVirtualSize(path, tInfo.installPath.substring(tInfo.installPath.lastIndexOf(File.separator) + 1));
-                    tInfo.size = vSize;
-                    loc.updateVirtualSize(vSize);
-                    loc.save();
-                } catch (Exception e) {
-                    s_logger.error("Unable to get the virtual size of the template: " + tInfo.installPath + " due to " + e.getMessage());
-                }
-            }
-
-            result.put(tInfo.templateName, tInfo);
-            s_logger.debug("Added template name: " + tInfo.templateName + ", path: " + tmplt);
-        }
-        /*
-        for (String tmplt : isoTmplts) {
-            String tmp[];
-            tmp = tmplt.split("/");
-            String tmpltName = tmp[tmp.length - 2];
-            tmplt = tmplt.substring(tmplt.lastIndexOf("iso/"));
-            TemplateInfo tInfo = new TemplateInfo(tmpltName, tmplt, false);
-            s_logger.debug("Added iso template name: " + tmpltName + ", path: " + tmplt);
-            result.put(tmpltName, tInfo);
-        }
-         */
-        return result;
-    }
-
-    @Override
-    public Map<Long, TemplateInfo> gatherVolumeInfo(String rootDir) {	
-        Map<Long, TemplateInfo> result = new HashMap<Long, TemplateInfo>();
-        String volumeDir = rootDir + File.separator + _volumeDir;
-
-        if (! _storage.exists(volumeDir)) {
-            _storage.mkdirs(volumeDir);
-        }
-
-        List<String> vols = listVolumes(volumeDir);
-        for (String vol : vols) {
-            String path = vol.substring(0, vol.lastIndexOf(File.separator));
-            TemplateLocation loc = new TemplateLocation(_storage, path);
-            try {
-                if (!loc.load()) {
-                    s_logger.warn("Post download installation was not completed for " + path);
-                    //loc.purge();
-                    _storage.cleanup(path, volumeDir);
-                    continue;
-                }
-            } catch (IOException e) {
-                s_logger.warn("Unable to load volume location " + path, e);
-                continue;
-            }
-
-            TemplateInfo vInfo = loc.getTemplateInfo();
-
-            if ((vInfo.size == vInfo.physicalSize) && (vInfo.installPath.endsWith(ImageFormat.OVA.getFileExtension()))) {
-                try {
-                    Processor processor = _processors.get("VMDK Processor");
-                    VmdkProcessor vmdkProcessor = (VmdkProcessor)processor;
-                    long vSize = vmdkProcessor.getTemplateVirtualSize(path, vInfo.installPath.substring(vInfo.installPath.lastIndexOf(File.separator) + 1));
-                    vInfo.size = vSize;
-                    loc.updateVirtualSize(vSize);
-                    loc.save();
-                } catch (Exception e) {
-                    s_logger.error("Unable to get the virtual size of the volume: " + vInfo.installPath + " due to " + e.getMessage());
-                }
-            }
-
-            result.put(vInfo.getId(), vInfo);
-            s_logger.debug("Added volume name: " + vInfo.templateName + ", path: " + vol);
-        }
-        return result;
-    }
-
-    private int deleteDownloadDirectories(File downloadPath, int deleted) {
-        try {
-            if (downloadPath.exists()) {
-                File[] files = downloadPath.listFiles();
-                for (int i = 0; i < files.length; i++) {
-                    if (files[i].isDirectory()) {
-                        deleteDownloadDirectories(files[i], deleted);
-                        files[i].delete();
-                        deleted++;
-                    } else {
-                        files[i].delete();
-                        deleted++;
-                    }
-                }
-            }
-        } catch (Exception ex) {
-            s_logger.info("Failed to clean up template downloads directory " + ex.toString());
-        }
-        return deleted;
-    }
-
-    public static class ZfsPathParser extends OutputInterpreter {
-        String _parent;
-        List<String> paths = new ArrayList<String>();
-
-        public ZfsPathParser(String parent) {
-            _parent = parent;
-        }
-
-        @Override
-        public String interpret(BufferedReader reader) throws IOException {
-            String line = null;
-            while ((line = reader.readLine()) != null) {
-                paths.add(line);
-            }
-            return null;
-        }
-
-        public List<String> getPaths() {
-            return paths;
-        }
-
-        @Override
-        public boolean drain() {
-            return true;
-        }
-    }
-
-    public DownloadManagerImpl() {
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-        _name = name;
-
-        String value = null;
-
-        _storage = (StorageLayer)params.get(StorageLayer.InstanceConfigKey);
-        if (_storage == null) {
-            value = (String) params.get(StorageLayer.ClassConfigKey);
-            if (value == null) {
-                throw new ConfigurationException("Unable to find the storage layer");
-            }
-
-            Class<StorageLayer> clazz;
-            try {
-                clazz = (Class<StorageLayer>) Class.forName(value);
-                _storage = clazz.newInstance();
-            } catch (ClassNotFoundException e) {
-                throw new ConfigurationException("Unable to instantiate " + value);
-            } catch (InstantiationException e) {
-                throw new ConfigurationException("Unable to instantiate " + value);
-            } catch (IllegalAccessException e) {
-                throw new ConfigurationException("Unable to instantiate " + value);
-            }
-        }
-        String useSsl = (String)params.get("sslcopy");
-        if (useSsl != null) {
-            _sslCopy = Boolean.parseBoolean(useSsl);
-
-        }
-        String inSystemVM = (String)params.get("secondary.storage.vm");
-        if (inSystemVM != null && "true".equalsIgnoreCase(inSystemVM)) {
-            s_logger.info("DownloadManager: starting additional services since we are inside system vm");
-            startAdditionalServices();
-            blockOutgoingOnPrivate();
-        }
-
-        value = (String) params.get("install.timeout.pergig");
-        this.installTimeoutPerGig = NumbersUtil.parseInt(value, 15 * 60) * 1000;
-
-        value = (String) params.get("install.numthreads");
-        final int numInstallThreads = NumbersUtil.parseInt(value, 10);
-
-        String scriptsDir = (String) params.get("template.scripts.dir");
-        if (scriptsDir == null) {
-            scriptsDir = "scripts/storage/secondary";
-        }
-
-        listTmpltScr = Script.findScript(scriptsDir, "listvmtmplt.sh");
-        if (listTmpltScr == null) {
-            throw new ConfigurationException("Unable to find the listvmtmplt.sh");
-        }
-        s_logger.info("listvmtmplt.sh found in " + listTmpltScr);
-
-        createTmpltScr = Script.findScript(scriptsDir, "createtmplt.sh");
-        if (createTmpltScr == null) {
-            throw new ConfigurationException("Unable to find createtmplt.sh");
-        }
-        s_logger.info("createtmplt.sh found in " + createTmpltScr);
-
-        listVolScr = Script.findScript(scriptsDir, "listvolume.sh");
-        if (listVolScr == null) {
-            throw new ConfigurationException("Unable to find the listvolume.sh");
-        }
-        s_logger.info("listvolume.sh found in " + listVolScr);
-
-        createVolScr = Script.findScript(scriptsDir, "createvolume.sh");
-        if (createVolScr == null) {
-            throw new ConfigurationException("Unable to find createvolume.sh");
-        }
-        s_logger.info("createvolume.sh found in " + createVolScr);
-
-        _processors = new HashMap<String, Processor>();
-
-        Processor processor = new VhdProcessor();
-        processor.configure("VHD Processor", params);
-        _processors.put("VHD Processor", processor);
-
-        processor = new IsoProcessor();
-        processor.configure("ISO Processor", params);
-        _processors.put("ISO Processor", processor);
-
-        processor = new QCOW2Processor();
-        processor.configure("QCOW2 Processor", params);
-        _processors.put("QCOW2 Processor", processor);
-
-        processor = new VmdkProcessor();
-        processor.configure("VMDK Processor", params);
-        _processors.put("VMDK Processor", processor);
-
-        processor = new RawImageProcessor();
-        processor.configure("Raw Image Processor", params);
-        _processors.put("Raw Image Processor", processor);
-
-        _templateDir = (String) params.get("public.templates.root.dir");
-        if (_templateDir == null) {
-            _templateDir = TemplateConstants.DEFAULT_TMPLT_ROOT_DIR;
-        }
-        _templateDir += File.separator + TemplateConstants.DEFAULT_TMPLT_FIRST_LEVEL_DIR;
-        _volumeDir = TemplateConstants.DEFAULT_VOLUME_ROOT_DIR + File.separator;
-        // Add more processors here.
-        threadPool = Executors.newFixedThreadPool(numInstallThreads);
-        return true;
-    }
-
-    private void blockOutgoingOnPrivate() {
-        Script command = new Script("/bin/bash", s_logger);
-        String intf = "eth1";
-        command.add("-c");
-        command.add("iptables -A OUTPUT -o " + intf + " -p tcp -m state --state NEW -m tcp --dport " + "80" + " -j REJECT;" +
-                "iptables -A OUTPUT -o " + intf + " -p tcp -m state --state NEW -m tcp --dport " + "443" + " -j REJECT;");
-
-        String result = command.execute();
-        if (result != null) {
-            s_logger.warn("Error in blocking outgoing to port 80/443 err=" + result );
-            return;
-        }
-    }
-
-    @Override
-    public String getName() {
-        return _name;
-    }
-
-    @Override
-    public boolean start() {
-        return true;
-    }
-
-    @Override
-    public boolean stop() {
-        return true;
-    }
-
-    private void startAdditionalServices() {
-
-        Script command = new Script("/bin/bash", s_logger);
-        command.add("-c");
-        command.add("if [ -d /etc/apache2 ] ; then service apache2 stop; else service httpd stop; fi ");
-        String result = command.execute();
-        if (result != null) {
-            s_logger.warn("Error in stopping httpd service err=" + result );
-        }
-        String port = Integer.toString(TemplateConstants.DEFAULT_TMPLT_COPY_PORT);
-        String intf = TemplateConstants.DEFAULT_TMPLT_COPY_INTF;
-
-        command = new Script("/bin/bash", s_logger);
-        command.add("-c");
-        command.add("iptables -I INPUT -i " + intf + " -p tcp -m state --state NEW -m tcp --dport " + port + " -j ACCEPT;" +
-                "iptables -I INPUT -i " + intf + " -p tcp -m state --state NEW -m tcp --dport " + "443" + " -j ACCEPT;");
-
-        result = command.execute();
-        if (result != null) {
-            s_logger.warn("Error in opening up httpd port err=" + result );
-            return;
-        }
-
-        command = new Script("/bin/bash", s_logger);
-        command.add("-c");
-        command.add("if [ -d /etc/apache2 ] ; then service apache2 start; else service httpd start; fi ");
-        result = command.execute();
-        if (result != null) {
-            s_logger.warn("Error in starting httpd service err=" + result );
-            return;
-        }
-        command = new Script("mkdir", s_logger);
-        command.add("-p");
-        command.add("/var/www/html/copy/template");
-        result = command.execute();
-        if (result != null) {
-            s_logger.warn("Error in creating directory =" + result );
-            return;
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/core/src/com/cloud/storage/template/UploadManager.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/storage/template/UploadManager.java b/core/src/com/cloud/storage/template/UploadManager.java
deleted file mode 100755
index fa40b8c..0000000
--- a/core/src/com/cloud/storage/template/UploadManager.java
+++ /dev/null
@@ -1,85 +0,0 @@
-// 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.storage.template;
-
-import com.cloud.agent.api.storage.CreateEntityDownloadURLAnswer;
-import com.cloud.agent.api.storage.CreateEntityDownloadURLCommand;
-import com.cloud.agent.api.storage.DeleteEntityDownloadURLAnswer;
-import com.cloud.agent.api.storage.DeleteEntityDownloadURLCommand;
-import com.cloud.agent.api.storage.UploadAnswer;
-import com.cloud.agent.api.storage.UploadCommand;
-import com.cloud.storage.Storage.ImageFormat;
-import com.cloud.storage.Upload.Status;
-import com.cloud.storage.resource.SecondaryStorageResource;
-import com.cloud.utils.component.Manager;
-
-public interface UploadManager extends Manager {
-
-
-	/**
-	 * @param jobId job Id
-	 * @return status of the upload job
-	 */
-	public TemplateUploader.Status getUploadStatus(String jobId);
-	
-	/**
-	 * @param jobId job Id
-	 * @return status of the upload job
-	 */
-	public Status getUploadStatus2(String jobId);
-
-	/**
-	 * Get the upload percent of a upload job
-	 * @param jobId job Id
-	 * @return
-	 */
-	public int getUploadPct(String jobId);
-
-	/**
-	 * Get the upload error if any
-	 * @param jobId job Id
-	 * @return
-	 */
-	public String getUploadError(String jobId);
-
-	/**
-	 * Get the local path for the upload
-	 * @param jobId job Id
-	 * @return
-	public String getUploadLocalPath(String jobId);
-     */
-	
-	/** Handle upload commands from the management server
-	 * @param cmd cmd from server
-	 * @return answer representing status of upload.
-	 */
-	public UploadAnswer handleUploadCommand(SecondaryStorageResource resource, UploadCommand cmd);		
-    
-    public String getPublicTemplateRepo();
-
-
-	String uploadPublicTemplate(long id, String url, String name,
-			ImageFormat format, Long accountId, String descr,
-			String cksum, String installPathPrefix, String user,
-			String password, long maxTemplateSizeInBytes);
-	
-
-    CreateEntityDownloadURLAnswer handleCreateEntityURLCommand(CreateEntityDownloadURLCommand cmd);
-    
-    DeleteEntityDownloadURLAnswer handleDeleteEntityDownloadURLCommand(DeleteEntityDownloadURLCommand cmd);
-	
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/core/src/com/cloud/storage/template/UploadManagerImpl.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/storage/template/UploadManagerImpl.java b/core/src/com/cloud/storage/template/UploadManagerImpl.java
deleted file mode 100755
index 2492a1b..0000000
--- a/core/src/com/cloud/storage/template/UploadManagerImpl.java
+++ /dev/null
@@ -1,645 +0,0 @@
-// 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.storage.template;
-
-import java.io.File;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-
-import javax.naming.ConfigurationException;
-
-import org.apache.log4j.Logger;
-
-import com.cloud.agent.api.storage.CreateEntityDownloadURLAnswer;
-import com.cloud.agent.api.storage.CreateEntityDownloadURLCommand;
-import com.cloud.agent.api.storage.DeleteEntityDownloadURLAnswer;
-import com.cloud.agent.api.storage.DeleteEntityDownloadURLCommand;
-import com.cloud.agent.api.storage.UploadAnswer;
-import com.cloud.agent.api.storage.UploadCommand;
-import com.cloud.agent.api.storage.UploadProgressCommand;
-import com.cloud.storage.Storage.ImageFormat;
-import com.cloud.storage.StorageLayer;
-import com.cloud.storage.Upload;
-import com.cloud.storage.UploadVO;
-import com.cloud.storage.resource.SecondaryStorageResource;
-import com.cloud.storage.template.TemplateUploader.Status;
-import com.cloud.storage.template.TemplateUploader.UploadCompleteCallback;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.script.Script;
-
-public class UploadManagerImpl extends ManagerBase implements UploadManager {
-
-
-    public class Completion implements UploadCompleteCallback {
-        private final String jobId;
-
-        public Completion(String jobId) {
-            this.jobId = jobId;
-        }
-
-        @Override
-        public void uploadComplete(Status status) {
-            setUploadStatus(jobId, status);
-        }
-    }
-
-    private static class UploadJob {
-        private final TemplateUploader tu;
-        private final String jobId;
-        private final String name;
-        private final ImageFormat format;
-        private String tmpltPath;
-        private String description;
-        private String checksum;
-        private Long accountId;
-        private String installPathPrefix;
-        private long templatesize;
-        private long id;
-
-        public UploadJob(TemplateUploader tu, String jobId, long id, String name, ImageFormat format, boolean hvm, Long accountId, String descr, String cksum, String installPathPrefix) {
-            super();
-            this.tu = tu;
-            this.jobId = jobId;
-            this.name = name;
-            this.format = format;
-            this.accountId = accountId;
-            this.description = descr;
-            this.checksum = cksum;
-            this.installPathPrefix = installPathPrefix;
-            this.templatesize = 0;
-            this.id = id;
-        }
-
-        public TemplateUploader getTd() {
-            return tu;
-        }
-
-        public String getDescription() {
-            return description;
-        }
-
-        public String getChecksum() {
-            return checksum;
-        }
-
-        public UploadJob(TemplateUploader td, String jobId, UploadCommand cmd) {
-            this.tu = td;
-            this.jobId = jobId;
-            this.name = cmd.getName();
-            this.format = cmd.getFormat();           
-        }
-
-        public TemplateUploader getTemplateUploader() {
-            return tu;
-        }
-
-        public String getJobId() {
-            return jobId;
-        }
-
-        public String getTmpltName() {
-            return name;
-        }
-
-        public ImageFormat getFormat() {
-            return format;
-        }
-
-        public Long getAccountId() {
-            return accountId;
-        }
-
-        public long getId() {
-            return id;
-        }
-
-        public void setTmpltPath(String tmpltPath) {
-            this.tmpltPath = tmpltPath;
-        }
-
-        public String getTmpltPath() {
-            return tmpltPath;
-        }
-
-        public String getInstallPathPrefix() {
-            return installPathPrefix;
-        }
-
-        public void cleanup() {
-            if (tu != null) {
-                String upldPath = tu.getUploadLocalPath();
-                if (upldPath != null) {
-                    File f = new File(upldPath);
-                    f.delete();
-                }
-            }
-        }
-
-        public void setTemplatesize(long templatesize) {
-            this.templatesize = templatesize;
-        }
-
-        public long getTemplatesize() {
-            return templatesize;
-        }
-    }
-    public static final Logger s_logger = Logger.getLogger(UploadManagerImpl.class);
-    private ExecutorService threadPool;
-    private final Map<String, UploadJob> jobs = new ConcurrentHashMap<String, UploadJob>();
-    private String parentDir;
-    private List<Processor> _processors;
-    private String publicTemplateRepo;
-    private final String extractMountPoint = "/mnt/SecStorage/extractmnt";
-    private StorageLayer _storage;
-    private int installTimeoutPerGig;
-    private boolean _sslCopy;
-    private boolean hvm;
-
-
-    @Override
-    public String uploadPublicTemplate(long id, String url, String name,
-            ImageFormat format, Long accountId, String descr,
-            String cksum, String installPathPrefix, String userName,
-            String passwd, long templateSizeInBytes) {		
-
-        UUID uuid = UUID.randomUUID();
-        String jobId = uuid.toString();
-
-        String completePath = parentDir + File.separator + installPathPrefix;
-        s_logger.debug("Starting upload from " + completePath);
-
-        URI uri;
-        try {
-            uri = new URI(url);
-        } catch (URISyntaxException e) {
-            s_logger.error("URI is incorrect: " + url);
-            throw new CloudRuntimeException("URI is incorrect: " + url);
-        }
-        TemplateUploader tu;
-        if ((uri != null) && (uri.getScheme() != null)) {
-            if (uri.getScheme().equalsIgnoreCase("ftp")) {
-                tu = new FtpTemplateUploader(completePath, url, new Completion(jobId), templateSizeInBytes);                                
-            } else {
-                s_logger.error("Scheme is not supported " + url);
-                throw new CloudRuntimeException("Scheme is not supported " + url);
-            }
-        } else {
-            s_logger.error("Unable to download from URL: " + url);
-            throw new CloudRuntimeException("Unable to download from URL: " + url);
-        }
-        UploadJob uj = new UploadJob(tu, jobId, id, name, format, hvm, accountId, descr, cksum, installPathPrefix);
-        jobs.put(jobId, uj);
-        threadPool.execute(tu);
-
-        return jobId;
-
-    }
-
-    @Override
-    public String getUploadError(String jobId) {
-        UploadJob uj = jobs.get(jobId);
-        if (uj != null) {
-            return uj.getTemplateUploader().getUploadError();
-        }
-        return null;
-    }
-
-    @Override
-    public int getUploadPct(String jobId) {
-        UploadJob uj = jobs.get(jobId);
-        if (uj != null) {
-            return uj.getTemplateUploader().getUploadPercent();
-        }
-        return 0;
-    }
-
-    @Override
-    public Status getUploadStatus(String jobId) {
-        UploadJob job = jobs.get(jobId);
-        if (job != null) {
-            TemplateUploader tu = job.getTemplateUploader();
-            if (tu != null) {
-                return tu.getStatus();
-            }
-        }
-        return Status.UNKNOWN;
-    }
-
-    public static UploadVO.Status convertStatus(Status tds) {
-        switch (tds) {
-        case ABORTED:
-            return UploadVO.Status.NOT_UPLOADED;
-        case UPLOAD_FINISHED:
-            return UploadVO.Status.UPLOAD_IN_PROGRESS;
-        case IN_PROGRESS:
-            return UploadVO.Status.UPLOAD_IN_PROGRESS;
-        case NOT_STARTED:
-            return UploadVO.Status.NOT_UPLOADED;
-        case RECOVERABLE_ERROR:
-            return UploadVO.Status.NOT_UPLOADED;
-        case UNKNOWN:
-            return UploadVO.Status.UNKNOWN;
-        case UNRECOVERABLE_ERROR:
-            return UploadVO.Status.UPLOAD_ERROR;
-        case POST_UPLOAD_FINISHED:
-            return UploadVO.Status.UPLOADED;
-        default:
-            return UploadVO.Status.UNKNOWN;
-        }
-    }
-
-    @Override
-    public com.cloud.storage.UploadVO.Status getUploadStatus2(String jobId) {
-        return convertStatus(getUploadStatus(jobId));
-    }
-    @Override
-    public String getPublicTemplateRepo() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    private UploadAnswer handleUploadProgressCmd(UploadProgressCommand cmd) {
-        String jobId = cmd.getJobId();
-        UploadAnswer answer;
-        UploadJob uj = null;
-        if (jobId != null)
-            uj = jobs.get(jobId);
-        if (uj == null) {           
-            return new UploadAnswer(null, 0, "Cannot find job", com.cloud.storage.UploadVO.Status.UNKNOWN, "", "", 0);            
-        }
-        TemplateUploader td = uj.getTemplateUploader();
-        switch (cmd.getRequest()) {
-        case GET_STATUS:
-            break;
-        case ABORT:
-            td.stopUpload();
-            sleep();
-            break;
-            /*case RESTART:
-            td.stopUpload();
-            sleep();
-            threadPool.execute(td);
-            break;*/
-        case PURGE:
-            td.stopUpload();
-            answer = new UploadAnswer(jobId, getUploadPct(jobId), getUploadError(jobId), getUploadStatus2(jobId), getUploadLocalPath(jobId), getInstallPath(jobId), getUploadTemplateSize(jobId));
-            jobs.remove(jobId);
-            return answer;
-        default:
-            break; // TODO
-        }
-        return new UploadAnswer(jobId, getUploadPct(jobId), getUploadError(jobId), getUploadStatus2(jobId), getUploadLocalPath(jobId), getInstallPath(jobId),
-                getUploadTemplateSize(jobId));
-    }	
-
-    @Override
-    public UploadAnswer handleUploadCommand(SecondaryStorageResource resource, UploadCommand cmd) {
-        s_logger.warn("Handling the upload " +cmd.getInstallPath() + " " + cmd.getId());
-        if (cmd instanceof UploadProgressCommand) {
-            return handleUploadProgressCmd((UploadProgressCommand) cmd);
-        }
-
-        String user = null;
-        String password = null;
-        String jobId = uploadPublicTemplate(cmd.getId(), cmd.getUrl(), cmd.getName(), 
-                cmd.getFormat(), cmd.getAccountId(), cmd.getDescription(),
-                cmd.getChecksum(), cmd.getInstallPath(), user, password,
-                cmd.getTemplateSizeInBytes());
-        sleep();
-        if (jobId == null) {
-            return new UploadAnswer(null, 0, "Internal Error", com.cloud.storage.UploadVO.Status.UPLOAD_ERROR, "", "", 0);
-        }
-        return new UploadAnswer(jobId, getUploadPct(jobId), getUploadError(jobId), getUploadStatus2(jobId), getUploadLocalPath(jobId), getInstallPath(jobId),
-                getUploadTemplateSize(jobId));
-    }
-
-    @Override
-    public CreateEntityDownloadURLAnswer handleCreateEntityURLCommand(CreateEntityDownloadURLCommand cmd){       
-
-        boolean isApacheUp = checkAndStartApache();
-        if (!isApacheUp){
-            String errorString = "Error in starting Apache server ";
-            s_logger.error(errorString);
-            return new CreateEntityDownloadURLAnswer(errorString, CreateEntityDownloadURLAnswer.RESULT_FAILURE);
-        }
-        // Create the directory structure so that its visible under apache server root
-        String extractDir = "/var/www/html/userdata/";
-        Script command = new Script("mkdir", s_logger);
-        command.add("-p");
-        command.add(extractDir);
-        String result = command.execute();
-        if (result != null) {
-            String errorString = "Error in creating directory =" + result;
-            s_logger.error(errorString);
-            return new CreateEntityDownloadURLAnswer(errorString, CreateEntityDownloadURLAnswer.RESULT_FAILURE);
-        }
-
-        // Create a random file under the directory for security reasons.
-        String uuid = cmd.getExtractLinkUUID();
-        command = new Script("touch", s_logger);
-        command.add(extractDir + uuid);
-        result = command.execute();
-        if (result != null) {
-            String errorString = "Error in creating file " +uuid+ " ,error: " + result; 
-            s_logger.warn(errorString);
-            return new CreateEntityDownloadURLAnswer(errorString, CreateEntityDownloadURLAnswer.RESULT_FAILURE);
-        }
-
-
-        // Create a symbolic link from the actual directory to the template location. The entity would be directly visible under /var/www/html/userdata/cmd.getInstallPath();
-        command = new Script("/bin/bash", s_logger);
-        command.add("-c");
-        command.add("ln -sf /mnt/SecStorage/" + cmd.getParent() + File.separator + cmd.getInstallPath() + " " + extractDir + uuid);
-        result = command.execute();
-        if (result != null) {
-            String errorString = "Error in linking  err=" + result; 
-            s_logger.error(errorString);
-            return new CreateEntityDownloadURLAnswer(errorString, CreateEntityDownloadURLAnswer.RESULT_FAILURE);
-        }
-
-        return new CreateEntityDownloadURLAnswer("", CreateEntityDownloadURLAnswer.RESULT_SUCCESS);
-
-    }
-
-    @Override
-    public DeleteEntityDownloadURLAnswer handleDeleteEntityDownloadURLCommand(DeleteEntityDownloadURLCommand cmd){
-
-        //Delete the soft link. Example path = volumes/8/74eeb2c6-8ab1-4357-841f-2e9d06d1f360.vhd
-        s_logger.warn("handleDeleteEntityDownloadURLCommand Path:"+cmd.getPath() + " Type:" +cmd.getType().toString());
-        String path = cmd.getPath();
-        Script command = new Script("/bin/bash", s_logger);
-        command.add("-c");
-
-        //We just need to remove the UUID.vhd
-        String extractUrl = cmd.getExtractUrl();
-        command.add("unlink /var/www/html/userdata/" +extractUrl.substring(extractUrl.lastIndexOf(File.separator) + 1));
-        String result = command.execute();
-        if (result != null) {
-            String errorString = "Error in deleting =" + result;
-            s_logger.warn(errorString);
-            return new DeleteEntityDownloadURLAnswer(errorString, CreateEntityDownloadURLAnswer.RESULT_FAILURE);
-        }
-
-        // If its a volume also delete the Hard link since it was created only for the purpose of download.
-        if(cmd.getType() == Upload.Type.VOLUME){
-            command = new Script("/bin/bash", s_logger);
-            command.add("-c");
-            command.add("rm -f /mnt/SecStorage/" + cmd.getParentPath() +File.separator+ path);
-            s_logger.warn(" " +parentDir +File.separator+ path);
-            result = command.execute();
-            if (result != null) {
-                String errorString = "Error in linking  err=" + result;
-                s_logger.warn(errorString);
-                return new DeleteEntityDownloadURLAnswer(errorString, CreateEntityDownloadURLAnswer.RESULT_FAILURE);
-            }
-        }
-
-        return new DeleteEntityDownloadURLAnswer("", CreateEntityDownloadURLAnswer.RESULT_SUCCESS);
-    }
-
-    private String getInstallPath(String jobId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    private String getUploadLocalPath(String jobId) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    private long getUploadTemplateSize(String jobId){
-        UploadJob uj = jobs.get(jobId);
-        if (uj != null) {
-            return uj.getTemplatesize();
-        }
-        return 0;
-    }
-
-    @Override
-    public boolean configure(String name, Map<String, Object> params)
-            throws ConfigurationException {
-
-        String value = null;
-
-        _storage = (StorageLayer) params.get(StorageLayer.InstanceConfigKey);
-        if (_storage == null) {
-            value = (String) params.get(StorageLayer.ClassConfigKey);
-            if (value == null) {
-                throw new ConfigurationException("Unable to find the storage layer");
-            }
-
-            Class<StorageLayer> clazz;
-            try {
-                clazz = (Class<StorageLayer>) Class.forName(value);
-                _storage = clazz.newInstance();
-            } catch (ClassNotFoundException e) {
-                throw new ConfigurationException("Unable to instantiate " + value);
-            } catch (InstantiationException e) {
-                throw new ConfigurationException("Unable to instantiate " + value);
-            } catch (IllegalAccessException e) {
-                throw new ConfigurationException("Unable to instantiate " + value);
-            }
-        }
-        String useSsl = (String)params.get("sslcopy");
-        if (useSsl != null) {
-            _sslCopy = Boolean.parseBoolean(useSsl);
-
-        }
-        String inSystemVM = (String)params.get("secondary.storage.vm");
-        if (inSystemVM != null && "true".equalsIgnoreCase(inSystemVM)) {
-            s_logger.info("UploadManager: starting additional services since we are inside system vm");
-            startAdditionalServices();
-            //blockOutgoingOnPrivate();
-        }
-
-        value = (String) params.get("install.timeout.pergig");
-        this.installTimeoutPerGig = NumbersUtil.parseInt(value, 15 * 60) * 1000;
-
-        value = (String) params.get("install.numthreads");
-        final int numInstallThreads = NumbersUtil.parseInt(value, 10);        
-
-        String scriptsDir = (String) params.get("template.scripts.dir");
-        if (scriptsDir == null) {
-            scriptsDir = "scripts/storage/secondary";
-        }
-
-        // Add more processors here.
-        threadPool = Executors.newFixedThreadPool(numInstallThreads);
-
-        return true;
-    }
-
-    private void startAdditionalServices() {
-
-
-        Script command = new Script("rm", s_logger);
-        command.add("-rf");
-        command.add(extractMountPoint);
-        String result = command.execute();
-        if (result != null) {
-            s_logger.warn("Error in creating file " +extractMountPoint+ " ,error: " + result );
-            return;
-        }
-
-        command = new Script("touch", s_logger);
-        command.add(extractMountPoint);
-        result = command.execute();
-        if (result != null) {
-            s_logger.warn("Error in creating file " +extractMountPoint+ " ,error: " + result );
-            return;
-        }
-
-        command = new Script("/bin/bash", s_logger);
-        command.add("-c");
-        command.add("ln -sf " + parentDir + " " +extractMountPoint);
-        result = command.execute();
-        if (result != null) {
-            s_logger.warn("Error in linking  err=" + result );
-            return;
-        }
-
-    }
-
-    /**
-     * Get notified of change of job status. Executed in context of uploader thread
-     * 
-     * @param jobId
-     *            the id of the job
-     * @param status
-     *            the status of the job
-     */
-    public void setUploadStatus(String jobId, Status status) {
-        UploadJob uj = jobs.get(jobId);
-        if (uj == null) {
-            s_logger.warn("setUploadStatus for jobId: " + jobId + ", status=" + status + " no job found");
-            return;
-        }
-        TemplateUploader tu = uj.getTemplateUploader();
-        s_logger.warn("Upload Completion for jobId: " + jobId + ", status=" + status);
-        s_logger.warn("UploadedBytes=" + tu.getUploadedBytes() + ", error=" + tu.getUploadError() + ", pct=" + tu.getUploadPercent());
-
-        switch (status) {
-        case ABORTED:
-        case NOT_STARTED:
-        case UNRECOVERABLE_ERROR:
-            // Delete the entity only if its a volume. TO DO - find a better way of finding it a volume.
-            if(uj.getTemplateUploader().getUploadLocalPath().indexOf("volume") > -1){
-                uj.cleanup();
-            }
-            break;
-        case UNKNOWN:
-            return;
-        case IN_PROGRESS:
-            s_logger.info("Resuming jobId: " + jobId + ", status=" + status);
-            tu.setResume(true);
-            threadPool.execute(tu);
-            break;
-        case RECOVERABLE_ERROR:
-            threadPool.execute(tu);
-            break;
-        case UPLOAD_FINISHED:
-            tu.setUploadError("Upload success, starting install ");
-            String result = postUpload(jobId);
-            if (result != null) {
-                s_logger.error("Failed post upload script: " + result);
-                tu.setStatus(Status.UNRECOVERABLE_ERROR);
-                tu.setUploadError("Failed post upload script: " + result);
-            } else {
-                s_logger.warn("Upload completed successfully at " + new SimpleDateFormat().format(new Date()));
-                tu.setStatus(Status.POST_UPLOAD_FINISHED);
-                tu.setUploadError("Upload completed successfully at " + new SimpleDateFormat().format(new Date()));
-            }
-            // Delete the entity only if its a volume. TO DO - find a better way of finding it a volume.
-            if(uj.getTemplateUploader().getUploadLocalPath().indexOf("volume") > -1){
-                uj.cleanup();
-            }
-            break;
-        default:
-            break;
-        }
-    }
-
-    private String postUpload(String jobId) {
-        return null;
-    }
-
-    private void sleep() {
-        try {
-            Thread.sleep(3000);
-        } catch (InterruptedException e) {
-            // ignore
-        }
-    }
-
-    private boolean checkAndStartApache() {
-
-        //Check whether the Apache server is running
-        Script command = new Script("/bin/bash", s_logger);
-        command.add("-c");
-        command.add("if [ -d /etc/apache2 ] ; then service apache2 status | grep pid; else service httpd status | grep pid; fi ");
-        String result = command.execute();
-
-        //Apache Server is not running. Try to start it.
-        if (result != null) { 				  	
-
-            /*s_logger.warn("Apache server not running, trying to start it");
-			String port = Integer.toString(TemplateConstants.DEFAULT_TMPLT_COPY_PORT);
-			String intf = TemplateConstants.DEFAULT_TMPLT_COPY_INTF;
-
-			command = new Script("/bin/bash", s_logger);
-			command.add("-c");
-			command.add("iptables -D INPUT -i " + intf + " -p tcp -m state --state NEW -m tcp --dport " + port + " -j DROP;" +
-				        "iptables -D INPUT -i " + intf + " -p tcp -m state --state NEW -m tcp --dport " + port + " -j HTTP;" +
-				        "iptables -D INPUT -i " + intf + " -p tcp -m state --state NEW -m tcp --dport " + "443" + " -j DROP;" +
-				        "iptables -D INPUT -i " + intf + " -p tcp -m state --state NEW -m tcp --dport " + "443" + " -j HTTP;" +
-				        "iptables -F HTTP;" +
-				        "iptables -X HTTP;" +
-				        "iptables -N HTTP;" +
-					    "iptables -I INPUT -i " + intf + " -p tcp -m state --state NEW -m tcp --dport " + port + " -j DROP;" +
-					    "iptables -I INPUT -i " + intf + " -p tcp -m state --state NEW -m tcp --dport " + "443" + " -j DROP;" +
-					    "iptables -I INPUT -i " + intf + " -p tcp -m state --state NEW -m tcp --dport " + port + " -j HTTP;" +
-			            "iptables -I INPUT -i " + intf + " -p tcp -m state --state NEW -m tcp --dport " + "443" + " -j HTTP;");
-
-			result = command.execute();
-			if (result != null) {
-				s_logger.warn("Error in opening up httpd port err=" + result );
-				return false;
-			}*/			
-
-            command = new Script("/bin/bash", s_logger);
-            command.add("-c");
-            command.add("if [ -d /etc/apache2 ] ; then service apache2 start; else service httpd start; fi ");
-            result = command.execute();
-            if (result != null) {
-                s_logger.warn("Error in starting httpd service err=" + result );
-                return false;
-            }
-        }
-
-        return true;
-    }
-}    

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/plugins/hypervisors/simulator/src/com/cloud/resource/AgentStorageResource.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/simulator/src/com/cloud/resource/AgentStorageResource.java b/plugins/hypervisors/simulator/src/com/cloud/resource/AgentStorageResource.java
index 2d81c2a..a012340 100644
--- a/plugins/hypervisors/simulator/src/com/cloud/resource/AgentStorageResource.java
+++ b/plugins/hypervisors/simulator/src/com/cloud/resource/AgentStorageResource.java
@@ -20,6 +20,7 @@ import java.util.Map;
 
 import javax.naming.ConfigurationException;
 
+import org.apache.cloudstack.storage.resource.SecondaryStorageResource;
 import org.apache.log4j.Logger;
 
 import com.cloud.agent.api.Answer;
@@ -35,7 +36,6 @@ import com.cloud.agent.manager.SimulatorManager;
 import com.cloud.agent.manager.SimulatorManager.AgentType;
 import com.cloud.host.Host;
 import com.cloud.host.Host.Type;
-import com.cloud.storage.resource.SecondaryStorageResource;
 import com.cloud.vm.SecondaryStorageVm;
 
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/plugins/hypervisors/vmware/src/com/cloud/storage/resource/PremiumSecondaryStorageResource.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/PremiumSecondaryStorageResource.java b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/PremiumSecondaryStorageResource.java
index 856982a..3966e02 100644
--- a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/PremiumSecondaryStorageResource.java
+++ b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/PremiumSecondaryStorageResource.java
@@ -21,6 +21,8 @@ import java.util.Map;
 
 import javax.naming.ConfigurationException;
 
+import org.apache.cloudstack.storage.resource.NfsSecondaryStorageResource;
+import org.apache.cloudstack.storage.resource.SecondaryStorageResourceHandler;
 import org.apache.log4j.Logger;
 
 import com.cloud.agent.api.Answer;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java
index 566e750..ce42f67 100644
--- a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java
+++ b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java
@@ -18,6 +18,7 @@ package com.cloud.storage.resource;
 
 import java.util.List;
 
+import org.apache.cloudstack.storage.resource.SecondaryStorageResourceHandler;
 import org.apache.log4j.Logger;
 
 import com.cloud.agent.api.Answer;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/scripts/vm/systemvm/injectkeys.sh
----------------------------------------------------------------------
diff --git a/scripts/vm/systemvm/injectkeys.sh b/scripts/vm/systemvm/injectkeys.sh
index e56eb85..49adfb3 100755
--- a/scripts/vm/systemvm/injectkeys.sh
+++ b/scripts/vm/systemvm/injectkeys.sh
@@ -22,6 +22,7 @@
 # $2 = new private key
 
 #set -x
+set -e
 
 TMP=/tmp
 MOUNTPATH=${HOME}/systemvm_mnt
@@ -29,7 +30,7 @@ TMPDIR=${TMP}/cloud/systemvm
 
 
 clean_up() {
-  sudo umount $MOUNTPATH
+  $SUDO umount $MOUNTPATH
 }
 
 inject_into_iso() {
@@ -39,23 +40,23 @@ inject_into_iso() {
   local tmpiso=${TMP}/$1
   mkdir -p $MOUNTPATH
   [ ! -f $isofile ] && echo "$(basename $0): Could not find systemvm iso patch file $isofile" && return 1
-  sudo mount -o loop $isofile $MOUNTPATH 
+  $SUDO mount -o loop $isofile $MOUNTPATH 
   [ $? -ne 0 ] && echo "$(basename $0): Failed to mount original iso $isofile" && clean_up && return 1
   diff -q $MOUNTPATH/authorized_keys $newpubkey &> /dev/null && clean_up && return 0
-  sudo cp -b $isofile $backup
+  $SUDO cp -b $isofile $backup
   [ $? -ne 0 ] && echo "$(basename $0): Failed to backup original iso $isofile" && clean_up && return 1
   rm -rf $TMPDIR
   mkdir -p $TMPDIR
   [ ! -d $TMPDIR  ] && echo "$(basename $0): Could not find/create temporary dir $TMPDIR" && clean_up && return 1
-  sudo cp -fr $MOUNTPATH/* $TMPDIR/
+  $SUDO cp -fr $MOUNTPATH/* $TMPDIR/
   [ $? -ne 0 ] && echo "$(basename $0): Failed to copy from original iso $isofile" && clean_up && return 1
-  sudo cp $newpubkey $TMPDIR/authorized_keys
+  $SUDO cp $newpubkey $TMPDIR/authorized_keys
   [ $? -ne 0 ] && echo "$(basename $0): Failed to copy key $newpubkey from original iso to new iso " && clean_up && return 1
   mkisofs -quiet -r -o $tmpiso $TMPDIR
   [ $? -ne 0 ] && echo "$(basename $0): Failed to create new iso $tmpiso from $TMPDIR" && clean_up && return 1
-  sudo umount $MOUNTPATH
+  $SUDO umount $MOUNTPATH
   [ $? -ne 0 ] && echo "$(basename $0): Failed to unmount old iso from $MOUNTPATH" && return 1
-  sudo cp -f $tmpiso $isofile
+  $SUDO cp -f $tmpiso $isofile
   [ $? -ne 0 ] && echo "$(basename $0): Failed to overwrite old iso $isofile with $tmpiso" && return 1
   rm -rf $TMPDIR
 }
@@ -63,12 +64,17 @@ inject_into_iso() {
 copy_priv_key() {
   local newprivkey=$1
   diff -q $newprivkey $(dirname $0)/id_rsa.cloud && return 0
-  sudo cp -fb $newprivkey $(dirname $0)/id_rsa.cloud
-  sudo chmod 644 $(dirname $0)/id_rsa.cloud
+  $SUDO cp -fb $newprivkey $(dirname $0)/id_rsa.cloud
+  $SUDO chmod 644 $(dirname $0)/id_rsa.cloud
   return $?
 }
 
-sudo mkdir -p $MOUNTPATH
+if [[ `whoami` == cloud* ]]
+then
+   SUDO=$SUDO
+fi
+
+$SUDO mkdir -p $MOUNTPATH
 
 [ $# -ne 3 ] && echo "Usage: $(basename $0)  <new public key file> <new private key file> <systemvm iso path>" && exit 3
 newpubkey=$1

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/server/pom.xml
----------------------------------------------------------------------
diff --git a/server/pom.xml b/server/pom.xml
index a397195..8a6a10c 100644
--- a/server/pom.xml
+++ b/server/pom.xml
@@ -32,6 +32,11 @@
       <version>${project.version}</version>
     </dependency>
     <dependency>
+      <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-secondary-storage</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
       <groupId>javax.servlet</groupId>
       <artifactId>servlet-api</artifactId>
       <version>${cs.servlet.version}</version>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/server/src/com/cloud/storage/secondary/SecondaryStorageDiscoverer.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/secondary/SecondaryStorageDiscoverer.java b/server/src/com/cloud/storage/secondary/SecondaryStorageDiscoverer.java
index 3ca74a3..6e66e0d 100755
--- a/server/src/com/cloud/storage/secondary/SecondaryStorageDiscoverer.java
+++ b/server/src/com/cloud/storage/secondary/SecondaryStorageDiscoverer.java
@@ -30,6 +30,8 @@ import javax.ejb.Local;
 import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
+import org.apache.cloudstack.storage.resource.LocalSecondaryStorageResource;
+import org.apache.cloudstack.storage.resource.NfsSecondaryStorageResource;
 import org.apache.log4j.Logger;
 
 import com.cloud.agent.AgentManager;
@@ -47,8 +49,6 @@ import com.cloud.storage.dao.VMTemplateDao;
 import com.cloud.storage.dao.VMTemplateHostDao;
 import com.cloud.storage.dao.VMTemplateZoneDao;
 import com.cloud.storage.resource.DummySecondaryStorageResource;
-import com.cloud.storage.resource.LocalSecondaryStorageResource;
-import com.cloud.storage.resource.NfsSecondaryStorageResource;
 import com.cloud.utils.component.ComponentContext;
 import com.cloud.utils.net.NfsUtils;
 import com.cloud.utils.script.Script;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/services/pom.xml
----------------------------------------------------------------------
diff --git a/services/pom.xml b/services/pom.xml
index 35ec2e1..54b22bb 100644
--- a/services/pom.xml
+++ b/services/pom.xml
@@ -32,5 +32,6 @@
   </build>
   <modules>
     <module>console-proxy</module>
+    <module>secondary-storage</module>
   </modules>
 </project>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/services/secondary-storage/conf/agent.properties
----------------------------------------------------------------------
diff --git a/services/secondary-storage/conf/agent.properties b/services/secondary-storage/conf/agent.properties
new file mode 100644
index 0000000..4a25cbd
--- /dev/null
+++ b/services/secondary-storage/conf/agent.properties
@@ -0,0 +1,11 @@
+#Storage
+#Sun Mar 24 22:52:35 PDT 2013
+mount.path=/Users/chiradeep/secondary-storage
+eth1ip=192.168.56.1
+name=192.168.56.10
+eth2ip=192.168.56.10
+resource=org.apache.cloudstack.storage.resource.NfsSecondaryStorageResource
+piddir=.
+instance=SecondaryStorage
+developer=true
+secondary.storage.vm=false

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/services/secondary-storage/conf/environment.properties
----------------------------------------------------------------------
diff --git a/services/secondary-storage/conf/environment.properties b/services/secondary-storage/conf/environment.properties
new file mode 100644
index 0000000..269acad
--- /dev/null
+++ b/services/secondary-storage/conf/environment.properties
@@ -0,0 +1,2 @@
+paths.script=../../scripts/storage/secondary/
+paths.pid=.

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/services/secondary-storage/conf/log4j-cloud.xml
----------------------------------------------------------------------
diff --git a/services/secondary-storage/conf/log4j-cloud.xml b/services/secondary-storage/conf/log4j-cloud.xml
new file mode 100644
index 0000000..7d9d22c
--- /dev/null
+++ b/services/secondary-storage/conf/log4j-cloud.xml
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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.
+-->
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
+
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="false">
+
+   <!-- ================================= -->
+   <!-- Preserve messages in a local file -->
+   <!-- ================================= -->
+
+   <!-- A time/date based rolling appender -->
+   <appender name="FILE" class="org.apache.log4j.DailyRollingFileAppender">
+      <param name="File" value="${ss.log.home}systemvm.log"/>
+      <param name="Append" value="true"/>
+      <param name="Threshold" value="DEBUG"/>
+
+      <!-- Rollover at midnight each day -->
+      <param name="DatePattern" value="'.'yyyy-MM-dd"/>
+
+      <layout class="org.apache.log4j.PatternLayout">
+         <param name="ConversionPattern" value="%d %-5p [%c{3}] (%t:%x) %m%n"/>
+      </layout>
+   </appender>
+   
+   <!-- ============================== -->
+   <!-- Append messages to the console -->
+   <!-- ============================== -->
+
+   <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
+      <param name="Target" value="System.out"/>
+      <param name="Threshold" value="WARN"/>
+
+      <layout class="org.apache.log4j.PatternLayout">
+         <param name="ConversionPattern" value="%d{ABSOLUTE} %5p %c{1}:%L - %m%n"/>
+      </layout>
+   </appender>
+
+   <!-- ================ -->
+   <!-- Limit categories -->
+   <!-- ================ -->
+
+   <category name="com.cloud.console.ConsoleCanvas">
+     <priority value="WARN"/>
+   </category>
+   
+   <category name="com.cloud.consoleproxy.ConsoleProxyAjaxImageHandler">
+     <priority value="WARN"/>
+   </category>
+   
+   <category name="com.cloud.consoleproxy.ConsoleProxyViewer">
+     <priority value="WARN"/>
+   </category>
+
+   <category name="com.cloud.consoleproxy">
+     <priority value="INFO"/>
+   </category>
+
+   <category name="com.cloud">
+     <priority value="DEBUG"/>
+   </category>
+   
+   <!-- Limit the org.apache category to INFO as its DEBUG is verbose -->
+   <category name="org.apache">
+      <priority value="DEBUG"/>
+   </category>
+
+   <category name="org">
+      <priority value="INFO"/>
+   </category>
+   
+   <category name="net">
+     <priority value="INFO"/>
+   </category>
+
+   <!-- ======================= -->
+   <!-- Setup the Root category -->
+   <!-- ======================= -->
+
+   <root>
+      <level value="DEBUG"/>
+      <appender-ref ref="CONSOLE"/>
+      <appender-ref ref="FILE"/>
+   </root>
+
+</log4j:configuration>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/services/secondary-storage/pom.xml
----------------------------------------------------------------------
diff --git a/services/secondary-storage/pom.xml b/services/secondary-storage/pom.xml
new file mode 100644
index 0000000..d8dbf1d
--- /dev/null
+++ b/services/secondary-storage/pom.xml
@@ -0,0 +1,113 @@
+<!--
+  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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <artifactId>cloud-secondary-storage</artifactId>
+  <name>Apache CloudStack Secondary Storage Service</name>
+  <parent>
+    <groupId>org.apache.cloudstack</groupId>
+    <artifactId>cloud-services</artifactId>
+    <version>4.2.0-SNAPSHOT</version>
+    <relativePath>../pom.xml</relativePath>
+  </parent>
+  <dependencies>
+    <dependency>
+      <groupId>log4j</groupId>
+      <artifactId>log4j</artifactId>
+      <version>${cs.log4j.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.google.code.gson</groupId>
+      <artifactId>gson</artifactId>
+      <version>${cs.gson.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>commons-codec</groupId>
+      <artifactId>commons-codec</artifactId>
+      <version>${cs.codec.version}</version>
+    </dependency>
+    <!-- required deps for the systemvm -->
+    <dependency>
+      <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-agent</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-patches</artifactId>
+      <version>${project.version}</version>
+      <type>pom</type>
+    </dependency>
+  </dependencies>
+  <build>
+    <defaultGoal>install</defaultGoal>
+    <sourceDirectory>src</sourceDirectory>
+    <plugins>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>exec-maven-plugin</artifactId>
+        <version>1.2.1</version>
+        <executions>
+          <execution>
+            <goals>
+              <goal>java</goal>
+            </goals>
+          </execution>
+        </executions>
+        <configuration>
+          <mainClass>com.cloud.agent.AgentShell</mainClass>
+          <arguments>
+            <argument>zone=1</argument>
+            <argument>pod=1</argument>
+            <argument>host=192.168.56.1</argument>
+          </arguments>
+          <systemProperties>
+            <systemProperty>
+              <key>javax.net.ssl.trustStore</key>
+              <value>certs/realhostip.keystore</value>
+            </systemProperty>
+          </systemProperties>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+  <profiles>
+    <profile>
+      <id>vmware</id>
+      <activation>
+        <property>
+          <name>nonoss</name>
+        </property>
+      </activation>
+        <dependencies>
+            <dependency>
+                <groupId>org.apache.cloudstack</groupId>
+                <artifactId>cloud-plugin-hypervisor-vmware</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.cloudstack</groupId>
+                <artifactId>cloud-vmware-base</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+        </dependencies>
+    </profile>
+  </profiles>
+
+</project>


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

Posted by ch...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
new file mode 100755
index 0000000..6bcf98e
--- /dev/null
+++ b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
@@ -0,0 +1,1882 @@
+// 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 static com.cloud.utils.S3Utils.deleteDirectory;
+import static com.cloud.utils.S3Utils.getDirectory;
+import static com.cloud.utils.S3Utils.putDirectory;
+import static com.cloud.utils.StringUtils.join;
+import static com.cloud.utils.db.GlobalLock.executeWithNoWaitLock;
+import static java.lang.String.format;
+import static java.util.Arrays.asList;
+import static org.apache.commons.lang.StringUtils.substringAfterLast;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileWriter;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.math.BigInteger;
+import java.net.InetAddress;
+import java.net.URI;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.Callable;
+
+import javax.naming.ConfigurationException;
+
+import org.apache.cloudstack.storage.template.DownloadManager;
+import org.apache.cloudstack.storage.template.DownloadManagerImpl;
+import org.apache.cloudstack.storage.template.DownloadManagerImpl.ZfsPathParser;
+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.CleanupSnapshotBackupCommand;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.ComputeChecksumCommand;
+import com.cloud.agent.api.DeleteObjectFromSwiftCommand;
+import com.cloud.agent.api.DeleteSnapshotBackupCommand;
+import com.cloud.agent.api.DeleteSnapshotsDirCommand;
+import com.cloud.agent.api.DeleteTemplateFromS3Command;
+import com.cloud.agent.api.DownloadSnapshotFromS3Command;
+import com.cloud.agent.api.DownloadTemplateFromS3ToSecondaryStorageCommand;
+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.SecStorageSetupAnswer;
+import com.cloud.agent.api.SecStorageSetupCommand;
+import com.cloud.agent.api.SecStorageSetupCommand.Certificates;
+import com.cloud.agent.api.SecStorageVMSetupCommand;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.StartupSecondaryStorageCommand;
+import com.cloud.agent.api.UploadTemplateToS3FromSecondaryStorageCommand;
+import com.cloud.agent.api.downloadSnapshotFromSwiftCommand;
+import com.cloud.agent.api.downloadTemplateFromSwiftToSecondaryStorageCommand;
+import com.cloud.agent.api.uploadTemplateToSwiftFromSecondaryStorageCommand;
+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.DeleteVolumeCommand;
+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.ListVolumeAnswer;
+import com.cloud.agent.api.storage.ListVolumeCommand;
+import com.cloud.agent.api.storage.UploadCommand;
+import com.cloud.agent.api.storage.ssCommand;
+import com.cloud.agent.api.to.S3TO;
+import com.cloud.agent.api.to.SwiftTO;
+import com.cloud.exception.InternalErrorException;
+import com.cloud.host.Host;
+import com.cloud.host.Host.Type;
+import com.cloud.resource.ServerResourceBase;
+import com.cloud.storage.StorageLayer;
+import com.cloud.storage.template.TemplateInfo;
+import com.cloud.storage.template.TemplateLocation;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.S3Utils;
+import com.cloud.utils.S3Utils.FileNamingStrategy;
+import com.cloud.utils.S3Utils.ObjectNamingStrategy;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.utils.script.OutputInterpreter;
+import com.cloud.utils.script.Script;
+import com.cloud.vm.SecondaryStorageVm;
+
+public class NfsSecondaryStorageResource extends ServerResourceBase implements
+SecondaryStorageResource {
+
+    private static final Logger s_logger = Logger
+            .getLogger(NfsSecondaryStorageResource.class);
+
+    private static final String TEMPLATE_ROOT_DIR = "template/tmpl";
+    private static final String SNAPSHOT_ROOT_DIR = "snapshots";
+
+    int _timeout;
+
+    String _instance;  
+    String _dc;
+    String _pod;
+    String _guid;
+    String _role;
+    Map<String, Object> _params;
+    StorageLayer _storage;
+    protected boolean _inSystemVM = false;
+    boolean _sslCopy = false;
+
+    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;
+    private String _storageIp;
+    private String _storageNetmask;
+    private String _storageGateway;
+    private final List<String> nfsIps = new ArrayList<String>();
+    private String _parent = "/mnt/SecStorage";
+    final private String _tmpltDir = "/var/cloudstack/template";
+    final private String _tmpltpp = "template.properties";
+    @Override
+    public void disconnected() {
+    }
+
+    @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 DeleteVolumeCommand) {
+            return execute((DeleteVolumeCommand) 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 execute((SecStorageSetupCommand)cmd);
+        } else if (cmd instanceof ComputeChecksumCommand){
+            return execute((ComputeChecksumCommand)cmd);
+        } else if (cmd instanceof ListTemplateCommand){
+            return execute((ListTemplateCommand)cmd);
+        } else if (cmd instanceof ListVolumeCommand){
+            return execute((ListVolumeCommand)cmd);
+        }else if (cmd instanceof downloadSnapshotFromSwiftCommand){
+            return execute((downloadSnapshotFromSwiftCommand)cmd);
+        } else if (cmd instanceof DownloadSnapshotFromS3Command) {
+            return execute((DownloadSnapshotFromS3Command) cmd);
+        } else if (cmd instanceof DeleteSnapshotBackupCommand){
+            return execute((DeleteSnapshotBackupCommand)cmd);
+        } else if (cmd instanceof DeleteSnapshotsDirCommand){
+            return execute((DeleteSnapshotsDirCommand)cmd);
+        } else if (cmd instanceof downloadTemplateFromSwiftToSecondaryStorageCommand) {
+            return execute((downloadTemplateFromSwiftToSecondaryStorageCommand) cmd);
+        } else if (cmd instanceof DownloadTemplateFromS3ToSecondaryStorageCommand) {
+            return execute((DownloadTemplateFromS3ToSecondaryStorageCommand) cmd);
+        } else if (cmd instanceof uploadTemplateToSwiftFromSecondaryStorageCommand) {
+            return execute((uploadTemplateToSwiftFromSecondaryStorageCommand) cmd);
+        } else if (cmd instanceof UploadTemplateToS3FromSecondaryStorageCommand) {
+            return execute((UploadTemplateToS3FromSecondaryStorageCommand) cmd);
+        } else if (cmd instanceof DeleteObjectFromSwiftCommand) {
+            return execute((DeleteObjectFromSwiftCommand) cmd);
+        } else if (cmd instanceof DeleteTemplateFromS3Command) {
+            return execute((DeleteTemplateFromS3Command) cmd);
+        } else if (cmd instanceof CleanupSnapshotBackupCommand){
+            return execute((CleanupSnapshotBackupCommand)cmd);
+        } else {
+            return Answer.createUnsupportedCommandAnswer(cmd);
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    private String determineS3TemplateDirectory(final Long accountId,
+            final Long templateId) {
+        return join(asList(TEMPLATE_ROOT_DIR, accountId, templateId),
+                S3Utils.SEPARATOR);
+    }
+
+    @SuppressWarnings("unchecked")
+    private String determineStorageTemplatePath(final String storagePath,
+            final Long accountId, final Long templateId) {
+        return join(
+                asList(getRootDir(storagePath), TEMPLATE_ROOT_DIR, accountId,
+                        templateId), File.separator);
+    }
+
+    private Answer execute(
+            final DownloadTemplateFromS3ToSecondaryStorageCommand cmd) {
+
+        final S3TO s3 = cmd.getS3();
+        final String storagePath = cmd.getStoragePath();
+        final Long accountId = cmd.getAccountId();
+        final Long templateId = cmd.getTemplateId();
+
+        try {
+
+            final File downloadDirectory = _storage
+                    .getFile(determineStorageTemplatePath(storagePath,
+                            accountId, templateId));
+            downloadDirectory.mkdirs();
+
+            if (!downloadDirectory.exists()) {
+                final String errMsg = format(
+                        "Unable to create directory "
+                                + "download directory %1$s for download of template id "
+                                + "%2$s from S3.", downloadDirectory.getName(),
+                                templateId);
+                s_logger.error(errMsg);
+                return new Answer(cmd, false, errMsg);
+            }
+
+            getDirectory(s3, s3.getBucketName(),
+                    determineS3TemplateDirectory(accountId, templateId),
+                    downloadDirectory, new FileNamingStrategy() {
+                @Override
+                public String determineFileName(final String key) {
+                    return substringAfterLast(key, S3Utils.SEPARATOR);
+                }
+            });
+
+            return new Answer(cmd, true, format("Successfully downloaded "
+                    + "template id %1$s from S3 to directory %2$s", templateId,
+                    downloadDirectory.getName()));
+
+        } catch (Exception e) {
+
+            final String errMsg = format("Failed to upload template id %1$s "
+                    + "due to $2%s", templateId, e.getMessage());
+            s_logger.error(errMsg, e);
+            return new Answer(cmd, false, errMsg);
+
+        }
+
+    }
+
+    private Answer execute(downloadTemplateFromSwiftToSecondaryStorageCommand cmd) {
+        SwiftTO swift = cmd.getSwift();
+        String secondaryStorageUrl = cmd.getSecondaryStorageUrl();
+        Long accountId = cmd.getAccountId();
+        Long templateId = cmd.getTemplateId();
+        String path = cmd.getPath();
+        String errMsg;
+        String lDir = null;
+        try {
+            String parent = getRootDir(secondaryStorageUrl);
+            lDir = parent + "/template/tmpl/" + accountId.toString() + "/" + templateId.toString();
+            String result = createLocalDir(lDir);
+            if (result != null) {
+                errMsg = "downloadTemplateFromSwiftToSecondaryStorageCommand failed due to Create local directory failed";
+                s_logger.warn(errMsg);
+                throw new InternalErrorException(errMsg);
+            }
+            String lPath = lDir + "/" + path;
+            result = swiftDownload(swift, "T-" + templateId.toString(), path, lPath);
+            if (result != null) {
+                errMsg = "failed to download template " + path + " from Swift to secondary storage " + lPath + " , err=" + result;
+                s_logger.warn(errMsg);
+                throw new CloudRuntimeException(errMsg);
+            }
+            path = "template.properties";
+            lPath = lDir + "/" + path;
+            result = swiftDownload(swift, "T-" + templateId.toString(), path, lPath);
+            if (result != null) {
+                errMsg = "failed to download template " + path + " from Swift to secondary storage " + lPath + " , err=" + result;
+                s_logger.warn(errMsg);
+                throw new CloudRuntimeException(errMsg);
+            }
+            return new Answer(cmd, true, "success");
+        } catch (Exception e) {
+            if (lDir != null) {
+                deleteLocalDir(lDir);
+            }
+            errMsg = cmd + " Command failed due to " + e.toString();
+            s_logger.warn(errMsg, e);
+            return new Answer(cmd, false, errMsg);
+        }
+    }
+
+    private Answer execute(uploadTemplateToSwiftFromSecondaryStorageCommand cmd) {
+        SwiftTO swift = cmd.getSwift();
+        String secondaryStorageUrl = cmd.getSecondaryStorageUrl();
+        Long accountId = cmd.getAccountId();
+        Long templateId = cmd.getTemplateId();
+        try {
+            String parent = getRootDir(secondaryStorageUrl);
+            String lPath = parent + "/template/tmpl/" + accountId.toString() + "/" + templateId.toString();
+            if (!_storage.isFile(lPath + "/template.properties")) {
+                String errMsg = cmd + " Command failed due to template doesn't exist ";
+                s_logger.debug(errMsg);
+                return new Answer(cmd, false, errMsg);
+            }
+            String result = swiftUpload(swift, "T-" + templateId.toString(), lPath, "*");
+            if (result != null) {
+                String errMsg = "failed to upload template from secondary storage " + lPath + " to swift  , err=" + result;
+                s_logger.debug(errMsg);
+                return new Answer(cmd, false, errMsg);
+            }
+            return new Answer(cmd, true, "success");
+        } catch (Exception e) {
+            String errMsg = cmd + " Command failed due to " + e.toString();
+            s_logger.warn(errMsg, e);
+            return new Answer(cmd, false, errMsg);
+        }
+    }
+
+    private Answer execute(UploadTemplateToS3FromSecondaryStorageCommand cmd) {
+
+        final S3TO s3 = cmd.getS3();
+        final Long accountId = cmd.getAccountId();
+        final Long templateId = cmd.getTemplateId();
+
+        try {
+
+            final String templatePath = determineStorageTemplatePath(
+                    cmd.getStoragePath(), accountId, templateId);
+
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Found template id " + templateId
+                        + " account id " + accountId + " from directory "
+                        + templatePath + " to upload to S3.");
+            }
+
+            if (!_storage.isDirectory(templatePath)) {
+                final String errMsg = format("S3 Sync Failure: Directory %1$s"
+                        + "for template id %2$s does not exist.", templatePath,
+                        templateId);
+                s_logger.error(errMsg);
+                return new Answer(cmd, false, errMsg);
+            }
+
+            if (!_storage.isFile(templatePath + "/template.properties")) {
+                final String errMsg = format("S3 Sync Failure: Template id "
+                        + "%1$s does not exist on the file system.",
+                        templatePath);
+                s_logger.error(errMsg);
+                return new Answer(cmd, false, errMsg);
+            }
+
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug(format(
+                        "Pushing template id %1$s from %2$s to S3...",
+                        templateId, templatePath));
+            }
+
+            final String bucket = s3.getBucketName();
+            putDirectory(s3, bucket, _storage.getFile(templatePath),
+                    new FilenameFilter() {
+                @Override
+                public boolean accept(final File directory,
+                        final String fileName) {
+                    File fileToUpload = new File(directory.getAbsolutePath() + "/" + fileName);
+                    return !fileName.startsWith(".") && !fileToUpload.isDirectory();
+                }
+            }, new ObjectNamingStrategy() {
+                @Override
+                public String determineKey(final File file) {
+                    s_logger.debug(String
+                            .format("Determining key using account id %1$s and template id %2$s",
+                                    accountId, templateId));
+                    return join(
+                            asList(determineS3TemplateDirectory(
+                                    accountId, templateId), file
+                                    .getName()), S3Utils.SEPARATOR);
+                }
+            });
+
+            return new Answer(
+                    cmd,
+                    true,
+                    format("Uploaded the contents of directory %1$s for template id %2$s to S3 bucket %3$s",
+                            templatePath, templateId, bucket));
+
+        } catch (Exception e) {
+
+            final String errMsg = format("Failed to upload template id %1$s",
+                    templateId);
+            s_logger.error(errMsg, e);
+            return new Answer(cmd, false, errMsg);
+
+        }
+
+    }
+
+    private Answer execute(DeleteObjectFromSwiftCommand cmd) {
+        SwiftTO swift = cmd.getSwift();
+        String container = cmd.getContainer();
+        String object = cmd.getObject();
+        if (object == null) {
+            object = "";
+        }
+        try {
+            String result = swiftDelete(swift, container, object);
+            if (result != null) {
+                String errMsg = "failed to delete object " + container + "/" + object + " , err=" + result;
+                s_logger.warn(errMsg);
+                return new Answer(cmd, false, errMsg);
+            }
+            return new Answer(cmd, true, "success");
+        } catch (Exception e) {
+            String errMsg = cmd + " Command failed due to " + e.toString();
+            s_logger.warn(errMsg, e);
+            return new Answer(cmd, false, errMsg);
+        }
+
+    }
+
+    private Answer execute(final DeleteTemplateFromS3Command cmd) {
+
+        final S3TO s3 = cmd.getS3();
+        final Long accountId = cmd.getAccountId();
+        final Long templateId = cmd.getTemplateId();
+
+        if (accountId == null || (accountId != null && accountId <= 0)) {
+            final String errorMessage = "No account id specified for S3 template deletion.";
+            s_logger.error(errorMessage);
+            return new Answer(cmd, false, errorMessage);
+        }
+
+        if (templateId == null || (templateId != null && templateId <= 0)) {
+            final String errorMessage = "No template id specified for S3 template deletion.";
+            s_logger.error(errorMessage);
+            return new Answer(cmd, false, errorMessage);
+        }
+
+        if (s3 == null) {
+            final String errorMessge = "No S3 client options provided";
+            s_logger.error(errorMessge);
+            return new Answer(cmd, false, errorMessge);
+        }
+
+        final String bucket = s3.getBucketName();
+        try {
+            deleteDirectory(s3, bucket,
+                    determineS3TemplateDirectory(templateId, accountId));
+            return new Answer(cmd, true, String.format(
+                    "Deleted template %1%s from bucket %2$s.", templateId,
+                    bucket));
+        } catch (Exception e) {
+            final String errorMessage = String
+                    .format("Failed to delete templaet id %1$s from bucket %2$s due to the following error: %3$s",
+                            templateId, bucket, e.getMessage());
+            s_logger.error(errorMessage, e);
+            return new Answer(cmd, false, errorMessage);
+        }
+
+    }
+
+    String swiftDownload(SwiftTO swift, String container, String rfilename, String lFullPath) {
+        Script command = new Script("/bin/bash", s_logger);
+        command.add("-c");
+        command.add("/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A "
+                + swift.getUrl() + " -U " + swift.getAccount() + ":" + swift.getUserName() + " -K " + swift.getKey()
+                + " download " + container + " " + rfilename + " -o " + lFullPath);
+        OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
+        String result = command.execute(parser);
+        if (result != null) {
+            String errMsg = "swiftDownload failed  err=" + result;
+            s_logger.warn(errMsg);
+            return errMsg;
+        }
+        if (parser.getLines() != null) {
+            String[] lines = parser.getLines().split("\\n");
+            for (String line : lines) {
+                if (line.contains("Errno") || line.contains("failed")) {
+                    String errMsg = "swiftDownload failed , err=" + lines.toString();
+                    s_logger.warn(errMsg);
+                    return errMsg;
+                }
+            }
+        }
+        return null;
+
+    }
+
+    String swiftDownloadContainer(SwiftTO swift, String container, String ldir) {
+        Script command = new Script("/bin/bash", s_logger);
+        command.add("-c");
+        command.add("cd " + ldir + ";/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + swift.getAccount() + ":" + swift.getUserName() + " -K "
+                + swift.getKey() + " download " + container);
+        OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
+        String result = command.execute(parser);
+        if (result != null) {
+            String errMsg = "swiftDownloadContainer failed  err=" + result;
+            s_logger.warn(errMsg);
+            return errMsg;
+        }
+        if (parser.getLines() != null) {
+            String[] lines = parser.getLines().split("\\n");
+            for (String line : lines) {
+                if (line.contains("Errno") || line.contains("failed")) {
+                    String errMsg = "swiftDownloadContainer failed , err=" + lines.toString();
+                    s_logger.warn(errMsg);
+                    return errMsg;
+                }
+            }
+        }
+        return null;
+
+    }
+
+    String swiftUpload(SwiftTO swift, String container, String lDir, String lFilename) {
+        long SWIFT_MAX_SIZE = 5L * 1024L * 1024L * 1024L;
+        List<String> files = new ArrayList<String>();
+        if (lFilename.equals("*")) {
+            File dir = new File(lDir);
+            for (String file : dir.list()) {
+                if (file.startsWith(".")) {
+                    continue;
+                }
+                files.add(file);
+            }
+        } else {
+            files.add(lFilename);
+        }
+
+        for (String file : files) {
+            File f = new File(lDir + "/" + file);
+            long size = f.length();
+            Script command = new Script("/bin/bash", s_logger);
+            command.add("-c");
+            if (size <= SWIFT_MAX_SIZE) {
+                command.add("cd " + lDir + ";/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + swift.getAccount() + ":" + swift.getUserName()
+                        + " -K " + swift.getKey() + " upload " + container + " " + file);
+            } else {
+                command.add("cd " + lDir + ";/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + swift.getAccount() + ":" + swift.getUserName()
+                        + " -K " + swift.getKey() + " upload -S " + SWIFT_MAX_SIZE + " " + container + " " + file);
+            }
+            OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
+            String result = command.execute(parser);
+            if (result != null) {
+                String errMsg = "swiftUpload failed , err=" + result;
+                s_logger.warn(errMsg);
+                return errMsg;
+            }
+            if (parser.getLines() != null) {
+                String[] lines = parser.getLines().split("\\n");
+                for (String line : lines) {
+                    if (line.contains("Errno") || line.contains("failed")) {
+                        String errMsg = "swiftUpload failed , err=" + lines.toString();
+                        s_logger.warn(errMsg);
+                        return errMsg;
+                    }
+                }
+            }
+        }
+
+        return null;
+    }
+
+    String[] swiftList(SwiftTO swift, String container, String rFilename) {
+        Script command = new Script("/bin/bash", s_logger);
+        command.add("-c");
+        command.add("/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + swift.getAccount() + ":" + swift.getUserName() + " -K "
+                + swift.getKey() + " list " + container + " " + rFilename);
+        OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
+        String result = command.execute(parser);
+        if (result == null && parser.getLines() != null) {
+            String[] lines = parser.getLines().split("\\n");
+            return lines;
+        } else {
+            if (result != null) {
+                String errMsg = "swiftList failed , err=" + result;
+                s_logger.warn(errMsg);
+            } else {
+                String errMsg = "swiftList failed, no lines returns";
+                s_logger.warn(errMsg);
+            }
+        }
+        return null;
+    }
+
+    String swiftDelete(SwiftTO swift, String container, String object) {
+        Script command = new Script("/bin/bash", s_logger);
+        command.add("-c");
+        command.add("/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A "
+                + swift.getUrl() + " -U " + swift.getAccount() + ":" + swift.getUserName() + " -K " + swift.getKey()
+                + " delete " + container + " " + object);
+        OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
+        String result = command.execute(parser);
+        if (result != null) {
+            String errMsg = "swiftDelete failed , err=" + result;
+            s_logger.warn(errMsg);
+            return errMsg;
+        }
+        if (parser.getLines() != null) {
+            String[] lines = parser.getLines().split("\\n");
+            for (String line : lines) {
+                if (line.contains("Errno") || line.contains("failed")) {
+                    String errMsg = "swiftDelete failed , err=" + lines.toString();
+                    s_logger.warn(errMsg);
+                    return errMsg;
+                }
+            }
+        }
+        return null;
+    }
+
+
+    public Answer execute(DeleteSnapshotsDirCommand cmd){
+        String secondaryStorageUrl = cmd.getSecondaryStorageUrl();
+        Long accountId = cmd.getAccountId();
+        Long volumeId = cmd.getVolumeId();
+        try {
+            String parent = getRootDir(secondaryStorageUrl);
+            String lPath = parent + "/snapshots/" + String.valueOf(accountId) + "/" + String.valueOf(volumeId) + "/*";
+            String result = deleteLocalFile(lPath);
+            if (result != null) {
+                String errMsg = "failed to delete all snapshots " + lPath + " , err=" + result;
+                s_logger.warn(errMsg);
+                return new Answer(cmd, false, errMsg);
+            }
+            return new Answer(cmd, true, "success");
+        } catch (Exception e) {
+            String errMsg = cmd + " Command failed due to " + e.toString();
+            s_logger.warn(errMsg, e);
+            return new Answer(cmd, false, errMsg);
+        }
+    }
+
+    public Answer execute(final DownloadSnapshotFromS3Command cmd) {
+
+        final S3TO s3 = cmd.getS3();
+        final String secondaryStorageUrl = cmd.getSecondaryStorageUrl();
+        final Long accountId = cmd.getAccountId();
+        final Long volumeId = cmd.getVolumeId();
+
+        try {
+
+            executeWithNoWaitLock(determineSnapshotLockId(accountId, volumeId),
+                    new Callable<Void>() {
+
+                @Override
+                public Void call() throws Exception {
+
+                    final String directoryName = determineSnapshotLocalDirectory(
+                            secondaryStorageUrl, accountId, volumeId);
+
+                    String result = createLocalDir(directoryName);
+                    if (result != null) {
+                        throw new InternalErrorException(
+                                format("Failed to create directory %1$s during S3 snapshot download.",
+                                        directoryName));
+                    }
+
+                    final String snapshotFileName = determineSnapshotBackupFilename(cmd
+                            .getSnapshotUuid());
+                    final String key = determineSnapshotS3Key(
+                            accountId, volumeId, snapshotFileName);
+                    final File targetFile = S3Utils.getFile(s3,
+                            s3.getBucketName(), key,
+                            _storage.getFile(directoryName),
+                            new FileNamingStrategy() {
+
+                        @Override
+                        public String determineFileName(
+                                String key) {
+                            return snapshotFileName;
+                        }
+
+                    });
+
+                    if (cmd.getParent() != null) {
+
+                        final String parentPath = join(
+                                File.pathSeparator, directoryName,
+                                determineSnapshotBackupFilename(cmd
+                                        .getParent()));
+                        result = setVhdParent(
+                                targetFile.getAbsolutePath(),
+                                parentPath);
+                        if (result != null) {
+                            throw new InternalErrorException(
+                                    format("Failed to set the parent for backup %1$s to %2$s due to %3$s.",
+                                            targetFile
+                                            .getAbsolutePath(),
+                                            parentPath, result));
+                        }
+
+                    }
+
+                    return null;
+
+                }
+
+            });
+
+            return new Answer(
+                    cmd,
+                    true,
+                    format("Succesfully retrieved volume id %1$s for account id %2$s to %3$s from S3.",
+                            volumeId, accountId, secondaryStorageUrl));
+
+        } catch (Exception e) {
+            final String errMsg = format(
+                    "Failed to retrieve volume id %1$s for account id %2$s to %3$s from S3 due to exception %4$s",
+                    volumeId, accountId, secondaryStorageUrl, e.getMessage());
+            s_logger.error(errMsg);
+            return new Answer(cmd, false, errMsg);
+        }
+
+    }
+
+    private String determineSnapshotS3Directory(final Long accountId,
+            final Long volumeId) {
+        return join(S3Utils.SEPARATOR, SNAPSHOT_ROOT_DIR, accountId, volumeId);
+    }
+
+    private String determineSnapshotS3Key(final Long accountId,
+            final Long volumeId, final String snapshotFileName) {
+
+        final String directoryName = determineSnapshotS3Directory(accountId,
+                volumeId);
+        return join(S3Utils.SEPARATOR, directoryName, snapshotFileName);
+
+    }
+
+    private String determineSnapshotLocalDirectory(
+            final String secondaryStorageUrl, final Long accountId,
+            final Long volumeId) {
+        return join(File.pathSeparator, getRootDir(secondaryStorageUrl),
+                SNAPSHOT_ROOT_DIR, accountId, volumeId);
+    }
+
+    public Answer execute(downloadSnapshotFromSwiftCommand cmd){
+        SwiftTO swift = cmd.getSwift();
+        String secondaryStorageUrl = cmd.getSecondaryStorageUrl();
+        Long accountId = cmd.getAccountId();
+        Long volumeId = cmd.getVolumeId();
+        String rFilename = cmd.getSnapshotUuid();
+        String sParent = cmd.getParent();
+        String errMsg = "";
+        try {
+            String parent = getRootDir(secondaryStorageUrl);
+            String lPath = parent + "/snapshots/" + String.valueOf(accountId) + "/" + String.valueOf(volumeId);
+
+            String result = createLocalDir(lPath);
+            if ( result != null ) {
+                errMsg = "downloadSnapshotFromSwiftCommand failed due to Create local path failed";
+                s_logger.warn(errMsg);
+                throw new InternalErrorException(errMsg);
+            }
+            String lFilename = rFilename;
+            if ( rFilename.startsWith("VHD-") ) {
+                lFilename = rFilename.replace("VHD-", "") + ".vhd";
+            }
+            String lFullPath = lPath + "/" + lFilename;
+            result = swiftDownload(swift, "S-" + volumeId.toString(), rFilename, lFullPath);
+            if (result != null) {
+                return new Answer(cmd, false, result);
+            }
+            if (sParent != null) {
+                if (sParent.startsWith("VHD-") || sParent.endsWith(".vhd")) {
+                    String pFilename = sParent;
+                    if (sParent.startsWith("VHD-")) {
+                        pFilename = pFilename.replace("VHD-", "") + ".vhd";
+                    }
+                    String pFullPath = lPath + "/" + pFilename;
+                    result = setVhdParent(lFullPath, pFullPath);
+                    if (result != null) {
+                        return new Answer(cmd, false, result);
+                    }
+                }
+            }
+
+            return new Answer(cmd, true, "success");
+        } catch (Exception e) {
+            String msg = cmd + " Command failed due to " + e.toString();
+            s_logger.warn(msg, e);
+            throw new CloudRuntimeException(msg);
+        }
+    }
+
+    private Answer execute(ComputeChecksumCommand cmd) {
+
+        String relativeTemplatePath = cmd.getTemplatePath();
+        String parent = getRootDir(cmd);
+
+        if (relativeTemplatePath.startsWith(File.separator)) {
+            relativeTemplatePath = relativeTemplatePath.substring(1);
+        }
+
+        if (!parent.endsWith(File.separator)) {
+            parent += File.separator;
+        }
+        String absoluteTemplatePath = parent + relativeTemplatePath;
+        MessageDigest digest;
+        String checksum = null;
+        File f = new File(absoluteTemplatePath);   
+        InputStream is = null;
+        byte[] buffer = new byte[8192];
+        int read = 0;
+        if(s_logger.isDebugEnabled()){
+            s_logger.debug("parent path " +parent+ " relative template path " +relativeTemplatePath );   
+        }
+
+
+        try {
+            digest = MessageDigest.getInstance("MD5");           
+            is = new FileInputStream(f);     
+            while( (read = is.read(buffer)) > 0) {
+                digest.update(buffer, 0, read);
+            }       
+            byte[] md5sum = digest.digest();
+            BigInteger bigInt = new BigInteger(1, md5sum);
+            checksum = bigInt.toString(16);
+            if(s_logger.isDebugEnabled()){
+                s_logger.debug("Successfully calculated checksum for file " +absoluteTemplatePath+ " - " +checksum );   
+            }
+
+        }catch(IOException e) {
+            String logMsg = "Unable to process file for MD5 - " + absoluteTemplatePath;
+            s_logger.error(logMsg);
+            return new Answer(cmd, false, checksum); 
+        }catch (NoSuchAlgorithmException e) {         
+            return new Answer(cmd, false, checksum);
+        }
+        finally {
+            try {
+                if(is != null)
+                    is.close();
+            } catch (IOException e) {
+                if(s_logger.isDebugEnabled()){
+                    s_logger.debug("Could not close the file " +absoluteTemplatePath);   
+                }
+                return new Answer(cmd, false, checksum);   
+            }                        
+        }
+
+        return new Answer(cmd, true, checksum);
+    }
+
+    private void configCerts(Certificates certs) {
+        if (certs == null) {
+            configureSSL();
+        } else {
+            String prvKey = certs.getPrivKey();
+            String pubCert = certs.getPrivCert();
+            String certChain = certs.getCertChain();
+
+            try {
+                File prvKeyFile = File.createTempFile("prvkey", null);
+                String prvkeyPath = prvKeyFile.getAbsolutePath();
+                BufferedWriter out = new BufferedWriter(new FileWriter(prvKeyFile));
+                out.write(prvKey);
+                out.close();
+
+                File pubCertFile = File.createTempFile("pubcert", null);
+                String pubCertFilePath = pubCertFile.getAbsolutePath();
+
+                out = new BufferedWriter(new FileWriter(pubCertFile));
+                out.write(pubCert);
+                out.close();
+
+                configureSSL(prvkeyPath, pubCertFilePath, null);
+
+                prvKeyFile.delete();
+                pubCertFile.delete();
+
+            } catch (IOException e) {
+                s_logger.debug("Failed to config ssl: " + e.toString());
+            }
+        }
+    }
+
+    private Answer execute(SecStorageSetupCommand cmd) {
+        if (!_inSystemVM){
+            return new Answer(cmd, true, null);
+        }
+        String secUrl = cmd.getSecUrl();
+        try {
+            URI uri = new URI(secUrl);
+            String nfsHost = uri.getHost();
+
+            InetAddress nfsHostAddr = InetAddress.getByName(nfsHost);
+            String nfsHostIp = nfsHostAddr.getHostAddress();
+
+            addRouteToInternalIpOrCidr(_storageGateway, _storageIp, _storageNetmask, nfsHostIp);
+            String nfsPath = nfsHostIp + ":" + uri.getPath();
+            String dir = UUID.nameUUIDFromBytes(nfsPath.getBytes()).toString();
+            String root = _parent + "/" + dir;
+            mount(root, nfsPath);
+
+            configCerts(cmd.getCerts());
+
+            nfsIps.add(nfsHostIp);
+            return new SecStorageSetupAnswer(dir);
+        } catch (Exception e) {
+            String msg = "GetRootDir for " + secUrl + " failed due to " + e.toString();
+            s_logger.error(msg);
+            return new Answer(cmd, false, msg);
+
+        }
+    }
+
+    private String deleteSnapshotBackupFromLocalFileSystem(
+            final String secondaryStorageUrl, final Long accountId,
+            final Long volumeId, final String name, final Boolean deleteAllFlag) {
+
+        final String lPath = determineSnapshotLocalDirectory(
+                secondaryStorageUrl, accountId, volumeId)
+                + File.pathSeparator
+                + (deleteAllFlag ? "*" : "*" + name + "*");
+
+        final String result = deleteLocalFile(lPath);
+
+        if (result != null) {
+            return "failed to delete snapshot " + lPath + " , err=" + result;
+        }
+
+        return null;
+
+    }
+
+    private String deleteSnapshotBackupfromS3(final S3TO s3,
+            final String secondaryStorageUrl, final Long accountId,
+            final Long volumeId, final String name, final Boolean deleteAllFlag) {
+
+        try {
+
+            final String bucket = s3.getBucketName();
+
+            final String result = executeWithNoWaitLock(
+                    determineSnapshotLockId(accountId, volumeId),
+                    new Callable<String>() {
+
+                        @Override
+                        public String call() throws Exception {
+
+                            final String innerResult = deleteSnapshotBackupFromLocalFileSystem(
+                                    secondaryStorageUrl, accountId, volumeId,
+                                    name, deleteAllFlag);
+                            if (innerResult != null) {
+                                return innerResult;
+                            }
+
+                            if (deleteAllFlag) {
+                                S3Utils.deleteDirectory(
+                                        s3,
+                                        bucket,
+                                        determineSnapshotS3Directory(accountId,
+                                                volumeId));
+                            } else {
+                                S3Utils.deleteObject(
+                                        s3,
+                                        bucket,
+                                        determineSnapshotS3Key(
+                                                accountId,
+                                                volumeId,
+                                                determineSnapshotBackupFilename(name)));
+                            }
+
+                            return null;
+
+                        }
+
+                    });
+
+            return result;
+
+        } catch (Exception e) {
+
+            s_logger.error(
+                    String.format(
+                            "Failed to delete snapshot backup for account id %1$s volume id %2$sfrom S3.",
+                            accountId, volumeId), e);
+            return e.getMessage();
+
+        }
+
+    }
+
+    private String determineSnapshotBackupFilename(final String snapshotUuid) {
+        return snapshotUuid + ".vhd";
+    }
+
+    private String determineSnapshotLockId(final Long accountId,
+            final Long volumeId) {
+        return join("_", "SNAPSHOT", accountId, volumeId);
+    }
+
+    protected Answer execute(final DeleteSnapshotBackupCommand cmd) {
+        String secondaryStorageUrl = cmd.getSecondaryStorageUrl();
+        Long accountId = cmd.getAccountId();
+        Long volumeId = cmd.getVolumeId();
+        String name = cmd.getSnapshotUuid();
+        try {
+            SwiftTO swift = cmd.getSwift();
+            S3TO s3 = cmd.getS3();
+            if (swift == null) {
+                final String result = deleteSnapshotBackupFromLocalFileSystem(
+                        secondaryStorageUrl, accountId, volumeId, name,
+                        cmd.isAll());
+                if (result != null) {
+                    s_logger.warn(result);
+                    return new Answer(cmd, false, result);
+                }
+            } else if (s3 != null) {
+                final String result = deleteSnapshotBackupfromS3(s3,
+                        secondaryStorageUrl, accountId, volumeId, name,
+                        cmd.isAll());
+                if (result != null) {
+                    s_logger.warn(result);
+                    return new Answer(cmd, false, result);
+                }
+            } else {
+                String filename;
+                if (cmd.isAll()) {
+                    filename = "";
+                } else {
+                    filename = name;
+                }
+                String result = swiftDelete(swift, "V-" + volumeId.toString(), filename);
+                if (result != null) {
+                    String errMsg = "failed to delete snapshot " + filename + " , err=" + result;
+                    s_logger.warn(errMsg);
+                    return new Answer(cmd, false, errMsg);
+                }
+            }
+            return new Answer(cmd, true, "success");
+        } catch (Exception e) {
+            String errMsg = cmd + " Command failed due to " + e.toString();
+            s_logger.warn(errMsg, e);
+            return new Answer(cmd, false, errMsg);
+        }
+    }
+
+    Map<String, TemplateInfo> swiftListTemplate(SwiftTO swift) {
+        String[] containers = swiftList(swift, "", "");
+        if (containers == null) {
+            return null;
+        }
+        Map<String, TemplateInfo> tmpltInfos = new HashMap<String, TemplateInfo>();
+        for( String container : containers) {
+            if ( container.startsWith("T-")) {
+                String ldir = _tmpltDir + "/" + UUID.randomUUID().toString();
+                createLocalDir(ldir);
+                String lFullPath = ldir + "/" + _tmpltpp;
+                swiftDownload(swift, container, _tmpltpp, lFullPath);
+                TemplateLocation loc = new TemplateLocation(_storage, ldir);
+                try {
+                    if (!loc.load()) {
+                        s_logger.warn("Can not parse template.properties file for template " + container);
+                        continue;
+                    }
+                } catch (IOException e) {
+                    s_logger.warn("Unable to load template location " + ldir + " due to " + e.toString(), e);
+                    continue;
+                }
+                TemplateInfo tInfo = loc.getTemplateInfo();
+                tInfo.setInstallPath(container);
+                tmpltInfos.put(tInfo.getTemplateName(), tInfo);
+                loc.purge();
+                deleteLocalDir(ldir);
+            }
+        }
+        return tmpltInfos;
+
+    }
+
+    private Answer execute(ListTemplateCommand cmd) {
+
+        if (cmd.getSwift() != null) {
+            Map<String, TemplateInfo> templateInfos = swiftListTemplate(cmd.getSwift());
+            return new ListTemplateAnswer(cmd.getSwift().toString(), templateInfos);
+        } else {
+            String root = getRootDir(cmd.getSecUrl());
+            Map<String, TemplateInfo> templateInfos = _dlMgr.gatherTemplateInfo(root);
+            return new ListTemplateAnswer(cmd.getSecUrl(), templateInfos);
+        }
+    }
+
+    private Answer execute(ListVolumeCommand cmd) {
+
+        String root = getRootDir(cmd.getSecUrl());
+        Map<Long, TemplateInfo> templateInfos = _dlMgr.gatherVolumeInfo(root);
+        return new ListVolumeAnswer(cmd.getSecUrl(), templateInfos);
+
+    }
+
+    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()) {
+            if (nfsIps.contains(cidr)) {
+                /*
+                 * if the internal download ip is the same with secondary storage ip, adding internal sites will flush
+                 * ip route to nfs through storage ip. 
+                 */
+                continue;
+            }
+            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 setVhdParent(String lFullPath, String pFullPath) {
+        Script command = new Script("/bin/bash", s_logger);
+        command.add("-c");
+        command.add("/bin/vhd-util modify -n " + lFullPath + " -p " + pFullPath);
+        String result = command.execute();
+        if (result != null) {
+            String errMsg = "failed to set vhd parent, child " + lFullPath + " parent " + pFullPath + ", err=" + result;
+            s_logger.warn(errMsg);
+            return errMsg;
+        }
+        return null;
+    }
+
+    private String createLocalDir(String folder) {
+        Script command = new Script("/bin/bash", s_logger);
+        command.add("-c");
+        command.add("mkdir -p " + folder);
+        String result = command.execute();
+        if (result != null) {
+            String errMsg = "Create local path " + folder + " failed , err=" + result;
+            s_logger.warn(errMsg);
+            return errMsg;
+        }
+        return null;
+    }
+
+    private String deleteLocalDir(String folder) {
+        Script command = new Script("/bin/bash", s_logger);
+        command.add("-c");
+        command.add("rmdir " + folder);
+        String result = command.execute();
+        if (result != null) {
+            String errMsg = "Delete local path " + folder + " failed , err=" + result;
+            s_logger.warn(errMsg);
+            return errMsg;
+        }
+        return null;
+    }
+
+    private String deleteLocalFile(String fullPath) {
+        Script command = new Script("/bin/bash", s_logger);
+        command.add("-c");
+        command.add("rm -f " + fullPath);
+        String result = command.execute();
+        if (result != null) {
+            String errMsg = "Failed to delete file " + fullPath + ", err=" + result;
+            s_logger.warn(errMsg);
+            return errMsg;
+        }
+        return null;
+    }
+
+    public String allowOutgoingOnPrivate(String destCidr) {
+        if (!_inSystemVM) {
+            return null;
+        }
+        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, cmd.getIsAppendAIp());
+        if (result !=null)
+            success = false;
+
+        return new Answer(cmd, success, result);
+    }
+
+    protected GetStorageStatsAnswer execute(final GetStorageStatsCommand cmd) {
+        String rootDir = getRootDir(cmd.getSecUrl());
+        final long usedSize = getUsedSize(rootDir);
+        final long totalSize = getTotalSize(rootDir);
+        if (usedSize == -1 || totalSize == -1) {
+            return new GetStorageStatsAnswer(cmd, "Unable to get storage stats");
+        } else {
+            return new GetStorageStatsAnswer(cmd, totalSize, usedSize) ;
+        }
+    }
+
+    protected Answer execute(final DeleteTemplateCommand cmd) {
+        String relativeTemplatePath = cmd.getTemplatePath();
+        String parent = getRootDir(cmd);
+
+        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 Answer execute(final DeleteVolumeCommand cmd) {
+        String relativeVolumePath = cmd.getVolumePath();
+        String parent = getRootDir(cmd);
+
+        if (relativeVolumePath.startsWith(File.separator)) {
+            relativeVolumePath = relativeVolumePath.substring(1);
+        }
+
+        if (!parent.endsWith(File.separator)) {
+            parent += File.separator;
+        }
+        String absoluteVolumePath = parent + relativeVolumePath;
+        File tmpltParent = new File(absoluteVolumePath).getParentFile();
+        String details = null;
+        if (!tmpltParent.exists()) {
+            details = "volume 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 volume parent directory " + tmpltParent.getName();
+            s_logger.debug(details);
+        } else {
+            boolean found = false;
+            for (File f : tmpltFiles) {
+                if (!found && f.getName().equals("volume.properties")) {
+                    found = true;
+                }
+                if (!f.delete()) {
+                    return new Answer(cmd, false, "Unable to delete file " + f.getName() + " under Volume path "
+                            + relativeVolumePath);
+                }
+            }
+            if (!found) {
+                details = "Can not find volume.properties under " + tmpltParent.getName();
+                s_logger.debug(details);
+            }
+        }
+        if (!tmpltParent.delete()) {
+            details = "Unable to delete directory " + tmpltParent.getName() + " under Volume path "
+                    + relativeVolumePath;
+            s_logger.debug(details);
+            return new Answer(cmd, false, details);
+        }
+        return new Answer(cmd, true, null);
+    }
+
+    Answer execute(CleanupSnapshotBackupCommand cmd) {
+        String parent = getRootDir(cmd.getSecondaryStoragePoolURL());
+        if (!parent.endsWith(File.separator)) {
+            parent += File.separator;
+        }
+        String absoluteSnapsthotDir = parent + File.separator + "snapshots" + File.separator + cmd.getAccountId() + File.separator + cmd.getVolumeId();
+        File ssParent = new File(absoluteSnapsthotDir);
+        if (ssParent.exists() && ssParent.isDirectory()) {
+            File[] files = ssParent.listFiles();
+            for (File file : files) {
+                boolean found = false;
+                String filename = file.getName();
+                for (String uuid : cmd.getValidBackupUUIDs()) {
+                    if (filename.startsWith(uuid)) {
+                        found = true;
+                        break;
+                    }
+                }
+                if (!found) {
+                    file.delete();
+                    String msg = "snapshot " + filename + " is not recorded in DB, remove it";
+                    s_logger.warn(msg);
+                }
+            }
+        }
+        return new Answer(cmd, true, null);
+    }
+
+
+    synchronized public String getRootDir(String secUrl) {
+        if (!_inSystemVM) {
+            return _parent;
+        }
+        try {
+            URI uri = new URI(secUrl);
+            String nfsHost = uri.getHost();
+
+            InetAddress nfsHostAddr = InetAddress.getByName(nfsHost);
+            String nfsHostIp = nfsHostAddr.getHostAddress();
+            String nfsPath = nfsHostIp + ":" + uri.getPath();
+            String dir = UUID.nameUUIDFromBytes(nfsPath.getBytes()).toString();
+            String root = _parent + "/" + dir;
+            mount(root, nfsPath);    
+            return root;
+        } catch (Exception e) {
+            String msg = "GetRootDir for " + secUrl + " failed due to " + e.toString();
+            s_logger.error(msg, e);
+            throw new CloudRuntimeException(msg);
+        }
+    }
+
+
+    @Override
+    public String getRootDir(ssCommand cmd){
+        return getRootDir(cmd.getSecUrl());
+
+    }
+
+    protected long getUsedSize(String rootDir) {
+        return _storage.getUsedSpace(rootDir);
+    }
+
+    protected long getTotalSize(String rootDir) {
+        return _storage.getTotalSpace(rootDir);
+    }
+
+    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() {
+        if(SecondaryStorageVm.Role.templateProcessor.toString().equals(_role))
+            return Host.Type.SecondaryStorage;
+
+        return Host.Type.SecondaryStorageCmdExecutor;
+    }
+
+    @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");
+        _eth1mask = (String)params.get("eth1mask");
+        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");
+
+        String inSystemVM = (String) params.get("secondary.storage.vm");
+        if (inSystemVM == null || "true".equalsIgnoreCase(inSystemVM)) {
+            _inSystemVM = true;
+        }
+
+        _storageIp = (String) params.get("storageip");
+        if (_storageIp == null) {
+            s_logger.warn("Wait, there is no storageip in /proc/cmdline, something wrong!");
+        }
+        _storageNetmask = (String) params.get("storagenetmask");
+        _storageGateway = (String) params.get("storagegateway");
+        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)clazz.newInstance();
+                _storage.configure("StorageLayer", params);
+            } catch (ClassNotFoundException e) {
+                throw new ConfigurationException("Unable to find class " + value);
+            } catch (InstantiationException e) {
+                throw new ConfigurationException("Unable to find class " + value);
+            } catch (IllegalAccessException e) {
+                throw new ConfigurationException("Unable to find class " + value);
+            }
+        }
+
+        if (_inSystemVM)
+            _storage.mkdirs(_parent);
+
+        _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);
+        }
+
+        _role = (String)params.get("role");
+        if(_role == null)
+            _role = SecondaryStorageVm.Role.templateProcessor.toString();
+        s_logger.info("Secondary storage runs in role " + _role);
+
+        _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");
+
+        if (!_inSystemVM) {
+            _parent = (String) params.get("mount.path");
+        }
+
+
+        if (_inSystemVM) {
+            _localgw = (String)params.get("localgw");
+            if (_localgw != null) { // can only happen inside service vm
+                String mgmtHost = (String) params.get("host");
+                addRouteToInternalIpOrCidr(_localgw, _eth1ip, _eth1mask, mgmtHost);
+
+                String internalDns1 = (String) params.get("internaldns1");
+                if (internalDns1 == null) {
+                    s_logger.warn("No DNS entry found during configuration of NfsSecondaryStorage");
+                } else {
+                    addRouteToInternalIpOrCidr(_localgw, _eth1ip, _eth1mask, internalDns1);
+                }
+
+                String internalDns2 = (String) params.get("internaldns2");
+                if (internalDns2 != null) {
+                    addRouteToInternalIpOrCidr(_localgw, _eth1ip, _eth1mask, internalDns2);
+                }
+
+            }
+
+            startAdditionalServices();
+            _params.put("install.numthreads", "50");
+            _params.put("secondary.storage.vm", "true");
+        }
+
+        try {
+            _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() {
+        if (!_inSystemVM) {
+            return;
+        }
+        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) {
+        if (!_inSystemVM) {
+            return;
+        }
+        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() {
+        if (!_inSystemVM) {
+            return;
+        }
+        Script command = new Script(_configSslScr);
+        command.add("-i", _publicIp);
+        command.add("-h", _hostname);
+        String result = command.execute();
+        if (result != null) {
+            s_logger.warn("Unable to configure httpd to use ssl");
+        }
+    }
+
+    private void configureSSL(String prvkeyPath, String prvCertPath, String certChainPath) {
+        if (!_inSystemVM) {
+            return;
+        }
+        Script command = new Script(_configSslScr);
+        command.add("-i", _publicIp);
+        command.add("-h", _hostname);
+        command.add("-k", prvkeyPath);
+        command.add("-p", prvCertPath);
+        if (certChainPath != null) {
+            command.add("-t", certChainPath);
+        }
+        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, boolean isAppend){
+        Script command = new Script(_configIpFirewallScr);
+        command.add(String.valueOf(isAppend));
+        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 root, String nfsPath) {
+        File file = new File(root);
+        if (!file.exists()) {
+            if (_storage.mkdir(root)) {
+                s_logger.debug("create mount point: " + root);
+            } else {
+                s_logger.debug("Unable to create mount point: " + root);
+                return null;       
+            }
+        }
+
+        Script script = null;
+        String result = null;
+        script = new Script(!_inSystemVM, "mount", _timeout, s_logger);
+        List<String> res = new ArrayList<String>();
+        ZfsPathParser parser = new ZfsPathParser(root);
+        script.execute(parser);
+        res.addAll(parser.getPaths());
+        for( String s : res ) {
+            if ( s.contains(root)) {
+                return root;
+            }
+        }
+
+        Script command = new Script(!_inSystemVM, "mount", _timeout, s_logger);
+        command.add("-t", "nfs");
+        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");
+        }
+        command.add(nfsPath);
+        command.add(root);
+        result = command.execute();
+        if (result != null) {
+            s_logger.warn("Unable to mount " + nfsPath + " due to " + result);
+            file = new File(root);
+            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(root)) {
+            return null;
+        }
+
+        // Create the volumes dir
+        if (!checkForVolumesDir(root)) {
+            return null;
+        }
+
+        return root;
+    }
+
+    @Override
+    public boolean start() {
+        return true;
+    }
+
+    @Override
+    public boolean stop() {
+        return true;
+    }
+
+    @Override
+    public StartupCommand[] initialize() {
+
+        final StartupSecondaryStorageCommand cmd = new StartupSecondaryStorageCommand();
+        fillNetworkInformation(cmd);
+        if(_publicIp != null)
+            cmd.setPublicIpAddress(_publicIp);
+
+        if (_inSystemVM) {
+            Script command = new Script("/bin/bash", s_logger);
+            command.add("-c");
+            command.add("ln -sf " + _parent + " /var/www/html/copy");
+            String result = command.execute();
+            if (result != null) {
+                s_logger.warn("Error in linking  err=" + result);
+                return null;
+            }
+        }
+        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
+
+    }
+
+    @Override
+    public void fillNetworkInformation(final StartupCommand cmd) {
+        final String dummyMac = "00:06:0A:0B:0C:0D";
+        final String dummyNetmask = "255.255.255.0";
+        if (!_inSystemVM) {
+            cmd.setPrivateIpAddress(_eth1ip);
+            cmd.setPrivateMacAddress(dummyMac);
+            cmd.setPrivateNetmask(dummyNetmask);
+            cmd.setPublicIpAddress(_publicIp);
+            cmd.setPublicMacAddress(dummyMac);
+            cmd.setPublicNetmask(dummyNetmask);
+            cmd.setName(_hostname);
+        } else {
+            super.fillNetworkInformation(cmd);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/services/secondary-storage/src/org/apache/cloudstack/storage/resource/SecondaryStorageResource.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/SecondaryStorageResource.java b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/SecondaryStorageResource.java
new file mode 100755
index 0000000..5c87b0d
--- /dev/null
+++ b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/SecondaryStorageResource.java
@@ -0,0 +1,28 @@
+// 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 com.cloud.agent.api.storage.ssCommand;
+import com.cloud.resource.ServerResource;
+/**
+ *
+ * SecondaryStorageServerResource is a generic container to execute commands sent
+ */
+public interface SecondaryStorageResource extends ServerResource {
+    
+    public String getRootDir(ssCommand cmd);
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/services/secondary-storage/src/org/apache/cloudstack/storage/resource/SecondaryStorageResourceHandler.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/SecondaryStorageResourceHandler.java b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/SecondaryStorageResourceHandler.java
new file mode 100644
index 0000000..d03d983
--- /dev/null
+++ b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/SecondaryStorageResourceHandler.java
@@ -0,0 +1,24 @@
+// 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 com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
+
+public interface SecondaryStorageResourceHandler {
+	Answer executeRequest(Command cmd);
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/services/secondary-storage/src/org/apache/cloudstack/storage/template/DownloadManager.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/template/DownloadManager.java b/services/secondary-storage/src/org/apache/cloudstack/storage/template/DownloadManager.java
new file mode 100644
index 0000000..3e5072a
--- /dev/null
+++ b/services/secondary-storage/src/org/apache/cloudstack/storage/template/DownloadManager.java
@@ -0,0 +1,105 @@
+// 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.template;
+
+import java.util.Map;
+
+import org.apache.cloudstack.storage.resource.SecondaryStorageResource;
+
+import com.cloud.agent.api.storage.DownloadAnswer;
+import com.cloud.agent.api.storage.DownloadCommand;
+import com.cloud.agent.api.storage.DownloadCommand.Proxy;
+import com.cloud.agent.api.storage.DownloadCommand.ResourceType;
+import com.cloud.storage.Storage.ImageFormat;
+import com.cloud.storage.VMTemplateHostVO;
+import com.cloud.storage.template.TemplateDownloader;
+import com.cloud.storage.template.TemplateInfo;
+import com.cloud.utils.component.Manager;
+
+public interface DownloadManager extends Manager {
+
+	/**
+	 * Initiate download of a public template
+	 * @param id unique id.
+	 * @param url  the url from where to download from
+     * @param hvm  whether the template is a hardware virtual machine
+     * @param accountId the accountId of the iso owner (null if public iso)
+	 * @param descr	description of the template
+	 * @param user username used for authentication to the server
+	 * @param password password used for authentication to the server
+	 * @param maxDownloadSizeInBytes (optional) max download size for the template, in bytes.
+	 * @param resourceType signifying the type of resource like template, volume etc. 
+	 * @return job-id that can be used to interrogate the status of the download.
+	 */
+	public String downloadPublicTemplate(long id, String url, String name, ImageFormat format, boolean hvm, Long accountId, String descr, String cksum, String installPathPrefix, String userName, String passwd, long maxDownloadSizeInBytes, Proxy proxy, ResourceType resourceType);
+	
+	
+	/**
+	 * Get the status of a download job
+	 * @param jobId job Id
+	 * @return status of the download job
+	 */
+	public TemplateDownloader.Status getDownloadStatus(String jobId);
+	
+	/**
+	 * Get the status of a download job
+	 * @param jobId job Id
+	 * @return status of the download job
+	 */
+	public VMTemplateHostVO.Status getDownloadStatus2(String jobId);
+
+	/**
+	 * Get the download percent of a download job
+	 * @param jobId job Id
+	 * @return
+	 */
+	public int getDownloadPct(String jobId);
+
+	/**
+	 * Get the download error if any
+	 * @param jobId job Id
+	 * @return
+	 */
+	public String getDownloadError(String jobId);
+
+	/**
+	 * Get the local path for the download
+	 * @param jobId job Id
+	 * @return
+	public String getDownloadLocalPath(String jobId);
+     */
+	
+	/** Handle download commands from the management server
+	 * @param cmd cmd from server
+	 * @return answer representing status of download.
+	 */
+	public DownloadAnswer handleDownloadCommand(SecondaryStorageResource resource, DownloadCommand cmd);
+		
+	/**
+	/**
+	 * @return list of template info for installed templates
+	 */
+	public Map<String, TemplateInfo> gatherTemplateInfo(String templateDir);
+	
+	/**
+	/**
+	 * @return list of volume info for installed volumes
+	 */
+	public Map<Long, TemplateInfo> gatherVolumeInfo(String volumeDir);
+
+
+}
\ No newline at end of file


[14/19] git commit: updated refs/heads/master to bf56403

Posted by ch...@apache.org.
QuickCloud: when using SSVM, pass in the new name of the SS class (com.cloud -> org.apache.cloudstack)
QuickCloud : configuration moved to applicationContext.xml from componentContext.xml
QuickCloud: default to enabled state for devcloud zone
QuickCloud: environment.properties helps customize location of pid file


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

Branch: refs/heads/master
Commit: 5ff8bcaa2e16035197c6d58bb212ba1696411dce
Parents: 936973a
Author: Chiradeep Vittal <ch...@apache.org>
Authored: Thu Apr 4 17:23:10 2013 -0700
Committer: Chiradeep Vittal <ch...@apache.org>
Committed: Tue Apr 9 14:45:26 2013 -0700

----------------------------------------------------------------------
 client/pom.xml                                     |    6 +-
 .../tomcatconf/quickCloudComponentContext.xml.in   |  336 ---------------
 .../secondary/SecondaryStorageManagerImpl.java     |    8 +-
 .../server/conf/environment.properties             |    2 +
 tools/devcloud/devcloud.cfg                        |    1 +
 5 files changed, 9 insertions(+), 344 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/5ff8bcaa/client/pom.xml
----------------------------------------------------------------------
diff --git a/client/pom.xml b/client/pom.xml
index 4bd1a6f..b3d7acb 100644
--- a/client/pom.xml
+++ b/client/pom.xml
@@ -463,9 +463,9 @@
               <target if="${quickcloud}">
                 <echo>quickcloud</echo>
                 <replaceregexp
-                  file="${basedir}/target/generated-webapp/WEB-INF/web.xml"
-                  match="classpath:componentContext.xml"
-                  replace="classpath:quickCloudComponentContext.xml" byline="true" />
+                    file="${basedir}/target/generated-webapp/WEB-INF/classes/applicationContext.xml"
+                  match="com.cloud.consoleproxy.ConsoleProxyManagerImpl"
+                  replace="com.cloud.consoleproxy.StaticConsoleProxyManager" byline="true" />
               </target>
             </configuration>
           </execution>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/5ff8bcaa/client/tomcatconf/quickCloudComponentContext.xml.in
----------------------------------------------------------------------
diff --git a/client/tomcatconf/quickCloudComponentContext.xml.in b/client/tomcatconf/quickCloudComponentContext.xml.in
deleted file mode 100644
index dbd3117..0000000
--- a/client/tomcatconf/quickCloudComponentContext.xml.in
+++ /dev/null
@@ -1,336 +0,0 @@
-<!--
-  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.
--->
-<beans xmlns="http://www.springframework.org/schema/beans"
-  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
-  xmlns:context="http://www.springframework.org/schema/context"
-  xmlns:tx="http://www.springframework.org/schema/tx" 
-  xmlns:aop="http://www.springframework.org/schema/aop"
-  xsi:schemaLocation="http://www.springframework.org/schema/beans
-                      http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
-                      http://www.springframework.org/schema/tx 
-                      http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
-                      http://www.springframework.org/schema/aop
-                      http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
-                      http://www.springframework.org/schema/context
-                      http://www.springframework.org/schema/context/spring-context-3.0.xsd">                     
-
-
-  <!--
-      Compose a CloudStack deployment with selected components here
-  -->
-  <bean id="databaseUpgradeChecker" class="com.cloud.upgrade.DatabaseUpgradeChecker" />
-  <bean id="encryptionSecretKeyChecker" class="com.cloud.utils.crypt.EncryptionSecretKeyChecker" />
-  <bean id="configurationServerImpl" class="com.cloud.server.ConfigurationServerImpl" />
-  
-  <bean id="managementServerImpl" class ="com.cloud.server.ManagementServerImpl" >
-    <property name="UserAuthenticators">
-        <list>
-            <ref bean="MD5UserAuthenticator"/>
-            <ref bean="LDAPUserAuthenticator"/>
-        </list>
-    </property>
-  </bean>
- 
-  <bean id ="AccountManagerImpl" class="com.cloud.user.AccountManagerImpl">
-    <property name="UserAuthenticators">
-        <list>
-            <ref bean="MD5UserAuthenticator"/>
-            <ref bean="LDAPUserAuthenticator"/>
-        </list>
-    </property>
-  </bean>
-   
-  <bean id="clusterManagerImpl" class="com.cloud.cluster.ClusterManagerImpl" />
-  <bean id="clusteredAgentManagerImpl" class="com.cloud.agent.manager.ClusteredAgentManagerImpl" />
-  <bean id="clusteredVirtualMachineManagerImpl" class="com.cloud.vm.ClusteredVirtualMachineManagerImpl" />
-  <bean id="highAvailabilityManagerExtImpl" class="com.cloud.ha.HighAvailabilityManagerExtImpl" />
-  <bean id="userVmManagerImpl" class="com.cloud.vm.UserVmManagerImpl" />
-  <bean id="consoleProxyManagerImpl" class="com.cloud.consoleproxy.StaticConsoleProxyManager" />
-  <bean id="securityGroupManagerImpl2" class="com.cloud.network.security.SecurityGroupManagerImpl2" />
-  <bean id="premiumSecondaryStorageManagerImpl" class="com.cloud.secstorage.PremiumSecondaryStorageManagerImpl" />
-  <bean id="userVmDaoImpl" class="com.cloud.vm.dao.UserVmDaoImpl" />
-  <bean id="ipv6AddressManagerImpl" class="com.cloud.network.Ipv6AddressManagerImpl" />
-
-  <bean id="apiRateLimitServiceImpl" class="org.apache.cloudstack.ratelimit.ApiRateLimitServiceImpl"/>
-  <bean id="BaremetalManager" class="com.cloud.baremetal.manager.BaremetalManagerImpl"/>
-  <bean id="BaremetalDhcpManager" class="com.cloud.baremetal.networkservice.BaremetalDhcpManagerImpl"/>
-  <bean id="BaremetalKickStartPxeService" class="com.cloud.baremetal.networkservice.BaremetalKickStartServiceImpl"/>
-  <bean id="BaremetalPingPxeService" class="com.cloud.baremetal.networkservice.BareMetalPingServiceImpl" />
-  <bean id="BaremetalPxeManager" class="com.cloud.baremetal.networkservice.BaremetalPxeManagerImpl" />
-  <bean id="UcsManager" class="com.cloud.ucs.manager.UcsManagerImpl" />
-  <bean id="UcsBladeDao" class="com.cloud.ucs.database.UcsBladeDaoImpl" />
-  <bean id="UcsManagerDao" class="com.cloud.ucs.database.UcsManagerDaoImpl" />
-
-   
-  <!--
-      Network Elements
-  -->
-  <bean id="Ovs" class="com.cloud.network.element.OvsElement">
-    <property name="name" value="Ovs"/>
-  </bean>
-  <bean id="BareMetalDhcp" class="com.cloud.baremetal.networkservice.BaremetalDhcpElement">
-      <property name="name" value="BareMetalDhcp"/>
-  </bean>
-  <bean id="BareMetalPxe" class="com.cloud.baremetal.networkservice.BaremetalPxeElement">
-      <property name="name" value="BareMetalPxe"/>
-  </bean>
-  <bean id="BareMetalUserdata" class="com.cloud.baremetal.networkservice.BaremetalUserdataElement">
-      <property name="name" value="BareMetalUserdata"/>
-  </bean>
-  <bean id="SecurityGroupProvider" class="com.cloud.network.element.SecurityGroupElement">
-    <property name="name" value="SecurityGroupProvider"/>
-  </bean>
-  <bean id="VirtualRouter" class="com.cloud.network.element.VirtualRouterElement">
-    <property name="name" value="VirtualRouter"/>
-  </bean>
-  <bean id="VpcVirtualRouter" class="com.cloud.network.element.VpcVirtualRouterElement">
-    <property name="name" value="VpcVirtualRouter"/>
-  </bean>
-  <!--
-  <bean id="NiciraNvp" class="com.cloud.network.element.NiciraNvpElement">
-    <property name="name" value="NiciraNvp"/>
-  </bean>
-  -->
-  
-<!--
-  <bean id="BigSwitchVnsElementService" class="com.cloud.network.element.BigSwitchVnsElement">
-    <property name="name" value="BigSwitchVnsElementService"/>
-  </bean>
--->
-                   
-  <!--
-     Adapters
-  -->
-  <bean id="FirstFitRouting" class="com.cloud.agent.manager.allocator.impl.FirstFitRoutingAllocator">
-    <property name="name" value="FirstFitRouting"/>
-  </bean>
-  
-  <bean id="hypervisorTemplateAdapter" class="com.cloud.template.HypervisorTemplateAdapter">
-    <property name="name" value="HypervisorAdapter"/>
-  </bean>
-  
-  <!--
-    Storage pool allocators
-  -->
-
-  <bean id="LocalStoragePoolAllocator" class="org.apache.cloudstack.storage.allocator.LocalStoragePoolAllocator">
-    <property name="name" value="LocalStorage"/>
-  </bean>
-  <!--
-  <bean id="FirstFitStoragePoolAllocator" class="org.apache.cloudstack.storage.allocator.FirstFitStoragePoolAllocator">
-    <property name="name" value="Storage"/>
-  </bean>
-  -->
-
-  <bean id="UserConcentratedAllocator" class="com.cloud.agent.manager.allocator.impl.UserConcentratedAllocator">
-    <property name="name" value="User First"/>
-  </bean>
-
-  <bean id="ConsoleProxyAllocator" class="com.cloud.consoleproxy.ConsoleProxyBalanceAllocator">
-    <property name="name" value="Balance"/>
-  </bean>
-
-  <bean id="StaticRoleBasedAPIAccessChecker" class="org.apache.cloudstack.acl.StaticRoleBasedAPIAccessChecker"/>
-
-  <bean id="ExteralIpAddressAllocator" class="com.cloud.network.ExteralIpAddressAllocator">
-    <property name="name" value="Basic"/>
-  </bean>
-
-  <bean id="HypervisorTemplateAdapter" class="com.cloud.template.HypervisorTemplateAdapter">
-    <property name="name" value="HypervisorAdapter"/>
-  </bean>
-
-  <bean id="BareMetalTemplateAdapter" class="com.cloud.baremetal.manager.BareMetalTemplateAdapter" >
-    <property name="name" value="BareMetalTemplateAdapter"/>
-  </bean>
-
-  <!--
-    Authenticators
-  -->
-  <bean id="MD5UserAuthenticator" class="com.cloud.server.auth.MD5UserAuthenticator">
-    <property name="name" value="MD5"/>
-  </bean>
-
-  <bean id="LDAPUserAuthenticator" class="com.cloud.server.auth.LDAPUserAuthenticator">
-    <property name="name" value="LDAP"/>
-  </bean>
-
-  <!--
-    Investigators
-  -->
-  <bean id="CheckOnAgentInvestigator" class="com.cloud.ha.CheckOnAgentInvestigator">
-    <property name="name" value="SimpleInvestigator"/>
-  </bean>
-
-  <bean id="XenServerInvestigator" class="com.cloud.ha.XenServerInvestigator">
-    <property name="name" value="XenServerInvestigator"/>
-  </bean>
-  
-  <bean id="UserVmDomRInvestigator" class="com.cloud.ha.UserVmDomRInvestigator">
-    <property name="name" value="PingInvestigator"/>
-  </bean>
-
-  <bean id="ManagementIPSystemVMInvestigator" class="com.cloud.ha.ManagementIPSystemVMInvestigator">
-    <property name="name" value="ManagementIPSysVMInvestigator"/>
-  </bean>
-
-  <!--
-    Fencers
-  -->
-  <bean id="XenServerFencer" class="com.cloud.ha.XenServerFencer">
-    <property name="name" value="XenServerFenceBuilder"/>
-  </bean>
-  <bean id="KVMFencer" class="com.cloud.ha.KVMFencer">
-    <property name="name" value="KVMFenceBuilder"/>
-  </bean>
-  <bean id="OvmFencer" class="com.cloud.ovm.hypervisor.OvmFencer">
-    <property name="name" value="OvmFenceBuilder"/>
-  </bean>
-
-  <bean id="XcpServerDiscoverer" class="com.cloud.hypervisor.xen.discoverer.XcpServerDiscoverer">
-    <property name="name" value="XCP Agent"/>
-  </bean>
-
-  <!--
-  <bean id="SimulatorSecondaryStorageDiscoverer" class="com.cloud.resource.SimulatorSecondaryDiscoverer">
-    <property name="name" value="SecondaryStorage"/>
-  </bean>
-  -->
-
-  <bean id="SecondaryStorageDiscoverer" class="org.apache.cloudstack.storage.resource.SecondaryStorageDiscoverer">
-    <property name="name" value="SecondaryStorage"/>
-  </bean>
-
-  <bean id="KvmServerDiscoverer" class="com.cloud.hypervisor.kvm.discoverer.KvmServerDiscoverer">
-    <property name="name" value="KVM Agent"/>
-  </bean>
-
-  <bean id="SimulatorDiscoverer" class="com.cloud.resource.SimulatorDiscoverer">
-    <property name="name" value="Simulator Agent"/>
-  </bean>
-
-
-  <bean id="BareMetalDiscoverer" class="com.cloud.baremetal.manager.BareMetalDiscoverer">
-    <property name="name" value="Bare Metal Agent"/>
-  </bean>
-
-  <bean id="HypervServerDiscoverer" class="com.cloud.hypervisor.hyperv.HypervServerDiscoverer">
-    <property name="name" value="SCVMMServer"/>
-  </bean>
-
-  <bean id="OvmDiscoverer" class="com.cloud.ovm.hypervisor.OvmDiscoverer">
-    <property name="name" value="Ovm Discover"/>
-  </bean>
-
-  <bean id="FirstFitPlanner" class="com.cloud.deploy.FirstFitPlanner">
-    <property name="name" value="First Fit"/>
-  </bean>
-
-  <bean id="UserDispersingPlanner" class="com.cloud.deploy.UserDispersingPlanner">
-    <property name="name" value="UserDispersing"/>
-  </bean>
-  
-  <bean id="UserConcentratedPodPlanner" class="com.cloud.deploy.UserConcentratedPodPlanner">
-    <property name="name" value="UserConcentratedPod"/>
-  </bean>
-
-  <bean id="BareMetalPlanner" class="com.cloud.baremetal.manager.BareMetalPlanner">
-    <property name="name" value="BareMetal Fit"/>
-  </bean>
-    
-  <bean id="BaremetalPlannerSelector" class="com.cloud.baremetal.manager.BaremetalPlannerSelector">
-    <property name="name" value="BaremetalPlannerSelector"/>
-  </bean>
-
-  <bean id="HypervisorPlannerSelector" class="com.cloud.deploy.HypervisorVmPlannerSelector">
-    <property name="name" value="HypervisorPlannerSelector"/>
-  </bean>
-    
-   
-  <!--
-    Network Gurus
-  -->
-  <bean id="StorageNetworkGuru" class="com.cloud.network.guru.StorageNetworkGuru">
-    <property name="name" value="StorageNetworkGuru"/>
-  </bean>
-  <bean id="ExternalGuestNetworkGuru" class="com.cloud.network.guru.ExternalGuestNetworkGuru">
-    <property name="name" value="ExternalGuestNetworkGuru"/>
-  </bean>
-  <bean id="PublicNetworkGuru" class="com.cloud.network.guru.PublicNetworkGuru">
-    <property name="name" value="PublicNetworkGuru"/>
-  </bean>
-  <bean id="PodBasedNetworkGuru" class="com.cloud.network.guru.PodBasedNetworkGuru">
-    <property name="name" value="PodBasedNetworkGuru"/>
-  </bean>
-  <bean id="ControlNetworkGuru" class="com.cloud.network.guru.ControlNetworkGuru">
-    <property name="name" value="ControlNetworkGuru"/>
-  </bean>
-  <bean id="DirectNetworkGuru" class="com.cloud.network.guru.DirectNetworkGuru">
-    <property name="name" value="DirectNetworkGuru"/>
-  </bean>
-  <bean id="DirectPodBasedNetworkGuru" class="com.cloud.network.guru.DirectPodBasedNetworkGuru">
-    <property name="name" value="DirectPodBasedNetworkGuru"/>
-  </bean>
-  <bean id="OvsGuestNetworkGuru" class="com.cloud.network.guru.OvsGuestNetworkGuru">
-    <property name="name" value="OvsGuestNetworkGuru"/>
-  </bean>
-  <bean id="PrivateNetworkGuru" class="com.cloud.network.guru.PrivateNetworkGuru">
-    <property name="name" value="PrivateNetworkGuru"/>
-  </bean>
-  <bean id="NiciraNvpGuestNetworkGuru" class="com.cloud.network.guru.NiciraNvpGuestNetworkGuru">
-    <property name="name" value="NiciraNvpGuestNetworkGuru"/>
-  </bean>
-  
-<!--  
-  <bean id="BigSwitchVnsGuestNetworkGuru" class=".BigSwitchVnsGuestNetworkGuru">
-    <property name="name" value="com.cloud.network.guru.BigSwitchVnsGuestNetworkGuru"/>
-  </bean>
--->
- 
-  <!--
-   Hypervisor Gurus
-  -->
-  <bean id="XenServerGuru" class="com.cloud.hypervisor.XenServerGuru">
-    <property name="name" value="XenServerGuru"/>
-  </bean>
-  
-  <bean id="KVMGuru" class="com.cloud.hypervisor.KVMGuru">
-    <property name="name" value="KVMGuru"/>
-  </bean>
-  
-  <bean id="HypervGuru" class="com.cloud.hypervisor.guru.HypervGuru">
-    <property name="name" value="HypervGuru"/>
-  </bean>
-
-  <bean id="OvmGuru" class="com.cloud.ovm.hypervisor.OvmGuru">
-    <property name="name" value="OvmGuru"/>
-  </bean>
-  
-  <bean id="SimulatorGuru" class="com.cloud.simulator.SimulatorGuru">
-    <property name="name" value="SimulatorGuru"/>
-  </bean>
-
-  <bean id="BaremetalGuru" class="com.cloud.baremetal.manager.BareMetalGuru">
-    <property name="name" value="BaremetalGuru"/>
-  </bean>
-
-  <bean id="ClassicalPrimaryDataStoreProvider" class="org.apache.cloudstack.storage.datastore.provider.CloudStackPrimaryDataStoreProviderImpl">
-  </bean>
-  
-</beans>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/5ff8bcaa/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java
index c94224b..d6d6fc0 100755
--- a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java
+++ b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java
@@ -30,8 +30,6 @@ import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
 import org.apache.log4j.Logger;
-import org.springframework.context.annotation.Primary;
-import org.springframework.stereotype.Component;
 
 import com.cloud.agent.AgentManager;
 import com.cloud.agent.api.Answer;
@@ -98,8 +96,8 @@ import com.cloud.service.dao.ServiceOfferingDao;
 import com.cloud.storage.SnapshotVO;
 import com.cloud.storage.Storage;
 import com.cloud.storage.VMTemplateHostVO;
-import com.cloud.storage.VMTemplateVO;
 import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
+import com.cloud.storage.VMTemplateVO;
 import com.cloud.storage.dao.SnapshotDao;
 import com.cloud.storage.dao.StoragePoolHostDao;
 import com.cloud.storage.dao.VMTemplateDao;
@@ -1066,10 +1064,10 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar
             	buf.append(" resource=com.cloud.storage.resource.PremiumSecondaryStorageResource");
             } else {
             	s_logger.debug("Telling the ssvm to load the NfsSecondaryStorageResource");
-                buf.append(" resource=com.cloud.storage.resource.NfsSecondaryStorageResource");
+                buf.append(" resource=org.apache.cloudstack.storage.resource.NfsSecondaryStorageResource");
             }
         } else {
-            buf.append(" resource=com.cloud.storage.resource.NfsSecondaryStorageResource");
+            buf.append(" resource=org.apache.cloudstack.storage.resource.NfsSecondaryStorageResource");
         }
         buf.append(" instance=SecStorage");
         buf.append(" sslcopy=").append(Boolean.toString(_useSSlCopy));

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/5ff8bcaa/services/console-proxy/server/conf/environment.properties
----------------------------------------------------------------------
diff --git a/services/console-proxy/server/conf/environment.properties b/services/console-proxy/server/conf/environment.properties
new file mode 100644
index 0000000..269acad
--- /dev/null
+++ b/services/console-proxy/server/conf/environment.properties
@@ -0,0 +1,2 @@
+paths.script=../../scripts/storage/secondary/
+paths.pid=.

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/5ff8bcaa/tools/devcloud/devcloud.cfg
----------------------------------------------------------------------
diff --git a/tools/devcloud/devcloud.cfg b/tools/devcloud/devcloud.cfg
index c41f8bc..e6ab71b 100644
--- a/tools/devcloud/devcloud.cfg
+++ b/tools/devcloud/devcloud.cfg
@@ -20,6 +20,7 @@
     "zones": [
         {
             "name": "DevCloud0", 
+            "enabled" : "True",
             "physical_networks": [
                 {
                     "broadcastdomainrange": "Zone", 


[16/19] git commit: updated refs/heads/master to bf56403

Posted by ch...@apache.org.
QuickCloud: allow specification of network offering name in datacenter config. The deployDatacenter python script will use this to pick the network offering during creation of the default network in a basic zone


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

Branch: refs/heads/master
Commit: a806ce43d32e8d5ac064b79dd623c01be4489126
Parents: 1d70b9e
Author: Chiradeep Vittal <ch...@apache.org>
Authored: Tue Mar 26 14:11:36 2013 -0700
Committer: Chiradeep Vittal <ch...@apache.org>
Committed: Tue Apr 9 14:45:26 2013 -0700

----------------------------------------------------------------------
 tools/devcloud/quickcloud.cfg           |    1 +
 tools/marvin/marvin/deployDataCenter.py |    3 ++-
 2 files changed, 3 insertions(+), 1 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a806ce43/tools/devcloud/quickcloud.cfg
----------------------------------------------------------------------
diff --git a/tools/devcloud/quickcloud.cfg b/tools/devcloud/quickcloud.cfg
index 0e1fb4f..a2613d2 100644
--- a/tools/devcloud/quickcloud.cfg
+++ b/tools/devcloud/quickcloud.cfg
@@ -54,6 +54,7 @@
             "securitygroupenabled": "true", 
             "localstorageenabled": "true",
             "networktype": "Basic", 
+            "networkofferingname": "QuickCloudNoServices", 
             "pods": [
                 {
                     "endip": "192.168.56.220", 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a806ce43/tools/marvin/marvin/deployDataCenter.py
----------------------------------------------------------------------
diff --git a/tools/marvin/marvin/deployDataCenter.py b/tools/marvin/marvin/deployDataCenter.py
index 42bc5f9..d365395 100644
--- a/tools/marvin/marvin/deployDataCenter.py
+++ b/tools/marvin/marvin/deployDataCenter.py
@@ -299,10 +299,11 @@ class deployDataCenters():
 
             if zone.networktype == "Basic":
                 listnetworkoffering = listNetworkOfferings.listNetworkOfferingsCmd()
-                
                 listnetworkoffering.name = "DefaultSharedNetscalerEIPandELBNetworkOffering" \
                         if len(filter(lambda x : x.typ == 'Public', zone.physical_networks[0].traffictypes)) > 0 \
                         else "DefaultSharedNetworkOfferingWithSGService"
+                if zone.networkofferingname  is not None:
+                   listnetworkoffering.name = zone.networkofferingname 
 
                 listnetworkofferingresponse = \
                 self.apiClient.listNetworkOfferings(listnetworkoffering)


[11/19] git commit: updated refs/heads/master to bf56403

Posted by ch...@apache.org.
QuickCloud: launch scripts for secondary storage and console proxy outside system vm

QuickCloud: remove stuff added by the daemon


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

Branch: refs/heads/master
Commit: 936973aff7ba372abe442a7a40e112219fba7570
Parents: c5b11df
Author: Chiradeep Vittal <ch...@apache.org>
Authored: Wed Mar 27 16:49:56 2013 -0700
Committer: Chiradeep Vittal <ch...@apache.org>
Committed: Tue Apr 9 14:45:26 2013 -0700

----------------------------------------------------------------------
 services/console-proxy/server/scripts/_run.sh      |    3 +-
 .../console-proxy/server/scripts/consoleproxy.sh   |   33 +++++++++++++++
 services/secondary-storage/conf/agent.properties   |    4 +-
 services/secondary-storage/scripts/_run.sh         |    3 +-
 services/secondary-storage/scripts/secstorage.sh   |   33 +++++++++++++++
 5 files changed, 71 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/936973af/services/console-proxy/server/scripts/_run.sh
----------------------------------------------------------------------
diff --git a/services/console-proxy/server/scripts/_run.sh b/services/console-proxy/server/scripts/_run.sh
index e408378..bd06346 100755
--- a/services/console-proxy/server/scripts/_run.sh
+++ b/services/console-proxy/server/scripts/_run.sh
@@ -35,6 +35,7 @@ do
   CP=${CP}:$file
 done
 keyvalues=
+LOGHOME=/var/log/cloud/
 
 CMDLINE=$(cat /var/cache/cloud/cmdline)
 
@@ -60,4 +61,4 @@ then
   maxmem=$eightypcnt
 fi
 
-java -Djavax.net.ssl.trustStore=./certs/realhostip.keystore -mx${maxmem}m -cp $CP com.cloud.agent.AgentShell $keyvalues $@
+java -Djavax.net.ssl.trustStore=./certs/realhostip.keystore -Dlog.home=$LOGHOME -mx${maxmem}m -cp $CP com.cloud.agent.AgentShell $keyvalues $@

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/936973af/services/console-proxy/server/scripts/consoleproxy.sh
----------------------------------------------------------------------
diff --git a/services/console-proxy/server/scripts/consoleproxy.sh b/services/console-proxy/server/scripts/consoleproxy.sh
new file mode 100755
index 0000000..4a6acde
--- /dev/null
+++ b/services/console-proxy/server/scripts/consoleproxy.sh
@@ -0,0 +1,33 @@
+#!/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.
+
+
+
+#runs the console proxy as a standalone server
+#i.e., not in the system vm
+
+CP=./:./conf
+for file in *.jar
+do
+  CP=${CP}:$file
+done
+keyvalues=
+#LOGHOME=/var/log/cloud/
+LOGHOME=$PWD
+
+java -Djavax.net.ssl.trustStore=./certs/realhostip.keystore -Dlog.home=$LOGHOME -cp $CP com.cloud.agent.AgentShell $keyvalues $@

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/936973af/services/secondary-storage/conf/agent.properties
----------------------------------------------------------------------
diff --git a/services/secondary-storage/conf/agent.properties b/services/secondary-storage/conf/agent.properties
index 4a25cbd..554007f 100644
--- a/services/secondary-storage/conf/agent.properties
+++ b/services/secondary-storage/conf/agent.properties
@@ -1,6 +1,4 @@
-#Storage
-#Sun Mar 24 22:52:35 PDT 2013
-mount.path=/Users/chiradeep/secondary-storage
+#mount.path=~/secondary-storage
 eth1ip=192.168.56.1
 name=192.168.56.10
 eth2ip=192.168.56.10

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/936973af/services/secondary-storage/scripts/_run.sh
----------------------------------------------------------------------
diff --git a/services/secondary-storage/scripts/_run.sh b/services/secondary-storage/scripts/_run.sh
index e408378..cb9624c 100755
--- a/services/secondary-storage/scripts/_run.sh
+++ b/services/secondary-storage/scripts/_run.sh
@@ -36,6 +36,7 @@ do
 done
 keyvalues=
 
+LOGHOME=/var/log/cloud/
 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"
@@ -60,4 +61,4 @@ then
   maxmem=$eightypcnt
 fi
 
-java -Djavax.net.ssl.trustStore=./certs/realhostip.keystore -mx${maxmem}m -cp $CP com.cloud.agent.AgentShell $keyvalues $@
+java -Djavax.net.ssl.trustStore=./certs/realhostip.keystore -Dlog.home=$LOGHOME -mx${maxmem}m -cp $CP com.cloud.agent.AgentShell $keyvalues $@

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/936973af/services/secondary-storage/scripts/secstorage.sh
----------------------------------------------------------------------
diff --git a/services/secondary-storage/scripts/secstorage.sh b/services/secondary-storage/scripts/secstorage.sh
new file mode 100755
index 0000000..9afc521
--- /dev/null
+++ b/services/secondary-storage/scripts/secstorage.sh
@@ -0,0 +1,33 @@
+#!/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.
+
+
+
+#runs the secondary storage service as a standalone server
+#i.e., not in the system vm
+
+CP=./:./conf
+for file in *.jar
+do
+  CP=${CP}:$file
+done
+keyvalues=
+#LOGHOME=/var/log/cloud/
+LOGHOME=$PWD
+
+java -Djavax.net.ssl.trustStore=./certs/realhostip.keystore -Dlog.home=$LOGHOME -cp $CP com.cloud.agent.AgentShell $keyvalues $@


[09/19] git commit: updated refs/heads/master to bf56403

Posted by ch...@apache.org.
QuickCloud: option to build with componentContext tailored for quickcloud
For now it replaces ConsoleProxyManagerImpl with StaticConsoleProxyManager
Usage: mvn install -Dquickcloud

QuickCloud: rename deploy profile

QuickCloud: remove cyclic dependency introduced in nonoss build by moving SecondaryStorageDiscoverer into services
However with this fix, developers will be unable to run 'PremiumSecondaryStorageResource' (for VMWare installations) using mvn exec:java.
Instead they will have to use the exploded archive from systemvm.zip


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

Branch: refs/heads/master
Commit: c5b11df6b78dd755acc4141dc2063608e581996d
Parents: a806ce4
Author: Chiradeep Vittal <ch...@apache.org>
Authored: Tue Mar 26 16:40:19 2013 -0700
Committer: Chiradeep Vittal <ch...@apache.org>
Committed: Tue Apr 9 14:45:26 2013 -0700

----------------------------------------------------------------------
 client/pom.xml                                     |   16 +
 .../tomcatconf/quickCloudComponentContext.xml.in   |  336 +++++++++++++++
 plugins/hypervisors/simulator/pom.xml              |    5 +
 .../resource/SimulatorSecondaryDiscoverer.java     |    3 +-
 plugins/hypervisors/vmware/pom.xml                 |    5 +
 server/pom.xml                                     |    5 -
 .../secondary/SecondaryStorageDiscoverer.java      |  322 --------------
 services/console-proxy/server/pom.xml              |   10 +-
 services/secondary-storage/pom.xml                 |   28 +-
 .../resource/SecondaryStorageDiscoverer.java       |  320 ++++++++++++++
 tools/devcloud/pom.xml                             |    4 +-
 11 files changed, 695 insertions(+), 359 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c5b11df6/client/pom.xml
----------------------------------------------------------------------
diff --git a/client/pom.xml b/client/pom.xml
index 9323d0f..4bd1a6f 100644
--- a/client/pom.xml
+++ b/client/pom.xml
@@ -453,6 +453,22 @@
               </target>
             </configuration>
           </execution>
+          <execution>
+            <id>process-quickcloud-spring-context</id>
+            <phase>process-resources</phase>
+            <goals>
+              <goal>run</goal>
+            </goals>
+            <configuration>
+              <target if="${quickcloud}">
+                <echo>quickcloud</echo>
+                <replaceregexp
+                  file="${basedir}/target/generated-webapp/WEB-INF/web.xml"
+                  match="classpath:componentContext.xml"
+                  replace="classpath:quickCloudComponentContext.xml" byline="true" />
+              </target>
+            </configuration>
+          </execution>
         </executions>
       </plugin>
       <!-- there are the jasypt libs requires by some of the python scripts -->

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c5b11df6/client/tomcatconf/quickCloudComponentContext.xml.in
----------------------------------------------------------------------
diff --git a/client/tomcatconf/quickCloudComponentContext.xml.in b/client/tomcatconf/quickCloudComponentContext.xml.in
new file mode 100644
index 0000000..dbd3117
--- /dev/null
+++ b/client/tomcatconf/quickCloudComponentContext.xml.in
@@ -0,0 +1,336 @@
+<!--
+  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.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+  xmlns:context="http://www.springframework.org/schema/context"
+  xmlns:tx="http://www.springframework.org/schema/tx" 
+  xmlns:aop="http://www.springframework.org/schema/aop"
+  xsi:schemaLocation="http://www.springframework.org/schema/beans
+                      http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
+                      http://www.springframework.org/schema/tx 
+                      http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
+                      http://www.springframework.org/schema/aop
+                      http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
+                      http://www.springframework.org/schema/context
+                      http://www.springframework.org/schema/context/spring-context-3.0.xsd">                     
+
+
+  <!--
+      Compose a CloudStack deployment with selected components here
+  -->
+  <bean id="databaseUpgradeChecker" class="com.cloud.upgrade.DatabaseUpgradeChecker" />
+  <bean id="encryptionSecretKeyChecker" class="com.cloud.utils.crypt.EncryptionSecretKeyChecker" />
+  <bean id="configurationServerImpl" class="com.cloud.server.ConfigurationServerImpl" />
+  
+  <bean id="managementServerImpl" class ="com.cloud.server.ManagementServerImpl" >
+    <property name="UserAuthenticators">
+        <list>
+            <ref bean="MD5UserAuthenticator"/>
+            <ref bean="LDAPUserAuthenticator"/>
+        </list>
+    </property>
+  </bean>
+ 
+  <bean id ="AccountManagerImpl" class="com.cloud.user.AccountManagerImpl">
+    <property name="UserAuthenticators">
+        <list>
+            <ref bean="MD5UserAuthenticator"/>
+            <ref bean="LDAPUserAuthenticator"/>
+        </list>
+    </property>
+  </bean>
+   
+  <bean id="clusterManagerImpl" class="com.cloud.cluster.ClusterManagerImpl" />
+  <bean id="clusteredAgentManagerImpl" class="com.cloud.agent.manager.ClusteredAgentManagerImpl" />
+  <bean id="clusteredVirtualMachineManagerImpl" class="com.cloud.vm.ClusteredVirtualMachineManagerImpl" />
+  <bean id="highAvailabilityManagerExtImpl" class="com.cloud.ha.HighAvailabilityManagerExtImpl" />
+  <bean id="userVmManagerImpl" class="com.cloud.vm.UserVmManagerImpl" />
+  <bean id="consoleProxyManagerImpl" class="com.cloud.consoleproxy.StaticConsoleProxyManager" />
+  <bean id="securityGroupManagerImpl2" class="com.cloud.network.security.SecurityGroupManagerImpl2" />
+  <bean id="premiumSecondaryStorageManagerImpl" class="com.cloud.secstorage.PremiumSecondaryStorageManagerImpl" />
+  <bean id="userVmDaoImpl" class="com.cloud.vm.dao.UserVmDaoImpl" />
+  <bean id="ipv6AddressManagerImpl" class="com.cloud.network.Ipv6AddressManagerImpl" />
+
+  <bean id="apiRateLimitServiceImpl" class="org.apache.cloudstack.ratelimit.ApiRateLimitServiceImpl"/>
+  <bean id="BaremetalManager" class="com.cloud.baremetal.manager.BaremetalManagerImpl"/>
+  <bean id="BaremetalDhcpManager" class="com.cloud.baremetal.networkservice.BaremetalDhcpManagerImpl"/>
+  <bean id="BaremetalKickStartPxeService" class="com.cloud.baremetal.networkservice.BaremetalKickStartServiceImpl"/>
+  <bean id="BaremetalPingPxeService" class="com.cloud.baremetal.networkservice.BareMetalPingServiceImpl" />
+  <bean id="BaremetalPxeManager" class="com.cloud.baremetal.networkservice.BaremetalPxeManagerImpl" />
+  <bean id="UcsManager" class="com.cloud.ucs.manager.UcsManagerImpl" />
+  <bean id="UcsBladeDao" class="com.cloud.ucs.database.UcsBladeDaoImpl" />
+  <bean id="UcsManagerDao" class="com.cloud.ucs.database.UcsManagerDaoImpl" />
+
+   
+  <!--
+      Network Elements
+  -->
+  <bean id="Ovs" class="com.cloud.network.element.OvsElement">
+    <property name="name" value="Ovs"/>
+  </bean>
+  <bean id="BareMetalDhcp" class="com.cloud.baremetal.networkservice.BaremetalDhcpElement">
+      <property name="name" value="BareMetalDhcp"/>
+  </bean>
+  <bean id="BareMetalPxe" class="com.cloud.baremetal.networkservice.BaremetalPxeElement">
+      <property name="name" value="BareMetalPxe"/>
+  </bean>
+  <bean id="BareMetalUserdata" class="com.cloud.baremetal.networkservice.BaremetalUserdataElement">
+      <property name="name" value="BareMetalUserdata"/>
+  </bean>
+  <bean id="SecurityGroupProvider" class="com.cloud.network.element.SecurityGroupElement">
+    <property name="name" value="SecurityGroupProvider"/>
+  </bean>
+  <bean id="VirtualRouter" class="com.cloud.network.element.VirtualRouterElement">
+    <property name="name" value="VirtualRouter"/>
+  </bean>
+  <bean id="VpcVirtualRouter" class="com.cloud.network.element.VpcVirtualRouterElement">
+    <property name="name" value="VpcVirtualRouter"/>
+  </bean>
+  <!--
+  <bean id="NiciraNvp" class="com.cloud.network.element.NiciraNvpElement">
+    <property name="name" value="NiciraNvp"/>
+  </bean>
+  -->
+  
+<!--
+  <bean id="BigSwitchVnsElementService" class="com.cloud.network.element.BigSwitchVnsElement">
+    <property name="name" value="BigSwitchVnsElementService"/>
+  </bean>
+-->
+                   
+  <!--
+     Adapters
+  -->
+  <bean id="FirstFitRouting" class="com.cloud.agent.manager.allocator.impl.FirstFitRoutingAllocator">
+    <property name="name" value="FirstFitRouting"/>
+  </bean>
+  
+  <bean id="hypervisorTemplateAdapter" class="com.cloud.template.HypervisorTemplateAdapter">
+    <property name="name" value="HypervisorAdapter"/>
+  </bean>
+  
+  <!--
+    Storage pool allocators
+  -->
+
+  <bean id="LocalStoragePoolAllocator" class="org.apache.cloudstack.storage.allocator.LocalStoragePoolAllocator">
+    <property name="name" value="LocalStorage"/>
+  </bean>
+  <!--
+  <bean id="FirstFitStoragePoolAllocator" class="org.apache.cloudstack.storage.allocator.FirstFitStoragePoolAllocator">
+    <property name="name" value="Storage"/>
+  </bean>
+  -->
+
+  <bean id="UserConcentratedAllocator" class="com.cloud.agent.manager.allocator.impl.UserConcentratedAllocator">
+    <property name="name" value="User First"/>
+  </bean>
+
+  <bean id="ConsoleProxyAllocator" class="com.cloud.consoleproxy.ConsoleProxyBalanceAllocator">
+    <property name="name" value="Balance"/>
+  </bean>
+
+  <bean id="StaticRoleBasedAPIAccessChecker" class="org.apache.cloudstack.acl.StaticRoleBasedAPIAccessChecker"/>
+
+  <bean id="ExteralIpAddressAllocator" class="com.cloud.network.ExteralIpAddressAllocator">
+    <property name="name" value="Basic"/>
+  </bean>
+
+  <bean id="HypervisorTemplateAdapter" class="com.cloud.template.HypervisorTemplateAdapter">
+    <property name="name" value="HypervisorAdapter"/>
+  </bean>
+
+  <bean id="BareMetalTemplateAdapter" class="com.cloud.baremetal.manager.BareMetalTemplateAdapter" >
+    <property name="name" value="BareMetalTemplateAdapter"/>
+  </bean>
+
+  <!--
+    Authenticators
+  -->
+  <bean id="MD5UserAuthenticator" class="com.cloud.server.auth.MD5UserAuthenticator">
+    <property name="name" value="MD5"/>
+  </bean>
+
+  <bean id="LDAPUserAuthenticator" class="com.cloud.server.auth.LDAPUserAuthenticator">
+    <property name="name" value="LDAP"/>
+  </bean>
+
+  <!--
+    Investigators
+  -->
+  <bean id="CheckOnAgentInvestigator" class="com.cloud.ha.CheckOnAgentInvestigator">
+    <property name="name" value="SimpleInvestigator"/>
+  </bean>
+
+  <bean id="XenServerInvestigator" class="com.cloud.ha.XenServerInvestigator">
+    <property name="name" value="XenServerInvestigator"/>
+  </bean>
+  
+  <bean id="UserVmDomRInvestigator" class="com.cloud.ha.UserVmDomRInvestigator">
+    <property name="name" value="PingInvestigator"/>
+  </bean>
+
+  <bean id="ManagementIPSystemVMInvestigator" class="com.cloud.ha.ManagementIPSystemVMInvestigator">
+    <property name="name" value="ManagementIPSysVMInvestigator"/>
+  </bean>
+
+  <!--
+    Fencers
+  -->
+  <bean id="XenServerFencer" class="com.cloud.ha.XenServerFencer">
+    <property name="name" value="XenServerFenceBuilder"/>
+  </bean>
+  <bean id="KVMFencer" class="com.cloud.ha.KVMFencer">
+    <property name="name" value="KVMFenceBuilder"/>
+  </bean>
+  <bean id="OvmFencer" class="com.cloud.ovm.hypervisor.OvmFencer">
+    <property name="name" value="OvmFenceBuilder"/>
+  </bean>
+
+  <bean id="XcpServerDiscoverer" class="com.cloud.hypervisor.xen.discoverer.XcpServerDiscoverer">
+    <property name="name" value="XCP Agent"/>
+  </bean>
+
+  <!--
+  <bean id="SimulatorSecondaryStorageDiscoverer" class="com.cloud.resource.SimulatorSecondaryDiscoverer">
+    <property name="name" value="SecondaryStorage"/>
+  </bean>
+  -->
+
+  <bean id="SecondaryStorageDiscoverer" class="org.apache.cloudstack.storage.resource.SecondaryStorageDiscoverer">
+    <property name="name" value="SecondaryStorage"/>
+  </bean>
+
+  <bean id="KvmServerDiscoverer" class="com.cloud.hypervisor.kvm.discoverer.KvmServerDiscoverer">
+    <property name="name" value="KVM Agent"/>
+  </bean>
+
+  <bean id="SimulatorDiscoverer" class="com.cloud.resource.SimulatorDiscoverer">
+    <property name="name" value="Simulator Agent"/>
+  </bean>
+
+
+  <bean id="BareMetalDiscoverer" class="com.cloud.baremetal.manager.BareMetalDiscoverer">
+    <property name="name" value="Bare Metal Agent"/>
+  </bean>
+
+  <bean id="HypervServerDiscoverer" class="com.cloud.hypervisor.hyperv.HypervServerDiscoverer">
+    <property name="name" value="SCVMMServer"/>
+  </bean>
+
+  <bean id="OvmDiscoverer" class="com.cloud.ovm.hypervisor.OvmDiscoverer">
+    <property name="name" value="Ovm Discover"/>
+  </bean>
+
+  <bean id="FirstFitPlanner" class="com.cloud.deploy.FirstFitPlanner">
+    <property name="name" value="First Fit"/>
+  </bean>
+
+  <bean id="UserDispersingPlanner" class="com.cloud.deploy.UserDispersingPlanner">
+    <property name="name" value="UserDispersing"/>
+  </bean>
+  
+  <bean id="UserConcentratedPodPlanner" class="com.cloud.deploy.UserConcentratedPodPlanner">
+    <property name="name" value="UserConcentratedPod"/>
+  </bean>
+
+  <bean id="BareMetalPlanner" class="com.cloud.baremetal.manager.BareMetalPlanner">
+    <property name="name" value="BareMetal Fit"/>
+  </bean>
+    
+  <bean id="BaremetalPlannerSelector" class="com.cloud.baremetal.manager.BaremetalPlannerSelector">
+    <property name="name" value="BaremetalPlannerSelector"/>
+  </bean>
+
+  <bean id="HypervisorPlannerSelector" class="com.cloud.deploy.HypervisorVmPlannerSelector">
+    <property name="name" value="HypervisorPlannerSelector"/>
+  </bean>
+    
+   
+  <!--
+    Network Gurus
+  -->
+  <bean id="StorageNetworkGuru" class="com.cloud.network.guru.StorageNetworkGuru">
+    <property name="name" value="StorageNetworkGuru"/>
+  </bean>
+  <bean id="ExternalGuestNetworkGuru" class="com.cloud.network.guru.ExternalGuestNetworkGuru">
+    <property name="name" value="ExternalGuestNetworkGuru"/>
+  </bean>
+  <bean id="PublicNetworkGuru" class="com.cloud.network.guru.PublicNetworkGuru">
+    <property name="name" value="PublicNetworkGuru"/>
+  </bean>
+  <bean id="PodBasedNetworkGuru" class="com.cloud.network.guru.PodBasedNetworkGuru">
+    <property name="name" value="PodBasedNetworkGuru"/>
+  </bean>
+  <bean id="ControlNetworkGuru" class="com.cloud.network.guru.ControlNetworkGuru">
+    <property name="name" value="ControlNetworkGuru"/>
+  </bean>
+  <bean id="DirectNetworkGuru" class="com.cloud.network.guru.DirectNetworkGuru">
+    <property name="name" value="DirectNetworkGuru"/>
+  </bean>
+  <bean id="DirectPodBasedNetworkGuru" class="com.cloud.network.guru.DirectPodBasedNetworkGuru">
+    <property name="name" value="DirectPodBasedNetworkGuru"/>
+  </bean>
+  <bean id="OvsGuestNetworkGuru" class="com.cloud.network.guru.OvsGuestNetworkGuru">
+    <property name="name" value="OvsGuestNetworkGuru"/>
+  </bean>
+  <bean id="PrivateNetworkGuru" class="com.cloud.network.guru.PrivateNetworkGuru">
+    <property name="name" value="PrivateNetworkGuru"/>
+  </bean>
+  <bean id="NiciraNvpGuestNetworkGuru" class="com.cloud.network.guru.NiciraNvpGuestNetworkGuru">
+    <property name="name" value="NiciraNvpGuestNetworkGuru"/>
+  </bean>
+  
+<!--  
+  <bean id="BigSwitchVnsGuestNetworkGuru" class=".BigSwitchVnsGuestNetworkGuru">
+    <property name="name" value="com.cloud.network.guru.BigSwitchVnsGuestNetworkGuru"/>
+  </bean>
+-->
+ 
+  <!--
+   Hypervisor Gurus
+  -->
+  <bean id="XenServerGuru" class="com.cloud.hypervisor.XenServerGuru">
+    <property name="name" value="XenServerGuru"/>
+  </bean>
+  
+  <bean id="KVMGuru" class="com.cloud.hypervisor.KVMGuru">
+    <property name="name" value="KVMGuru"/>
+  </bean>
+  
+  <bean id="HypervGuru" class="com.cloud.hypervisor.guru.HypervGuru">
+    <property name="name" value="HypervGuru"/>
+  </bean>
+
+  <bean id="OvmGuru" class="com.cloud.ovm.hypervisor.OvmGuru">
+    <property name="name" value="OvmGuru"/>
+  </bean>
+  
+  <bean id="SimulatorGuru" class="com.cloud.simulator.SimulatorGuru">
+    <property name="name" value="SimulatorGuru"/>
+  </bean>
+
+  <bean id="BaremetalGuru" class="com.cloud.baremetal.manager.BareMetalGuru">
+    <property name="name" value="BaremetalGuru"/>
+  </bean>
+
+  <bean id="ClassicalPrimaryDataStoreProvider" class="org.apache.cloudstack.storage.datastore.provider.CloudStackPrimaryDataStoreProviderImpl">
+  </bean>
+  
+</beans>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c5b11df6/plugins/hypervisors/simulator/pom.xml
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/simulator/pom.xml b/plugins/hypervisors/simulator/pom.xml
index ff1664a..e4ca927 100644
--- a/plugins/hypervisors/simulator/pom.xml
+++ b/plugins/hypervisors/simulator/pom.xml
@@ -40,5 +40,10 @@
       <artifactId>cloud-utils</artifactId>
       <version>${project.version}</version>
     </dependency>
+    <dependency>
+      <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-secondary-storage</artifactId>
+      <version>${project.version}</version>
+    </dependency>
   </dependencies>
 </project>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c5b11df6/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorSecondaryDiscoverer.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorSecondaryDiscoverer.java b/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorSecondaryDiscoverer.java
index 3a8cf17..c121fba 100644
--- a/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorSecondaryDiscoverer.java
+++ b/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorSecondaryDiscoverer.java
@@ -24,6 +24,7 @@ import javax.ejb.Local;
 import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
+import org.apache.cloudstack.storage.resource.SecondaryStorageDiscoverer;
 import org.apache.log4j.Logger;
 
 import com.cloud.agent.AgentManager;
@@ -40,9 +41,7 @@ import com.cloud.host.HostVO;
 import com.cloud.host.Status;
 import com.cloud.storage.SnapshotVO;
 import com.cloud.storage.dao.SnapshotDao;
-import com.cloud.storage.secondary.SecondaryStorageDiscoverer;
 import com.cloud.utils.exception.CloudRuntimeException;
-import org.springframework.stereotype.Component;
 
 
 @Local(value=Discoverer.class)

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c5b11df6/plugins/hypervisors/vmware/pom.xml
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/vmware/pom.xml b/plugins/hypervisors/vmware/pom.xml
index 468e0a5..d65ef64 100644
--- a/plugins/hypervisors/vmware/pom.xml
+++ b/plugins/hypervisors/vmware/pom.xml
@@ -33,6 +33,11 @@
       <version>${project.version}</version>
     </dependency>
     <dependency>
+      <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-secondary-storage</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
       <groupId>com.cloud.com.vmware</groupId>
       <artifactId>vmware-vim25</artifactId>
       <version>${cs.vmware.api.version}</version>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c5b11df6/server/pom.xml
----------------------------------------------------------------------
diff --git a/server/pom.xml b/server/pom.xml
index 8a6a10c..a397195 100644
--- a/server/pom.xml
+++ b/server/pom.xml
@@ -32,11 +32,6 @@
       <version>${project.version}</version>
     </dependency>
     <dependency>
-      <groupId>org.apache.cloudstack</groupId>
-      <artifactId>cloud-secondary-storage</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    <dependency>
       <groupId>javax.servlet</groupId>
       <artifactId>servlet-api</artifactId>
       <version>${cs.servlet.version}</version>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c5b11df6/server/src/com/cloud/storage/secondary/SecondaryStorageDiscoverer.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/secondary/SecondaryStorageDiscoverer.java b/server/src/com/cloud/storage/secondary/SecondaryStorageDiscoverer.java
deleted file mode 100755
index 6e66e0d..0000000
--- a/server/src/com/cloud/storage/secondary/SecondaryStorageDiscoverer.java
+++ /dev/null
@@ -1,322 +0,0 @@
-// 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.storage.secondary;
-
-import java.io.File;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.net.URI;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-
-import javax.ejb.Local;
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.apache.cloudstack.storage.resource.LocalSecondaryStorageResource;
-import org.apache.cloudstack.storage.resource.NfsSecondaryStorageResource;
-import org.apache.log4j.Logger;
-
-import com.cloud.agent.AgentManager;
-import com.cloud.configuration.dao.ConfigurationDao;
-import com.cloud.host.HostVO;
-import com.cloud.host.Status.Event;
-import com.cloud.host.dao.HostDao;
-import com.cloud.hypervisor.Hypervisor;
-import com.cloud.resource.Discoverer;
-import com.cloud.resource.DiscovererBase;
-import com.cloud.resource.ServerResource;
-import com.cloud.storage.VMTemplateVO;
-import com.cloud.storage.VMTemplateZoneVO;
-import com.cloud.storage.dao.VMTemplateDao;
-import com.cloud.storage.dao.VMTemplateHostDao;
-import com.cloud.storage.dao.VMTemplateZoneDao;
-import com.cloud.storage.resource.DummySecondaryStorageResource;
-import com.cloud.utils.component.ComponentContext;
-import com.cloud.utils.net.NfsUtils;
-import com.cloud.utils.script.Script;
-
-/**
- * SecondaryStorageDiscoverer is used to discover secondary
- * storage servers and make sure everything it can do is
- * correct.
- */
-@Local(value=Discoverer.class)
-public class SecondaryStorageDiscoverer extends DiscovererBase implements Discoverer {
-    private static final Logger s_logger = Logger.getLogger(SecondaryStorageDiscoverer.class);
-    
-    long _timeout = 2 * 60 * 1000; // 2 minutes
-    String _mountParent;
-    boolean _useServiceVM = false;
-    
-    Random _random = new Random(System.currentTimeMillis());
-    @Inject
-    protected HostDao _hostDao = null;
-    @Inject
-    protected VMTemplateDao _tmpltDao = null;
-    @Inject
-    protected VMTemplateHostDao _vmTemplateHostDao = null;
-    @Inject
-    protected VMTemplateZoneDao _vmTemplateZoneDao = null;
-    @Inject
-    protected VMTemplateDao _vmTemplateDao = null;
-    @Inject
-    protected ConfigurationDao _configDao = null;
-    @Inject
-    protected AgentManager _agentMgr = null;
-    
-    protected SecondaryStorageDiscoverer() {
-    }
-    
-    @Override
-    public Map<? extends ServerResource, Map<String, String>> find(long dcId, Long podId, Long clusterId, URI uri, String username, String password, List<String> hostTags) {
-        if (!uri.getScheme().equalsIgnoreCase("nfs") && !uri.getScheme().equalsIgnoreCase("file")
-                && !uri.getScheme().equalsIgnoreCase("iso") && !uri.getScheme().equalsIgnoreCase("dummy")) {
-            s_logger.debug("It's not NFS or file or ISO, so not a secondary storage server: " + uri.toString());
-            return null;
-        }
-
-        if (uri.getScheme().equalsIgnoreCase("nfs") || uri.getScheme().equalsIgnoreCase("iso")) {
-            return createNfsSecondaryStorageResource(dcId, podId, uri);
-        } else if (uri.getScheme().equalsIgnoreCase("file")) {
-            return createLocalSecondaryStorageResource(dcId, podId, uri);
-        } else if (uri.getScheme().equalsIgnoreCase("dummy")) {
-            return createDummySecondaryStorageResource(dcId, podId, uri);
-        } else {
-            return null;
-        }
-    }
-    
-    protected Map<? extends ServerResource, Map<String, String>> createNfsSecondaryStorageResource(long dcId, Long podId, URI uri) {
-        
-    	if (_useServiceVM) {
-    	    return createDummySecondaryStorageResource(dcId, podId, uri);
-    	}
-        String mountStr = NfsUtils.uri2Mount(uri);
-        
-        Script script = new Script(true, "mount", _timeout, s_logger);
-        String mntPoint = null;
-        File file = null;
-        do {
-            mntPoint = _mountParent + File.separator + Integer.toHexString(_random.nextInt(Integer.MAX_VALUE));
-            file = new File(mntPoint);
-        } while (file.exists());
-                
-        if (!file.mkdirs()) {
-            s_logger.warn("Unable to make directory: " + mntPoint);
-            return null;
-        }
-        
-        script.add(mountStr, mntPoint);
-        String result = script.execute();
-        if (result != null && !result.contains("already mounted")) {
-            s_logger.warn("Unable to mount " + uri.toString() + " due to " + result);
-            file.delete();
-            return null;
-        }
-        
-        script = new Script(true, "umount", 0, s_logger);
-        script.add(mntPoint);
-        script.execute();
-        
-        file.delete();
-        
-        Map<NfsSecondaryStorageResource, Map<String, String>> srs = new HashMap<NfsSecondaryStorageResource, Map<String, String>>();
-        
-        NfsSecondaryStorageResource storage;
-        if(_configDao.isPremium()) {
-            Class<?> impl;
-            String name = "com.cloud.storage.resource.PremiumSecondaryStorageResource";
-            try {
-                impl = Class.forName(name);
-                final Constructor<?> constructor = impl.getDeclaredConstructor();
-                constructor.setAccessible(true);
-                storage = (NfsSecondaryStorageResource)constructor.newInstance();
-            } catch (final ClassNotFoundException e) {
-            	s_logger.error("Unable to load com.cloud.storage.resource.PremiumSecondaryStorageResource due to ClassNotFoundException");
-            	return null;
-            } catch (final SecurityException e) {
-            	s_logger.error("Unable to load com.cloud.storage.resource.PremiumSecondaryStorageResource due to SecurityException");
-            	return null;
-            } catch (final NoSuchMethodException e) {
-            	s_logger.error("Unable to load com.cloud.storage.resource.PremiumSecondaryStorageResource due to NoSuchMethodException");
-            	return null;
-            } catch (final IllegalArgumentException e) {
-            	s_logger.error("Unable to load com.cloud.storage.resource.PremiumSecondaryStorageResource due to IllegalArgumentException");
-            	return null;
-            } catch (final InstantiationException e) {
-            	s_logger.error("Unable to load com.cloud.storage.resource.PremiumSecondaryStorageResource due to InstantiationException");
-            	return null;
-            } catch (final IllegalAccessException e) {
-            	s_logger.error("Unable to load com.cloud.storage.resource.PremiumSecondaryStorageResource due to IllegalAccessException");
-            	return null;
-            } catch (final InvocationTargetException e) {
-            	s_logger.error("Unable to load com.cloud.storage.resource.PremiumSecondaryStorageResource due to InvocationTargetException");
-            	return null;
-            }
-        } else {
-        	storage = new NfsSecondaryStorageResource();
-        }
-        
-        Map<String, String> details = new HashMap<String, String>();
-        details.put("mount.path", mountStr);
-        details.put("orig.url", uri.toString());
-        details.put("mount.parent", _mountParent);
-        
-        Map<String, Object> params = new HashMap<String, Object>();
-        params.putAll(details);
-        params.put("zone", Long.toString(dcId));
-        if (podId != null) {
-            params.put("pod", podId.toString());
-        }
-        params.put("guid", uri.toString());
-        params.put("secondary.storage.vm", "false");
-        params.put("max.template.iso.size", _configDao.getValue("max.template.iso.size"));
-        
-        try {
-            storage.configure("Storage", params);
-        } catch (ConfigurationException e) {
-            s_logger.warn("Unable to configure the storage ", e);
-            return null;
-        }
-        srs.put(storage, details);
-        
-        return srs;
-    }
-    
-    protected Map<? extends ServerResource, Map<String, String>> createLocalSecondaryStorageResource(long dcId, Long podId, URI uri) {
-        Map<LocalSecondaryStorageResource, Map<String, String>> srs = new HashMap<LocalSecondaryStorageResource, Map<String, String>>();
-        
-        LocalSecondaryStorageResource storage = new LocalSecondaryStorageResource();
-        storage = ComponentContext.inject(storage);
-        
-        Map<String, String> details = new HashMap<String, String>();
-        
-        File file = new File(uri);
-        details.put("mount.path", file.getAbsolutePath());
-        details.put("orig.url", uri.toString());
-        
-        Map<String, Object> params = new HashMap<String, Object>();
-        params.putAll(details);
-        params.put("zone", Long.toString(dcId));
-        if (podId != null) {
-            params.put("pod", podId.toString());
-        }
-        params.put("guid", uri.toString());
-        
-        try {
-            storage.configure("Storage", params);
-        } catch (ConfigurationException e) {
-            s_logger.warn("Unable to configure the storage ", e);
-            return null;
-        }
-        srs.put(storage, details);
-        
-        return srs;
-    }
-    
-    protected Map<ServerResource, Map<String, String>> createDummySecondaryStorageResource(long dcId, Long podId, URI uri) {
-        Map<ServerResource, Map<String, String>> srs = new HashMap<ServerResource, Map<String, String>>();
-        
-        DummySecondaryStorageResource storage = new DummySecondaryStorageResource(_useServiceVM);
-        storage = ComponentContext.inject(storage);
-        
-        Map<String, String> details = new HashMap<String, String>();
-        
-        details.put("mount.path", uri.toString());
-        details.put("orig.url", uri.toString());
-        
-        Map<String, Object> params = new HashMap<String, Object>();
-        params.putAll(details);
-        params.put("zone", Long.toString(dcId));
-        if (podId != null) {
-            params.put("pod", podId.toString());
-        }
-        params.put("guid", uri.toString());
-        
-        try {
-            storage.configure("Storage", params);
-        } catch (ConfigurationException e) {
-            s_logger.warn("Unable to configure the storage ", e);
-            return null;
-        }
-        srs.put(storage, details);
-        
-        return srs;
-    }
-    
-    @Override
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-        super.configure(name, params);
-        
-        _mountParent = _params.get("mount.parent");
-        if (_mountParent == null) {
-            _mountParent = "/mnt";
-        }
-        
-        String useServiceVM = _params.get("secondary.storage.vm");
-        if ("true".equalsIgnoreCase(useServiceVM)){
-        	_useServiceVM = true;
-        }
-        return true;
-    }
-    
-    @Override
-	public boolean matchHypervisor(String hypervisor) {
-        if( hypervisor.equals("SecondaryStorage")) {
-            return true;
-        } else {
-            return false;
-        }
-    }
-
-    @Override
-	public Hypervisor.HypervisorType getHypervisorType() {
-    	return Hypervisor.HypervisorType.None;
-    }
-    
-	@Override
-	public void postDiscovery(List<HostVO> hosts, long msId) {
-		if (_useServiceVM) {
-			for (HostVO h: hosts) {
-				_agentMgr.agentStatusTransitTo(h, Event.AgentDisconnected, msId);
-			}
-		}
-		for (HostVO h: hosts) {
-			associateTemplatesToZone(h.getId(), h.getDataCenterId());
-		}
-		
-	}
-	
-    private void associateTemplatesToZone(long hostId, long dcId){
-    	VMTemplateZoneVO tmpltZone;
-
-    	List<VMTemplateVO> allTemplates = _vmTemplateDao.listAll();
-    	for (VMTemplateVO vt: allTemplates){
-    		if (vt.isCrossZones()) {
-    			tmpltZone = _vmTemplateZoneDao.findByZoneTemplate(dcId, vt.getId());
-    			if (tmpltZone == null) {
-    				VMTemplateZoneVO vmTemplateZone = new VMTemplateZoneVO(dcId, vt.getId(), new Date());
-    				_vmTemplateZoneDao.persist(vmTemplateZone);
-    			}
-    		}
-    	}
-    }
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c5b11df6/services/console-proxy/server/pom.xml
----------------------------------------------------------------------
diff --git a/services/console-proxy/server/pom.xml b/services/console-proxy/server/pom.xml
index fd7b964..3d149a5 100644
--- a/services/console-proxy/server/pom.xml
+++ b/services/console-proxy/server/pom.xml
@@ -57,6 +57,11 @@
       <version>${project.version}</version>
       <type>pom</type>
     </dependency>
+    <dependency>
+      <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-secondary-storage</artifactId>
+      <version>${project.version}</version>
+    </dependency>
   </dependencies>
   <build>
     <defaultGoal>install</defaultGoal>
@@ -256,11 +261,6 @@
     </profile>
     <profile>
       <id>quickcloud</id>
-      <activation>
-        <property>
-          <name>quickcloud</name>
-        </property>
-      </activation>
       <build>
       <plugins>
       <plugin>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c5b11df6/services/secondary-storage/pom.xml
----------------------------------------------------------------------
diff --git a/services/secondary-storage/pom.xml b/services/secondary-storage/pom.xml
index d8dbf1d..0577084 100644
--- a/services/secondary-storage/pom.xml
+++ b/services/secondary-storage/pom.xml
@@ -54,6 +54,11 @@
       <version>${project.version}</version>
       <type>pom</type>
     </dependency>
+    <dependency>
+      <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-server</artifactId>
+      <version>${project.version}</version>
+    </dependency>
   </dependencies>
   <build>
     <defaultGoal>install</defaultGoal>
@@ -87,27 +92,4 @@
       </plugin>
     </plugins>
   </build>
-  <profiles>
-    <profile>
-      <id>vmware</id>
-      <activation>
-        <property>
-          <name>nonoss</name>
-        </property>
-      </activation>
-        <dependencies>
-            <dependency>
-                <groupId>org.apache.cloudstack</groupId>
-                <artifactId>cloud-plugin-hypervisor-vmware</artifactId>
-                <version>${project.version}</version>
-            </dependency>
-            <dependency>
-                <groupId>org.apache.cloudstack</groupId>
-                <artifactId>cloud-vmware-base</artifactId>
-                <version>${project.version}</version>
-            </dependency>
-        </dependencies>
-    </profile>
-  </profiles>
-
 </project>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c5b11df6/services/secondary-storage/src/org/apache/cloudstack/storage/resource/SecondaryStorageDiscoverer.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/SecondaryStorageDiscoverer.java b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/SecondaryStorageDiscoverer.java
new file mode 100755
index 0000000..d3af792
--- /dev/null
+++ b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/SecondaryStorageDiscoverer.java
@@ -0,0 +1,320 @@
+// 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.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.net.URI;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+
+import javax.ejb.Local;
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.configuration.dao.ConfigurationDao;
+import com.cloud.host.HostVO;
+import com.cloud.host.Status.Event;
+import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor;
+import com.cloud.resource.Discoverer;
+import com.cloud.resource.DiscovererBase;
+import com.cloud.resource.ServerResource;
+import com.cloud.storage.VMTemplateVO;
+import com.cloud.storage.VMTemplateZoneVO;
+import com.cloud.storage.dao.VMTemplateDao;
+import com.cloud.storage.dao.VMTemplateHostDao;
+import com.cloud.storage.dao.VMTemplateZoneDao;
+import com.cloud.storage.resource.DummySecondaryStorageResource;
+import com.cloud.utils.component.ComponentContext;
+import com.cloud.utils.net.NfsUtils;
+import com.cloud.utils.script.Script;
+
+/**
+ * SecondaryStorageDiscoverer is used to discover secondary
+ * storage servers and make sure everything it can do is
+ * correct.
+ */
+@Local(value=Discoverer.class)
+public class SecondaryStorageDiscoverer extends DiscovererBase implements Discoverer {
+    private static final Logger s_logger = Logger.getLogger(SecondaryStorageDiscoverer.class);
+    
+    long _timeout = 2 * 60 * 1000; // 2 minutes
+    String _mountParent;
+    boolean _useServiceVM = false;
+    
+    Random _random = new Random(System.currentTimeMillis());
+    @Inject
+    protected HostDao _hostDao = null;
+    @Inject
+    protected VMTemplateDao _tmpltDao = null;
+    @Inject
+    protected VMTemplateHostDao _vmTemplateHostDao = null;
+    @Inject
+    protected VMTemplateZoneDao _vmTemplateZoneDao = null;
+    @Inject
+    protected VMTemplateDao _vmTemplateDao = null;
+    @Inject
+    protected ConfigurationDao _configDao = null;
+    @Inject
+    protected AgentManager _agentMgr = null;
+    
+    protected SecondaryStorageDiscoverer() {
+    }
+    
+    @Override
+    public Map<? extends ServerResource, Map<String, String>> find(long dcId, Long podId, Long clusterId, URI uri, String username, String password, List<String> hostTags) {
+        if (!uri.getScheme().equalsIgnoreCase("nfs") && !uri.getScheme().equalsIgnoreCase("file")
+                && !uri.getScheme().equalsIgnoreCase("iso") && !uri.getScheme().equalsIgnoreCase("dummy")) {
+            s_logger.debug("It's not NFS or file or ISO, so not a secondary storage server: " + uri.toString());
+            return null;
+        }
+
+        if (uri.getScheme().equalsIgnoreCase("nfs") || uri.getScheme().equalsIgnoreCase("iso")) {
+            return createNfsSecondaryStorageResource(dcId, podId, uri);
+        } else if (uri.getScheme().equalsIgnoreCase("file")) {
+            return createLocalSecondaryStorageResource(dcId, podId, uri);
+        } else if (uri.getScheme().equalsIgnoreCase("dummy")) {
+            return createDummySecondaryStorageResource(dcId, podId, uri);
+        } else {
+            return null;
+        }
+    }
+    
+    protected Map<? extends ServerResource, Map<String, String>> createNfsSecondaryStorageResource(long dcId, Long podId, URI uri) {
+        
+    	if (_useServiceVM) {
+    	    return createDummySecondaryStorageResource(dcId, podId, uri);
+    	}
+        String mountStr = NfsUtils.uri2Mount(uri);
+        
+        Script script = new Script(true, "mount", _timeout, s_logger);
+        String mntPoint = null;
+        File file = null;
+        do {
+            mntPoint = _mountParent + File.separator + Integer.toHexString(_random.nextInt(Integer.MAX_VALUE));
+            file = new File(mntPoint);
+        } while (file.exists());
+                
+        if (!file.mkdirs()) {
+            s_logger.warn("Unable to make directory: " + mntPoint);
+            return null;
+        }
+        
+        script.add(mountStr, mntPoint);
+        String result = script.execute();
+        if (result != null && !result.contains("already mounted")) {
+            s_logger.warn("Unable to mount " + uri.toString() + " due to " + result);
+            file.delete();
+            return null;
+        }
+        
+        script = new Script(true, "umount", 0, s_logger);
+        script.add(mntPoint);
+        script.execute();
+        
+        file.delete();
+        
+        Map<NfsSecondaryStorageResource, Map<String, String>> srs = new HashMap<NfsSecondaryStorageResource, Map<String, String>>();
+        
+        NfsSecondaryStorageResource storage;
+        if(_configDao.isPremium()) {
+            Class<?> impl;
+            String name = "com.cloud.storage.resource.PremiumSecondaryStorageResource";
+            try {
+                impl = Class.forName(name);
+                final Constructor<?> constructor = impl.getDeclaredConstructor();
+                constructor.setAccessible(true);
+                storage = (NfsSecondaryStorageResource)constructor.newInstance();
+            } catch (final ClassNotFoundException e) {
+            	s_logger.error("Unable to load com.cloud.storage.resource.PremiumSecondaryStorageResource due to ClassNotFoundException");
+            	return null;
+            } catch (final SecurityException e) {
+            	s_logger.error("Unable to load com.cloud.storage.resource.PremiumSecondaryStorageResource due to SecurityException");
+            	return null;
+            } catch (final NoSuchMethodException e) {
+            	s_logger.error("Unable to load com.cloud.storage.resource.PremiumSecondaryStorageResource due to NoSuchMethodException");
+            	return null;
+            } catch (final IllegalArgumentException e) {
+            	s_logger.error("Unable to load com.cloud.storage.resource.PremiumSecondaryStorageResource due to IllegalArgumentException");
+            	return null;
+            } catch (final InstantiationException e) {
+            	s_logger.error("Unable to load com.cloud.storage.resource.PremiumSecondaryStorageResource due to InstantiationException");
+            	return null;
+            } catch (final IllegalAccessException e) {
+            	s_logger.error("Unable to load com.cloud.storage.resource.PremiumSecondaryStorageResource due to IllegalAccessException");
+            	return null;
+            } catch (final InvocationTargetException e) {
+            	s_logger.error("Unable to load com.cloud.storage.resource.PremiumSecondaryStorageResource due to InvocationTargetException");
+            	return null;
+            }
+        } else {
+        	storage = new NfsSecondaryStorageResource();
+        }
+        
+        Map<String, String> details = new HashMap<String, String>();
+        details.put("mount.path", mountStr);
+        details.put("orig.url", uri.toString());
+        details.put("mount.parent", _mountParent);
+        
+        Map<String, Object> params = new HashMap<String, Object>();
+        params.putAll(details);
+        params.put("zone", Long.toString(dcId));
+        if (podId != null) {
+            params.put("pod", podId.toString());
+        }
+        params.put("guid", uri.toString());
+        params.put("secondary.storage.vm", "false");
+        params.put("max.template.iso.size", _configDao.getValue("max.template.iso.size"));
+        
+        try {
+            storage.configure("Storage", params);
+        } catch (ConfigurationException e) {
+            s_logger.warn("Unable to configure the storage ", e);
+            return null;
+        }
+        srs.put(storage, details);
+        
+        return srs;
+    }
+    
+    protected Map<? extends ServerResource, Map<String, String>> createLocalSecondaryStorageResource(long dcId, Long podId, URI uri) {
+        Map<LocalSecondaryStorageResource, Map<String, String>> srs = new HashMap<LocalSecondaryStorageResource, Map<String, String>>();
+        
+        LocalSecondaryStorageResource storage = new LocalSecondaryStorageResource();
+        storage = ComponentContext.inject(storage);
+        
+        Map<String, String> details = new HashMap<String, String>();
+        
+        File file = new File(uri);
+        details.put("mount.path", file.getAbsolutePath());
+        details.put("orig.url", uri.toString());
+        
+        Map<String, Object> params = new HashMap<String, Object>();
+        params.putAll(details);
+        params.put("zone", Long.toString(dcId));
+        if (podId != null) {
+            params.put("pod", podId.toString());
+        }
+        params.put("guid", uri.toString());
+        
+        try {
+            storage.configure("Storage", params);
+        } catch (ConfigurationException e) {
+            s_logger.warn("Unable to configure the storage ", e);
+            return null;
+        }
+        srs.put(storage, details);
+        
+        return srs;
+    }
+    
+    protected Map<ServerResource, Map<String, String>> createDummySecondaryStorageResource(long dcId, Long podId, URI uri) {
+        Map<ServerResource, Map<String, String>> srs = new HashMap<ServerResource, Map<String, String>>();
+        
+        DummySecondaryStorageResource storage = new DummySecondaryStorageResource(_useServiceVM);
+        storage = ComponentContext.inject(storage);
+        
+        Map<String, String> details = new HashMap<String, String>();
+        
+        details.put("mount.path", uri.toString());
+        details.put("orig.url", uri.toString());
+        
+        Map<String, Object> params = new HashMap<String, Object>();
+        params.putAll(details);
+        params.put("zone", Long.toString(dcId));
+        if (podId != null) {
+            params.put("pod", podId.toString());
+        }
+        params.put("guid", uri.toString());
+        
+        try {
+            storage.configure("Storage", params);
+        } catch (ConfigurationException e) {
+            s_logger.warn("Unable to configure the storage ", e);
+            return null;
+        }
+        srs.put(storage, details);
+        
+        return srs;
+    }
+    
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+        super.configure(name, params);
+        
+        _mountParent = _params.get("mount.parent");
+        if (_mountParent == null) {
+            _mountParent = "/mnt";
+        }
+        
+        String useServiceVM = _params.get("secondary.storage.vm");
+        if ("true".equalsIgnoreCase(useServiceVM)){
+        	_useServiceVM = true;
+        }
+        return true;
+    }
+    
+    @Override
+	public boolean matchHypervisor(String hypervisor) {
+        if( hypervisor.equals("SecondaryStorage")) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    @Override
+	public Hypervisor.HypervisorType getHypervisorType() {
+    	return Hypervisor.HypervisorType.None;
+    }
+    
+	@Override
+	public void postDiscovery(List<HostVO> hosts, long msId) {
+		if (_useServiceVM) {
+			for (HostVO h: hosts) {
+				_agentMgr.agentStatusTransitTo(h, Event.AgentDisconnected, msId);
+			}
+		}
+		for (HostVO h: hosts) {
+			associateTemplatesToZone(h.getId(), h.getDataCenterId());
+		}
+		
+	}
+	
+    private void associateTemplatesToZone(long hostId, long dcId){
+    	VMTemplateZoneVO tmpltZone;
+
+    	List<VMTemplateVO> allTemplates = _vmTemplateDao.listAll();
+    	for (VMTemplateVO vt: allTemplates){
+    		if (vt.isCrossZones()) {
+    			tmpltZone = _vmTemplateZoneDao.findByZoneTemplate(dcId, vt.getId());
+    			if (tmpltZone == null) {
+    				VMTemplateZoneVO vmTemplateZone = new VMTemplateZoneVO(dcId, vt.getId(), new Date());
+    				_vmTemplateZoneDao.persist(vmTemplateZone);
+    			}
+    		}
+    	}
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c5b11df6/tools/devcloud/pom.xml
----------------------------------------------------------------------
diff --git a/tools/devcloud/pom.xml b/tools/devcloud/pom.xml
index d32d84b..93029e1 100644
--- a/tools/devcloud/pom.xml
+++ b/tools/devcloud/pom.xml
@@ -143,10 +143,10 @@
       </build>
     </profile>
     <profile>
-      <id>quicksvr</id>
+      <id>quickcloud</id>
       <activation>
         <property>
-          <name>quicksvr</name>
+          <name>quickcloud</name>
         </property>
       </activation>
       <build> 


[08/19] git commit: updated refs/heads/master to bf56403

Posted by ch...@apache.org.
QuickCloud: move devcloud configuration into pom profile for exec:java
Also ignore agent.properties in RAT since
a. they are trivial
b. they are modified by the java code (stripping the license)

QuickCloud: proper path for log.home

QuickCloud: proper path for secstorage.sh


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

Branch: refs/heads/master
Commit: 778a59fbf6bc8957771718123079bd8a2707affa
Parents: 5ff8bca
Author: Chiradeep Vittal <ch...@apache.org>
Authored: Fri Apr 5 14:25:44 2013 -0700
Committer: Chiradeep Vittal <ch...@apache.org>
Committed: Tue Apr 9 14:45:26 2013 -0700

----------------------------------------------------------------------
 pom.xml                                            |    4 ++
 .../console-proxy/server/conf/agent.properties     |   17 --------
 services/console-proxy/server/pom.xml              |    3 +
 .../console-proxy/server/scripts/consoleproxy.sh   |    2 +-
 .../console-proxy/server/scripts/secstorage.sh     |   33 +++++++++++++++
 services/secondary-storage/conf/agent.properties   |    9 +----
 services/secondary-storage/pom.xml                 |    8 ++++
 services/secondary-storage/scripts/secstorage.sh   |   33 ---------------
 8 files changed, 50 insertions(+), 59 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/778a59fb/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 6208124..dbc3907 100644
--- a/pom.xml
+++ b/pom.xml
@@ -317,6 +317,10 @@
               <exclude>deps/XenServerJava/Makefile</exclude>
               <exclude>dist/console-proxy/js/jquery.js</exclude>
               <exclude>scripts/vm/systemvm/id_rsa.cloud</exclude>
+              <exclude>services/console-proxy/server/conf/agent.properties</exclude>
+              <exclude>services/console-proxy/server/conf/environment.properties</exclude>
+              <exclude>services/secondary-storage/conf/agent.properties</exclude>
+              <exclude>services/secondary-storage/conf/environment.properties</exclude>
               <exclude>tools/devcloud/basebuild/puppet-devcloudinitial/files/network.conf</exclude>
               <exclude>tools/appliance/definitions/devcloud/*</exclude>
               <exclude>tools/appliance/definitions/systemvmtemplate/*</exclude>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/778a59fb/services/console-proxy/server/conf/agent.properties
----------------------------------------------------------------------
diff --git a/services/console-proxy/server/conf/agent.properties b/services/console-proxy/server/conf/agent.properties
index 4e217f2..246cb1c 100644
--- a/services/console-proxy/server/conf/agent.properties
+++ b/services/console-proxy/server/conf/agent.properties
@@ -1,19 +1,2 @@
-# 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.
-
 instance=ConsoleProxy
 resource=com.cloud.agent.resource.consoleproxy.ConsoleProxyResource

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/778a59fb/services/console-proxy/server/pom.xml
----------------------------------------------------------------------
diff --git a/services/console-proxy/server/pom.xml b/services/console-proxy/server/pom.xml
index 3d149a5..3ac5d59 100644
--- a/services/console-proxy/server/pom.xml
+++ b/services/console-proxy/server/pom.xml
@@ -280,11 +280,14 @@
             <argument>zone=1</argument>
             <argument>pod=1</argument>
             <argument>host=192.168.56.1</argument>
+            <argument>guid=ConsoleProxy.1</argument>
           </arguments>
           <systemProperties>
             <systemProperty>
               <key>javax.net.ssl.trustStore</key>
               <value>certs/realhostip.keystore</value>
+              <key>log.home</key>
+              <value>${PWD}/</value>
             </systemProperty>
           </systemProperties>
         </configuration>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/778a59fb/services/console-proxy/server/scripts/consoleproxy.sh
----------------------------------------------------------------------
diff --git a/services/console-proxy/server/scripts/consoleproxy.sh b/services/console-proxy/server/scripts/consoleproxy.sh
index 4a6acde..294d597 100755
--- a/services/console-proxy/server/scripts/consoleproxy.sh
+++ b/services/console-proxy/server/scripts/consoleproxy.sh
@@ -28,6 +28,6 @@ do
 done
 keyvalues=
 #LOGHOME=/var/log/cloud/
-LOGHOME=$PWD
+LOGHOME=$PWD/
 
 java -Djavax.net.ssl.trustStore=./certs/realhostip.keystore -Dlog.home=$LOGHOME -cp $CP com.cloud.agent.AgentShell $keyvalues $@

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/778a59fb/services/console-proxy/server/scripts/secstorage.sh
----------------------------------------------------------------------
diff --git a/services/console-proxy/server/scripts/secstorage.sh b/services/console-proxy/server/scripts/secstorage.sh
new file mode 100755
index 0000000..b45afc2
--- /dev/null
+++ b/services/console-proxy/server/scripts/secstorage.sh
@@ -0,0 +1,33 @@
+#!/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.
+
+
+
+#runs the secondary storage service as a standalone server
+#i.e., not in the system vm
+
+CP=./:./conf
+for file in *.jar
+do
+  CP=${CP}:$file
+done
+keyvalues=
+#LOGHOME=/var/log/cloud/
+LOGHOME=$PWD/
+
+java -Djavax.net.ssl.trustStore=./certs/realhostip.keystore -Dlog.home=$LOGHOME -cp $CP com.cloud.agent.AgentShell $keyvalues $@

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/778a59fb/services/secondary-storage/conf/agent.properties
----------------------------------------------------------------------
diff --git a/services/secondary-storage/conf/agent.properties b/services/secondary-storage/conf/agent.properties
index 554007f..aab82b6 100644
--- a/services/secondary-storage/conf/agent.properties
+++ b/services/secondary-storage/conf/agent.properties
@@ -1,9 +1,2 @@
-#mount.path=~/secondary-storage
-eth1ip=192.168.56.1
-name=192.168.56.10
-eth2ip=192.168.56.10
+#mount.path=~/secondary-storage/
 resource=org.apache.cloudstack.storage.resource.NfsSecondaryStorageResource
-piddir=.
-instance=SecondaryStorage
-developer=true
-secondary.storage.vm=false

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/778a59fb/services/secondary-storage/pom.xml
----------------------------------------------------------------------
diff --git a/services/secondary-storage/pom.xml b/services/secondary-storage/pom.xml
index 0577084..2c8a1d0 100644
--- a/services/secondary-storage/pom.xml
+++ b/services/secondary-storage/pom.xml
@@ -81,11 +81,19 @@
             <argument>zone=1</argument>
             <argument>pod=1</argument>
             <argument>host=192.168.56.1</argument>
+            <argument>name=192.168.56.10</argument>
+            <argument>eth1ip=192.168.56.10</argument>
+            <argument>eth2ip=192.168.56.10</argument>
+            <argument>guid=SecondaryStorage.1</argument>
+            <argument>secondary.storage.vm=false</argument>
+            <argument>instance=Secondary</argument>
           </arguments>
           <systemProperties>
             <systemProperty>
               <key>javax.net.ssl.trustStore</key>
               <value>certs/realhostip.keystore</value>
+              <key>log.home</key>
+              <value>${PWD}/</value>
             </systemProperty>
           </systemProperties>
         </configuration>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/778a59fb/services/secondary-storage/scripts/secstorage.sh
----------------------------------------------------------------------
diff --git a/services/secondary-storage/scripts/secstorage.sh b/services/secondary-storage/scripts/secstorage.sh
deleted file mode 100755
index 9afc521..0000000
--- a/services/secondary-storage/scripts/secstorage.sh
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/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.
-
-
-
-#runs the secondary storage service as a standalone server
-#i.e., not in the system vm
-
-CP=./:./conf
-for file in *.jar
-do
-  CP=${CP}:$file
-done
-keyvalues=
-#LOGHOME=/var/log/cloud/
-LOGHOME=$PWD
-
-java -Djavax.net.ssl.trustStore=./certs/realhostip.keystore -Dlog.home=$LOGHOME -cp $CP com.cloud.agent.AgentShell $keyvalues $@


[06/19] QuickCloud: Enable secondary storage daemon to run outside the system vm

Posted by ch...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java
deleted file mode 100755
index e65cbe1..0000000
--- a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java
+++ /dev/null
@@ -1,1842 +0,0 @@
-// 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.storage.resource;
-
-import static com.cloud.utils.S3Utils.deleteDirectory;
-import static com.cloud.utils.S3Utils.getDirectory;
-import static com.cloud.utils.S3Utils.putDirectory;
-import static com.cloud.utils.StringUtils.join;
-import static com.cloud.utils.db.GlobalLock.executeWithNoWaitLock;
-import static java.lang.String.format;
-import static java.util.Arrays.asList;
-import static org.apache.commons.lang.StringUtils.substringAfterLast;
-
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileWriter;
-import java.io.FilenameFilter;
-import java.io.IOException;
-import java.io.InputStream;
-import java.math.BigInteger;
-import java.net.InetAddress;
-import java.net.URI;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-import java.util.concurrent.Callable;
-
-import javax.naming.ConfigurationException;
-
-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.CleanupSnapshotBackupCommand;
-import com.cloud.agent.api.Command;
-import com.cloud.agent.api.ComputeChecksumCommand;
-import com.cloud.agent.api.DeleteObjectFromSwiftCommand;
-import com.cloud.agent.api.DeleteSnapshotBackupCommand;
-import com.cloud.agent.api.DeleteSnapshotsDirCommand;
-import com.cloud.agent.api.DeleteTemplateFromS3Command;
-import com.cloud.agent.api.DownloadSnapshotFromS3Command;
-import com.cloud.agent.api.DownloadTemplateFromS3ToSecondaryStorageCommand;
-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.SecStorageSetupAnswer;
-import com.cloud.agent.api.SecStorageSetupCommand;
-import com.cloud.agent.api.SecStorageSetupCommand.Certificates;
-import com.cloud.agent.api.SecStorageVMSetupCommand;
-import com.cloud.agent.api.StartupCommand;
-import com.cloud.agent.api.StartupSecondaryStorageCommand;
-import com.cloud.agent.api.UploadTemplateToS3FromSecondaryStorageCommand;
-import com.cloud.agent.api.downloadSnapshotFromSwiftCommand;
-import com.cloud.agent.api.downloadTemplateFromSwiftToSecondaryStorageCommand;
-import com.cloud.agent.api.uploadTemplateToSwiftFromSecondaryStorageCommand;
-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.DeleteVolumeCommand;
-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.ListVolumeAnswer;
-import com.cloud.agent.api.storage.ListVolumeCommand;
-import com.cloud.agent.api.storage.UploadCommand;
-import com.cloud.agent.api.storage.ssCommand;
-import com.cloud.agent.api.to.S3TO;
-import com.cloud.agent.api.to.SwiftTO;
-import com.cloud.exception.InternalErrorException;
-import com.cloud.host.Host;
-import com.cloud.host.Host.Type;
-import com.cloud.resource.ServerResourceBase;
-import com.cloud.storage.StorageLayer;
-import com.cloud.storage.template.DownloadManager;
-import com.cloud.storage.template.DownloadManagerImpl;
-import com.cloud.storage.template.DownloadManagerImpl.ZfsPathParser;
-import com.cloud.storage.template.TemplateInfo;
-import com.cloud.storage.template.TemplateLocation;
-import com.cloud.storage.template.UploadManager;
-import com.cloud.storage.template.UploadManagerImpl;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.S3Utils;
-import com.cloud.utils.S3Utils.FileNamingStrategy;
-import com.cloud.utils.S3Utils.ObjectNamingStrategy;
-import com.cloud.utils.component.ComponentContext;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.net.NetUtils;
-import com.cloud.utils.script.OutputInterpreter;
-import com.cloud.utils.script.Script;
-import com.cloud.vm.SecondaryStorageVm;
-
-public class NfsSecondaryStorageResource extends ServerResourceBase implements
-SecondaryStorageResource {
-
-    private static final Logger s_logger = Logger
-            .getLogger(NfsSecondaryStorageResource.class);
-
-    private static final String TEMPLATE_ROOT_DIR = "template/tmpl";
-    private static final String SNAPSHOT_ROOT_DIR = "snapshots";
-
-    int _timeout;
-
-    String _instance;  
-    String _dc;
-    String _pod;
-    String _guid;
-    String _role;
-    Map<String, Object> _params;
-    StorageLayer _storage;
-    boolean _inSystemVM = false;
-    boolean _sslCopy = false;
-
-    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;
-    private String _storageIp;
-    private String _storageNetmask;
-    private String _storageGateway;
-    private final List<String> nfsIps = new ArrayList<String>();
-    final private String _parent = "/mnt/SecStorage";
-    final private String _tmpltDir = "/var/cloudstack/template";
-    final private String _tmpltpp = "template.properties";
-    @Override
-    public void disconnected() {
-    }
-
-    @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 DeleteVolumeCommand) {
-            return execute((DeleteVolumeCommand) 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 execute((SecStorageSetupCommand)cmd);
-        } else if (cmd instanceof ComputeChecksumCommand){
-            return execute((ComputeChecksumCommand)cmd);
-        } else if (cmd instanceof ListTemplateCommand){
-            return execute((ListTemplateCommand)cmd);
-        } else if (cmd instanceof ListVolumeCommand){
-            return execute((ListVolumeCommand)cmd);
-        }else if (cmd instanceof downloadSnapshotFromSwiftCommand){
-            return execute((downloadSnapshotFromSwiftCommand)cmd);
-        } else if (cmd instanceof DownloadSnapshotFromS3Command) {
-            return execute((DownloadSnapshotFromS3Command) cmd);
-        } else if (cmd instanceof DeleteSnapshotBackupCommand){
-            return execute((DeleteSnapshotBackupCommand)cmd);
-        } else if (cmd instanceof DeleteSnapshotsDirCommand){
-            return execute((DeleteSnapshotsDirCommand)cmd);
-        } else if (cmd instanceof downloadTemplateFromSwiftToSecondaryStorageCommand) {
-            return execute((downloadTemplateFromSwiftToSecondaryStorageCommand) cmd);
-        } else if (cmd instanceof DownloadTemplateFromS3ToSecondaryStorageCommand) {
-            return execute((DownloadTemplateFromS3ToSecondaryStorageCommand) cmd);
-        } else if (cmd instanceof uploadTemplateToSwiftFromSecondaryStorageCommand) {
-            return execute((uploadTemplateToSwiftFromSecondaryStorageCommand) cmd);
-        } else if (cmd instanceof UploadTemplateToS3FromSecondaryStorageCommand) {
-            return execute((UploadTemplateToS3FromSecondaryStorageCommand) cmd);
-        } else if (cmd instanceof DeleteObjectFromSwiftCommand) {
-            return execute((DeleteObjectFromSwiftCommand) cmd);
-        } else if (cmd instanceof DeleteTemplateFromS3Command) {
-            return execute((DeleteTemplateFromS3Command) cmd);
-        } else if (cmd instanceof CleanupSnapshotBackupCommand){
-            return execute((CleanupSnapshotBackupCommand)cmd);
-        } else {
-            return Answer.createUnsupportedCommandAnswer(cmd);
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    private String determineS3TemplateDirectory(final Long accountId,
-            final Long templateId) {
-        return join(asList(TEMPLATE_ROOT_DIR, accountId, templateId),
-                S3Utils.SEPARATOR);
-    }
-
-    @SuppressWarnings("unchecked")
-    private String determineStorageTemplatePath(final String storagePath,
-            final Long accountId, final Long templateId) {
-        return join(
-                asList(getRootDir(storagePath), TEMPLATE_ROOT_DIR, accountId,
-                        templateId), File.separator);
-    }
-
-    private Answer execute(
-            final DownloadTemplateFromS3ToSecondaryStorageCommand cmd) {
-
-        final S3TO s3 = cmd.getS3();
-        final String storagePath = cmd.getStoragePath();
-        final Long accountId = cmd.getAccountId();
-        final Long templateId = cmd.getTemplateId();
-
-        try {
-
-            final File downloadDirectory = _storage
-                    .getFile(determineStorageTemplatePath(storagePath,
-                            accountId, templateId));
-            downloadDirectory.mkdirs();
-
-            if (!downloadDirectory.exists()) {
-                final String errMsg = format(
-                        "Unable to create directory "
-                                + "download directory %1$s for download of template id "
-                                + "%2$s from S3.", downloadDirectory.getName(),
-                                templateId);
-                s_logger.error(errMsg);
-                return new Answer(cmd, false, errMsg);
-            }
-
-            getDirectory(s3, s3.getBucketName(),
-                    determineS3TemplateDirectory(accountId, templateId),
-                    downloadDirectory, new FileNamingStrategy() {
-                @Override
-                public String determineFileName(final String key) {
-                    return substringAfterLast(key, S3Utils.SEPARATOR);
-                }
-            });
-
-            return new Answer(cmd, true, format("Successfully downloaded "
-                    + "template id %1$s from S3 to directory %2$s", templateId,
-                    downloadDirectory.getName()));
-
-        } catch (Exception e) {
-
-            final String errMsg = format("Failed to upload template id %1$s "
-                    + "due to $2%s", templateId, e.getMessage());
-            s_logger.error(errMsg, e);
-            return new Answer(cmd, false, errMsg);
-
-        }
-
-    }
-
-    private Answer execute(downloadTemplateFromSwiftToSecondaryStorageCommand cmd) {
-        SwiftTO swift = cmd.getSwift();
-        String secondaryStorageUrl = cmd.getSecondaryStorageUrl();
-        Long accountId = cmd.getAccountId();
-        Long templateId = cmd.getTemplateId();
-        String path = cmd.getPath();
-        String errMsg;
-        String lDir = null;
-        try {
-            String parent = getRootDir(secondaryStorageUrl);
-            lDir = parent + "/template/tmpl/" + accountId.toString() + "/" + templateId.toString();
-            String result = createLocalDir(lDir);
-            if (result != null) {
-                errMsg = "downloadTemplateFromSwiftToSecondaryStorageCommand failed due to Create local directory failed";
-                s_logger.warn(errMsg);
-                throw new InternalErrorException(errMsg);
-            }
-            String lPath = lDir + "/" + path;
-            result = swiftDownload(swift, "T-" + templateId.toString(), path, lPath);
-            if (result != null) {
-                errMsg = "failed to download template " + path + " from Swift to secondary storage " + lPath + " , err=" + result;
-                s_logger.warn(errMsg);
-                throw new CloudRuntimeException(errMsg);
-            }
-            path = "template.properties";
-            lPath = lDir + "/" + path;
-            result = swiftDownload(swift, "T-" + templateId.toString(), path, lPath);
-            if (result != null) {
-                errMsg = "failed to download template " + path + " from Swift to secondary storage " + lPath + " , err=" + result;
-                s_logger.warn(errMsg);
-                throw new CloudRuntimeException(errMsg);
-            }
-            return new Answer(cmd, true, "success");
-        } catch (Exception e) {
-            if (lDir != null) {
-                deleteLocalDir(lDir);
-            }
-            errMsg = cmd + " Command failed due to " + e.toString();
-            s_logger.warn(errMsg, e);
-            return new Answer(cmd, false, errMsg);
-        }
-    }
-
-    private Answer execute(uploadTemplateToSwiftFromSecondaryStorageCommand cmd) {
-        SwiftTO swift = cmd.getSwift();
-        String secondaryStorageUrl = cmd.getSecondaryStorageUrl();
-        Long accountId = cmd.getAccountId();
-        Long templateId = cmd.getTemplateId();
-        try {
-            String parent = getRootDir(secondaryStorageUrl);
-            String lPath = parent + "/template/tmpl/" + accountId.toString() + "/" + templateId.toString();
-            if (!_storage.isFile(lPath + "/template.properties")) {
-                String errMsg = cmd + " Command failed due to template doesn't exist ";
-                s_logger.debug(errMsg);
-                return new Answer(cmd, false, errMsg);
-            }
-            String result = swiftUpload(swift, "T-" + templateId.toString(), lPath, "*");
-            if (result != null) {
-                String errMsg = "failed to upload template from secondary storage " + lPath + " to swift  , err=" + result;
-                s_logger.debug(errMsg);
-                return new Answer(cmd, false, errMsg);
-            }
-            return new Answer(cmd, true, "success");
-        } catch (Exception e) {
-            String errMsg = cmd + " Command failed due to " + e.toString();
-            s_logger.warn(errMsg, e);
-            return new Answer(cmd, false, errMsg);
-        }
-    }
-
-    private Answer execute(UploadTemplateToS3FromSecondaryStorageCommand cmd) {
-
-        final S3TO s3 = cmd.getS3();
-        final Long accountId = cmd.getAccountId();
-        final Long templateId = cmd.getTemplateId();
-
-        try {
-
-            final String templatePath = determineStorageTemplatePath(
-                    cmd.getStoragePath(), accountId, templateId);
-
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Found template id " + templateId
-                        + " account id " + accountId + " from directory "
-                        + templatePath + " to upload to S3.");
-            }
-
-            if (!_storage.isDirectory(templatePath)) {
-                final String errMsg = format("S3 Sync Failure: Directory %1$s"
-                        + "for template id %2$s does not exist.", templatePath,
-                        templateId);
-                s_logger.error(errMsg);
-                return new Answer(cmd, false, errMsg);
-            }
-
-            if (!_storage.isFile(templatePath + "/template.properties")) {
-                final String errMsg = format("S3 Sync Failure: Template id "
-                        + "%1$s does not exist on the file system.",
-                        templatePath);
-                s_logger.error(errMsg);
-                return new Answer(cmd, false, errMsg);
-            }
-
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug(format(
-                        "Pushing template id %1$s from %2$s to S3...",
-                        templateId, templatePath));
-            }
-
-            final String bucket = s3.getBucketName();
-            putDirectory(s3, bucket, _storage.getFile(templatePath),
-                    new FilenameFilter() {
-                @Override
-                public boolean accept(final File directory,
-                        final String fileName) {
-                            File fileToUpload = new File(directory.getAbsolutePath() + "/" + fileName);
-                            return !fileName.startsWith(".") && !fileToUpload.isDirectory();
-                }
-            }, new ObjectNamingStrategy() {
-                @Override
-                public String determineKey(final File file) {
-                    s_logger.debug(String
-                            .format("Determining key using account id %1$s and template id %2$s",
-                                    accountId, templateId));
-                    return join(
-                            asList(determineS3TemplateDirectory(
-                                    accountId, templateId), file
-                                    .getName()), S3Utils.SEPARATOR);
-                }
-            });
-
-            return new Answer(
-                    cmd,
-                    true,
-                    format("Uploaded the contents of directory %1$s for template id %2$s to S3 bucket %3$s",
-                            templatePath, templateId, bucket));
-
-        } catch (Exception e) {
-
-            final String errMsg = format("Failed to upload template id %1$s",
-                    templateId);
-            s_logger.error(errMsg, e);
-            return new Answer(cmd, false, errMsg);
-
-        }
-
-    }
-
-    private Answer execute(DeleteObjectFromSwiftCommand cmd) {
-        SwiftTO swift = cmd.getSwift();
-        String container = cmd.getContainer();
-        String object = cmd.getObject();
-        if (object == null) {
-            object = "";
-        }
-        try {
-            String result = swiftDelete(swift, container, object);
-            if (result != null) {
-                String errMsg = "failed to delete object " + container + "/" + object + " , err=" + result;
-                s_logger.warn(errMsg);
-                return new Answer(cmd, false, errMsg);
-            }
-            return new Answer(cmd, true, "success");
-        } catch (Exception e) {
-            String errMsg = cmd + " Command failed due to " + e.toString();
-            s_logger.warn(errMsg, e);
-            return new Answer(cmd, false, errMsg);
-        }
-
-    }
-
-    private Answer execute(final DeleteTemplateFromS3Command cmd) {
-
-        final S3TO s3 = cmd.getS3();
-        final Long accountId = cmd.getAccountId();
-        final Long templateId = cmd.getTemplateId();
-
-        if (accountId == null || (accountId != null && accountId <= 0)) {
-            final String errorMessage = "No account id specified for S3 template deletion.";
-            s_logger.error(errorMessage);
-            return new Answer(cmd, false, errorMessage);
-        }
-
-        if (templateId == null || (templateId != null && templateId <= 0)) {
-            final String errorMessage = "No template id specified for S3 template deletion.";
-            s_logger.error(errorMessage);
-            return new Answer(cmd, false, errorMessage);
-        }
-
-        if (s3 == null) {
-            final String errorMessge = "No S3 client options provided";
-            s_logger.error(errorMessge);
-            return new Answer(cmd, false, errorMessge);
-        }
-
-        final String bucket = s3.getBucketName();
-        try {
-            deleteDirectory(s3, bucket,
-                    determineS3TemplateDirectory(templateId, accountId));
-            return new Answer(cmd, true, String.format(
-                    "Deleted template %1%s from bucket %2$s.", templateId,
-                    bucket));
-        } catch (Exception e) {
-            final String errorMessage = String
-                    .format("Failed to delete templaet id %1$s from bucket %2$s due to the following error: %3$s",
-                            templateId, bucket, e.getMessage());
-            s_logger.error(errorMessage, e);
-            return new Answer(cmd, false, errorMessage);
-        }
-
-    }
-
-    String swiftDownload(SwiftTO swift, String container, String rfilename, String lFullPath) {
-        Script command = new Script("/bin/bash", s_logger);
-        command.add("-c");
-        command.add("/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A "
-                + swift.getUrl() + " -U " + swift.getAccount() + ":" + swift.getUserName() + " -K " + swift.getKey()
-                + " download " + container + " " + rfilename + " -o " + lFullPath);
-        OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
-        String result = command.execute(parser);
-        if (result != null) {
-            String errMsg = "swiftDownload failed  err=" + result;
-            s_logger.warn(errMsg);
-            return errMsg;
-        }
-        if (parser.getLines() != null) {
-            String[] lines = parser.getLines().split("\\n");
-            for (String line : lines) {
-                if (line.contains("Errno") || line.contains("failed")) {
-                    String errMsg = "swiftDownload failed , err=" + lines.toString();
-                    s_logger.warn(errMsg);
-                    return errMsg;
-                }
-            }
-        }
-        return null;
-
-    }
-
-    String swiftDownloadContainer(SwiftTO swift, String container, String ldir) {
-        Script command = new Script("/bin/bash", s_logger);
-        command.add("-c");
-        command.add("cd " + ldir + ";/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + swift.getAccount() + ":" + swift.getUserName() + " -K "
-                + swift.getKey() + " download " + container);
-        OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
-        String result = command.execute(parser);
-        if (result != null) {
-            String errMsg = "swiftDownloadContainer failed  err=" + result;
-            s_logger.warn(errMsg);
-            return errMsg;
-        }
-        if (parser.getLines() != null) {
-            String[] lines = parser.getLines().split("\\n");
-            for (String line : lines) {
-                if (line.contains("Errno") || line.contains("failed")) {
-                    String errMsg = "swiftDownloadContainer failed , err=" + lines.toString();
-                    s_logger.warn(errMsg);
-                    return errMsg;
-                }
-            }
-        }
-        return null;
-
-    }
-
-    String swiftUpload(SwiftTO swift, String container, String lDir, String lFilename) {
-        long SWIFT_MAX_SIZE = 5L * 1024L * 1024L * 1024L;
-        List<String> files = new ArrayList<String>();
-        if (lFilename.equals("*")) {
-            File dir = new File(lDir);
-            for (String file : dir.list()) {
-                if (file.startsWith(".")) {
-                    continue;
-                }
-                files.add(file);
-            }
-        } else {
-            files.add(lFilename);
-        }
-
-        for (String file : files) {
-            File f = new File(lDir + "/" + file);
-            long size = f.length();
-            Script command = new Script("/bin/bash", s_logger);
-            command.add("-c");
-            if (size <= SWIFT_MAX_SIZE) {
-                command.add("cd " + lDir + ";/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + swift.getAccount() + ":" + swift.getUserName()
-                        + " -K " + swift.getKey() + " upload " + container + " " + file);
-            } else {
-                command.add("cd " + lDir + ";/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + swift.getAccount() + ":" + swift.getUserName()
-                        + " -K " + swift.getKey() + " upload -S " + SWIFT_MAX_SIZE + " " + container + " " + file);
-            }
-            OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
-            String result = command.execute(parser);
-            if (result != null) {
-                String errMsg = "swiftUpload failed , err=" + result;
-                s_logger.warn(errMsg);
-                return errMsg;
-            }
-            if (parser.getLines() != null) {
-                String[] lines = parser.getLines().split("\\n");
-                for (String line : lines) {
-                    if (line.contains("Errno") || line.contains("failed")) {
-                        String errMsg = "swiftUpload failed , err=" + lines.toString();
-                        s_logger.warn(errMsg);
-                        return errMsg;
-                    }
-                }
-            }
-        }
-
-        return null;
-    }
-
-    String[] swiftList(SwiftTO swift, String container, String rFilename) {
-        Script command = new Script("/bin/bash", s_logger);
-        command.add("-c");
-        command.add("/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + swift.getAccount() + ":" + swift.getUserName() + " -K "
-                + swift.getKey() + " list " + container + " " + rFilename);
-        OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
-        String result = command.execute(parser);
-        if (result == null && parser.getLines() != null) {
-            String[] lines = parser.getLines().split("\\n");
-            return lines;
-        } else {
-            if (result != null) {
-                String errMsg = "swiftList failed , err=" + result;
-                s_logger.warn(errMsg);
-            } else {
-                String errMsg = "swiftList failed, no lines returns";
-                s_logger.warn(errMsg);
-            }
-        }
-        return null;
-    }
-
-    String swiftDelete(SwiftTO swift, String container, String object) {
-        Script command = new Script("/bin/bash", s_logger);
-        command.add("-c");
-        command.add("/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A "
-                + swift.getUrl() + " -U " + swift.getAccount() + ":" + swift.getUserName() + " -K " + swift.getKey()
-                + " delete " + container + " " + object);
-        OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
-        String result = command.execute(parser);
-        if (result != null) {
-            String errMsg = "swiftDelete failed , err=" + result;
-            s_logger.warn(errMsg);
-            return errMsg;
-        }
-        if (parser.getLines() != null) {
-            String[] lines = parser.getLines().split("\\n");
-            for (String line : lines) {
-                if (line.contains("Errno") || line.contains("failed")) {
-                    String errMsg = "swiftDelete failed , err=" + lines.toString();
-                    s_logger.warn(errMsg);
-                    return errMsg;
-                }
-            }
-        }
-        return null;
-    }
-
-
-    public Answer execute(DeleteSnapshotsDirCommand cmd){
-        String secondaryStorageUrl = cmd.getSecondaryStorageUrl();
-        Long accountId = cmd.getAccountId();
-        Long volumeId = cmd.getVolumeId();
-        try {
-            String parent = getRootDir(secondaryStorageUrl);
-            String lPath = parent + "/snapshots/" + String.valueOf(accountId) + "/" + String.valueOf(volumeId) + "/*";
-            String result = deleteLocalFile(lPath);
-            if (result != null) {
-                String errMsg = "failed to delete all snapshots " + lPath + " , err=" + result;
-                s_logger.warn(errMsg);
-                return new Answer(cmd, false, errMsg);
-            }
-            return new Answer(cmd, true, "success");
-        } catch (Exception e) {
-            String errMsg = cmd + " Command failed due to " + e.toString();
-            s_logger.warn(errMsg, e);
-            return new Answer(cmd, false, errMsg);
-        }
-    }
-
-    public Answer execute(final DownloadSnapshotFromS3Command cmd) {
-
-        final S3TO s3 = cmd.getS3();
-        final String secondaryStorageUrl = cmd.getSecondaryStorageUrl();
-        final Long accountId = cmd.getAccountId();
-        final Long volumeId = cmd.getVolumeId();
-
-        try {
-
-            executeWithNoWaitLock(determineSnapshotLockId(accountId, volumeId),
-                    new Callable<Void>() {
-
-                @Override
-                public Void call() throws Exception {
-
-                    final String directoryName = determineSnapshotLocalDirectory(
-                            secondaryStorageUrl, accountId, volumeId);
-
-                    String result = createLocalDir(directoryName);
-                    if (result != null) {
-                        throw new InternalErrorException(
-                                format("Failed to create directory %1$s during S3 snapshot download.",
-                                        directoryName));
-                    }
-
-                    final String snapshotFileName = determineSnapshotBackupFilename(cmd
-                            .getSnapshotUuid());
-                    final String key = determineSnapshotS3Key(
-                            accountId, volumeId, snapshotFileName);
-                    final File targetFile = S3Utils.getFile(s3,
-                            s3.getBucketName(), key,
-                            _storage.getFile(directoryName),
-                            new FileNamingStrategy() {
-
-                        @Override
-                        public String determineFileName(
-                                String key) {
-                            return snapshotFileName;
-                        }
-
-                    });
-
-                    if (cmd.getParent() != null) {
-
-                        final String parentPath = join(
-                                File.pathSeparator, directoryName,
-                                determineSnapshotBackupFilename(cmd
-                                        .getParent()));
-                        result = setVhdParent(
-                                targetFile.getAbsolutePath(),
-                                parentPath);
-                        if (result != null) {
-                            throw new InternalErrorException(
-                                    format("Failed to set the parent for backup %1$s to %2$s due to %3$s.",
-                                            targetFile
-                                            .getAbsolutePath(),
-                                            parentPath, result));
-                        }
-
-                    }
-
-                    return null;
-
-                }
-
-            });
-
-            return new Answer(
-                    cmd,
-                    true,
-                    format("Succesfully retrieved volume id %1$s for account id %2$s to %3$s from S3.",
-                            volumeId, accountId, secondaryStorageUrl));
-
-        } catch (Exception e) {
-            final String errMsg = format(
-                    "Failed to retrieve volume id %1$s for account id %2$s to %3$s from S3 due to exception %4$s",
-                    volumeId, accountId, secondaryStorageUrl, e.getMessage());
-            s_logger.error(errMsg);
-            return new Answer(cmd, false, errMsg);
-        }
-
-    }
-
-    private String determineSnapshotS3Directory(final Long accountId,
-            final Long volumeId) {
-        return join(S3Utils.SEPARATOR, SNAPSHOT_ROOT_DIR, accountId, volumeId);
-    }
-
-    private String determineSnapshotS3Key(final Long accountId,
-            final Long volumeId, final String snapshotFileName) {
-
-        final String directoryName = determineSnapshotS3Directory(accountId,
-                volumeId);
-        return join(S3Utils.SEPARATOR, directoryName, snapshotFileName);
-
-    }
-
-    private String determineSnapshotLocalDirectory(
-            final String secondaryStorageUrl, final Long accountId,
-            final Long volumeId) {
-        return join(File.pathSeparator, getRootDir(secondaryStorageUrl),
-                SNAPSHOT_ROOT_DIR, accountId, volumeId);
-    }
-
-    public Answer execute(downloadSnapshotFromSwiftCommand cmd){
-        SwiftTO swift = cmd.getSwift();
-        String secondaryStorageUrl = cmd.getSecondaryStorageUrl();
-        Long accountId = cmd.getAccountId();
-        Long volumeId = cmd.getVolumeId();
-        String rFilename = cmd.getSnapshotUuid();
-        String sParent = cmd.getParent();
-        String errMsg = "";
-        try {
-            String parent = getRootDir(secondaryStorageUrl);
-            String lPath = parent + "/snapshots/" + String.valueOf(accountId) + "/" + String.valueOf(volumeId);
-
-            String result = createLocalDir(lPath);
-            if ( result != null ) {
-                errMsg = "downloadSnapshotFromSwiftCommand failed due to Create local path failed";
-                s_logger.warn(errMsg);
-                throw new InternalErrorException(errMsg);
-            }
-            String lFilename = rFilename;
-            if ( rFilename.startsWith("VHD-") ) {
-                lFilename = rFilename.replace("VHD-", "") + ".vhd";
-            }
-            String lFullPath = lPath + "/" + lFilename;
-            result = swiftDownload(swift, "S-" + volumeId.toString(), rFilename, lFullPath);
-            if (result != null) {
-                return new Answer(cmd, false, result);
-            }
-            if (sParent != null) {
-                if (sParent.startsWith("VHD-") || sParent.endsWith(".vhd")) {
-                    String pFilename = sParent;
-                    if (sParent.startsWith("VHD-")) {
-                        pFilename = pFilename.replace("VHD-", "") + ".vhd";
-                    }
-                    String pFullPath = lPath + "/" + pFilename;
-                    result = setVhdParent(lFullPath, pFullPath);
-                    if (result != null) {
-                        return new Answer(cmd, false, result);
-                    }
-                }
-            }
-
-            return new Answer(cmd, true, "success");
-        } catch (Exception e) {
-            String msg = cmd + " Command failed due to " + e.toString();
-            s_logger.warn(msg, e);
-            throw new CloudRuntimeException(msg);
-        }
-    }
-
-    private Answer execute(ComputeChecksumCommand cmd) {
-
-        String relativeTemplatePath = cmd.getTemplatePath();
-        String parent = getRootDir(cmd);
-
-        if (relativeTemplatePath.startsWith(File.separator)) {
-            relativeTemplatePath = relativeTemplatePath.substring(1);
-        }
-
-        if (!parent.endsWith(File.separator)) {
-            parent += File.separator;
-        }
-        String absoluteTemplatePath = parent + relativeTemplatePath;
-        MessageDigest digest;
-        String checksum = null;
-        File f = new File(absoluteTemplatePath);   
-        InputStream is = null;
-        byte[] buffer = new byte[8192];
-        int read = 0;
-        if(s_logger.isDebugEnabled()){
-            s_logger.debug("parent path " +parent+ " relative template path " +relativeTemplatePath );   
-        }
-
-
-        try {
-            digest = MessageDigest.getInstance("MD5");           
-            is = new FileInputStream(f);     
-            while( (read = is.read(buffer)) > 0) {
-                digest.update(buffer, 0, read);
-            }       
-            byte[] md5sum = digest.digest();
-            BigInteger bigInt = new BigInteger(1, md5sum);
-            checksum = bigInt.toString(16);
-            if(s_logger.isDebugEnabled()){
-                s_logger.debug("Successfully calculated checksum for file " +absoluteTemplatePath+ " - " +checksum );   
-            }
-
-        }catch(IOException e) {
-            String logMsg = "Unable to process file for MD5 - " + absoluteTemplatePath;
-            s_logger.error(logMsg);
-            return new Answer(cmd, false, checksum); 
-        }catch (NoSuchAlgorithmException e) {         
-            return new Answer(cmd, false, checksum);
-        }
-        finally {
-            try {
-                if(is != null)
-                    is.close();
-            } catch (IOException e) {
-                if(s_logger.isDebugEnabled()){
-                    s_logger.debug("Could not close the file " +absoluteTemplatePath);   
-                }
-                return new Answer(cmd, false, checksum);   
-            }                        
-        }
-
-        return new Answer(cmd, true, checksum);
-    }
-
-    private void configCerts(Certificates certs) {
-        if (certs == null) {
-            configureSSL();
-        } else {
-            String prvKey = certs.getPrivKey();
-            String pubCert = certs.getPrivCert();
-            String certChain = certs.getCertChain();
-
-            try {
-                File prvKeyFile = File.createTempFile("prvkey", null);
-                String prvkeyPath = prvKeyFile.getAbsolutePath();
-                BufferedWriter out = new BufferedWriter(new FileWriter(prvKeyFile));
-                out.write(prvKey);
-                out.close();
-
-                File pubCertFile = File.createTempFile("pubcert", null);
-                String pubCertFilePath = pubCertFile.getAbsolutePath();
-
-                out = new BufferedWriter(new FileWriter(pubCertFile));
-                out.write(pubCert);
-                out.close();
-
-                configureSSL(prvkeyPath, pubCertFilePath, null);
-
-                prvKeyFile.delete();
-                pubCertFile.delete();
-
-            } catch (IOException e) {
-                s_logger.debug("Failed to config ssl: " + e.toString());
-            }
-        }
-    }
-
-    private Answer execute(SecStorageSetupCommand cmd) {
-        if (!_inSystemVM){
-            return new Answer(cmd, true, null);
-        }
-        String secUrl = cmd.getSecUrl();
-        try {
-            URI uri = new URI(secUrl);
-            String nfsHost = uri.getHost();
-
-            InetAddress nfsHostAddr = InetAddress.getByName(nfsHost);
-            String nfsHostIp = nfsHostAddr.getHostAddress();
-
-            addRouteToInternalIpOrCidr(_storageGateway, _storageIp, _storageNetmask, nfsHostIp);
-            String nfsPath = nfsHostIp + ":" + uri.getPath();
-            String dir = UUID.nameUUIDFromBytes(nfsPath.getBytes()).toString();
-            String root = _parent + "/" + dir;
-            mount(root, nfsPath);
-
-            configCerts(cmd.getCerts());
-
-            nfsIps.add(nfsHostIp);
-            return new SecStorageSetupAnswer(dir);
-        } catch (Exception e) {
-            String msg = "GetRootDir for " + secUrl + " failed due to " + e.toString();
-            s_logger.error(msg);
-            return new Answer(cmd, false, msg);
-
-        }
-    }
-
-    private String deleteSnapshotBackupFromLocalFileSystem(
-            final String secondaryStorageUrl, final Long accountId,
-            final Long volumeId, final String name, final Boolean deleteAllFlag) {
-
-        final String lPath = determineSnapshotLocalDirectory(
-                secondaryStorageUrl, accountId, volumeId)
-                + File.pathSeparator
-                + (deleteAllFlag ? "*" : "*" + name + "*");
-
-        final String result = deleteLocalFile(lPath);
-
-        if (result != null) {
-            return "failed to delete snapshot " + lPath + " , err=" + result;
-        }
-
-        return null;
-
-    }
-
-    private String deleteSnapshotBackupfromS3(final S3TO s3,
-            final String secondaryStorageUrl, final Long accountId,
-            final Long volumeId, final String name, final Boolean deleteAllFlag) {
-
-        try {
-
-            final String bucket = s3.getBucketName();
-
-            final String result = executeWithNoWaitLock(
-                    determineSnapshotLockId(accountId, volumeId),
-                    new Callable<String>() {
-
-                        @Override
-                        public String call() throws Exception {
-
-                            final String innerResult = deleteSnapshotBackupFromLocalFileSystem(
-                                    secondaryStorageUrl, accountId, volumeId,
-                                    name, deleteAllFlag);
-                            if (innerResult != null) {
-                                return innerResult;
-                            }
-
-                            if (deleteAllFlag) {
-                                S3Utils.deleteDirectory(
-                                        s3,
-                                        bucket,
-                                        determineSnapshotS3Directory(accountId,
-                                                volumeId));
-                            } else {
-                                S3Utils.deleteObject(
-                                        s3,
-                                        bucket,
-                                        determineSnapshotS3Key(
-                                                accountId,
-                                                volumeId,
-                                                determineSnapshotBackupFilename(name)));
-                            }
-
-                            return null;
-
-                        }
-
-                    });
-
-            return result;
-
-        } catch (Exception e) {
-
-            s_logger.error(
-                    String.format(
-                            "Failed to delete snapshot backup for account id %1$s volume id %2$sfrom S3.",
-                            accountId, volumeId), e);
-            return e.getMessage();
-
-        }
-
-    }
-
-    private String determineSnapshotBackupFilename(final String snapshotUuid) {
-        return snapshotUuid + ".vhd";
-    }
-
-    private String determineSnapshotLockId(final Long accountId,
-            final Long volumeId) {
-        return join("_", "SNAPSHOT", accountId, volumeId);
-    }
-
-    protected Answer execute(final DeleteSnapshotBackupCommand cmd) {
-        String secondaryStorageUrl = cmd.getSecondaryStorageUrl();
-        Long accountId = cmd.getAccountId();
-        Long volumeId = cmd.getVolumeId();
-        String name = cmd.getSnapshotUuid();
-        try {
-            SwiftTO swift = cmd.getSwift();
-            S3TO s3 = cmd.getS3();
-            if (swift == null) {
-                final String result = deleteSnapshotBackupFromLocalFileSystem(
-                        secondaryStorageUrl, accountId, volumeId, name,
-                        cmd.isAll());
-                if (result != null) {
-                    s_logger.warn(result);
-                    return new Answer(cmd, false, result);
-                }
-            } else if (s3 != null) {
-                final String result = deleteSnapshotBackupfromS3(s3,
-                        secondaryStorageUrl, accountId, volumeId, name,
-                        cmd.isAll());
-                if (result != null) {
-                    s_logger.warn(result);
-                    return new Answer(cmd, false, result);
-                }
-            } else {
-                String filename;
-                if (cmd.isAll()) {
-                    filename = "";
-                } else {
-                    filename = name;
-                }
-                String result = swiftDelete(swift, "V-" + volumeId.toString(), filename);
-                if (result != null) {
-                    String errMsg = "failed to delete snapshot " + filename + " , err=" + result;
-                    s_logger.warn(errMsg);
-                    return new Answer(cmd, false, errMsg);
-                }
-            }
-            return new Answer(cmd, true, "success");
-        } catch (Exception e) {
-            String errMsg = cmd + " Command failed due to " + e.toString();
-            s_logger.warn(errMsg, e);
-            return new Answer(cmd, false, errMsg);
-        }
-    }
-
-    Map<String, TemplateInfo> swiftListTemplate(SwiftTO swift) {
-        String[] containers = swiftList(swift, "", "");
-        if (containers == null) {
-            return null;
-        }
-        Map<String, TemplateInfo> tmpltInfos = new HashMap<String, TemplateInfo>();
-        for( String container : containers) {
-            if ( container.startsWith("T-")) {
-                String ldir = _tmpltDir + "/" + UUID.randomUUID().toString();
-                createLocalDir(ldir);
-                String lFullPath = ldir + "/" + _tmpltpp;
-                swiftDownload(swift, container, _tmpltpp, lFullPath);
-                TemplateLocation loc = new TemplateLocation(_storage, ldir);
-                try {
-                    if (!loc.load()) {
-                        s_logger.warn("Can not parse template.properties file for template " + container);
-                        continue;
-                    }
-                } catch (IOException e) {
-                    s_logger.warn("Unable to load template location " + ldir + " due to " + e.toString(), e);
-                    continue;
-                }
-                TemplateInfo tInfo = loc.getTemplateInfo();
-                tInfo.setInstallPath(container);
-                tmpltInfos.put(tInfo.getTemplateName(), tInfo);
-                loc.purge();
-                deleteLocalDir(ldir);
-            }
-        }
-        return tmpltInfos;
-
-    }
-
-    private Answer execute(ListTemplateCommand cmd) {
-        if (!_inSystemVM){
-            return new Answer(cmd, true, null);
-        }
-        if (cmd.getSwift() != null) {
-            Map<String, TemplateInfo> templateInfos = swiftListTemplate(cmd.getSwift());
-            return new ListTemplateAnswer(cmd.getSwift().toString(), templateInfos);
-        } else {
-            String root = getRootDir(cmd.getSecUrl());
-            Map<String, TemplateInfo> templateInfos = _dlMgr.gatherTemplateInfo(root);
-            return new ListTemplateAnswer(cmd.getSecUrl(), templateInfos);
-        }
-    }
-
-    private Answer execute(ListVolumeCommand cmd) {
-        if (!_inSystemVM){
-            return new Answer(cmd, true, null);
-        }
-
-        String root = getRootDir(cmd.getSecUrl());
-        Map<Long, TemplateInfo> templateInfos = _dlMgr.gatherVolumeInfo(root);
-        return new ListVolumeAnswer(cmd.getSecUrl(), templateInfos);
-
-    }
-
-    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()) {
-            if (nfsIps.contains(cidr)) {
-                /*
-                 * if the internal download ip is the same with secondary storage ip, adding internal sites will flush
-                 * ip route to nfs through storage ip. 
-                 */
-                continue;
-            }
-            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 setVhdParent(String lFullPath, String pFullPath) {
-        Script command = new Script("/bin/bash", s_logger);
-        command.add("-c");
-        command.add("/bin/vhd-util modify -n " + lFullPath + " -p " + pFullPath);
-        String result = command.execute();
-        if (result != null) {
-            String errMsg = "failed to set vhd parent, child " + lFullPath + " parent " + pFullPath + ", err=" + result;
-            s_logger.warn(errMsg);
-            return errMsg;
-        }
-        return null;
-    }
-
-    private String createLocalDir(String folder) {
-        Script command = new Script("/bin/bash", s_logger);
-        command.add("-c");
-        command.add("mkdir -p " + folder);
-        String result = command.execute();
-        if (result != null) {
-            String errMsg = "Create local path " + folder + " failed , err=" + result;
-            s_logger.warn(errMsg);
-            return errMsg;
-        }
-        return null;
-    }
-
-    private String deleteLocalDir(String folder) {
-        Script command = new Script("/bin/bash", s_logger);
-        command.add("-c");
-        command.add("rmdir " + folder);
-        String result = command.execute();
-        if (result != null) {
-            String errMsg = "Delete local path " + folder + " failed , err=" + result;
-            s_logger.warn(errMsg);
-            return errMsg;
-        }
-        return null;
-    }
-
-    private String deleteLocalFile(String fullPath) {
-        Script command = new Script("/bin/bash", s_logger);
-        command.add("-c");
-        command.add("rm -f " + fullPath);
-        String result = command.execute();
-        if (result != null) {
-            String errMsg = "Failed to delete file " + fullPath + ", err=" + result;
-            s_logger.warn(errMsg);
-            return errMsg;
-        }
-        return null;
-    }
-
-    public 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, cmd.getIsAppendAIp());
-        if (result !=null)
-            success = false;
-
-        return new Answer(cmd, success, result);
-    }
-
-    protected GetStorageStatsAnswer execute(final GetStorageStatsCommand cmd) {
-        String rootDir = getRootDir(cmd.getSecUrl());
-        final long usedSize = getUsedSize(rootDir);
-        final long totalSize = getTotalSize(rootDir);
-        if (usedSize == -1 || totalSize == -1) {
-            return new GetStorageStatsAnswer(cmd, "Unable to get storage stats");
-        } else {
-            return new GetStorageStatsAnswer(cmd, totalSize, usedSize) ;
-        }
-    }
-
-    protected Answer execute(final DeleteTemplateCommand cmd) {
-        String relativeTemplatePath = cmd.getTemplatePath();
-        String parent = getRootDir(cmd);
-
-        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 Answer execute(final DeleteVolumeCommand cmd) {
-        String relativeVolumePath = cmd.getVolumePath();
-        String parent = getRootDir(cmd);
-
-        if (relativeVolumePath.startsWith(File.separator)) {
-            relativeVolumePath = relativeVolumePath.substring(1);
-        }
-
-        if (!parent.endsWith(File.separator)) {
-            parent += File.separator;
-        }
-        String absoluteVolumePath = parent + relativeVolumePath;
-        File tmpltParent = new File(absoluteVolumePath).getParentFile();
-        String details = null;
-        if (!tmpltParent.exists()) {
-            details = "volume 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 volume parent directory " + tmpltParent.getName();
-            s_logger.debug(details);
-        } else {
-            boolean found = false;
-            for (File f : tmpltFiles) {
-                if (!found && f.getName().equals("volume.properties")) {
-                    found = true;
-                }
-                if (!f.delete()) {
-                    return new Answer(cmd, false, "Unable to delete file " + f.getName() + " under Volume path "
-                            + relativeVolumePath);
-                }
-            }
-            if (!found) {
-                details = "Can not find volume.properties under " + tmpltParent.getName();
-                s_logger.debug(details);
-            }
-        }
-        if (!tmpltParent.delete()) {
-            details = "Unable to delete directory " + tmpltParent.getName() + " under Volume path "
-                    + relativeVolumePath;
-            s_logger.debug(details);
-            return new Answer(cmd, false, details);
-        }
-        return new Answer(cmd, true, null);
-    }
-
-    Answer execute(CleanupSnapshotBackupCommand cmd) {
-        String parent = getRootDir(cmd.getSecondaryStoragePoolURL());
-        if (!parent.endsWith(File.separator)) {
-            parent += File.separator;
-        }
-        String absoluteSnapsthotDir = parent + File.separator + "snapshots" + File.separator + cmd.getAccountId() + File.separator + cmd.getVolumeId();
-        File ssParent = new File(absoluteSnapsthotDir);
-        if (ssParent.exists() && ssParent.isDirectory()) {
-            File[] files = ssParent.listFiles();
-            for (File file : files) {
-                boolean found = false;
-                String filename = file.getName();
-                for (String uuid : cmd.getValidBackupUUIDs()) {
-                    if (filename.startsWith(uuid)) {
-                        found = true;
-                        break;
-                    }
-                }
-                if (!found) {
-                    file.delete();
-                    String msg = "snapshot " + filename + " is not recorded in DB, remove it";
-                    s_logger.warn(msg);
-                }
-            }
-        }
-        return new Answer(cmd, true, null);
-    }
-
-
-    synchronized public String getRootDir(String secUrl) {
-        try {
-            URI uri = new URI(secUrl);
-            String nfsHost = uri.getHost();
-
-            InetAddress nfsHostAddr = InetAddress.getByName(nfsHost);
-            String nfsHostIp = nfsHostAddr.getHostAddress();
-            String nfsPath = nfsHostIp + ":" + uri.getPath();
-            String dir = UUID.nameUUIDFromBytes(nfsPath.getBytes()).toString();
-            String root = _parent + "/" + dir;
-            mount(root, nfsPath);    
-            return root;
-        } catch (Exception e) {
-            String msg = "GetRootDir for " + secUrl + " failed due to " + e.toString();
-            s_logger.error(msg, e);
-            throw new CloudRuntimeException(msg);
-        }
-    }
-
-
-    @Override
-    public String getRootDir(ssCommand cmd){
-        return getRootDir(cmd.getSecUrl());
-
-    }
-
-    protected long getUsedSize(String rootDir) {
-        return _storage.getUsedSpace(rootDir);
-    }
-
-    protected long getTotalSize(String rootDir) {
-        return _storage.getTotalSpace(rootDir);
-    }
-
-    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() {
-        if(SecondaryStorageVm.Role.templateProcessor.toString().equals(_role))
-            return Host.Type.SecondaryStorage;
-
-        return Host.Type.SecondaryStorageCmdExecutor;
-    }
-
-    @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");
-        _eth1mask = (String)params.get("eth1mask");
-        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");
-
-        _storageIp = (String) params.get("storageip");
-        if (_storageIp == null) {
-            s_logger.warn("Wait, there is no storageip in /proc/cmdline, something wrong!");
-        }
-        _storageNetmask = (String) params.get("storagenetmask");
-        _storageGateway = (String) params.get("storagegateway");
-        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)clazz.newInstance();
-                _storage.configure("StorageLayer", params);
-            } catch (ClassNotFoundException e) {
-                throw new ConfigurationException("Unable to find class " + value);
-            } catch (InstantiationException e) {
-                throw new ConfigurationException("Unable to find class " + value);
-            } catch (IllegalAccessException e) {
-                throw new ConfigurationException("Unable to find class " + value);
-            }
-        }
-        _storage.mkdirs(_parent);
-        _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);
-        }
-
-        _role = (String)params.get("role");
-        if(_role == null)
-            _role = SecondaryStorageVm.Role.templateProcessor.toString();
-        s_logger.info("Secondary storage runs in role " + _role);
-
-        _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");
-
-
-        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
-                String mgmtHost = (String) params.get("host");
-                addRouteToInternalIpOrCidr(_localgw, _eth1ip, _eth1mask, mgmtHost);
-
-                String internalDns1 = (String) params.get("internaldns1");
-                if (internalDns1 == null) {
-                    s_logger.warn("No DNS entry found during configuration of NfsSecondaryStorage");
-                } else {
-                    addRouteToInternalIpOrCidr(_localgw, _eth1ip, _eth1mask, internalDns1);
-                }
-
-                String internalDns2 = (String) params.get("internaldns2");
-                if (internalDns2 != null) {
-                    addRouteToInternalIpOrCidr(_localgw, _eth1ip, _eth1mask, internalDns2);
-                }
-
-            }
-
-            startAdditionalServices();
-            _params.put("install.numthreads", "50");
-            _params.put("secondary.storage.vm", "true");
-        }
-
-        try {
-            _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("-i", _publicIp);
-        command.add("-h", _hostname);
-        String result = command.execute();
-        if (result != null) {
-            s_logger.warn("Unable to configure httpd to use ssl");
-        }
-    }
-
-    private void configureSSL(String prvkeyPath, String prvCertPath, String certChainPath) {
-        Script command = new Script(_configSslScr);
-        command.add("-i", _publicIp);
-        command.add("-h", _hostname);
-        command.add("-k", prvkeyPath);
-        command.add("-p", prvCertPath);
-        if (certChainPath != null) {
-            command.add("-t", certChainPath);
-        }
-        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, boolean isAppend){
-        Script command = new Script(_configIpFirewallScr);
-        command.add(String.valueOf(isAppend));
-        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 root, String nfsPath) {
-        File file = new File(root);
-        if (!file.exists()) {
-            if (_storage.mkdir(root)) {
-                s_logger.debug("create mount point: " + root);
-            } else {
-                s_logger.debug("Unable to create mount point: " + root);
-                return null;       
-            }
-        }
-
-        Script script = null;
-        String result = null;
-        script = new Script(!_inSystemVM, "mount", _timeout, s_logger);
-        List<String> res = new ArrayList<String>();
-        ZfsPathParser parser = new ZfsPathParser(root);
-        script.execute(parser);
-        res.addAll(parser.getPaths());
-        for( String s : res ) {
-            if ( s.contains(root)) {
-                return root;
-            }
-        }
-
-        Script command = new Script(!_inSystemVM, "mount", _timeout, s_logger);
-        command.add("-t", "nfs");
-        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");
-        }
-        command.add(nfsPath);
-        command.add(root);
-        result = command.execute();
-        if (result != null) {
-            s_logger.warn("Unable to mount " + nfsPath + " due to " + result);
-            file = new File(root);
-            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(root)) {
-            return null;
-        }
-
-        // Create the volumes dir
-        if (!checkForVolumesDir(root)) {
-            return null;
-        }
-
-        return root;
-    }
-
-    @Override
-    public boolean start() {
-        return true;
-    }
-
-    @Override
-    public boolean stop() {
-        return true;
-    }
-
-    @Override
-    public StartupCommand[] initialize() {
-
-        final StartupSecondaryStorageCommand cmd = new StartupSecondaryStorageCommand();
-        fillNetworkInformation(cmd);
-        if(_publicIp != null)
-            cmd.setPublicIpAddress(_publicIp);
-
-        Script command = new Script("/bin/bash", s_logger);
-        command.add("-c");
-        command.add("ln -sf " + _parent + " /var/www/html/copy");
-        String result = command.execute();
-        if (result != null) {
-            s_logger.warn("Error in linking  err=" + result);
-            return null;
-        }
-        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/core/src/com/cloud/storage/resource/SecondaryStorageResource.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/storage/resource/SecondaryStorageResource.java b/core/src/com/cloud/storage/resource/SecondaryStorageResource.java
deleted file mode 100755
index 37c6686..0000000
--- a/core/src/com/cloud/storage/resource/SecondaryStorageResource.java
+++ /dev/null
@@ -1,28 +0,0 @@
-// 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.storage.resource;
-import com.cloud.agent.api.storage.ssCommand;
-import com.cloud.resource.ServerResource;
-/**
- *
- * SecondaryStorageServerResource is a generic container to execute commands sent
- */
-public interface SecondaryStorageResource extends ServerResource {
-    
-    public String getRootDir(ssCommand cmd);
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/core/src/com/cloud/storage/resource/SecondaryStorageResourceHandler.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/storage/resource/SecondaryStorageResourceHandler.java b/core/src/com/cloud/storage/resource/SecondaryStorageResourceHandler.java
deleted file mode 100644
index 28b96b6..0000000
--- a/core/src/com/cloud/storage/resource/SecondaryStorageResourceHandler.java
+++ /dev/null
@@ -1,24 +0,0 @@
-// 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.storage.resource;
-
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.Command;
-
-public interface SecondaryStorageResourceHandler {
-	Answer executeRequest(Command cmd);
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/core/src/com/cloud/storage/template/DownloadManager.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/storage/template/DownloadManager.java b/core/src/com/cloud/storage/template/DownloadManager.java
deleted file mode 100644
index f4f8a0f..0000000
--- a/core/src/com/cloud/storage/template/DownloadManager.java
+++ /dev/null
@@ -1,103 +0,0 @@
-// 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.storage.template;
-
-import java.util.List;
-import java.util.Map;
-
-import com.cloud.agent.api.storage.DownloadAnswer;
-import com.cloud.agent.api.storage.DownloadCommand;
-import com.cloud.agent.api.storage.DownloadCommand.Proxy;
-import com.cloud.agent.api.storage.DownloadCommand.ResourceType;
-import com.cloud.storage.VMTemplateHostVO;
-import com.cloud.storage.Storage.ImageFormat;
-import com.cloud.storage.resource.SecondaryStorageResource;
-import com.cloud.utils.component.Manager;
-
-public interface DownloadManager extends Manager {
-
-	/**
-	 * Initiate download of a public template
-	 * @param id unique id.
-	 * @param url  the url from where to download from
-     * @param hvm  whether the template is a hardware virtual machine
-     * @param accountId the accountId of the iso owner (null if public iso)
-	 * @param descr	description of the template
-	 * @param user username used for authentication to the server
-	 * @param password password used for authentication to the server
-	 * @param maxDownloadSizeInBytes (optional) max download size for the template, in bytes.
-	 * @param resourceType signifying the type of resource like template, volume etc. 
-	 * @return job-id that can be used to interrogate the status of the download.
-	 */
-	public String downloadPublicTemplate(long id, String url, String name, ImageFormat format, boolean hvm, Long accountId, String descr, String cksum, String installPathPrefix, String userName, String passwd, long maxDownloadSizeInBytes, Proxy proxy, ResourceType resourceType);
-	
-	
-	/**
-	 * Get the status of a download job
-	 * @param jobId job Id
-	 * @return status of the download job
-	 */
-	public TemplateDownloader.Status getDownloadStatus(String jobId);
-	
-	/**
-	 * Get the status of a download job
-	 * @param jobId job Id
-	 * @return status of the download job
-	 */
-	public VMTemplateHostVO.Status getDownloadStatus2(String jobId);
-
-	/**
-	 * Get the download percent of a download job
-	 * @param jobId job Id
-	 * @return
-	 */
-	public int getDownloadPct(String jobId);
-
-	/**
-	 * Get the download error if any
-	 * @param jobId job Id
-	 * @return
-	 */
-	public String getDownloadError(String jobId);
-
-	/**
-	 * Get the local path for the download
-	 * @param jobId job Id
-	 * @return
-	public String getDownloadLocalPath(String jobId);
-     */
-	
-	/** Handle download commands from the management server
-	 * @param cmd cmd from server
-	 * @return answer representing status of download.
-	 */
-	public DownloadAnswer handleDownloadCommand(SecondaryStorageResource resource, DownloadCommand cmd);
-		
-	/**
-	/**
-	 * @return list of template info for installed templates
-	 */
-	public Map<String, TemplateInfo> gatherTemplateInfo(String templateDir);
-	
-	/**
-	/**
-	 * @return list of volume info for installed volumes
-	 */
-	public Map<Long, TemplateInfo> gatherVolumeInfo(String volumeDir);
-
-
-}
\ No newline at end of file


[13/19] git commit: updated refs/heads/master to bf56403

Posted by ch...@apache.org.
QuickCloud: add a network offering without any services
This can be used to avoid starting up a virtual router simply for the purposes of offering dhcp and dns services
With the QuickCloudNoServices offering, no virtual router will be started up and the vm instance will not get a CloudStack-assigned IP address.
Instead, the VM will simply get whatever IP address is offered by an DHCP service that happens to be running in the same network


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

Branch: refs/heads/master
Commit: 1d70b9ea77fd1e9fce98f7d9cd5fd92cfe444c39
Parents: 21b4635
Author: Chiradeep Vittal <ch...@apache.org>
Authored: Tue Mar 26 13:36:04 2013 -0700
Committer: Chiradeep Vittal <ch...@apache.org>
Committed: Tue Apr 9 14:45:26 2013 -0700

----------------------------------------------------------------------
 api/src/com/cloud/offering/NetworkOffering.java    |    1 +
 .../src/com/cloud/network/NetworkManagerImpl.java  |   16 +++++++++++++-
 2 files changed, 15 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1d70b9ea/api/src/com/cloud/offering/NetworkOffering.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/offering/NetworkOffering.java b/api/src/com/cloud/offering/NetworkOffering.java
index 8cb8299..bd14acd 100644
--- a/api/src/com/cloud/offering/NetworkOffering.java
+++ b/api/src/com/cloud/offering/NetworkOffering.java
@@ -46,6 +46,7 @@ public interface NetworkOffering extends InfrastructureEntity, InternalIdentity,
     public final static String SystemPrivateGatewayNetworkOffering = "System-Private-Gateway-Network-Offering";
 
     public final static String DefaultSharedNetworkOfferingWithSGService = "DefaultSharedNetworkOfferingWithSGService";
+    public final static String QuickCloudNoServices = "QuickCloudNoServices";
     public final static String DefaultIsolatedNetworkOfferingWithSourceNatService = "DefaultIsolatedNetworkOfferingWithSourceNatService";
     public final static String OvsIsolatedNetworkOfferingWithSourceNatService = "OvsIsolatedNetworkOfferingWithSourceNatService";
     public final static String DefaultSharedNetworkOffering = "DefaultSharedNetworkOffering";

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1d70b9ea/server/src/com/cloud/network/NetworkManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java
index 6296011..a97f2ce 100755
--- a/server/src/com/cloud/network/NetworkManagerImpl.java
+++ b/server/src/com/cloud/network/NetworkManagerImpl.java
@@ -968,9 +968,21 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L
         // diff between offering #1 and #2 - securityGroup is enabled for the first, and disabled for the third
 
         NetworkOfferingVO offering = null;
+        if (_networkOfferingDao.findByUniqueName(NetworkOffering.QuickCloudNoServices) == null) {
+            offering =
+                    _configMgr.createNetworkOffering(NetworkOffering.QuickCloudNoServices,
+                            "Offering for QuickCloud with no services", TrafficType.Guest, null, true,
+                            Availability.Optional, null, new HashMap<Network.Service, Set<Network.Provider>>(), true,
+                            Network.GuestType.Shared, false, null, true, null, true, false);
+            offering.setState(NetworkOffering.State.Enabled);
+            _networkOfferingDao.update(offering.getId(), offering);
+        }
         if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultSharedNetworkOfferingWithSGService) == null) {
-            offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultSharedNetworkOfferingWithSGService, "Offering for Shared Security group enabled networks", TrafficType.Guest, null,
-                    true, Availability.Optional, null, defaultSharedNetworkOfferingProviders, true, Network.GuestType.Shared, false, null, true, null, true, false);
+            offering =
+                    _configMgr.createNetworkOffering(NetworkOffering.DefaultSharedNetworkOfferingWithSGService,
+                            "Offering for Shared Security group enabled networks", TrafficType.Guest, null, true,
+                            Availability.Optional, null, defaultSharedNetworkOfferingProviders, true,
+                            Network.GuestType.Shared, false, null, true, null, true, false);
             offering.setState(NetworkOffering.State.Enabled);
             _networkOfferingDao.update(offering.getId(), offering);
         }


[12/19] git commit: updated refs/heads/master to bf56403

Posted by ch...@apache.org.
QuickCloud: copy authorization code from ConsoleProxyManagerImpl

QuickCloud: refactor to avoid copy paste of authentication and startup code


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

Branch: refs/heads/master
Commit: 3d78019e571677f1b2ac87acebe6192f2a4fa96c
Parents: 790d2ce
Author: Chiradeep Vittal <ch...@apache.org>
Authored: Tue Mar 26 10:05:06 2013 -0700
Committer: Chiradeep Vittal <ch...@apache.org>
Committed: Tue Apr 9 14:45:26 2013 -0700

----------------------------------------------------------------------
 .../AgentBasedConsoleProxyManager.java             |  184 +-------
 .../src/com/cloud/consoleproxy/AgentHookBase.java  |  266 +++++++++++
 .../consoleproxy/ConsoleProxyManagerImpl.java      |  362 ++++++---------
 .../consoleproxy/StaticConsoleProxyManager.java    |   84 +++-
 4 files changed, 489 insertions(+), 407 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3d78019e/server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java b/server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java
index 6f8575d..ff6e64e 100755
--- a/server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java
+++ b/server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java
@@ -23,48 +23,28 @@ import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
 import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
 
 import com.cloud.agent.AgentManager;
-import com.cloud.agent.api.AgentControlAnswer;
-import com.cloud.agent.api.ConsoleAccessAuthenticationAnswer;
-import com.cloud.agent.api.ConsoleAccessAuthenticationCommand;
-import com.cloud.agent.api.ConsoleProxyLoadReportCommand;
 import com.cloud.agent.api.GetVncPortAnswer;
 import com.cloud.agent.api.GetVncPortCommand;
-import com.cloud.agent.api.StartupCommand;
 import com.cloud.agent.api.StartupProxyCommand;
-import com.cloud.agent.api.StopAnswer;
-import com.cloud.agent.api.to.NicTO;
-import com.cloud.agent.api.to.VirtualMachineTO;
-import com.cloud.agent.manager.Commands;
 import com.cloud.configuration.dao.ConfigurationDao;
-import com.cloud.deploy.DeployDestination;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.ResourceUnavailableException;
 import com.cloud.host.HostVO;
-import com.cloud.host.Status;
 import com.cloud.host.dao.HostDao;
 import com.cloud.info.ConsoleProxyInfo;
-import com.cloud.network.Network;
+import com.cloud.keystore.KeystoreManager;
 import com.cloud.utils.NumbersUtil;
 import com.cloud.utils.component.ManagerBase;
 import com.cloud.vm.ConsoleProxyVO;
-import com.cloud.vm.ReservationContext;
 import com.cloud.vm.UserVmVO;
 import com.cloud.vm.VMInstanceVO;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.VirtualMachineGuru;
 import com.cloud.vm.VirtualMachineManager;
-import com.cloud.vm.VirtualMachineName;
-import com.cloud.vm.VirtualMachineProfile;
 import com.cloud.vm.dao.ConsoleProxyDao;
 import com.cloud.vm.dao.UserVmDao;
 import com.cloud.vm.dao.VMInstanceDao;
 
 @Local(value = { ConsoleProxyManager.class })
-public class AgentBasedConsoleProxyManager extends ManagerBase implements ConsoleProxyManager, VirtualMachineGuru<ConsoleProxyVO>, AgentHook {
+public class AgentBasedConsoleProxyManager extends ManagerBase implements ConsoleProxyManager {
     private static final Logger s_logger = Logger.getLogger(AgentBasedConsoleProxyManager.class);
 
     @Inject
@@ -85,9 +65,25 @@ public class AgentBasedConsoleProxyManager extends ManagerBase implements Consol
     VirtualMachineManager _itMgr;
     @Inject
     protected ConsoleProxyDao _cpDao;
+    @Inject
+    protected KeystoreManager _ksMgr;
 
     @Inject ConfigurationDao _configDao;
 
+    public class AgentBasedAgentHook extends AgentHookBase {
+
+        public AgentBasedAgentHook(VMInstanceDao instanceDao, HostDao hostDao, ConfigurationDao cfgDao,
+                KeystoreManager ksMgr, AgentManager agentMgr) {
+            super(instanceDao, hostDao, cfgDao, ksMgr, agentMgr);
+        }
+
+        @Override
+        protected HostVO findConsoleProxyHost(StartupProxyCommand cmd) {
+            return _hostDao.findByGuid(cmd.getGuid());
+        }
+
+    }
+
     public int getVncPort(VMInstanceVO vm) {
         if (vm.getHostId() == null) {
             return -1;
@@ -123,11 +119,10 @@ public class AgentBasedConsoleProxyManager extends ManagerBase implements Consol
 
         _consoleProxyUrlDomain = configs.get("consoleproxy.url.domain");
 
-        _listener = new ConsoleProxyListener(this);
+        _listener =
+                new ConsoleProxyListener(new AgentBasedAgentHook(_instanceDao, _hostDao, _configDao, _ksMgr, _agentMgr));
         _agentMgr.registerForHostEvents(_listener, true, true, false);
 
-        _itMgr.registerGuru(VirtualMachine.Type.ConsoleProxy, this);
-
         if (s_logger.isInfoEnabled()) {
             s_logger.info("AgentBasedConsoleProxyManager has been configured. SSL enabled: " + _sslEnabled);
         }
@@ -177,64 +172,8 @@ public class AgentBasedConsoleProxyManager extends ManagerBase implements Consol
         return null;
     }
 
-    @Override
-    public void onLoadReport(ConsoleProxyLoadReportCommand cmd) {
-    }
-
-    @Override
-    public AgentControlAnswer onConsoleAccessAuthentication(ConsoleAccessAuthenticationCommand cmd) {
-        long vmId = 0;
-
-        if (cmd.getVmId() != null && cmd.getVmId().isEmpty()) {
-            if (s_logger.isTraceEnabled()) {
-                s_logger.trace("Invalid vm id sent from proxy(happens when proxy session has terminated)");
-            }
-            return new ConsoleAccessAuthenticationAnswer(cmd, false);
-        }
-
-        try {
-            vmId = Long.parseLong(cmd.getVmId());
-        } catch (NumberFormatException e) {
-            s_logger.error("Invalid vm id " + cmd.getVmId() + " sent from console access authentication", e);
-            return new ConsoleAccessAuthenticationAnswer(cmd, false);
-        }
-
-        // TODO authentication channel between console proxy VM and management
-        // server needs to be secured,
-        // the data is now being sent through private network, but this is
-        // apparently not enough
-        VMInstanceVO vm = _instanceDao.findById(vmId);
-        if (vm == null) {
-            return new ConsoleAccessAuthenticationAnswer(cmd, false);
-        }
-
-        if (vm.getHostId() == null) {
-            s_logger.warn("VM " + vmId + " lost host info, failed authentication request");
-            return new ConsoleAccessAuthenticationAnswer(cmd, false);
-        }
-
-        HostVO host = _hostDao.findById(vm.getHostId());
-        if (host == null) {
-            s_logger.warn("VM " + vmId + "'s host does not exist, fail authentication request");
-            return new ConsoleAccessAuthenticationAnswer(cmd, false);
-        }
 
-        String sid = cmd.getSid();
-        if (sid == null || !sid.equals(vm.getVncPassword())) {
-            s_logger.warn("sid " + sid + " in url does not match stored sid " + vm.getVncPassword());
-            return new ConsoleAccessAuthenticationAnswer(cmd, false);
-        }
 
-        return new ConsoleAccessAuthenticationAnswer(cmd, true);
-    }
-
-    @Override
-    public void onAgentConnect(HostVO host, StartupCommand cmd) {
-    }
-
-    @Override
-    public void onAgentDisconnect(long agentId, Status state) {
-    }
 
     @Override
     public ConsoleProxyVO startProxy(long proxyVmId) {
@@ -270,90 +209,7 @@ public class AgentBasedConsoleProxyManager extends ManagerBase implements Consol
     }
 
     @Override
-    public void startAgentHttpHandlerInVM(StartupProxyCommand startupCmd) {
-    }
-
-    @Override
     public String getName() {
         return _name;
     }
-
-    @Override
-    public Long convertToId(String vmName) {
-        if (!VirtualMachineName.isValidConsoleProxyName(vmName, _instance)) {
-            return null;
-        }
-        return VirtualMachineName.getConsoleProxyId(vmName);
-    }
-
-    @Override
-    public ConsoleProxyVO findByName(String name) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public ConsoleProxyVO findById(long id) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public ConsoleProxyVO persist(ConsoleProxyVO vm) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public boolean finalizeVirtualMachineProfile(VirtualMachineProfile<ConsoleProxyVO> profile, DeployDestination dest, ReservationContext context) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean finalizeDeployment(Commands cmds, VirtualMachineProfile<ConsoleProxyVO> profile, DeployDestination dest, ReservationContext context) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean finalizeCommandsOnStart(Commands cmds, VirtualMachineProfile<ConsoleProxyVO> profile) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public boolean finalizeStart(VirtualMachineProfile<ConsoleProxyVO> profile, long hostId, Commands cmds, ReservationContext context) {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    @Override
-    public void finalizeStop(VirtualMachineProfile<ConsoleProxyVO> profile, StopAnswer answer) {
-        // TODO Auto-generated method stub
-    }
-
-    @Override 
-    public void finalizeExpunge(ConsoleProxyVO proxy) {
-    }
-
-    @Override
-    public boolean plugNic(Network network, NicTO nic, VirtualMachineTO vm,
-            ReservationContext context, DeployDestination dest) throws ConcurrentOperationException, ResourceUnavailableException,
-            InsufficientCapacityException {
-        //not supported
-        throw new UnsupportedOperationException("Plug nic is not supported for vm of type " + vm.getType());
-    }
-
-
-    @Override
-    public boolean unplugNic(Network network, NicTO nic, VirtualMachineTO vm,
-            ReservationContext context, DeployDestination dest) throws ConcurrentOperationException, ResourceUnavailableException {
-        //not supported
-        throw new UnsupportedOperationException("Unplug nic is not supported for vm of type " + vm.getType());
-    }
-
-    @Override
-    public void prepareStop(VirtualMachineProfile<ConsoleProxyVO> profile) {
-    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3d78019e/server/src/com/cloud/consoleproxy/AgentHookBase.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/consoleproxy/AgentHookBase.java b/server/src/com/cloud/consoleproxy/AgentHookBase.java
new file mode 100644
index 0000000..b969f6d
--- /dev/null
+++ b/server/src/com/cloud/consoleproxy/AgentHookBase.java
@@ -0,0 +1,266 @@
+// 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.consoleproxy;
+
+import java.util.Date;
+import java.util.Random;
+import java.util.UUID;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.AgentControlAnswer;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.ConsoleAccessAuthenticationAnswer;
+import com.cloud.agent.api.ConsoleAccessAuthenticationCommand;
+import com.cloud.agent.api.ConsoleProxyLoadReportCommand;
+import com.cloud.agent.api.GetVncPortAnswer;
+import com.cloud.agent.api.GetVncPortCommand;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.StartupProxyCommand;
+import com.cloud.agent.api.proxy.StartConsoleProxyAgentHttpHandlerCommand;
+import com.cloud.configuration.Config;
+import com.cloud.configuration.dao.ConfigurationDao;
+import com.cloud.exception.AgentUnavailableException;
+import com.cloud.exception.OperationTimedoutException;
+import com.cloud.host.HostVO;
+import com.cloud.host.Status;
+import com.cloud.host.dao.HostDao;
+import com.cloud.keystore.KeystoreManager;
+import com.cloud.servlet.ConsoleProxyServlet;
+import com.cloud.utils.Ternary;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.dao.VMInstanceDao;
+
+/**
+ * Utility class to manage interactions with agent-based console access
+ * Extracted from ConsoleProxyManagerImpl so that other console proxy managers
+ * can reuse
+ */
+public abstract class AgentHookBase implements AgentHook {
+    private static final Logger s_logger = Logger.getLogger(AgentHookBase.class);
+
+    VMInstanceDao _instanceDao;
+    HostDao _hostDao;
+    ConfigurationDao _configDao;
+    AgentManager _agentMgr;
+    KeystoreManager _ksMgr;
+    final Random _random = new Random(System.currentTimeMillis());
+    private String _hashKey;
+
+
+    public AgentHookBase(VMInstanceDao instanceDao, HostDao hostDao, ConfigurationDao cfgDao, KeystoreManager ksMgr,
+            AgentManager agentMgr) {
+        this._instanceDao = instanceDao;
+        this._hostDao = hostDao;
+        this._agentMgr = agentMgr;
+        this._configDao = cfgDao;
+        this._ksMgr = ksMgr;
+    }
+
+    public String getHashKey() {
+        // although we may have race condition here, database transaction
+        // serialization should give us the same key
+        if (_hashKey == null) {
+            _hashKey =
+                    _configDao.getValueAndInitIfNotExist(Config.HashKey.key(), Config.HashKey.getCategory(), UUID
+                            .randomUUID().toString());
+        }
+        return _hashKey;
+    }
+
+    public AgentControlAnswer onConsoleAccessAuthentication(ConsoleAccessAuthenticationCommand cmd) {
+        Long vmId = null;
+
+        String ticketInUrl = cmd.getTicket();
+        if (ticketInUrl == null) {
+            s_logger.error("Access ticket could not be found, you could be running an old version of console proxy. vmId: "
+                    + cmd.getVmId());
+            return new ConsoleAccessAuthenticationAnswer(cmd, false);
+        }
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Console authentication. Ticket in url for " + cmd.getHost() + ":" + cmd.getPort() + "-"
+                    + cmd.getVmId() + " is " + ticketInUrl);
+        }
+
+        if (!cmd.isReauthenticating()) {
+            String ticket =
+                    ConsoleProxyServlet.genAccessTicket(cmd.getHost(), cmd.getPort(), cmd.getSid(), cmd.getVmId());
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Console authentication. Ticket in 1 minute boundary for " + cmd.getHost() + ":"
+                        + cmd.getPort() + "-" + cmd.getVmId() + " is " + ticket);
+            }
+
+            if (!ticket.equals(ticketInUrl)) {
+                Date now = new Date();
+                // considering of minute round-up
+                String minuteEarlyTicket =
+                        ConsoleProxyServlet.genAccessTicket(cmd.getHost(), cmd.getPort(), cmd.getSid(), cmd.getVmId(),
+                                new Date(now.getTime() - 60 * 1000));
+
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Console authentication. Ticket in 2-minute boundary for " + cmd.getHost() + ":"
+                            + cmd.getPort() + "-" + cmd.getVmId() + " is " + minuteEarlyTicket);
+                }
+
+                if (!minuteEarlyTicket.equals(ticketInUrl)) {
+                    s_logger.error("Access ticket expired or has been modified. vmId: " + cmd.getVmId()
+                            + "ticket in URL: " + ticketInUrl + ", tickets to check against: " + ticket + ","
+                            + minuteEarlyTicket);
+                    return new ConsoleAccessAuthenticationAnswer(cmd, false);
+                }
+            }
+        }
+
+        if (cmd.getVmId() != null && cmd.getVmId().isEmpty()) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Invalid vm id sent from proxy(happens when proxy session has terminated)");
+            }
+            return new ConsoleAccessAuthenticationAnswer(cmd, false);
+        }
+
+        VirtualMachine vm = _instanceDao.findByUuid(cmd.getVmId());
+        if (vm == null) {
+            vm = _instanceDao.findById(Long.parseLong(cmd.getVmId()));
+        }
+        if (vm == null) {
+            s_logger.error("Invalid vm id " + cmd.getVmId() + " sent from console access authentication");
+            return new ConsoleAccessAuthenticationAnswer(cmd, false);
+        }
+
+        if (vm.getHostId() == null) {
+            s_logger.warn("VM " + vmId + " lost host info, failed authentication request");
+            return new ConsoleAccessAuthenticationAnswer(cmd, false);
+        }
+
+        HostVO host = _hostDao.findById(vm.getHostId());
+        if (host == null) {
+            s_logger.warn("VM " + vmId + "'s host does not exist, fail authentication request");
+            return new ConsoleAccessAuthenticationAnswer(cmd, false);
+        }
+
+        String sid = cmd.getSid();
+        if (sid == null || !sid.equals(vm.getVncPassword())) {
+            s_logger.warn("sid " + sid + " in url does not match stored sid " + vm.getVncPassword());
+            return new ConsoleAccessAuthenticationAnswer(cmd, false);
+        }
+
+        if (cmd.isReauthenticating()) {
+            ConsoleAccessAuthenticationAnswer authenticationAnswer = new ConsoleAccessAuthenticationAnswer(cmd, true);
+            authenticationAnswer.setReauthenticating(true);
+
+            s_logger.info("Re-authentication request, ask host " + vm.getHostId() + " for new console info");
+            GetVncPortAnswer answer =
+                    (GetVncPortAnswer) _agentMgr.easySend(vm.getHostId(),
+                            new GetVncPortCommand(vm.getId(), vm.getInstanceName()));
+
+            if (answer != null && answer.getResult()) {
+                Ternary<String, String, String> parsedHostInfo = ConsoleProxyServlet.parseHostInfo(answer.getAddress());
+
+                if (parsedHostInfo.second() != null && parsedHostInfo.third() != null) {
+
+                    s_logger.info("Re-authentication result. vm: " + vm.getId() + ", tunnel url: "
+                            + parsedHostInfo.second() + ", tunnel session: " + parsedHostInfo.third());
+
+                    authenticationAnswer.setTunnelUrl(parsedHostInfo.second());
+                    authenticationAnswer.setTunnelSession(parsedHostInfo.third());
+                } else {
+                    s_logger.info("Re-authentication result. vm: " + vm.getId() + ", host address: "
+                            + parsedHostInfo.first() + ", port: " + answer.getPort());
+
+                    authenticationAnswer.setHost(parsedHostInfo.first());
+                    authenticationAnswer.setPort(answer.getPort());
+                }
+            } else {
+                s_logger.warn("Re-authentication request failed");
+
+                authenticationAnswer.setSuccess(false);
+            }
+
+            return authenticationAnswer;
+        }
+
+        return new ConsoleAccessAuthenticationAnswer(cmd, true);
+    }
+
+    public void startAgentHttpHandlerInVM(StartupProxyCommand startupCmd) {
+        StartConsoleProxyAgentHttpHandlerCommand cmd = null;
+        if (_configDao.isPremium()) {
+            String storePassword = String.valueOf(_random.nextLong());
+            byte[] ksBits =
+                    _ksMgr.getKeystoreBits(ConsoleProxyManager.CERTIFICATE_NAME, ConsoleProxyManager.CERTIFICATE_NAME,
+                            storePassword);
+
+            assert (ksBits != null);
+            if (ksBits == null) {
+                s_logger.error("Could not find and construct a valid SSL certificate");
+            }
+            cmd = new StartConsoleProxyAgentHttpHandlerCommand(ksBits, storePassword);
+            cmd.setEncryptorPassword(getHashKey());
+        } else {
+            cmd = new StartConsoleProxyAgentHttpHandlerCommand();
+            cmd.setEncryptorPassword(getHashKey());
+        }
+
+        try {
+
+            HostVO consoleProxyHost = findConsoleProxyHost(startupCmd);
+
+            assert (consoleProxyHost != null);
+
+            Answer answer = _agentMgr.send(consoleProxyHost.getId(), cmd);
+            if (answer == null || !answer.getResult()) {
+                s_logger.error("Console proxy agent reported that it failed to execute http handling startup command");
+            } else {
+                s_logger.info("Successfully sent out command to start HTTP handling in console proxy agent");
+            }
+        } catch (AgentUnavailableException e) {
+            s_logger.error("Unable to send http handling startup command to the console proxy resource for proxy:"
+                    + startupCmd.getProxyVmId(), e);
+        } catch (OperationTimedoutException e) {
+            s_logger.error(
+                    "Unable to send http handling startup command(time out) to the console proxy resource for proxy:"
+                            + startupCmd.getProxyVmId(), e);
+        } catch (OutOfMemoryError e) {
+            s_logger.error("Unrecoverable OutOfMemory Error, exit and let it be re-launched");
+            System.exit(1);
+        } catch (Exception e) {
+            s_logger.error(
+                    "Unexpected exception when sending http handling startup command(time out) to the console proxy resource for proxy:"
+                            + startupCmd.getProxyVmId(), e);
+        }
+    }
+
+    protected abstract HostVO findConsoleProxyHost(StartupProxyCommand cmd);
+
+    @Override
+    public void onLoadReport(ConsoleProxyLoadReportCommand cmd) {
+        // no-op since we do not auto-scale
+    }
+
+    @Override
+    public void onAgentConnect(HostVO host, StartupCommand cmd) {
+        // no-op
+    }
+
+    @Override
+    public void onAgentDisconnect(long agentId, Status state) {
+        // no-op since we do not autoscale
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3d78019e/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java
index fc4fc6e..9740d28 100755
--- a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java
+++ b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java
@@ -23,7 +23,6 @@ import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.Random;
 import java.util.UUID;
 
 import javax.ejb.Local;
@@ -35,13 +34,8 @@ import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
 import org.apache.log4j.Logger;
 
 import com.cloud.agent.AgentManager;
-import com.cloud.agent.api.AgentControlAnswer;
 import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.ConsoleAccessAuthenticationAnswer;
-import com.cloud.agent.api.ConsoleAccessAuthenticationCommand;
 import com.cloud.agent.api.ConsoleProxyLoadReportCommand;
-import com.cloud.agent.api.GetVncPortAnswer;
-import com.cloud.agent.api.GetVncPortCommand;
 import com.cloud.agent.api.RebootCommand;
 import com.cloud.agent.api.StartupCommand;
 import com.cloud.agent.api.StartupProxyCommand;
@@ -49,7 +43,6 @@ import com.cloud.agent.api.StopAnswer;
 import com.cloud.agent.api.check.CheckSshAnswer;
 import com.cloud.agent.api.check.CheckSshCommand;
 import com.cloud.agent.api.proxy.ConsoleProxyLoadAnswer;
-import com.cloud.agent.api.proxy.StartConsoleProxyAgentHttpHandlerCommand;
 import com.cloud.agent.api.to.NicTO;
 import com.cloud.agent.api.to.VirtualMachineTO;
 import com.cloud.agent.manager.Commands;
@@ -66,10 +59,8 @@ import com.cloud.dc.dao.DataCenterDao;
 import com.cloud.dc.dao.HostPodDao;
 import com.cloud.deploy.DataCenterDeployment;
 import com.cloud.deploy.DeployDestination;
-import com.cloud.exception.AgentUnavailableException;
 import com.cloud.exception.ConcurrentOperationException;
 import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.OperationTimedoutException;
 import com.cloud.exception.ResourceUnavailableException;
 import com.cloud.exception.StorageUnavailableException;
 import com.cloud.host.Host;
@@ -106,7 +97,6 @@ import com.cloud.resource.ServerResource;
 import com.cloud.resource.UnableDeleteHostException;
 import com.cloud.service.ServiceOfferingVO;
 import com.cloud.service.dao.ServiceOfferingDao;
-import com.cloud.servlet.ConsoleProxyServlet;
 import com.cloud.storage.StorageManager;
 import com.cloud.storage.StoragePoolStatus;
 import com.cloud.storage.VMTemplateHostVO;
@@ -123,7 +113,6 @@ import com.cloud.user.UserContext;
 import com.cloud.utils.DateUtil;
 import com.cloud.utils.NumbersUtil;
 import com.cloud.utils.Pair;
-import com.cloud.utils.Ternary;
 import com.cloud.utils.component.ManagerBase;
 import com.cloud.utils.db.DB;
 import com.cloud.utils.db.GlobalLock;
@@ -167,7 +156,7 @@ import com.google.gson.GsonBuilder;
 //
 @Local(value = { ConsoleProxyManager.class, ConsoleProxyService.class })
 public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxyManager,
-        AgentHook, VirtualMachineGuru<ConsoleProxyVO>, SystemVmLoadScanHandler<Long>, ResourceStateAdapter {
+        VirtualMachineGuru<ConsoleProxyVO>, SystemVmLoadScanHandler<Long>, ResourceStateAdapter {
     private static final Logger s_logger = Logger.getLogger(ConsoleProxyManagerImpl.class);
 
     private static final int DEFAULT_CAPACITY_SCAN_INTERVAL = 30000; // 30 seconds
@@ -455,7 +444,131 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
     private KeystoreDao _ksDao;
     @Inject
     private KeystoreManager _ksMgr;
-    private final Random _random = new Random(System.currentTimeMillis());
+
+    public class VmBasedAgentHook extends AgentHookBase {
+
+        public VmBasedAgentHook(VMInstanceDao instanceDao, HostDao hostDao, ConfigurationDao cfgDao,
+                KeystoreManager ksMgr, AgentManager agentMgr) {
+            super(instanceDao, hostDao, cfgDao, ksMgr, agentMgr);
+        }
+
+        @Override
+        public void onLoadReport(ConsoleProxyLoadReportCommand cmd) {
+            if (cmd.getLoadInfo() == null) {
+                return;
+            }
+
+            ConsoleProxyStatus status = null;
+            try {
+                GsonBuilder gb = new GsonBuilder();
+                gb.setVersion(1.3);
+                Gson gson = gb.create();
+                status = gson.fromJson(cmd.getLoadInfo(), ConsoleProxyStatus.class);
+            } catch (Throwable e) {
+                s_logger.warn("Unable to parse load info from proxy, proxy vm id : " + cmd.getProxyVmId() + ", info : " + cmd.getLoadInfo());
+            }
+
+            if (status != null) {
+                int count = 0;
+                if (status.getConnections() != null) {
+                    count = status.getConnections().length;
+                }
+
+                byte[] details = null;
+                if (cmd.getLoadInfo() != null) {
+                    details = cmd.getLoadInfo().getBytes(Charset.forName("US-ASCII"));
+                }
+                _consoleProxyDao.update(cmd.getProxyVmId(), count, DateUtil.currentGMTTime(), details);
+            } else {
+                if (s_logger.isTraceEnabled()) {
+                    s_logger.trace("Unable to get console proxy load info, id : " + cmd.getProxyVmId());
+                }
+
+                _consoleProxyDao.update(cmd.getProxyVmId(), 0, DateUtil.currentGMTTime(), null);
+            }
+        }
+
+        @Override
+        public void onAgentConnect(HostVO host, StartupCommand cmd) {
+            // no-op
+        }
+
+        @Override
+        public void onAgentDisconnect(long agentId, com.cloud.host.Status state) {
+
+            if (state == com.cloud.host.Status.Alert || state == com.cloud.host.Status.Disconnected) {
+                // be it either in alert or in disconnected state, the agent
+                // process
+                // may be gone in the VM,
+                // we will be reacting to stop the corresponding VM and let the
+                // scan
+                // process to
+                HostVO host = _hostDao.findById(agentId);
+                if (host.getType() == Type.ConsoleProxy) {
+                    String name = host.getName();
+                    if (s_logger.isInfoEnabled()) {
+                        s_logger.info("Console proxy agent disconnected, proxy: " + name);
+                    }
+                    if (name != null && name.startsWith("v-")) {
+                        String[] tokens = name.split("-");
+                        long proxyVmId = 0;
+                        try {
+                            proxyVmId = Long.parseLong(tokens[1]);
+                        } catch (NumberFormatException e) {
+                            s_logger.error("Unexpected exception " + e.getMessage(), e);
+                            return;
+                        }
+
+                        final ConsoleProxyVO proxy = _consoleProxyDao.findById(proxyVmId);
+                        if (proxy != null) {
+
+                            // Disable this feature for now, as it conflicts
+                            // with
+                            // the case of allowing user to reboot console proxy
+                            // when rebooting happens, we will receive
+                            // disconnect
+                            // here and we can't enter into stopping process,
+                            // as when the rebooted one comes up, it will kick
+                            // off a
+                            // newly started one and trigger the process
+                            // continue on forever
+
+                            /*
+                             * _capacityScanScheduler.execute(new Runnable() {
+                             * public void run() { if(s_logger.isInfoEnabled())
+                             * s_logger.info("Stop console proxy " +
+                             * proxy.getName() +
+                             * " VM because of that the agent running inside it has disconnected"
+                             * ); stopProxy(proxy.getId()); } });
+                             */
+                        } else {
+                            if (s_logger.isInfoEnabled()) {
+                                s_logger.info("Console proxy agent disconnected but corresponding console proxy VM no longer exists in DB, proxy: "
+                                        + name);
+                            }
+                        }
+                    } else {
+                        assert (false) : "Invalid console proxy name: " + name;
+                    }
+                }
+            }
+
+        }
+
+        @Override
+        protected HostVO findConsoleProxyHost(StartupProxyCommand startupCmd) {
+            long proxyVmId = startupCmd.getProxyVmId();
+            ConsoleProxyVO consoleProxy = _consoleProxyDao.findById(proxyVmId);
+            if (consoleProxy == null) {
+                s_logger.info("Proxy " + proxyVmId + " is no longer in DB, skip sending startup command");
+                return null;
+            }
+
+            assert (consoleProxy != null);
+            return findConsoleProxyHostByName(consoleProxy.getHostName());
+        }
+
+    }
 
     @Override
     public ConsoleProxyInfo assignProxy(final long dataCenterId, final long vmId) {
@@ -847,181 +960,9 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
         }
     }
 
-    @Override
-    public void onLoadReport(ConsoleProxyLoadReportCommand cmd) {
-        if (cmd.getLoadInfo() == null) {
-            return;
-        }
-
-        ConsoleProxyStatus status = null;
-        try {
-            GsonBuilder gb = new GsonBuilder();
-            gb.setVersion(1.3);
-            Gson gson = gb.create();
-            status = gson.fromJson(cmd.getLoadInfo(), ConsoleProxyStatus.class);
-        } catch (Throwable e) {
-            s_logger.warn("Unable to parse load info from proxy, proxy vm id : " + cmd.getProxyVmId() + ", info : " + cmd.getLoadInfo());
-        }
-
-        if (status != null) {
-            int count = 0;
-            if (status.getConnections() != null) {
-                count = status.getConnections().length;
-            }
-
-            byte[] details = null;
-            if (cmd.getLoadInfo() != null) {
-                details = cmd.getLoadInfo().getBytes(Charset.forName("US-ASCII"));
-            }
-            _consoleProxyDao.update(cmd.getProxyVmId(), count, DateUtil.currentGMTTime(), details);
-        } else {
-            if (s_logger.isTraceEnabled()) {
-                s_logger.trace("Unable to get console proxy load info, id : " + cmd.getProxyVmId());
-            }
 
-            _consoleProxyDao.update(cmd.getProxyVmId(), 0, DateUtil.currentGMTTime(), null);
-        }
-    }
 
-    @Override
-    public AgentControlAnswer onConsoleAccessAuthentication(ConsoleAccessAuthenticationCommand cmd) {
-        Long vmId = null;
-
-        String ticketInUrl = cmd.getTicket();
-        if (ticketInUrl == null) {
-            s_logger.error("Access ticket could not be found, you could be running an old version of console proxy. vmId: " + cmd.getVmId());
-            return new ConsoleAccessAuthenticationAnswer(cmd, false);
-        }
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Console authentication. Ticket in url for " + cmd.getHost() + ":" + cmd.getPort() + "-" + cmd.getVmId() + " is " + ticketInUrl);
-        }
-
-        if(!cmd.isReauthenticating()) {
-            String ticket = ConsoleProxyServlet.genAccessTicket(cmd.getHost(), cmd.getPort(), cmd.getSid(), cmd.getVmId());
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Console authentication. Ticket in 1 minute boundary for " + cmd.getHost() + ":" + cmd.getPort() + "-" + cmd.getVmId() + " is " + ticket);
-            }
-
-            if (!ticket.equals(ticketInUrl)) {
-                Date now = new Date();
-                // considering of minute round-up
-                String minuteEarlyTicket = ConsoleProxyServlet.genAccessTicket(cmd.getHost(), cmd.getPort(), cmd.getSid(), cmd.getVmId(), new Date(now.getTime() - 60 * 1000));
-
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Console authentication. Ticket in 2-minute boundary for " + cmd.getHost() + ":" + cmd.getPort() + "-" + cmd.getVmId() + " is " + minuteEarlyTicket);
-                }
-
-                if (!minuteEarlyTicket.equals(ticketInUrl)) {
-                    s_logger.error("Access ticket expired or has been modified. vmId: " + cmd.getVmId() + "ticket in URL: " + ticketInUrl + ", tickets to check against: " + ticket + ","
-                            + minuteEarlyTicket);
-                    return new ConsoleAccessAuthenticationAnswer(cmd, false);
-                }
-            }
-        }
-
-        if (cmd.getVmId() != null && cmd.getVmId().isEmpty()) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Invalid vm id sent from proxy(happens when proxy session has terminated)");
-            }
-            return new ConsoleAccessAuthenticationAnswer(cmd, false);
-        }
-
-        VirtualMachine vm = _instanceDao.findByUuid(cmd.getVmId());
-        if (vm == null) {
-            vm = _instanceDao.findById(Long.parseLong(cmd.getVmId()));
-        }
-        if (vm == null) {
-            s_logger.error("Invalid vm id " + cmd.getVmId() + " sent from console access authentication");
-            return new ConsoleAccessAuthenticationAnswer(cmd, false);
-        }
-
-        if (vm.getHostId() == null) {
-            s_logger.warn("VM " + vmId + " lost host info, failed authentication request");
-            return new ConsoleAccessAuthenticationAnswer(cmd, false);
-        }
-
-        HostVO host = _hostDao.findById(vm.getHostId());
-        if (host == null) {
-            s_logger.warn("VM " + vmId + "'s host does not exist, fail authentication request");
-            return new ConsoleAccessAuthenticationAnswer(cmd, false);
-        }
-
-        String sid = cmd.getSid();
-        if (sid == null || !sid.equals(vm.getVncPassword())) {
-            s_logger.warn("sid " + sid + " in url does not match stored sid " + vm.getVncPassword());
-            return new ConsoleAccessAuthenticationAnswer(cmd, false);
-        }
-
-        if(cmd.isReauthenticating()) {
-            ConsoleAccessAuthenticationAnswer authenticationAnswer = new ConsoleAccessAuthenticationAnswer(cmd, true);
-            authenticationAnswer.setReauthenticating(true);
-
-            s_logger.info("Re-authentication request, ask host " + vm.getHostId() + " for new console info");
-            GetVncPortAnswer answer = (GetVncPortAnswer) _agentMgr.easySend(vm.getHostId(), new 
-                    GetVncPortCommand(vm.getId(), vm.getInstanceName()));
-
-            if (answer != null && answer.getResult()) {
-                Ternary<String, String, String> parsedHostInfo = ConsoleProxyServlet.parseHostInfo(answer.getAddress());
-
-                if(parsedHostInfo.second() != null  && parsedHostInfo.third() != null) {
-
-                    s_logger.info("Re-authentication result. vm: " + vm.getId() + ", tunnel url: " + parsedHostInfo.second()
-                            + ", tunnel session: " + parsedHostInfo.third());
-
-                    authenticationAnswer.setTunnelUrl(parsedHostInfo.second());
-                    authenticationAnswer.setTunnelSession(parsedHostInfo.third());
-                } else {
-                    s_logger.info("Re-authentication result. vm: " + vm.getId() + ", host address: " + parsedHostInfo.first()
-                            + ", port: " + answer.getPort());
-
-                    authenticationAnswer.setHost(parsedHostInfo.first());
-                    authenticationAnswer.setPort(answer.getPort());
-                }
-            } else {
-                s_logger.warn("Re-authentication request failed");
-
-                authenticationAnswer.setSuccess(false);
-            }
-
-            return authenticationAnswer;
-        }
-
-        return new ConsoleAccessAuthenticationAnswer(cmd, true);
-    }
-
-    @Override
-    public void onAgentConnect(HostVO host, StartupCommand cmd) {
-        // if (host.getType() == Type.ConsoleProxy) {
-        // // TODO we can use this event to mark the proxy is up and
-        // // functioning instead of
-        // // pinging the console proxy VM command port
-        // //
-        // // for now, just log a message
-        // if (s_logger.isInfoEnabled()) {
-        // s_logger.info("Console proxy agent is connected. proxy: " + host.getName());
-        // }
-        //
-        // /* update public/private ip address */
-        // if (_IpAllocator != null && _IpAllocator.exteralIpAddressAllocatorEnabled()) {
-        // try {
-        // ConsoleProxyVO console = findConsoleProxyByHost(host);
-        // if (console == null) {
-        // s_logger.debug("Can't find console proxy ");
-        // return;
-        // }
-        // console.setPrivateIpAddress(cmd.getPrivateIpAddress());
-        // console.setPublicIpAddress(cmd.getPublicIpAddress());
-        // console.setPublicNetmask(cmd.getPublicNetmask());
-        // _consoleProxyDao.persist(console);
-        // } catch (NumberFormatException e) {
-        // }
-        // }
-        // }
-    }
-
-    @Override
-    public void onAgentDisconnect(long agentId, com.cloud.host.Status state) {
+    public void handleAgentDisconnect(long agentId, com.cloud.host.Status state) {
         if (state == com.cloud.host.Status.Alert || state == com.cloud.host.Status.Disconnected) {
             // be it either in alert or in disconnected state, the agent process
             // may be gone in the VM,
@@ -1496,7 +1437,9 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
         value = agentMgrConfigs.get("port");
         _mgmt_port = NumbersUtil.parseInt(value, 8250);
 
-        _listener = new ConsoleProxyListener(this);
+        _listener =
+                new ConsoleProxyListener(new VmBasedAgentHook(_instanceDao, _hostDao, _configDao, _ksMgr,
+                        _agentMgr));
         _agentMgr.registerForHostEvents(_listener, true, true, false);
 
         _itMgr.registerGuru(VirtualMachine.Type.ConsoleProxy, this);
@@ -1719,52 +1662,7 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
         _consoleProxyDao.update(proxy.getId(), proxy);
     }
 
-    @Override
-    public void startAgentHttpHandlerInVM(StartupProxyCommand startupCmd) {
-        StartConsoleProxyAgentHttpHandlerCommand cmd = null;
-        if (_configDao.isPremium()) {
-            String storePassword = String.valueOf(_random.nextLong());
-            byte[] ksBits = _ksMgr.getKeystoreBits(ConsoleProxyManager.CERTIFICATE_NAME, ConsoleProxyManager.CERTIFICATE_NAME, storePassword);
-
-            assert (ksBits != null);
-            if (ksBits == null) {
-                s_logger.error("Could not find and construct a valid SSL certificate");
-            }
-            cmd = new StartConsoleProxyAgentHttpHandlerCommand(ksBits, storePassword);
-            cmd.setEncryptorPassword(getHashKey());
-        } else {
-            cmd = new StartConsoleProxyAgentHttpHandlerCommand();
-            cmd.setEncryptorPassword(getHashKey());
-        }
-
-        try {
-            long proxyVmId = startupCmd.getProxyVmId();
-            ConsoleProxyVO consoleProxy = _consoleProxyDao.findById(proxyVmId);
-            if (consoleProxy == null) {
-                s_logger.info("Proxy " + proxyVmId + " is no longer in DB, skip sending startup command");
-                return;
-            }
-
-            assert (consoleProxy != null);
-            HostVO consoleProxyHost = findConsoleProxyHostByName(consoleProxy.getHostName());
 
-            Answer answer = _agentMgr.send(consoleProxyHost.getId(), cmd);
-            if (answer == null || !answer.getResult()) {
-                s_logger.error("Console proxy agent reported that it failed to execute http handling startup command");
-            } else {
-                s_logger.info("Successfully sent out command to start HTTP handling in console proxy agent");
-            }
-        } catch (AgentUnavailableException e) {
-            s_logger.error("Unable to send http handling startup command to the console proxy resource for proxy:" + startupCmd.getProxyVmId(), e);
-        } catch (OperationTimedoutException e) {
-            s_logger.error("Unable to send http handling startup command(time out) to the console proxy resource for proxy:" + startupCmd.getProxyVmId(), e);
-        } catch (OutOfMemoryError e) {
-            s_logger.error("Unrecoverable OutOfMemory Error, exit and let it be re-launched");
-            System.exit(1);
-        } catch (Exception e) {
-            s_logger.error("Unexpected exception when sending http handling startup command(time out) to the console proxy resource for proxy:" + startupCmd.getProxyVmId(), e);
-        }
-    }
 
     @Override
     public ConsoleProxyVO persist(ConsoleProxyVO proxy) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3d78019e/server/src/com/cloud/consoleproxy/StaticConsoleProxyManager.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/consoleproxy/StaticConsoleProxyManager.java b/server/src/com/cloud/consoleproxy/StaticConsoleProxyManager.java
index 3ba98a9..7b59a6b 100755
--- a/server/src/com/cloud/consoleproxy/StaticConsoleProxyManager.java
+++ b/server/src/com/cloud/consoleproxy/StaticConsoleProxyManager.java
@@ -16,29 +16,59 @@
 // under the License.
 package com.cloud.consoleproxy;
 
+
 import java.util.List;
 import java.util.Map;
+import java.util.Random;
 
 import javax.ejb.Local;
 import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
-import org.springframework.stereotype.Component;
+import org.apache.log4j.Logger;
 
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.StartupProxyCommand;
 import com.cloud.configuration.dao.ConfigurationDao;
 import com.cloud.host.Host.Type;
 import com.cloud.host.HostVO;
+import com.cloud.host.dao.HostDao;
 import com.cloud.info.ConsoleProxyInfo;
+import com.cloud.keystore.KeystoreDao;
+import com.cloud.keystore.KeystoreManager;
 import com.cloud.resource.ResourceManager;
+import com.cloud.resource.ResourceStateAdapter;
+import com.cloud.resource.ServerResource;
+import com.cloud.resource.UnableDeleteHostException;
+import com.cloud.utils.NumbersUtil;
 import com.cloud.vm.VMInstanceVO;
 import com.cloud.vm.dao.ConsoleProxyDao;
+import com.cloud.vm.dao.VMInstanceDao;
 
 @Local(value={ConsoleProxyManager.class})
-public class StaticConsoleProxyManager extends AgentBasedConsoleProxyManager implements ConsoleProxyManager {
-    String _ip = null;
-    @Inject ConsoleProxyDao _proxyDao;
-    @Inject ResourceManager _resourceMgr;
-    @Inject ConfigurationDao _configDao;
+public class StaticConsoleProxyManager extends AgentBasedConsoleProxyManager implements ConsoleProxyManager,
+        ResourceStateAdapter {
+    private static final Logger s_logger = Logger.getLogger(StaticConsoleProxyManager.class);
+
+    @Inject
+    ConsoleProxyDao _proxyDao;
+    @Inject
+    ResourceManager _resourceMgr;
+    @Inject
+    ConfigurationDao _configDao;
+    @Inject
+    private VMInstanceDao _instanceDao;
+    @Inject
+    KeystoreDao _ksDao;
+    @Inject
+    private KeystoreManager _ksMgr;
+    @Inject
+    private HostDao _hostDao;
+    private final Random _random = new Random(System.currentTimeMillis());
+    private String _hashKey;
+    private String _ip = null;
+
+
 
     @Override
     protected HostVO findHost(VMInstanceVO vm) {
@@ -50,20 +80,52 @@ public class StaticConsoleProxyManager extends AgentBasedConsoleProxyManager imp
 
     @Override
     public ConsoleProxyInfo assignProxy(long dataCenterId, long userVmId) {
-        return new ConsoleProxyInfo(false, _ip, _consoleProxyPort, _consoleProxyUrlPort, _consoleProxyUrlDomain);
+        return new ConsoleProxyInfo(_sslEnabled, _ip, _consoleProxyPort, _consoleProxyUrlPort, _consoleProxyUrlDomain);
     }
 
     @Override
     public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
         super.configure(name, params);
-
-        Map<String, String> dbParams = _configDao.getConfiguration("ManagementServer", params);
-
-        _ip = dbParams.get("public.ip");
+        _ip = _configDao.getValue("consoleproxy.static.publicIp");
         if (_ip == null) {
             _ip = "127.0.0.1";
         }
 
+
+        String value = (String) params.get("consoleproxy.sslEnabled");
+        if (value != null && value.equalsIgnoreCase("true")) {
+            _sslEnabled = true;
+        }
+        int defaultPort = 8088;
+        if (_sslEnabled)
+            defaultPort = 8443;
+        _consoleProxyUrlPort = NumbersUtil.parseInt(_configDao.getValue("consoleproxy.static.port"), defaultPort);
+
+        _resourceMgr.registerResourceStateAdapter(this.getClass().getSimpleName(), this);
+
         return true;
     }
+
+    @Override
+    public HostVO createHostVOForConnectedAgent(HostVO host, StartupCommand[] cmd) {
+        if (!(cmd[0] instanceof StartupProxyCommand)) {
+            return null;
+        }
+
+        host.setType(com.cloud.host.Host.Type.ConsoleProxy);
+        return host;
+    }
+
+    @Override
+    public HostVO createHostVOForDirectConnectAgent(HostVO host, StartupCommand[] startup, ServerResource resource,
+            Map<String, String> details, List<String> hostTags) {
+        return null;
+    }
+
+    @Override
+    public DeleteHostAnswer deleteHost(HostVO host, boolean isForced, boolean isForceDeleteStorage)
+            throws UnableDeleteHostException {
+        return null;
+    }
+
 }


[07/19] git commit: updated refs/heads/master to bf56403

Posted by ch...@apache.org.
QuickCloud: Enable secondary storage daemon to run outside the system vm


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

Branch: refs/heads/master
Commit: e7983b25cccc69abe0304a0b8d720c4c85c4561a
Parents: 4fd3fca
Author: Chiradeep Vittal <ch...@apache.org>
Authored: Sun Mar 24 23:50:02 2013 -0700
Committer: Chiradeep Vittal <ch...@apache.org>
Committed: Tue Apr 9 14:45:25 2013 -0700

----------------------------------------------------------------------
 agent/src/com/cloud/agent/AgentShell.java          |    3 +-
 .../resource/CifsSecondaryStorageResource.java     |  755 ------
 .../resource/LocalSecondaryStorageResource.java    |  246 --
 .../resource/NfsSecondaryStorageResource.java      | 1842 --------------
 .../storage/resource/SecondaryStorageResource.java |   28 -
 .../resource/SecondaryStorageResourceHandler.java  |   24 -
 .../cloud/storage/template/DownloadManager.java    |  103 -
 .../storage/template/DownloadManagerImpl.java      | 1049 --------
 .../com/cloud/storage/template/UploadManager.java  |   85 -
 .../cloud/storage/template/UploadManagerImpl.java  |  645 -----
 .../com/cloud/resource/AgentStorageResource.java   |    2 +-
 .../resource/PremiumSecondaryStorageResource.java  |    2 +
 .../VmwareSecondaryStorageResourceHandler.java     |    1 +
 scripts/vm/systemvm/injectkeys.sh                  |   26 +-
 server/pom.xml                                     |    5 +
 .../secondary/SecondaryStorageDiscoverer.java      |    4 +-
 services/pom.xml                                   |    1 +
 services/secondary-storage/conf/agent.properties   |   11 +
 .../secondary-storage/conf/environment.properties  |    2 +
 services/secondary-storage/conf/log4j-cloud.xml    |  102 +
 services/secondary-storage/pom.xml                 |  113 +
 services/secondary-storage/scripts/_run.sh         |   63 +
 services/secondary-storage/scripts/config_auth.sh  |   69 +
 services/secondary-storage/scripts/config_ssl.sh   |  174 ++
 services/secondary-storage/scripts/ipfirewall.sh   |   50 +
 services/secondary-storage/scripts/run-proxy.sh    |   48 +
 services/secondary-storage/scripts/run.bat         |   18 +
 services/secondary-storage/scripts/run.sh          |   45 +
 services/secondary-storage/scripts/ssvm-check.sh   |  136 ++
 .../resource/CifsSecondaryStorageResource.java     |  755 ++++++
 .../resource/LocalSecondaryStorageResource.java    |  246 ++
 .../resource/NfsSecondaryStorageResource.java      | 1882 +++++++++++++++
 .../storage/resource/SecondaryStorageResource.java |   28 +
 .../resource/SecondaryStorageResourceHandler.java  |   24 +
 .../storage/template/DownloadManager.java          |  105 +
 .../storage/template/DownloadManagerImpl.java      | 1074 ++++++++
 .../cloudstack/storage/template/UploadManager.java |   87 +
 .../storage/template/UploadManagerImpl.java        |  648 +++++
 tools/devcloud/pom.xml                             |   33 +
 tools/devcloud/quickcloud.cfg                      |  120 +
 tools/marvin/marvin/cloudstackConnection.py        |    6 +-
 tools/marvin/marvin/deployDataCenter.py            |   16 +-
 42 files changed, 5880 insertions(+), 4796 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/agent/src/com/cloud/agent/AgentShell.java
----------------------------------------------------------------------
diff --git a/agent/src/com/cloud/agent/AgentShell.java b/agent/src/com/cloud/agent/AgentShell.java
index 2af08e9..73b3950 100644
--- a/agent/src/com/cloud/agent/AgentShell.java
+++ b/agent/src/com/cloud/agent/AgentShell.java
@@ -38,12 +38,10 @@ import java.util.UUID;
 
 import javax.naming.ConfigurationException;
 
-import org.apache.commons.beanutils.PropertyUtils;
 import org.apache.commons.httpclient.HttpClient;
 import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
 import org.apache.commons.httpclient.methods.GetMethod;
 import org.apache.log4j.Logger;
-import org.apache.log4j.PropertyConfigurator;
 import org.apache.log4j.xml.DOMConfigurator;
 
 import com.cloud.agent.Agent.ExitStatus;
@@ -373,6 +371,7 @@ public class AgentShell implements IAgentShell {
                 throw new ConfigurationException("Unable to find the guid");
             }
             _guid = UUID.randomUUID().toString();
+            _properties.setProperty("guid", _guid);
         }
 
         return true;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/core/src/com/cloud/storage/resource/CifsSecondaryStorageResource.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/storage/resource/CifsSecondaryStorageResource.java b/core/src/com/cloud/storage/resource/CifsSecondaryStorageResource.java
deleted file mode 100755
index 285005a..0000000
--- a/core/src/com/cloud/storage/resource/CifsSecondaryStorageResource.java
+++ /dev/null
@@ -1,755 +0,0 @@
-// 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.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.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.DownloadManager;
-import com.cloud.storage.template.DownloadManagerImpl;
-import com.cloud.storage.template.TemplateInfo;
-import com.cloud.storage.template.UploadManager;
-import com.cloud.storage.template.UploadManagerImpl;
-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/core/src/com/cloud/storage/resource/LocalSecondaryStorageResource.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/storage/resource/LocalSecondaryStorageResource.java b/core/src/com/cloud/storage/resource/LocalSecondaryStorageResource.java
deleted file mode 100644
index c638c5d..0000000
--- a/core/src/com/cloud/storage/resource/LocalSecondaryStorageResource.java
+++ /dev/null
@@ -1,246 +0,0 @@
-// 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.storage.resource;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.naming.ConfigurationException;
-
-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.DownloadManager;
-import com.cloud.storage.template.DownloadManagerImpl;
-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
-		
-	}
-}


[10/19] git commit: updated refs/heads/master to bf56403

Posted by ch...@apache.org.
QuickCloud: Remove reference to unused code
QuickCloud: remove some dead code in ConsoleProxyManager


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

Branch: refs/heads/master
Commit: 790d2ce82ef6b1ac910124c8c9ab519e2431e622
Parents: 1679044
Author: Chiradeep Vittal <ch...@apache.org>
Authored: Mon Mar 25 12:13:51 2013 -0700
Committer: Chiradeep Vittal <ch...@apache.org>
Committed: Tue Apr 9 14:45:26 2013 -0700

----------------------------------------------------------------------
 .../cloud/api/commands/DestroyConsoleProxyCmd.java |   12 +------
 .../cloud/consoleproxy/ConsoleProxyService.java    |   23 ---------------
 api/src/org/apache/cloudstack/api/BaseCmd.java     |    2 -
 .../cloud/consoleproxy/ConsoleProxyManager.java    |   17 +----------
 .../consoleproxy/ConsoleProxyManagerImpl.java      |   20 ++-----------
 .../cloud/consoleproxy/ConsoleProxyService.java    |    9 ++++++
 6 files changed, 15 insertions(+), 68 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/790d2ce8/api/src/com/cloud/api/commands/DestroyConsoleProxyCmd.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/api/commands/DestroyConsoleProxyCmd.java b/api/src/com/cloud/api/commands/DestroyConsoleProxyCmd.java
index 829283e..f3210ce 100644
--- a/api/src/com/cloud/api/commands/DestroyConsoleProxyCmd.java
+++ b/api/src/com/cloud/api/commands/DestroyConsoleProxyCmd.java
@@ -17,14 +17,12 @@
 package com.cloud.api.commands;
 
 import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.ApiErrorCode;
 import org.apache.cloudstack.api.BaseAsyncCmd;
 import org.apache.cloudstack.api.Parameter;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.SuccessResponse;
 import org.apache.log4j.Logger;
 
 import com.cloud.event.EventTypes;
+import com.cloud.exception.UnsupportedServiceException;
 import com.cloud.user.Account;
 import com.cloud.user.UserContext;
 
@@ -82,12 +80,6 @@ public class DestroyConsoleProxyCmd extends BaseAsyncCmd {
 
     @Override
     public void execute(){
-        boolean result = _consoleProxyService.destroyConsoleProxy(this);
-        if (result) {
-            SuccessResponse response = new SuccessResponse(getCommandName());
-            this.setResponseObject(response);
-        } else {
-            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to destroy console proxy");
-        }
+        throw new UnsupportedServiceException("Use destroySystemVm API instead");
     }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/790d2ce8/api/src/com/cloud/consoleproxy/ConsoleProxyService.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/consoleproxy/ConsoleProxyService.java b/api/src/com/cloud/consoleproxy/ConsoleProxyService.java
deleted file mode 100644
index c347e0b..0000000
--- a/api/src/com/cloud/consoleproxy/ConsoleProxyService.java
+++ /dev/null
@@ -1,23 +0,0 @@
-// 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.consoleproxy;
-
-import com.cloud.api.commands.DestroyConsoleProxyCmd;
-
-public interface ConsoleProxyService {
-    boolean destroyConsoleProxy(DestroyConsoleProxyCmd cmd);
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/790d2ce8/api/src/org/apache/cloudstack/api/BaseCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/BaseCmd.java b/api/src/org/apache/cloudstack/api/BaseCmd.java
index 78a2af3..8fef422 100644
--- a/api/src/org/apache/cloudstack/api/BaseCmd.java
+++ b/api/src/org/apache/cloudstack/api/BaseCmd.java
@@ -32,7 +32,6 @@ import org.apache.cloudstack.usage.UsageService;
 import org.apache.log4j.Logger;
 
 import com.cloud.configuration.ConfigurationService;
-import com.cloud.consoleproxy.ConsoleProxyService;
 import com.cloud.dao.EntityManager;
 import com.cloud.domain.Domain;
 import com.cloud.exception.ConcurrentOperationException;
@@ -109,7 +108,6 @@ public abstract class BaseCmd {
     @Inject public TemplateService _templateService;
     @Inject public SecurityGroupService _securityGroupService;
     @Inject public SnapshotService _snapshotService;
-    @Inject public ConsoleProxyService _consoleProxyService;
     @Inject public VpcVirtualNetworkApplianceService _routerService;
     @Inject public ResponseGenerator _responseGenerator;
     @Inject public EntityManager _entityMgr;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/790d2ce8/server/src/com/cloud/consoleproxy/ConsoleProxyManager.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyManager.java b/server/src/com/cloud/consoleproxy/ConsoleProxyManager.java
index 6ebf3bc..faec513 100755
--- a/server/src/com/cloud/consoleproxy/ConsoleProxyManager.java
+++ b/server/src/com/cloud/consoleproxy/ConsoleProxyManager.java
@@ -16,17 +16,9 @@
 // under the License.
 package com.cloud.consoleproxy;
 
-import com.cloud.agent.api.AgentControlAnswer;
-import com.cloud.agent.api.ConsoleAccessAuthenticationCommand;
-import com.cloud.agent.api.ConsoleProxyLoadReportCommand;
-import com.cloud.agent.api.StartupCommand;
-import com.cloud.host.HostVO;
-import com.cloud.host.Status;
-import com.cloud.host.Host.Type;
-import com.cloud.info.ConsoleProxyInfo;
 import com.cloud.utils.component.Manager;
 import com.cloud.vm.ConsoleProxyVO;
-public interface ConsoleProxyManager extends Manager {
+public interface ConsoleProxyManager extends Manager, ConsoleProxyService {
 	
 	public static final int DEFAULT_PROXY_CAPACITY = 50;
 	public static final int DEFAULT_STANDBY_CAPACITY = 10;
@@ -45,16 +37,9 @@ public interface ConsoleProxyManager extends Manager {
     public ConsoleProxyManagementState getManagementState();
     public void resumeLastManagementState();
 	
-	public ConsoleProxyInfo assignProxy(long dataCenterId, long userVmId);
-	
 	public ConsoleProxyVO startProxy(long proxyVmId);
 	public boolean stopProxy(long proxyVmId);
 	public boolean rebootProxy(long proxyVmId);
 	public boolean destroyProxy(long proxyVmId);
-
-	public void onLoadReport(ConsoleProxyLoadReportCommand cmd);
-	public AgentControlAnswer onConsoleAccessAuthentication(ConsoleAccessAuthenticationCommand cmd);
 	
-    public void onAgentConnect(HostVO host, StartupCommand cmd);
-	public void onAgentDisconnect(long agentId, Status state);
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/790d2ce8/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java
index 1edd869..fc4fc6e 100755
--- a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java
+++ b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java
@@ -30,7 +30,6 @@ import javax.ejb.Local;
 import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
-import org.apache.cloudstack.api.ServerApiException;
 import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
 import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
 import org.apache.log4j.Logger;
@@ -54,7 +53,6 @@ import com.cloud.agent.api.proxy.StartConsoleProxyAgentHttpHandlerCommand;
 import com.cloud.agent.api.to.NicTO;
 import com.cloud.agent.api.to.VirtualMachineTO;
 import com.cloud.agent.manager.Commands;
-import com.cloud.api.commands.DestroyConsoleProxyCmd;
 import com.cloud.certificate.dao.CertificateDao;
 import com.cloud.cluster.ClusterManager;
 import com.cloud.configuration.Config;
@@ -71,7 +69,6 @@ import com.cloud.deploy.DeployDestination;
 import com.cloud.exception.AgentUnavailableException;
 import com.cloud.exception.ConcurrentOperationException;
 import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.InvalidParameterValueException;
 import com.cloud.exception.OperationTimedoutException;
 import com.cloud.exception.ResourceUnavailableException;
 import com.cloud.exception.StorageUnavailableException;
@@ -113,8 +110,8 @@ import com.cloud.servlet.ConsoleProxyServlet;
 import com.cloud.storage.StorageManager;
 import com.cloud.storage.StoragePoolStatus;
 import com.cloud.storage.VMTemplateHostVO;
-import com.cloud.storage.VMTemplateVO;
 import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
+import com.cloud.storage.VMTemplateVO;
 import com.cloud.storage.dao.DiskOfferingDao;
 import com.cloud.storage.dao.VMTemplateDao;
 import com.cloud.storage.dao.VMTemplateHostDao;
@@ -127,7 +124,6 @@ import com.cloud.utils.DateUtil;
 import com.cloud.utils.NumbersUtil;
 import com.cloud.utils.Pair;
 import com.cloud.utils.Ternary;
-import com.cloud.utils.component.Manager;
 import com.cloud.utils.component.ManagerBase;
 import com.cloud.utils.db.DB;
 import com.cloud.utils.db.GlobalLock;
@@ -170,7 +166,8 @@ import com.google.gson.GsonBuilder;
 // because sooner or later, it will be driven into Running state
 //
 @Local(value = { ConsoleProxyManager.class, ConsoleProxyService.class })
-public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxyManager, ConsoleProxyService, AgentHook, VirtualMachineGuru<ConsoleProxyVO>, SystemVmLoadScanHandler<Long>, ResourceStateAdapter {
+public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxyManager,
+        AgentHook, VirtualMachineGuru<ConsoleProxyVO>, SystemVmLoadScanHandler<Long>, ResourceStateAdapter {
     private static final Logger s_logger = Logger.getLogger(ConsoleProxyManagerImpl.class);
 
     private static final int DEFAULT_CAPACITY_SCAN_INTERVAL = 30000; // 30 seconds
@@ -1549,18 +1546,7 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
         return true;
     }
 
-    @Override
-    public boolean destroyConsoleProxy(DestroyConsoleProxyCmd cmd) throws ServerApiException {
-        Long proxyId = cmd.getId();
 
-        // verify parameters
-        ConsoleProxyVO proxy = _consoleProxyDao.findById(proxyId);
-        if (proxy == null) {
-            throw new InvalidParameterValueException("unable to find a console proxy with id " + proxyId);
-        }
-
-        return destroyProxy(proxyId);
-    }
 
     protected ConsoleProxyManagerImpl() {
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/790d2ce8/server/src/com/cloud/consoleproxy/ConsoleProxyService.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyService.java b/server/src/com/cloud/consoleproxy/ConsoleProxyService.java
new file mode 100644
index 0000000..e43e5c3
--- /dev/null
+++ b/server/src/com/cloud/consoleproxy/ConsoleProxyService.java
@@ -0,0 +1,9 @@
+package com.cloud.consoleproxy;
+
+import com.cloud.info.ConsoleProxyInfo;
+
+public interface ConsoleProxyService {
+
+    public abstract ConsoleProxyInfo assignProxy(long dataCenterId, long userVmId);
+
+}
\ No newline at end of file


[19/19] git commit: updated refs/heads/master to bf56403

Posted by ch...@apache.org.
QuickCloud: sanitize logs for normal running of agents outside systemvm


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

Branch: refs/heads/master
Commit: 2e6c65fd34dc5f4f885c12a4e5469b505975685d
Parents: 271d232
Author: Chiradeep Vittal <ch...@apache.org>
Authored: Fri Apr 5 14:11:05 2013 -0700
Committer: Chiradeep Vittal <ch...@apache.org>
Committed: Tue Apr 9 14:45:27 2013 -0700

----------------------------------------------------------------------
 .../consoleproxy/ConsoleProxyResource.java         |    4 +-
 .../src/com/cloud/resource/ServerResourceBase.java |    2 +-
 .../AgentBasedConsoleProxyManager.java.orig        |  298 +++++++++++++++
 .../PremiumSecondaryStorageManagerImpl.java        |    6 +-
 .../storage/download/DownloadMonitorImpl.java      |   11 +-
 .../secondary/SecondaryStorageManagerImpl.java     |    2 +-
 .../resource/NfsSecondaryStorageResource.java      |    6 +-
 utils/src/com/cloud/utils/nio/NioClient.java       |    3 +-
 utils/src/com/cloud/utils/nio/NioConnection.java   |    2 +-
 9 files changed, 320 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2e6c65fd/agent/src/com/cloud/agent/resource/consoleproxy/ConsoleProxyResource.java
----------------------------------------------------------------------
diff --git a/agent/src/com/cloud/agent/resource/consoleproxy/ConsoleProxyResource.java b/agent/src/com/cloud/agent/resource/consoleproxy/ConsoleProxyResource.java
index 516430b..991764c 100644
--- a/agent/src/com/cloud/agent/resource/consoleproxy/ConsoleProxyResource.java
+++ b/agent/src/com/cloud/agent/resource/consoleproxy/ConsoleProxyResource.java
@@ -235,14 +235,14 @@ public class ConsoleProxyResource extends ServerResourceBase implements
         if (_eth1ip != null) {
             params.put("private.network.device", "eth1");
         } else {
-            s_logger.warn("WARNING: eth1ip parameter is not found!");
+            s_logger.info("eth1ip parameter has not been configured, assuming that we are not inside a system vm");
         }
 
         String eth2ip = (String) params.get("eth2ip");
         if (eth2ip != null) {
             params.put("public.network.device", "eth2");
         } else {
-            s_logger.warn("WARNING: eth2ip parameter is not found!");
+            s_logger.info("eth2ip parameter is not found, assuming that we are not inside a system vm");
         }
 
         super.configure(name, params);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2e6c65fd/core/src/com/cloud/resource/ServerResourceBase.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/resource/ServerResourceBase.java b/core/src/com/cloud/resource/ServerResourceBase.java
index 9449b05..e381fcb 100755
--- a/core/src/com/cloud/resource/ServerResourceBase.java
+++ b/core/src/com/cloud/resource/ServerResourceBase.java
@@ -80,7 +80,7 @@ public abstract class ServerResourceBase implements ServerResource {
         _storageNic2 = getNetworkInterface(storageNic2);
         
         if (_privateNic == null) {
-            s_logger.error("Nics are not configured!");
+            s_logger.warn("Nics are not specified in properties file/db, will try to autodiscover");
 
 			Enumeration<NetworkInterface> nics = null;
             try {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2e6c65fd/server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java.orig
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java.orig b/server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java.orig
new file mode 100755
index 0000000..134d59d
--- /dev/null
+++ b/server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java.orig
@@ -0,0 +1,298 @@
+// 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.consoleproxy;
+
+import java.util.Map;
+
+import javax.ejb.Local;
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.GetVncPortAnswer;
+import com.cloud.agent.api.GetVncPortCommand;
+import com.cloud.agent.api.StartupProxyCommand;
+import com.cloud.configuration.dao.ConfigurationDao;
+import com.cloud.host.HostVO;
+import com.cloud.host.dao.HostDao;
+import com.cloud.info.ConsoleProxyInfo;
+import com.cloud.keystore.KeystoreManager;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.vm.ConsoleProxyVO;
+import com.cloud.vm.UserVmVO;
+import com.cloud.vm.VMInstanceVO;
+import com.cloud.vm.VirtualMachineManager;
+import com.cloud.vm.dao.ConsoleProxyDao;
+import com.cloud.vm.dao.UserVmDao;
+import com.cloud.vm.dao.VMInstanceDao;
+
+@Local(value = { ConsoleProxyManager.class })
+public class AgentBasedConsoleProxyManager extends ManagerBase implements ConsoleProxyManager {
+    private static final Logger s_logger = Logger.getLogger(AgentBasedConsoleProxyManager.class);
+
+    @Inject
+    protected HostDao _hostDao;
+    @Inject
+    protected UserVmDao _userVmDao;
+    private String _instance;
+    protected String _consoleProxyUrlDomain;
+    @Inject
+    private VMInstanceDao _instanceDao;
+    private ConsoleProxyListener _listener;
+    protected int _consoleProxyUrlPort = ConsoleProxyManager.DEFAULT_PROXY_URL_PORT;
+    protected int _consoleProxyPort = ConsoleProxyManager.DEFAULT_PROXY_VNC_PORT;
+    protected boolean _sslEnabled = false;
+    @Inject
+    AgentManager _agentMgr;
+    @Inject
+    VirtualMachineManager _itMgr;
+    @Inject
+    protected ConsoleProxyDao _cpDao;
+    @Inject
+    protected KeystoreManager _ksMgr;
+
+    @Inject ConfigurationDao _configDao;
+
+    public class AgentBasedAgentHook extends AgentHookBase {
+
+        public AgentBasedAgentHook(VMInstanceDao instanceDao, HostDao hostDao, ConfigurationDao cfgDao,
+                KeystoreManager ksMgr, AgentManager agentMgr) {
+            super(instanceDao, hostDao, cfgDao, ksMgr, agentMgr);
+        }
+
+        @Override
+        protected HostVO findConsoleProxyHost(StartupProxyCommand cmd) {
+            return _hostDao.findByGuid(cmd.getGuid());
+        }
+
+    }
+
+    public int getVncPort(VMInstanceVO vm) {
+        if (vm.getHostId() == null) {
+            return -1;
+        }
+        GetVncPortAnswer answer = (GetVncPortAnswer) _agentMgr.easySend(vm.getHostId(), new GetVncPortCommand(vm.getId(), vm.getHostName()));
+        return (answer == null || !answer.getResult()) ? -1 : answer.getPort();
+    }
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Start configuring AgentBasedConsoleProxyManager");
+        }
+
+        Map<String, String> configs = _configDao.getConfiguration("management-server", params);
+        String value = configs.get("consoleproxy.url.port");
+        if (value != null) {
+            _consoleProxyUrlPort = NumbersUtil.parseInt(value, ConsoleProxyManager.DEFAULT_PROXY_URL_PORT);
+        }
+
+        value = configs.get("consoleproxy.port");
+        if (value != null) {
+            _consoleProxyPort = NumbersUtil.parseInt(value, ConsoleProxyManager.DEFAULT_PROXY_VNC_PORT);
+        }
+
+        value = configs.get("consoleproxy.sslEnabled");
+        if (value != null && value.equalsIgnoreCase("true")) {
+            _sslEnabled = true;
+        }
+
+        _instance = configs.get("instance.name");
+
+        _consoleProxyUrlDomain = configs.get("consoleproxy.url.domain");
+
+        _listener =
+                new ConsoleProxyListener(new AgentBasedAgentHook(_instanceDao, _hostDao, _configDao, _ksMgr, _agentMgr));
+        _agentMgr.registerForHostEvents(_listener, true, true, false);
+
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("AgentBasedConsoleProxyManager has been configured. SSL enabled: " + _sslEnabled);
+        }
+        return true;
+    }
+
+    HostVO findHost(VMInstanceVO vm) {
+        return _hostDao.findById(vm.getHostId());
+    }
+
+    @Override
+    public ConsoleProxyInfo assignProxy(long dataCenterId, long userVmId) {
+        UserVmVO userVm = _userVmDao.findById(userVmId);
+        if (userVm == null) {
+            s_logger.warn("User VM " + userVmId + " no longer exists, return a null proxy for user vm:" + userVmId);
+            return null;
+        }
+
+        HostVO host = findHost(userVm);
+        if (host != null) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Assign embedded console proxy running at " + host.getName() + " to user vm " + userVmId + " with public IP "
+                        + host.getPublicIpAddress());
+            }
+
+            // only private IP, public IP, host id have meaningful values, rest
+            // of all are place-holder values
+            String publicIp = host.getPublicIpAddress();
+            if (publicIp == null) {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Host " + host.getName() + "/" + host.getPrivateIpAddress()
+                            + " does not have public interface, we will return its private IP for cosole proxy.");
+                }
+                publicIp = host.getPrivateIpAddress();
+            }
+
+            int urlPort = _consoleProxyUrlPort;
+
+            if (host.getProxyPort() != null && host.getProxyPort().intValue() > 0) {
+                urlPort = host.getProxyPort().intValue();
+            }
+
+            return new ConsoleProxyInfo(_sslEnabled, publicIp, _consoleProxyPort, urlPort, _consoleProxyUrlDomain);
+        } else {
+            s_logger.warn("Host that VM is running is no longer available, console access to VM " + userVmId + " will be temporarily unavailable.");
+        }
+        return null;
+    }
+
+
+
+
+    @Override
+    public ConsoleProxyVO startProxy(long proxyVmId) {
+        return null;
+    }
+
+    @Override
+    public boolean destroyProxy(long proxyVmId) {
+        return false;
+    }
+
+    @Override
+    public boolean rebootProxy(long proxyVmId) {
+        return false;
+    }
+
+    @Override
+    public boolean stopProxy(long proxyVmId) {
+        return false;
+    }
+
+    @Override
+    public void setManagementState(ConsoleProxyManagementState state) {
+    }
+
+    @Override
+    public ConsoleProxyManagementState getManagementState() {
+        return null;
+    }
+
+    @Override
+    public void resumeLastManagementState() {
+    }
+
+    @Override
+    public String getName() {
+        return _name;
+    }
+<<<<<<< HEAD
+
+    @Override
+    public Long convertToId(String vmName) {
+        if (!VirtualMachineName.isValidConsoleProxyName(vmName, _instance)) {
+            return null;
+        }
+        return VirtualMachineName.getConsoleProxyId(vmName);
+    }
+
+    @Override
+    public ConsoleProxyVO findByName(String name) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public ConsoleProxyVO findById(long id) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public ConsoleProxyVO persist(ConsoleProxyVO vm) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public boolean finalizeVirtualMachineProfile(VirtualMachineProfile<ConsoleProxyVO> profile, DeployDestination dest, ReservationContext context) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean finalizeDeployment(Commands cmds, VirtualMachineProfile<ConsoleProxyVO> profile, DeployDestination dest, ReservationContext context) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean finalizeCommandsOnStart(Commands cmds, VirtualMachineProfile<ConsoleProxyVO> profile) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean finalizeStart(VirtualMachineProfile<ConsoleProxyVO> profile, long hostId, Commands cmds, ReservationContext context) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public void finalizeStop(VirtualMachineProfile<ConsoleProxyVO> profile, StopAnswer answer) {
+        // TODO Auto-generated method stub
+    }
+
+    @Override 
+    public void finalizeExpunge(ConsoleProxyVO proxy) {
+    }
+
+    @Override
+    public boolean plugNic(Network network, NicTO nic, VirtualMachineTO vm,
+            ReservationContext context, DeployDestination dest) throws ConcurrentOperationException, ResourceUnavailableException,
+            InsufficientCapacityException {
+        //not supported
+        throw new UnsupportedOperationException("Plug nic is not supported for vm of type " + vm.getType());
+    }
+
+
+    @Override
+    public boolean unplugNic(Network network, NicTO nic, VirtualMachineTO vm,
+            ReservationContext context, DeployDestination dest) throws ConcurrentOperationException, ResourceUnavailableException {
+        //not supported
+        throw new UnsupportedOperationException("Unplug nic is not supported for vm of type " + vm.getType());
+    }
+
+    @Override
+    public void prepareStop(VirtualMachineProfile<ConsoleProxyVO> profile) {
+    }
+}
+=======
+}
+>>>>>>> QuickCloud: refactor to avoid copy paste of authentication and startup code

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2e6c65fd/server/src/com/cloud/secstorage/PremiumSecondaryStorageManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/secstorage/PremiumSecondaryStorageManagerImpl.java b/server/src/com/cloud/secstorage/PremiumSecondaryStorageManagerImpl.java
index 73015c1..8658113 100755
--- a/server/src/com/cloud/secstorage/PremiumSecondaryStorageManagerImpl.java
+++ b/server/src/com/cloud/secstorage/PremiumSecondaryStorageManagerImpl.java
@@ -25,8 +25,6 @@ import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
 import org.apache.log4j.Logger;
-import org.springframework.context.annotation.Primary;
-import org.springframework.stereotype.Component;
 
 import com.cloud.agent.api.Command;
 import com.cloud.configuration.Config;
@@ -90,6 +88,10 @@ public class PremiumSecondaryStorageManagerImpl extends SecondaryStorageManagerI
     @Override
 	public Pair<AfterScanAction, Object> scanPool(Long pool) {
 		long dataCenterId = pool.longValue();
+        if (!isSecondaryStorageVmRequired(dataCenterId)) {
+            return new Pair<AfterScanAction, Object>(AfterScanAction.nop, null);
+        }
+
 		Date cutTime = new Date(DateUtil.currentGMTTime().getTime() - _maxExecutionTimeMs);
 
 		_cmdExecLogDao.expungeExpiredRecords(cutTime);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2e6c65fd/server/src/com/cloud/storage/download/DownloadMonitorImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/download/DownloadMonitorImpl.java b/server/src/com/cloud/storage/download/DownloadMonitorImpl.java
index cfb92d5..5d7a210 100755
--- a/server/src/com/cloud/storage/download/DownloadMonitorImpl.java
+++ b/server/src/com/cloud/storage/download/DownloadMonitorImpl.java
@@ -851,7 +851,7 @@ public class DownloadMonitorImpl extends ManagerBase implements  DownloadMonitor
                 TemplateInfo tmpltInfo = templateInfos.remove(uniqueName);
                 toBeDownloaded.remove(tmplt);
                 if (tmpltHost != null) {
-                    s_logger.info("Template Sync found " + uniqueName + " already in the template host table");
+                    s_logger.info("Template Sync found " + tmplt.getName() + " already in the template host table");
                     if (tmpltHost.getDownloadState() != Status.DOWNLOADED) {
                         tmpltHost.setErrorString("");
                     }
@@ -911,10 +911,12 @@ public class DownloadMonitorImpl extends ManagerBase implements  DownloadMonitor
                 continue;
             }
             if (tmpltHost != null && tmpltHost.getDownloadState() != Status.DOWNLOADED) {
-                s_logger.info("Template Sync did not find " + uniqueName + " ready on server " + sserverId + ", will request download to start/resume shortly");
+                s_logger.info("Template Sync did not find " + tmplt.getName() + " ready on server " + sserverId
+                        + ", will request download to start/resume shortly");
 
             } else if (tmpltHost == null) {
-                s_logger.info("Template Sync did not find " + uniqueName + " on the server " + sserverId + ", will request download shortly");
+                s_logger.info("Template Sync did not find " + tmplt.getName() + " on the server " + sserverId
+                        + ", will request download shortly");
                 VMTemplateHostVO templtHost = new VMTemplateHostVO(sserverId, tmplt.getId(), new Date(), 0, Status.NOT_DOWNLOADED, null, null, null, null, tmplt.getUrl());
                 _vmTemplateHostDao.persist(templtHost);
                 VMTemplateZoneVO tmpltZoneVO = _vmTemplateZoneDao.findByZoneTemplate(zoneId, tmplt.getId());
@@ -964,6 +966,9 @@ public class DownloadMonitorImpl extends ManagerBase implements  DownloadMonitor
                     }
                     s_logger.debug("Template " + tmplt.getName() + " needs to be downloaded to " + ssHost.getName());
                     downloadTemplateToStorage(tmplt, ssHost);
+                } else {
+                    s_logger.info("Skipping download of template " + tmplt.getName() + " since we don't have any "
+                            + tmplt.getHypervisorType() + " hypervisors");
                 }
             }
         }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2e6c65fd/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java
index d6d6fc0..3cf9a7e 100755
--- a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java
+++ b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java
@@ -472,7 +472,7 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar
 
     }
 
-    private boolean isSecondaryStorageVmRequired(long dcId) {
+    protected boolean isSecondaryStorageVmRequired(long dcId) {
         DataCenterVO dc = _dcDao.findById(dcId);
         _dcDao.loadDetails(dc);
         String ssvmReq = dc.getDetail(ZoneConfig.EnableSecStorageVm.key());

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2e6c65fd/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
index 6bcf98e..1176d76 100755
--- a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
+++ b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
@@ -1464,7 +1464,7 @@ SecondaryStorageResource {
         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!!");
+            s_logger.warn("eth1ip parameter has not been configured, assuming that we are not inside a system vm");
         }
         String eth2ip = (String) params.get("eth2ip");
         if (eth2ip != null) {
@@ -1479,8 +1479,8 @@ SecondaryStorageResource {
         }
 
         _storageIp = (String) params.get("storageip");
-        if (_storageIp == null) {
-            s_logger.warn("Wait, there is no storageip in /proc/cmdline, something wrong!");
+        if (_storageIp == null && _inSystemVM) {
+            s_logger.warn("There is no storageip in /proc/cmdline, something wrong!");
         }
         _storageNetmask = (String) params.get("storagenetmask");
         _storageGateway = (String) params.get("storagegateway");

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2e6c65fd/utils/src/com/cloud/utils/nio/NioClient.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/nio/NioClient.java b/utils/src/com/cloud/utils/nio/NioClient.java
index 1e2aa52..8d12f93 100755
--- a/utils/src/com/cloud/utils/nio/NioClient.java
+++ b/utils/src/com/cloud/utils/nio/NioClient.java
@@ -22,8 +22,8 @@ import java.nio.channels.SelectionKey;
 import java.nio.channels.Selector;
 import java.nio.channels.SocketChannel;
 
-import javax.net.ssl.SSLEngine;
 import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLEngine;
 
 import org.apache.log4j.Logger;
 
@@ -78,6 +78,7 @@ public class NioClient extends NioConnection {
 
         	Link.doHandshake(sch, sslEngine, true);
         	s_logger.info("SSL: Handshake done");
+            s_logger.info("Connected to " + _host + ":" + _port);
         } catch (Exception e) {
         	_selector.close();
         	throw new IOException("SSL: Fail to init SSL! " + e);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/2e6c65fd/utils/src/com/cloud/utils/nio/NioConnection.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/nio/NioConnection.java b/utils/src/com/cloud/utils/nio/NioConnection.java
index 50e6a88..07c2bea 100755
--- a/utils/src/com/cloud/utils/nio/NioConnection.java
+++ b/utils/src/com/cloud/utils/nio/NioConnection.java
@@ -107,7 +107,7 @@ public abstract class NioConnection implements Runnable {
     		try {
     			init();
     		} catch (ConnectException e) {
-    			s_logger.error("Unable to connect to remote");
+                s_logger.warn("Unable to connect to remote: is there a server running on port " + _port);
     			return;
     		} catch (IOException e) {
     			s_logger.error("Unable to initialize the threads.", e);


[04/19] QuickCloud: Enable secondary storage daemon to run outside the system vm

Posted by ch...@apache.org.
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
+		
+	}
+}


[02/19] QuickCloud: Enable secondary storage daemon to run outside the system vm

Posted by ch...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/services/secondary-storage/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java b/services/secondary-storage/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java
new file mode 100755
index 0000000..a9d23cb
--- /dev/null
+++ b/services/secondary-storage/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java
@@ -0,0 +1,1074 @@
+// 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.template;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.math.BigInteger;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import javax.ejb.Local;
+import javax.naming.ConfigurationException;
+
+import org.apache.cloudstack.storage.resource.SecondaryStorageResource;
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.api.storage.DownloadAnswer;
+import com.cloud.agent.api.storage.DownloadCommand;
+import com.cloud.agent.api.storage.DownloadCommand.Proxy;
+import com.cloud.agent.api.storage.DownloadCommand.ResourceType;
+import com.cloud.agent.api.storage.DownloadProgressCommand;
+import com.cloud.agent.api.storage.DownloadProgressCommand.RequestType;
+import com.cloud.exception.InternalErrorException;
+import com.cloud.storage.Storage.ImageFormat;
+import com.cloud.storage.StorageLayer;
+import com.cloud.storage.VMTemplateHostVO;
+import com.cloud.storage.VMTemplateStorageResourceAssoc;
+import com.cloud.storage.template.HttpTemplateDownloader;
+import com.cloud.storage.template.IsoProcessor;
+import com.cloud.storage.template.LocalTemplateDownloader;
+import com.cloud.storage.template.Processor;
+import com.cloud.storage.template.Processor.FormatInfo;
+import com.cloud.storage.template.QCOW2Processor;
+import com.cloud.storage.template.RawImageProcessor;
+import com.cloud.storage.template.ScpTemplateDownloader;
+import com.cloud.storage.template.TemplateConstants;
+import com.cloud.storage.template.TemplateDownloader;
+import com.cloud.storage.template.TemplateDownloader.DownloadCompleteCallback;
+import com.cloud.storage.template.TemplateDownloader.Status;
+import com.cloud.storage.template.TemplateInfo;
+import com.cloud.storage.template.TemplateLocation;
+import com.cloud.storage.template.VhdProcessor;
+import com.cloud.storage.template.VmdkProcessor;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.script.OutputInterpreter;
+import com.cloud.utils.script.Script;
+
+@Local(value = DownloadManager.class)
+public class DownloadManagerImpl extends ManagerBase implements DownloadManager {
+    private String _name;
+    StorageLayer _storage;
+    Map<String, Processor> _processors;
+
+    public class Completion implements DownloadCompleteCallback {
+        private final String jobId;
+
+        public Completion(String jobId) {
+            this.jobId = jobId;
+        }
+
+        @Override
+        public void downloadComplete(Status status) {
+            setDownloadStatus(jobId, status);
+        }
+    }
+
+    private static class DownloadJob {
+        private final TemplateDownloader td;
+        private final String jobId;
+        private final String tmpltName;
+        private final boolean hvm;
+        private final ImageFormat format;
+        private String tmpltPath;
+        private final String description;
+        private String checksum;
+        private final Long accountId;
+        private final String installPathPrefix;
+        private long templatesize;
+        private long templatePhysicalSize;
+        private final long id;
+        private final ResourceType resourceType;
+
+        public DownloadJob(TemplateDownloader td, String jobId, long id, String tmpltName, ImageFormat format, boolean hvm, Long accountId, String descr, String cksum, String installPathPrefix, ResourceType resourceType) {
+            super();
+            this.td = td;
+            this.jobId = jobId;
+            this.tmpltName = tmpltName;
+            this.format = format;
+            this.hvm = hvm;
+            this.accountId = accountId;
+            this.description = descr;
+            this.checksum = cksum;
+            this.installPathPrefix = installPathPrefix;
+            this.templatesize = 0;
+            this.id = id;
+            this.resourceType = resourceType;
+        }
+
+        public TemplateDownloader getTd() {
+            return td;
+        }
+
+        public String getDescription() {
+            return description;
+        }
+
+        public String getChecksum() {
+            return checksum;
+        }
+
+        public TemplateDownloader getTemplateDownloader() {
+            return td;
+        }
+
+        public String getJobId() {
+            return jobId;
+        }
+
+        public String getTmpltName() {
+            return tmpltName;
+        }
+
+        public ImageFormat getFormat() {
+            return format;
+        }
+
+        public boolean isHvm() {
+            return hvm;
+        }
+
+        public Long getAccountId() {
+            return accountId;
+        }
+
+        public long getId() {
+            return id;
+        }
+
+        public ResourceType getResourceType() {
+            return resourceType;
+        }
+
+        public void setTmpltPath(String tmpltPath) {
+            this.tmpltPath = tmpltPath;
+        }
+
+        public String getTmpltPath() {
+            return tmpltPath;
+        }
+
+        public String getInstallPathPrefix() {
+            return installPathPrefix;
+        }
+
+        public void cleanup() {
+            if (td != null) {
+                String dnldPath = td.getDownloadLocalPath();
+                if (dnldPath != null) {
+                    File f = new File(dnldPath);
+                    File dir = f.getParentFile();
+                    f.delete();
+                    if (dir != null) {
+                        dir.delete();
+                    }
+                }
+            }
+
+        }
+
+        public void setTemplatesize(long templatesize) {
+            this.templatesize = templatesize;
+        }
+
+        public long getTemplatesize() {
+            return templatesize;
+        }
+
+        public void setTemplatePhysicalSize(long templatePhysicalSize) {
+            this.templatePhysicalSize = templatePhysicalSize;
+        }
+
+        public long getTemplatePhysicalSize() {
+            return templatePhysicalSize;
+        }
+
+        public void setCheckSum(String checksum) {
+            this.checksum = checksum;
+        }
+    }
+
+    public static final Logger s_logger = Logger.getLogger(DownloadManagerImpl.class);
+    private String _templateDir;
+    private String _volumeDir;
+    private String createTmpltScr;
+    private String createVolScr;
+    private List<Processor> processors;
+
+    private ExecutorService threadPool;
+
+    private final Map<String, DownloadJob> jobs = new ConcurrentHashMap<String, DownloadJob>();
+    private String listTmpltScr;
+    private String listVolScr;
+    private int installTimeoutPerGig = 180 * 60 * 1000;
+    private boolean _sslCopy;
+
+    /**
+     * Get notified of change of job status. Executed in context of downloader thread
+     * 
+     * @param jobId
+     *            the id of the job
+     * @param status
+     *            the status of the job
+     */
+    public void setDownloadStatus(String jobId, Status status) {
+        DownloadJob dj = jobs.get(jobId);
+        if (dj == null) {
+            s_logger.warn("setDownloadStatus for jobId: " + jobId + ", status=" + status + " no job found");
+            return;
+        }
+        TemplateDownloader td = dj.getTemplateDownloader();
+        s_logger.info("Download Completion for jobId: " + jobId + ", status=" + status);
+        s_logger.info("local: " + td.getDownloadLocalPath() + ", bytes=" + td.getDownloadedBytes() + ", error=" + td.getDownloadError() + ", pct=" + td.getDownloadPercent());
+
+        switch (status) {
+        case ABORTED:
+        case NOT_STARTED:
+        case UNRECOVERABLE_ERROR:
+            // TODO
+            dj.cleanup();
+            break;
+        case UNKNOWN:
+            return;
+        case IN_PROGRESS:
+            s_logger.info("Resuming jobId: " + jobId + ", status=" + status);
+            td.setResume(true);
+            threadPool.execute(td);
+            break;
+        case RECOVERABLE_ERROR:
+            threadPool.execute(td);
+            break;
+        case DOWNLOAD_FINISHED:
+            td.setDownloadError("Download success, starting install ");
+            String result = postDownload(jobId);
+            if (result != null) {
+                s_logger.error("Failed post download script: " + result);
+                td.setStatus(Status.UNRECOVERABLE_ERROR);
+                td.setDownloadError("Failed post download script: " + result);
+            } else {
+                td.setStatus(Status.POST_DOWNLOAD_FINISHED);
+                td.setDownloadError("Install completed successfully at " + new SimpleDateFormat().format(new Date()));
+            }
+            dj.cleanup();
+            break;
+        default:
+            break;
+        }
+    }
+
+    private String computeCheckSum(File f) {
+        byte[] buffer = new byte[8192];
+        int read = 0;
+        MessageDigest digest;
+        String checksum = null;        
+        InputStream is = null;
+        try {
+            digest = MessageDigest.getInstance("MD5");           
+            is = new FileInputStream(f);     
+            while( (read = is.read(buffer)) > 0) {
+                digest.update(buffer, 0, read);
+            }       
+            byte[] md5sum = digest.digest();
+            BigInteger bigInt = new BigInteger(1, md5sum);
+            checksum = String.format("%032x",bigInt);
+            return checksum;
+        }catch(IOException e) {
+            return null;
+        }catch (NoSuchAlgorithmException e) {         
+            return null;
+        }
+        finally {
+            try {
+                if(is != null)
+                    is.close();
+            } catch (IOException e) {
+                return null;
+            }                        
+        }
+    }
+
+    /**
+     * Post download activity (install and cleanup). Executed in context of downloader thread
+     * 
+     * @throws IOException
+     */
+    private String postDownload(String jobId) {
+        DownloadJob dnld = jobs.get(jobId);
+        TemplateDownloader td = dnld.getTemplateDownloader();
+        String resourcePath = null;               
+        ResourceType resourceType = dnld.getResourceType();
+
+        // once template path is set, remove the parent dir so that the template is installed with a relative path
+        String finalResourcePath = "";
+        if (resourceType == ResourceType.TEMPLATE){
+            finalResourcePath += _templateDir + File.separator + dnld.getAccountId() + File.separator + dnld.getId() + File.separator;
+            resourcePath = dnld.getInstallPathPrefix() + dnld.getAccountId() + File.separator + dnld.getId() + File.separator;// dnld.getTmpltName();
+        }else {
+            finalResourcePath += _volumeDir + File.separator + dnld.getId() + File.separator;
+            resourcePath = dnld.getInstallPathPrefix() + dnld.getId() + File.separator;// dnld.getTmpltName();
+        }
+
+        _storage.mkdirs(resourcePath);
+        dnld.setTmpltPath(finalResourcePath);
+
+        File originalTemplate = new File(td.getDownloadLocalPath());
+        String checkSum = computeCheckSum(originalTemplate);
+        if (checkSum == null) {
+            s_logger.warn("Something wrong happened when try to calculate the checksum of downloaded template!");
+        }
+        dnld.setCheckSum(checkSum);
+
+        int imgSizeGigs = (int) Math.ceil(_storage.getSize(td.getDownloadLocalPath()) * 1.0d / (1024 * 1024 * 1024));
+        imgSizeGigs++; // add one just in case
+        long timeout = imgSizeGigs * installTimeoutPerGig;
+        Script scr = null;
+        String script = resourceType == ResourceType.TEMPLATE ? createTmpltScr : createVolScr;
+        scr = new Script(script, timeout, s_logger);
+        scr.add("-s", Integer.toString(imgSizeGigs));
+        scr.add("-S", Long.toString(td.getMaxTemplateSizeInBytes()));
+        if (dnld.getDescription() != null && dnld.getDescription().length() > 1) {
+            scr.add("-d", dnld.getDescription());
+        }
+        if (dnld.isHvm()) {
+            scr.add("-h");
+        }
+
+        // add options common to ISO and template
+        String extension = dnld.getFormat().getFileExtension();
+        String templateName = "";
+        if( extension.equals("iso")) {
+            templateName = jobs.get(jobId).getTmpltName().trim().replace(" ", "_");
+        } else {
+            templateName = java.util.UUID.nameUUIDFromBytes((jobs.get(jobId).getTmpltName() + System.currentTimeMillis()).getBytes()).toString();
+        }
+
+        String templateFilename = templateName + "." + extension;
+        dnld.setTmpltPath(finalResourcePath + "/" + templateFilename);
+        scr.add("-n", templateFilename);
+
+        scr.add("-t", resourcePath);
+        scr.add("-f", td.getDownloadLocalPath());
+        if (dnld.getChecksum() != null && dnld.getChecksum().length() > 1) {
+            scr.add("-c", dnld.getChecksum());
+        }
+        scr.add("-u"); // cleanup
+        String result;
+        result = scr.execute();
+
+        if (result != null) {
+            return result;
+        }
+
+        // Set permissions for the downloaded template
+        File downloadedTemplate = new File(resourcePath + "/" + templateFilename);
+        _storage.setWorldReadableAndWriteable(downloadedTemplate);
+
+        // Set permissions for template/volume.properties
+        String propertiesFile = resourcePath;
+        if (resourceType == ResourceType.TEMPLATE){
+            propertiesFile += "/template.properties";
+        }else{
+            propertiesFile += "/volume.properties";
+        }
+        File templateProperties = new File(propertiesFile);
+        _storage.setWorldReadableAndWriteable(templateProperties);
+
+        TemplateLocation loc = new TemplateLocation(_storage, resourcePath);
+        try {
+            loc.create(dnld.getId(), true, dnld.getTmpltName());
+        } catch (IOException e) {
+            s_logger.warn("Something is wrong with template location " + resourcePath, e);
+            loc.purge();
+            return "Unable to download due to " + e.getMessage();
+        }
+
+        Iterator<Processor> en = _processors.values().iterator();
+        while (en.hasNext()) {
+            Processor processor = en.next();
+
+            FormatInfo info = null;
+            try {
+                info = processor.process(resourcePath, null, templateName);
+            } catch (InternalErrorException e) {
+                s_logger.error("Template process exception ", e);
+                return e.toString();
+            }
+            if (info != null) {
+                loc.addFormat(info);
+                dnld.setTemplatesize(info.virtualSize);
+                dnld.setTemplatePhysicalSize(info.size);
+                break;
+            }
+        }
+
+        if (!loc.save()) {
+            s_logger.warn("Cleaning up because we're unable to save the formats");
+            loc.purge();
+        }
+
+        return null;
+    }
+
+    @Override
+    public Status getDownloadStatus(String jobId) {
+        DownloadJob job = jobs.get(jobId);
+        if (job != null) {
+            TemplateDownloader td = job.getTemplateDownloader();
+            if (td != null) {
+                return td.getStatus();
+            }
+        }
+        return Status.UNKNOWN;
+    }
+
+    @Override
+    public String downloadPublicTemplate(long id, String url, String name, ImageFormat format, boolean hvm, Long accountId, String descr, String cksum, String installPathPrefix, String user, String password, long maxTemplateSizeInBytes, Proxy proxy, ResourceType resourceType) {
+        UUID uuid = UUID.randomUUID();
+        String jobId = uuid.toString();
+        String tmpDir = "";
+        if(resourceType == ResourceType.TEMPLATE){
+            tmpDir = installPathPrefix + File.separator + accountId + File.separator + id;
+        }else {
+            tmpDir = installPathPrefix + File.separator + id;
+        }
+
+        try {
+
+            if (!_storage.mkdirs(tmpDir)) {
+                s_logger.warn("Unable to create " + tmpDir);
+                return "Unable to create " + tmpDir;
+            }
+            //	TO DO - define constant for volume properties.
+            File file = ResourceType.TEMPLATE == resourceType ? _storage.getFile(tmpDir + File.separator + TemplateLocation.Filename) : 
+                _storage.getFile(tmpDir + File.separator + "volume.properties");
+            if ( file.exists() ) {
+                file.delete();
+            }
+
+            if (!file.createNewFile()) {
+                s_logger.warn("Unable to create new file: " + file.getAbsolutePath());
+                return "Unable to create new file: " + file.getAbsolutePath();
+            }
+
+            URI uri;
+            try {
+                uri = new URI(url);
+            } catch (URISyntaxException e) {
+                throw new CloudRuntimeException("URI is incorrect: " + url);
+            }
+            TemplateDownloader td;
+            if ((uri != null) && (uri.getScheme() != null)) {
+                if (uri.getScheme().equalsIgnoreCase("http") || uri.getScheme().equalsIgnoreCase("https")) {
+                    td = new HttpTemplateDownloader(_storage, url, tmpDir, new Completion(jobId), maxTemplateSizeInBytes, user, password, proxy, resourceType);
+                } else if (uri.getScheme().equalsIgnoreCase("file")) {
+                    td = new LocalTemplateDownloader(_storage, url, tmpDir, maxTemplateSizeInBytes, new Completion(jobId));
+                } else if (uri.getScheme().equalsIgnoreCase("scp")) {
+                    td = new ScpTemplateDownloader(_storage, url, tmpDir, maxTemplateSizeInBytes, new Completion(jobId));
+                } else if (uri.getScheme().equalsIgnoreCase("nfs")) {
+                    td = null;
+                    // TODO: implement this.
+                    throw new CloudRuntimeException("Scheme is not supported " + url);
+                } else {
+                    throw new CloudRuntimeException("Scheme is not supported " + url);
+                }
+            } else {
+                throw new CloudRuntimeException("Unable to download from URL: " + url);
+            }
+            DownloadJob dj = new DownloadJob(td, jobId, id, name, format, hvm, accountId, descr, cksum, installPathPrefix, resourceType);
+            jobs.put(jobId, dj);
+            threadPool.execute(td);
+
+            return jobId;
+        } catch (IOException e) {
+            s_logger.warn("Unable to download to " + tmpDir, e);
+            return null;
+        }
+    }
+
+    @Override
+    public String getDownloadError(String jobId) {
+        DownloadJob dj = jobs.get(jobId);
+        if (dj != null) {
+            return dj.getTemplateDownloader().getDownloadError();
+        }
+        return null;
+    }
+
+    public long getDownloadTemplateSize(String jobId) {
+        DownloadJob dj = jobs.get(jobId);
+        if (dj != null) {
+            return dj.getTemplatesize();
+        }
+        return 0;
+    }
+
+    public String getDownloadCheckSum(String jobId) {
+        DownloadJob dj = jobs.get(jobId);
+        if (dj != null) {
+            return dj.getChecksum();
+        }
+        return null;
+    }
+
+    public long getDownloadTemplatePhysicalSize(String jobId) {
+        DownloadJob dj = jobs.get(jobId);
+        if (dj != null) {
+            return dj.getTemplatePhysicalSize();
+        }
+        return 0;
+    }
+
+    // @Override
+    public String getDownloadLocalPath(String jobId) {
+        DownloadJob dj = jobs.get(jobId);
+        if (dj != null) {
+            return dj.getTemplateDownloader().getDownloadLocalPath();
+        }
+        return null;
+    }
+
+    @Override
+    public int getDownloadPct(String jobId) {
+        DownloadJob dj = jobs.get(jobId);
+        if (dj != null) {
+            return dj.getTemplateDownloader().getDownloadPercent();
+        }
+        return 0;
+    }
+
+    public static VMTemplateHostVO.Status convertStatus(Status tds) {
+        switch (tds) {
+        case ABORTED:
+            return VMTemplateHostVO.Status.NOT_DOWNLOADED;
+        case DOWNLOAD_FINISHED:
+            return VMTemplateHostVO.Status.DOWNLOAD_IN_PROGRESS;
+        case IN_PROGRESS:
+            return VMTemplateHostVO.Status.DOWNLOAD_IN_PROGRESS;
+        case NOT_STARTED:
+            return VMTemplateHostVO.Status.NOT_DOWNLOADED;
+        case RECOVERABLE_ERROR:
+            return VMTemplateHostVO.Status.NOT_DOWNLOADED;
+        case UNKNOWN:
+            return VMTemplateHostVO.Status.UNKNOWN;
+        case UNRECOVERABLE_ERROR:
+            return VMTemplateHostVO.Status.DOWNLOAD_ERROR;
+        case POST_DOWNLOAD_FINISHED:
+            return VMTemplateHostVO.Status.DOWNLOADED;
+        default:
+            return VMTemplateHostVO.Status.UNKNOWN;
+        }
+    }
+
+    @Override
+    public com.cloud.storage.VMTemplateHostVO.Status getDownloadStatus2(String jobId) {
+        return convertStatus(getDownloadStatus(jobId));
+    }
+
+    @Override
+    public DownloadAnswer handleDownloadCommand(SecondaryStorageResource resource, DownloadCommand cmd) {
+        ResourceType resourceType = cmd.getResourceType();
+        if (cmd instanceof DownloadProgressCommand) {
+            return handleDownloadProgressCmd( resource, (DownloadProgressCommand) cmd);
+        }
+
+        if (cmd.getUrl() == null) {
+            return new DownloadAnswer(resourceType.toString() + " is corrupted on storage due to an invalid url , cannot download", VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR);
+        }
+
+        if (cmd.getName() == null) {
+            return new DownloadAnswer("Invalid Name", VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR);
+        }
+
+        String installPathPrefix = null;
+        if (ResourceType.TEMPLATE == resourceType){
+            installPathPrefix = resource.getRootDir(cmd) + File.separator + _templateDir;
+        }else {
+            installPathPrefix = resource.getRootDir(cmd) + File.separator + _volumeDir;
+        }
+
+        String user = null;
+        String password = null;
+        if (cmd.getAuth() != null) {
+            user = cmd.getAuth().getUserName();
+            password = new String(cmd.getAuth().getPassword());
+        }
+        //TO DO - Define Volume max size as well
+        long maxDownloadSizeInBytes = (cmd.getMaxDownloadSizeInBytes() == null) ? TemplateDownloader.DEFAULT_MAX_TEMPLATE_SIZE_IN_BYTES : (cmd.getMaxDownloadSizeInBytes());
+        String jobId = downloadPublicTemplate(cmd.getId(), cmd.getUrl(), cmd.getName(), cmd.getFormat(), cmd.isHvm(), cmd.getAccountId(), cmd.getDescription(), cmd.getChecksum(), installPathPrefix, user, password, maxDownloadSizeInBytes, cmd.getProxy(), resourceType);
+        sleep();
+        if (jobId == null) {
+            return new DownloadAnswer("Internal Error", VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR);
+        }
+        return new DownloadAnswer(jobId, getDownloadPct(jobId), getDownloadError(jobId), getDownloadStatus2(jobId), getDownloadLocalPath(jobId), getInstallPath(jobId),
+                getDownloadTemplateSize(jobId), getDownloadTemplateSize(jobId), getDownloadCheckSum(jobId));
+    }
+
+    private void sleep() {
+        try {
+            Thread.sleep(3000);
+        } catch (InterruptedException e) {
+            // ignore
+        }
+    }
+
+    private DownloadAnswer handleDownloadProgressCmd(SecondaryStorageResource resource, DownloadProgressCommand cmd) {
+        String jobId = cmd.getJobId();
+        DownloadAnswer answer;
+        DownloadJob dj = null;
+        if (jobId != null) {
+            dj = jobs.get(jobId);
+        }
+        if (dj == null) {
+            if (cmd.getRequest() == RequestType.GET_OR_RESTART) {
+                DownloadCommand dcmd = new DownloadCommand(cmd);
+                return handleDownloadCommand(resource, dcmd);
+            } else {
+                return new DownloadAnswer("Cannot find job", VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR.UNKNOWN);
+            }
+        }
+        TemplateDownloader td = dj.getTemplateDownloader();
+        switch (cmd.getRequest()) {
+        case GET_STATUS:
+            break;
+        case ABORT:
+            td.stopDownload();
+            sleep();
+            break;
+        case RESTART:
+            td.stopDownload();
+            sleep();
+            threadPool.execute(td);
+            break;
+        case PURGE:
+            td.stopDownload();
+            answer = new DownloadAnswer(jobId, getDownloadPct(jobId), getDownloadError(jobId), getDownloadStatus2(jobId), getDownloadLocalPath(jobId),
+                    getInstallPath(jobId), getDownloadTemplateSize(jobId), getDownloadTemplatePhysicalSize(jobId), getDownloadCheckSum(jobId));
+            jobs.remove(jobId);
+            return answer;
+        default:
+            break; // TODO
+        }
+        return new DownloadAnswer(jobId, getDownloadPct(jobId), getDownloadError(jobId), getDownloadStatus2(jobId), getDownloadLocalPath(jobId),
+                getInstallPath(jobId), getDownloadTemplateSize(jobId), getDownloadTemplatePhysicalSize(jobId), getDownloadCheckSum(jobId));
+    }
+
+    private String getInstallPath(String jobId) {
+        DownloadJob dj = jobs.get(jobId);
+        if (dj != null) {
+            return dj.getTmpltPath();
+        }
+        return null;
+    }
+
+    private String createTempDir(File rootDir, String name) throws IOException {
+
+        File f = File.createTempFile(name, "", rootDir);
+        f.delete();
+        f.mkdir();
+        _storage.setWorldReadableAndWriteable(f);
+        return f.getAbsolutePath();
+
+    }
+
+
+    private List<String> listVolumes(String rootdir) {
+        List<String> result = new ArrayList<String>();
+
+        Script script = new Script(listVolScr, s_logger);
+        script.add("-r", rootdir);
+        ZfsPathParser zpp = new ZfsPathParser(rootdir);
+        script.execute(zpp);
+        result.addAll(zpp.getPaths());
+        s_logger.info("found " + zpp.getPaths().size() + " volumes" + zpp.getPaths());
+        return result;
+    }
+
+
+
+    private List<String> listTemplates(String rootdir) {
+        List<String> result = new ArrayList<String>();
+
+        Script script = new Script(listTmpltScr, s_logger);
+        script.add("-r", rootdir);
+        ZfsPathParser zpp = new ZfsPathParser(rootdir);
+        script.execute(zpp);
+        result.addAll(zpp.getPaths());
+        s_logger.info("found " + zpp.getPaths().size() + " templates" + zpp.getPaths());
+        return result;
+    }
+
+    @Override
+    public Map<String, TemplateInfo> gatherTemplateInfo(String rootDir) {
+        Map<String, TemplateInfo> result = new HashMap<String, TemplateInfo>();
+        String templateDir = rootDir + File.separator + _templateDir;
+
+        if (! _storage.exists(templateDir)) {
+            _storage.mkdirs(templateDir);
+        }
+
+        List<String> publicTmplts = listTemplates(templateDir);
+        for (String tmplt : publicTmplts) {
+            String path = tmplt.substring(0, tmplt.lastIndexOf(File.separator));
+            TemplateLocation loc = new TemplateLocation(_storage, path);
+            try {
+                if (!loc.load()) {
+                    s_logger.warn("Post download installation was not completed for " + path);
+                    //loc.purge();
+                    _storage.cleanup(path, templateDir);
+                    continue;
+                }
+            } catch (IOException e) {
+                s_logger.warn("Unable to load template location " + path, e);
+                continue;
+            }
+
+            TemplateInfo tInfo = loc.getTemplateInfo();
+
+			if ((tInfo.getSize() == tInfo.getPhysicalSize())
+					&& (tInfo.getInstallPath().endsWith(ImageFormat.OVA.getFileExtension()))) {
+                try {
+                    Processor processor = _processors.get("VMDK Processor");
+                    VmdkProcessor vmdkProcessor = (VmdkProcessor)processor;
+					long vSize =
+							vmdkProcessor.getTemplateVirtualSize(
+									path,
+									tInfo.getInstallPath().substring(
+											tInfo.getInstallPath().lastIndexOf(File.separator) + 1));
+					tInfo.setSize(vSize);
+                    loc.updateVirtualSize(vSize);
+                    loc.save();
+                } catch (Exception e) {
+					s_logger.error("Unable to get the virtual size of the template: " + tInfo.getInstallPath()
+							+ " due to " + e.getMessage());
+                }
+            }
+
+			result.put(tInfo.getTemplateName(), tInfo);
+			s_logger.debug("Added template name: " + tInfo.getTemplateName() + ", path: " + tmplt);
+        }
+        /*
+        for (String tmplt : isoTmplts) {
+            String tmp[];
+            tmp = tmplt.split("/");
+            String tmpltName = tmp[tmp.length - 2];
+            tmplt = tmplt.substring(tmplt.lastIndexOf("iso/"));
+            TemplateInfo tInfo = new TemplateInfo(tmpltName, tmplt, false);
+            s_logger.debug("Added iso template name: " + tmpltName + ", path: " + tmplt);
+            result.put(tmpltName, tInfo);
+        }
+         */
+        return result;
+    }
+
+    @Override
+    public Map<Long, TemplateInfo> gatherVolumeInfo(String rootDir) {	
+        Map<Long, TemplateInfo> result = new HashMap<Long, TemplateInfo>();
+        String volumeDir = rootDir + File.separator + _volumeDir;
+
+        if (! _storage.exists(volumeDir)) {
+            _storage.mkdirs(volumeDir);
+        }
+
+        List<String> vols = listVolumes(volumeDir);
+        for (String vol : vols) {
+            String path = vol.substring(0, vol.lastIndexOf(File.separator));
+            TemplateLocation loc = new TemplateLocation(_storage, path);
+            try {
+                if (!loc.load()) {
+                    s_logger.warn("Post download installation was not completed for " + path);
+                    //loc.purge();
+                    _storage.cleanup(path, volumeDir);
+                    continue;
+                }
+            } catch (IOException e) {
+                s_logger.warn("Unable to load volume location " + path, e);
+                continue;
+            }
+
+            TemplateInfo vInfo = loc.getTemplateInfo();
+
+			if ((vInfo.getSize() == vInfo.getPhysicalSize())
+					&& (vInfo.getInstallPath().endsWith(ImageFormat.OVA.getFileExtension()))) {
+                try {
+                    Processor processor = _processors.get("VMDK Processor");
+                    VmdkProcessor vmdkProcessor = (VmdkProcessor)processor;
+					long vSize =
+							vmdkProcessor.getTemplateVirtualSize(
+									path,
+									vInfo.getInstallPath().substring(
+											vInfo.getInstallPath().lastIndexOf(File.separator) + 1));
+					vInfo.setSize(vSize);
+                    loc.updateVirtualSize(vSize);
+                    loc.save();
+                } catch (Exception e) {
+					s_logger.error("Unable to get the virtual size of the volume: " + vInfo.getInstallPath()
+							+ " due to " + e.getMessage());
+                }
+            }
+
+            result.put(vInfo.getId(), vInfo);
+			s_logger.debug("Added volume name: " + vInfo.getTemplateName() + ", path: " + vol);
+        }
+        return result;
+    }
+
+    private int deleteDownloadDirectories(File downloadPath, int deleted) {
+        try {
+            if (downloadPath.exists()) {
+                File[] files = downloadPath.listFiles();
+                for (int i = 0; i < files.length; i++) {
+                    if (files[i].isDirectory()) {
+                        deleteDownloadDirectories(files[i], deleted);
+                        files[i].delete();
+                        deleted++;
+                    } else {
+                        files[i].delete();
+                        deleted++;
+                    }
+                }
+            }
+        } catch (Exception ex) {
+            s_logger.info("Failed to clean up template downloads directory " + ex.toString());
+        }
+        return deleted;
+    }
+
+    public static class ZfsPathParser extends OutputInterpreter {
+        String _parent;
+        List<String> paths = new ArrayList<String>();
+
+        public ZfsPathParser(String parent) {
+            _parent = parent;
+        }
+
+        @Override
+        public String interpret(BufferedReader reader) throws IOException {
+            String line = null;
+            while ((line = reader.readLine()) != null) {
+                paths.add(line);
+            }
+            return null;
+        }
+
+        public List<String> getPaths() {
+            return paths;
+        }
+
+        @Override
+        public boolean drain() {
+            return true;
+        }
+    }
+
+    public DownloadManagerImpl() {
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+        _name = name;
+
+        String value = null;
+
+        _storage = (StorageLayer)params.get(StorageLayer.InstanceConfigKey);
+        if (_storage == null) {
+            value = (String) params.get(StorageLayer.ClassConfigKey);
+            if (value == null) {
+                throw new ConfigurationException("Unable to find the storage layer");
+            }
+
+            Class<StorageLayer> clazz;
+            try {
+                clazz = (Class<StorageLayer>) Class.forName(value);
+                _storage = clazz.newInstance();
+            } catch (ClassNotFoundException e) {
+                throw new ConfigurationException("Unable to instantiate " + value);
+            } catch (InstantiationException e) {
+                throw new ConfigurationException("Unable to instantiate " + value);
+            } catch (IllegalAccessException e) {
+                throw new ConfigurationException("Unable to instantiate " + value);
+            }
+        }
+        String useSsl = (String)params.get("sslcopy");
+        if (useSsl != null) {
+            _sslCopy = Boolean.parseBoolean(useSsl);
+
+        }
+        String inSystemVM = (String)params.get("secondary.storage.vm");
+        if (inSystemVM != null && "true".equalsIgnoreCase(inSystemVM)) {
+            s_logger.info("DownloadManager: starting additional services since we are inside system vm");
+            startAdditionalServices();
+            blockOutgoingOnPrivate();
+        }
+
+        value = (String) params.get("install.timeout.pergig");
+        this.installTimeoutPerGig = NumbersUtil.parseInt(value, 15 * 60) * 1000;
+
+        value = (String) params.get("install.numthreads");
+        final int numInstallThreads = NumbersUtil.parseInt(value, 10);
+
+        String scriptsDir = (String) params.get("template.scripts.dir");
+        if (scriptsDir == null) {
+            scriptsDir = "scripts/storage/secondary";
+        }
+
+        listTmpltScr = Script.findScript(scriptsDir, "listvmtmplt.sh");
+        if (listTmpltScr == null) {
+            throw new ConfigurationException("Unable to find the listvmtmplt.sh");
+        }
+        s_logger.info("listvmtmplt.sh found in " + listTmpltScr);
+
+        createTmpltScr = Script.findScript(scriptsDir, "createtmplt.sh");
+        if (createTmpltScr == null) {
+            throw new ConfigurationException("Unable to find createtmplt.sh");
+        }
+        s_logger.info("createtmplt.sh found in " + createTmpltScr);
+
+        listVolScr = Script.findScript(scriptsDir, "listvolume.sh");
+        if (listVolScr == null) {
+            throw new ConfigurationException("Unable to find the listvolume.sh");
+        }
+        s_logger.info("listvolume.sh found in " + listVolScr);
+
+        createVolScr = Script.findScript(scriptsDir, "createvolume.sh");
+        if (createVolScr == null) {
+            throw new ConfigurationException("Unable to find createvolume.sh");
+        }
+        s_logger.info("createvolume.sh found in " + createVolScr);
+
+        _processors = new HashMap<String, Processor>();
+
+        Processor processor = new VhdProcessor();
+        processor.configure("VHD Processor", params);
+        _processors.put("VHD Processor", processor);
+
+        processor = new IsoProcessor();
+        processor.configure("ISO Processor", params);
+        _processors.put("ISO Processor", processor);
+
+        processor = new QCOW2Processor();
+        processor.configure("QCOW2 Processor", params);
+        _processors.put("QCOW2 Processor", processor);
+
+        processor = new VmdkProcessor();
+        processor.configure("VMDK Processor", params);
+        _processors.put("VMDK Processor", processor);
+
+        processor = new RawImageProcessor();
+        processor.configure("Raw Image Processor", params);
+        _processors.put("Raw Image Processor", processor);
+
+        _templateDir = (String) params.get("public.templates.root.dir");
+        if (_templateDir == null) {
+            _templateDir = TemplateConstants.DEFAULT_TMPLT_ROOT_DIR;
+        }
+        _templateDir += File.separator + TemplateConstants.DEFAULT_TMPLT_FIRST_LEVEL_DIR;
+        _volumeDir = TemplateConstants.DEFAULT_VOLUME_ROOT_DIR + File.separator;
+        // Add more processors here.
+        threadPool = Executors.newFixedThreadPool(numInstallThreads);
+        return true;
+    }
+
+    private void blockOutgoingOnPrivate() {
+        Script command = new Script("/bin/bash", s_logger);
+        String intf = "eth1";
+        command.add("-c");
+        command.add("iptables -A OUTPUT -o " + intf + " -p tcp -m state --state NEW -m tcp --dport " + "80" + " -j REJECT;" +
+                "iptables -A OUTPUT -o " + intf + " -p tcp -m state --state NEW -m tcp --dport " + "443" + " -j REJECT;");
+
+        String result = command.execute();
+        if (result != null) {
+            s_logger.warn("Error in blocking outgoing to port 80/443 err=" + result );
+            return;
+        }
+    }
+
+    @Override
+    public String getName() {
+        return _name;
+    }
+
+    @Override
+    public boolean start() {
+        return true;
+    }
+
+    @Override
+    public boolean stop() {
+        return true;
+    }
+
+    private void startAdditionalServices() {
+
+        Script command = new Script("/bin/bash", s_logger);
+        command.add("-c");
+        command.add("if [ -d /etc/apache2 ] ; then service apache2 stop; else service httpd stop; fi ");
+        String result = command.execute();
+        if (result != null) {
+            s_logger.warn("Error in stopping httpd service err=" + result );
+        }
+        String port = Integer.toString(TemplateConstants.DEFAULT_TMPLT_COPY_PORT);
+        String intf = TemplateConstants.DEFAULT_TMPLT_COPY_INTF;
+
+        command = new Script("/bin/bash", s_logger);
+        command.add("-c");
+        command.add("iptables -I INPUT -i " + intf + " -p tcp -m state --state NEW -m tcp --dport " + port + " -j ACCEPT;" +
+                "iptables -I INPUT -i " + intf + " -p tcp -m state --state NEW -m tcp --dport " + "443" + " -j ACCEPT;");
+
+        result = command.execute();
+        if (result != null) {
+            s_logger.warn("Error in opening up httpd port err=" + result );
+            return;
+        }
+
+        command = new Script("/bin/bash", s_logger);
+        command.add("-c");
+        command.add("if [ -d /etc/apache2 ] ; then service apache2 start; else service httpd start; fi ");
+        result = command.execute();
+        if (result != null) {
+            s_logger.warn("Error in starting httpd service err=" + result );
+            return;
+        }
+        command = new Script("mkdir", s_logger);
+        command.add("-p");
+        command.add("/var/www/html/copy/template");
+        result = command.execute();
+        if (result != null) {
+            s_logger.warn("Error in creating directory =" + result );
+            return;
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/services/secondary-storage/src/org/apache/cloudstack/storage/template/UploadManager.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/template/UploadManager.java b/services/secondary-storage/src/org/apache/cloudstack/storage/template/UploadManager.java
new file mode 100755
index 0000000..14de150
--- /dev/null
+++ b/services/secondary-storage/src/org/apache/cloudstack/storage/template/UploadManager.java
@@ -0,0 +1,87 @@
+// 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.template;
+
+import org.apache.cloudstack.storage.resource.SecondaryStorageResource;
+
+import com.cloud.agent.api.storage.CreateEntityDownloadURLAnswer;
+import com.cloud.agent.api.storage.CreateEntityDownloadURLCommand;
+import com.cloud.agent.api.storage.DeleteEntityDownloadURLAnswer;
+import com.cloud.agent.api.storage.DeleteEntityDownloadURLCommand;
+import com.cloud.agent.api.storage.UploadAnswer;
+import com.cloud.agent.api.storage.UploadCommand;
+import com.cloud.storage.Storage.ImageFormat;
+import com.cloud.storage.Upload.Status;
+import com.cloud.storage.template.TemplateUploader;
+import com.cloud.utils.component.Manager;
+
+public interface UploadManager extends Manager {
+
+
+	/**
+	 * @param jobId job Id
+	 * @return status of the upload job
+	 */
+	public TemplateUploader.Status getUploadStatus(String jobId);
+	
+	/**
+	 * @param jobId job Id
+	 * @return status of the upload job
+	 */
+	public Status getUploadStatus2(String jobId);
+
+	/**
+	 * Get the upload percent of a upload job
+	 * @param jobId job Id
+	 * @return
+	 */
+	public int getUploadPct(String jobId);
+
+	/**
+	 * Get the upload error if any
+	 * @param jobId job Id
+	 * @return
+	 */
+	public String getUploadError(String jobId);
+
+	/**
+	 * Get the local path for the upload
+	 * @param jobId job Id
+	 * @return
+	public String getUploadLocalPath(String jobId);
+     */
+	
+	/** Handle upload commands from the management server
+	 * @param cmd cmd from server
+	 * @return answer representing status of upload.
+	 */
+	public UploadAnswer handleUploadCommand(SecondaryStorageResource resource, UploadCommand cmd);		
+    
+    public String getPublicTemplateRepo();
+
+
+	String uploadPublicTemplate(long id, String url, String name,
+			ImageFormat format, Long accountId, String descr,
+			String cksum, String installPathPrefix, String user,
+			String password, long maxTemplateSizeInBytes);
+	
+
+    CreateEntityDownloadURLAnswer handleCreateEntityURLCommand(CreateEntityDownloadURLCommand cmd);
+    
+    DeleteEntityDownloadURLAnswer handleDeleteEntityDownloadURLCommand(DeleteEntityDownloadURLCommand cmd);
+	
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/services/secondary-storage/src/org/apache/cloudstack/storage/template/UploadManagerImpl.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/template/UploadManagerImpl.java b/services/secondary-storage/src/org/apache/cloudstack/storage/template/UploadManagerImpl.java
new file mode 100755
index 0000000..88623a9
--- /dev/null
+++ b/services/secondary-storage/src/org/apache/cloudstack/storage/template/UploadManagerImpl.java
@@ -0,0 +1,648 @@
+// 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.template;
+
+import java.io.File;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import javax.naming.ConfigurationException;
+
+import org.apache.cloudstack.storage.resource.SecondaryStorageResource;
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.api.storage.CreateEntityDownloadURLAnswer;
+import com.cloud.agent.api.storage.CreateEntityDownloadURLCommand;
+import com.cloud.agent.api.storage.DeleteEntityDownloadURLAnswer;
+import com.cloud.agent.api.storage.DeleteEntityDownloadURLCommand;
+import com.cloud.agent.api.storage.UploadAnswer;
+import com.cloud.agent.api.storage.UploadCommand;
+import com.cloud.agent.api.storage.UploadProgressCommand;
+import com.cloud.storage.Storage.ImageFormat;
+import com.cloud.storage.StorageLayer;
+import com.cloud.storage.Upload;
+import com.cloud.storage.UploadVO;
+import com.cloud.storage.template.FtpTemplateUploader;
+import com.cloud.storage.template.Processor;
+import com.cloud.storage.template.TemplateUploader;
+import com.cloud.storage.template.TemplateUploader.Status;
+import com.cloud.storage.template.TemplateUploader.UploadCompleteCallback;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.script.Script;
+
+public class UploadManagerImpl extends ManagerBase implements UploadManager {
+
+
+    public class Completion implements UploadCompleteCallback {
+        private final String jobId;
+
+        public Completion(String jobId) {
+            this.jobId = jobId;
+        }
+
+        @Override
+        public void uploadComplete(Status status) {
+            setUploadStatus(jobId, status);
+        }
+    }
+
+    private static class UploadJob {
+        private final TemplateUploader tu;
+        private final String jobId;
+        private final String name;
+        private final ImageFormat format;
+        private String tmpltPath;
+        private String description;
+        private String checksum;
+        private Long accountId;
+        private String installPathPrefix;
+        private long templatesize;
+        private long id;
+
+        public UploadJob(TemplateUploader tu, String jobId, long id, String name, ImageFormat format, boolean hvm, Long accountId, String descr, String cksum, String installPathPrefix) {
+            super();
+            this.tu = tu;
+            this.jobId = jobId;
+            this.name = name;
+            this.format = format;
+            this.accountId = accountId;
+            this.description = descr;
+            this.checksum = cksum;
+            this.installPathPrefix = installPathPrefix;
+            this.templatesize = 0;
+            this.id = id;
+        }
+
+        public TemplateUploader getTd() {
+            return tu;
+        }
+
+        public String getDescription() {
+            return description;
+        }
+
+        public String getChecksum() {
+            return checksum;
+        }
+
+        public UploadJob(TemplateUploader td, String jobId, UploadCommand cmd) {
+            this.tu = td;
+            this.jobId = jobId;
+            this.name = cmd.getName();
+            this.format = cmd.getFormat();           
+        }
+
+        public TemplateUploader getTemplateUploader() {
+            return tu;
+        }
+
+        public String getJobId() {
+            return jobId;
+        }
+
+        public String getTmpltName() {
+            return name;
+        }
+
+        public ImageFormat getFormat() {
+            return format;
+        }
+
+        public Long getAccountId() {
+            return accountId;
+        }
+
+        public long getId() {
+            return id;
+        }
+
+        public void setTmpltPath(String tmpltPath) {
+            this.tmpltPath = tmpltPath;
+        }
+
+        public String getTmpltPath() {
+            return tmpltPath;
+        }
+
+        public String getInstallPathPrefix() {
+            return installPathPrefix;
+        }
+
+        public void cleanup() {
+            if (tu != null) {
+                String upldPath = tu.getUploadLocalPath();
+                if (upldPath != null) {
+                    File f = new File(upldPath);
+                    f.delete();
+                }
+            }
+        }
+
+        public void setTemplatesize(long templatesize) {
+            this.templatesize = templatesize;
+        }
+
+        public long getTemplatesize() {
+            return templatesize;
+        }
+    }
+    public static final Logger s_logger = Logger.getLogger(UploadManagerImpl.class);
+    private ExecutorService threadPool;
+    private final Map<String, UploadJob> jobs = new ConcurrentHashMap<String, UploadJob>();
+    private String parentDir;
+    private List<Processor> _processors;
+    private String publicTemplateRepo;
+    private final String extractMountPoint = "/mnt/SecStorage/extractmnt";
+    private StorageLayer _storage;
+    private int installTimeoutPerGig;
+    private boolean _sslCopy;
+    private boolean hvm;
+
+
+    @Override
+    public String uploadPublicTemplate(long id, String url, String name,
+            ImageFormat format, Long accountId, String descr,
+            String cksum, String installPathPrefix, String userName,
+            String passwd, long templateSizeInBytes) {		
+
+        UUID uuid = UUID.randomUUID();
+        String jobId = uuid.toString();
+
+        String completePath = parentDir + File.separator + installPathPrefix;
+        s_logger.debug("Starting upload from " + completePath);
+
+        URI uri;
+        try {
+            uri = new URI(url);
+        } catch (URISyntaxException e) {
+            s_logger.error("URI is incorrect: " + url);
+            throw new CloudRuntimeException("URI is incorrect: " + url);
+        }
+        TemplateUploader tu;
+        if ((uri != null) && (uri.getScheme() != null)) {
+            if (uri.getScheme().equalsIgnoreCase("ftp")) {
+                tu = new FtpTemplateUploader(completePath, url, new Completion(jobId), templateSizeInBytes);                                
+            } else {
+                s_logger.error("Scheme is not supported " + url);
+                throw new CloudRuntimeException("Scheme is not supported " + url);
+            }
+        } else {
+            s_logger.error("Unable to download from URL: " + url);
+            throw new CloudRuntimeException("Unable to download from URL: " + url);
+        }
+        UploadJob uj = new UploadJob(tu, jobId, id, name, format, hvm, accountId, descr, cksum, installPathPrefix);
+        jobs.put(jobId, uj);
+        threadPool.execute(tu);
+
+        return jobId;
+
+    }
+
+    @Override
+    public String getUploadError(String jobId) {
+        UploadJob uj = jobs.get(jobId);
+        if (uj != null) {
+            return uj.getTemplateUploader().getUploadError();
+        }
+        return null;
+    }
+
+    @Override
+    public int getUploadPct(String jobId) {
+        UploadJob uj = jobs.get(jobId);
+        if (uj != null) {
+            return uj.getTemplateUploader().getUploadPercent();
+        }
+        return 0;
+    }
+
+    @Override
+    public Status getUploadStatus(String jobId) {
+        UploadJob job = jobs.get(jobId);
+        if (job != null) {
+            TemplateUploader tu = job.getTemplateUploader();
+            if (tu != null) {
+                return tu.getStatus();
+            }
+        }
+        return Status.UNKNOWN;
+    }
+
+    public static UploadVO.Status convertStatus(Status tds) {
+        switch (tds) {
+        case ABORTED:
+            return UploadVO.Status.NOT_UPLOADED;
+        case UPLOAD_FINISHED:
+            return UploadVO.Status.UPLOAD_IN_PROGRESS;
+        case IN_PROGRESS:
+            return UploadVO.Status.UPLOAD_IN_PROGRESS;
+        case NOT_STARTED:
+            return UploadVO.Status.NOT_UPLOADED;
+        case RECOVERABLE_ERROR:
+            return UploadVO.Status.NOT_UPLOADED;
+        case UNKNOWN:
+            return UploadVO.Status.UNKNOWN;
+        case UNRECOVERABLE_ERROR:
+            return UploadVO.Status.UPLOAD_ERROR;
+        case POST_UPLOAD_FINISHED:
+            return UploadVO.Status.UPLOADED;
+        default:
+            return UploadVO.Status.UNKNOWN;
+        }
+    }
+
+    @Override
+    public com.cloud.storage.UploadVO.Status getUploadStatus2(String jobId) {
+        return convertStatus(getUploadStatus(jobId));
+    }
+    @Override
+    public String getPublicTemplateRepo() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    private UploadAnswer handleUploadProgressCmd(UploadProgressCommand cmd) {
+        String jobId = cmd.getJobId();
+        UploadAnswer answer;
+        UploadJob uj = null;
+        if (jobId != null)
+            uj = jobs.get(jobId);
+        if (uj == null) {           
+            return new UploadAnswer(null, 0, "Cannot find job", com.cloud.storage.UploadVO.Status.UNKNOWN, "", "", 0);            
+        }
+        TemplateUploader td = uj.getTemplateUploader();
+        switch (cmd.getRequest()) {
+        case GET_STATUS:
+            break;
+        case ABORT:
+            td.stopUpload();
+            sleep();
+            break;
+            /*case RESTART:
+            td.stopUpload();
+            sleep();
+            threadPool.execute(td);
+            break;*/
+        case PURGE:
+            td.stopUpload();
+            answer = new UploadAnswer(jobId, getUploadPct(jobId), getUploadError(jobId), getUploadStatus2(jobId), getUploadLocalPath(jobId), getInstallPath(jobId), getUploadTemplateSize(jobId));
+            jobs.remove(jobId);
+            return answer;
+        default:
+            break; // TODO
+        }
+        return new UploadAnswer(jobId, getUploadPct(jobId), getUploadError(jobId), getUploadStatus2(jobId), getUploadLocalPath(jobId), getInstallPath(jobId),
+                getUploadTemplateSize(jobId));
+    }	
+
+    @Override
+    public UploadAnswer handleUploadCommand(SecondaryStorageResource resource, UploadCommand cmd) {
+        s_logger.warn("Handling the upload " +cmd.getInstallPath() + " " + cmd.getId());
+        if (cmd instanceof UploadProgressCommand) {
+            return handleUploadProgressCmd((UploadProgressCommand) cmd);
+        }
+
+        String user = null;
+        String password = null;
+        String jobId = uploadPublicTemplate(cmd.getId(), cmd.getUrl(), cmd.getName(), 
+                cmd.getFormat(), cmd.getAccountId(), cmd.getDescription(),
+                cmd.getChecksum(), cmd.getInstallPath(), user, password,
+                cmd.getTemplateSizeInBytes());
+        sleep();
+        if (jobId == null) {
+            return new UploadAnswer(null, 0, "Internal Error", com.cloud.storage.UploadVO.Status.UPLOAD_ERROR, "", "", 0);
+        }
+        return new UploadAnswer(jobId, getUploadPct(jobId), getUploadError(jobId), getUploadStatus2(jobId), getUploadLocalPath(jobId), getInstallPath(jobId),
+                getUploadTemplateSize(jobId));
+    }
+
+    @Override
+    public CreateEntityDownloadURLAnswer handleCreateEntityURLCommand(CreateEntityDownloadURLCommand cmd){       
+
+        boolean isApacheUp = checkAndStartApache();
+        if (!isApacheUp){
+            String errorString = "Error in starting Apache server ";
+            s_logger.error(errorString);
+            return new CreateEntityDownloadURLAnswer(errorString, CreateEntityDownloadURLAnswer.RESULT_FAILURE);
+        }
+        // Create the directory structure so that its visible under apache server root
+        String extractDir = "/var/www/html/userdata/";
+        Script command = new Script("mkdir", s_logger);
+        command.add("-p");
+        command.add(extractDir);
+        String result = command.execute();
+        if (result != null) {
+            String errorString = "Error in creating directory =" + result;
+            s_logger.error(errorString);
+            return new CreateEntityDownloadURLAnswer(errorString, CreateEntityDownloadURLAnswer.RESULT_FAILURE);
+        }
+
+        // Create a random file under the directory for security reasons.
+        String uuid = cmd.getExtractLinkUUID();
+        command = new Script("touch", s_logger);
+        command.add(extractDir + uuid);
+        result = command.execute();
+        if (result != null) {
+            String errorString = "Error in creating file " +uuid+ " ,error: " + result; 
+            s_logger.warn(errorString);
+            return new CreateEntityDownloadURLAnswer(errorString, CreateEntityDownloadURLAnswer.RESULT_FAILURE);
+        }
+
+
+        // Create a symbolic link from the actual directory to the template location. The entity would be directly visible under /var/www/html/userdata/cmd.getInstallPath();
+        command = new Script("/bin/bash", s_logger);
+        command.add("-c");
+        command.add("ln -sf /mnt/SecStorage/" + cmd.getParent() + File.separator + cmd.getInstallPath() + " " + extractDir + uuid);
+        result = command.execute();
+        if (result != null) {
+            String errorString = "Error in linking  err=" + result; 
+            s_logger.error(errorString);
+            return new CreateEntityDownloadURLAnswer(errorString, CreateEntityDownloadURLAnswer.RESULT_FAILURE);
+        }
+
+        return new CreateEntityDownloadURLAnswer("", CreateEntityDownloadURLAnswer.RESULT_SUCCESS);
+
+    }
+
+    @Override
+    public DeleteEntityDownloadURLAnswer handleDeleteEntityDownloadURLCommand(DeleteEntityDownloadURLCommand cmd){
+
+        //Delete the soft link. Example path = volumes/8/74eeb2c6-8ab1-4357-841f-2e9d06d1f360.vhd
+        s_logger.warn("handleDeleteEntityDownloadURLCommand Path:"+cmd.getPath() + " Type:" +cmd.getType().toString());
+        String path = cmd.getPath();
+        Script command = new Script("/bin/bash", s_logger);
+        command.add("-c");
+
+        //We just need to remove the UUID.vhd
+        String extractUrl = cmd.getExtractUrl();
+        command.add("unlink /var/www/html/userdata/" +extractUrl.substring(extractUrl.lastIndexOf(File.separator) + 1));
+        String result = command.execute();
+        if (result != null) {
+            String errorString = "Error in deleting =" + result;
+            s_logger.warn(errorString);
+            return new DeleteEntityDownloadURLAnswer(errorString, CreateEntityDownloadURLAnswer.RESULT_FAILURE);
+        }
+
+        // If its a volume also delete the Hard link since it was created only for the purpose of download.
+        if(cmd.getType() == Upload.Type.VOLUME){
+            command = new Script("/bin/bash", s_logger);
+            command.add("-c");
+            command.add("rm -f /mnt/SecStorage/" + cmd.getParentPath() +File.separator+ path);
+            s_logger.warn(" " +parentDir +File.separator+ path);
+            result = command.execute();
+            if (result != null) {
+                String errorString = "Error in linking  err=" + result;
+                s_logger.warn(errorString);
+                return new DeleteEntityDownloadURLAnswer(errorString, CreateEntityDownloadURLAnswer.RESULT_FAILURE);
+            }
+        }
+
+        return new DeleteEntityDownloadURLAnswer("", CreateEntityDownloadURLAnswer.RESULT_SUCCESS);
+    }
+
+    private String getInstallPath(String jobId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    private String getUploadLocalPath(String jobId) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    private long getUploadTemplateSize(String jobId){
+        UploadJob uj = jobs.get(jobId);
+        if (uj != null) {
+            return uj.getTemplatesize();
+        }
+        return 0;
+    }
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params)
+            throws ConfigurationException {
+
+        String value = null;
+
+        _storage = (StorageLayer) params.get(StorageLayer.InstanceConfigKey);
+        if (_storage == null) {
+            value = (String) params.get(StorageLayer.ClassConfigKey);
+            if (value == null) {
+                throw new ConfigurationException("Unable to find the storage layer");
+            }
+
+            Class<StorageLayer> clazz;
+            try {
+                clazz = (Class<StorageLayer>) Class.forName(value);
+                _storage = clazz.newInstance();
+            } catch (ClassNotFoundException e) {
+                throw new ConfigurationException("Unable to instantiate " + value);
+            } catch (InstantiationException e) {
+                throw new ConfigurationException("Unable to instantiate " + value);
+            } catch (IllegalAccessException e) {
+                throw new ConfigurationException("Unable to instantiate " + value);
+            }
+        }
+        String useSsl = (String)params.get("sslcopy");
+        if (useSsl != null) {
+            _sslCopy = Boolean.parseBoolean(useSsl);
+
+        }
+        String inSystemVM = (String)params.get("secondary.storage.vm");
+        if (inSystemVM != null && "true".equalsIgnoreCase(inSystemVM)) {
+            s_logger.info("UploadManager: starting additional services since we are inside system vm");
+            startAdditionalServices();
+            //blockOutgoingOnPrivate();
+        }
+
+        value = (String) params.get("install.timeout.pergig");
+        this.installTimeoutPerGig = NumbersUtil.parseInt(value, 15 * 60) * 1000;
+
+        value = (String) params.get("install.numthreads");
+        final int numInstallThreads = NumbersUtil.parseInt(value, 10);        
+
+        String scriptsDir = (String) params.get("template.scripts.dir");
+        if (scriptsDir == null) {
+            scriptsDir = "scripts/storage/secondary";
+        }
+
+        // Add more processors here.
+        threadPool = Executors.newFixedThreadPool(numInstallThreads);
+
+        return true;
+    }
+
+    private void startAdditionalServices() {
+
+
+        Script command = new Script("rm", s_logger);
+        command.add("-rf");
+        command.add(extractMountPoint);
+        String result = command.execute();
+        if (result != null) {
+            s_logger.warn("Error in creating file " +extractMountPoint+ " ,error: " + result );
+            return;
+        }
+
+        command = new Script("touch", s_logger);
+        command.add(extractMountPoint);
+        result = command.execute();
+        if (result != null) {
+            s_logger.warn("Error in creating file " +extractMountPoint+ " ,error: " + result );
+            return;
+        }
+
+        command = new Script("/bin/bash", s_logger);
+        command.add("-c");
+        command.add("ln -sf " + parentDir + " " +extractMountPoint);
+        result = command.execute();
+        if (result != null) {
+            s_logger.warn("Error in linking  err=" + result );
+            return;
+        }
+
+    }
+
+    /**
+     * Get notified of change of job status. Executed in context of uploader thread
+     * 
+     * @param jobId
+     *            the id of the job
+     * @param status
+     *            the status of the job
+     */
+    public void setUploadStatus(String jobId, Status status) {
+        UploadJob uj = jobs.get(jobId);
+        if (uj == null) {
+            s_logger.warn("setUploadStatus for jobId: " + jobId + ", status=" + status + " no job found");
+            return;
+        }
+        TemplateUploader tu = uj.getTemplateUploader();
+        s_logger.warn("Upload Completion for jobId: " + jobId + ", status=" + status);
+        s_logger.warn("UploadedBytes=" + tu.getUploadedBytes() + ", error=" + tu.getUploadError() + ", pct=" + tu.getUploadPercent());
+
+        switch (status) {
+        case ABORTED:
+        case NOT_STARTED:
+        case UNRECOVERABLE_ERROR:
+            // Delete the entity only if its a volume. TO DO - find a better way of finding it a volume.
+            if(uj.getTemplateUploader().getUploadLocalPath().indexOf("volume") > -1){
+                uj.cleanup();
+            }
+            break;
+        case UNKNOWN:
+            return;
+        case IN_PROGRESS:
+            s_logger.info("Resuming jobId: " + jobId + ", status=" + status);
+            tu.setResume(true);
+            threadPool.execute(tu);
+            break;
+        case RECOVERABLE_ERROR:
+            threadPool.execute(tu);
+            break;
+        case UPLOAD_FINISHED:
+            tu.setUploadError("Upload success, starting install ");
+            String result = postUpload(jobId);
+            if (result != null) {
+                s_logger.error("Failed post upload script: " + result);
+                tu.setStatus(Status.UNRECOVERABLE_ERROR);
+                tu.setUploadError("Failed post upload script: " + result);
+            } else {
+                s_logger.warn("Upload completed successfully at " + new SimpleDateFormat().format(new Date()));
+                tu.setStatus(Status.POST_UPLOAD_FINISHED);
+                tu.setUploadError("Upload completed successfully at " + new SimpleDateFormat().format(new Date()));
+            }
+            // Delete the entity only if its a volume. TO DO - find a better way of finding it a volume.
+            if(uj.getTemplateUploader().getUploadLocalPath().indexOf("volume") > -1){
+                uj.cleanup();
+            }
+            break;
+        default:
+            break;
+        }
+    }
+
+    private String postUpload(String jobId) {
+        return null;
+    }
+
+    private void sleep() {
+        try {
+            Thread.sleep(3000);
+        } catch (InterruptedException e) {
+            // ignore
+        }
+    }
+
+    private boolean checkAndStartApache() {
+
+        //Check whether the Apache server is running
+        Script command = new Script("/bin/bash", s_logger);
+        command.add("-c");
+        command.add("if [ -d /etc/apache2 ] ; then service apache2 status | grep pid; else service httpd status | grep pid; fi ");
+        String result = command.execute();
+
+        //Apache Server is not running. Try to start it.
+        if (result != null) { 				  	
+
+            /*s_logger.warn("Apache server not running, trying to start it");
+			String port = Integer.toString(TemplateConstants.DEFAULT_TMPLT_COPY_PORT);
+			String intf = TemplateConstants.DEFAULT_TMPLT_COPY_INTF;
+
+			command = new Script("/bin/bash", s_logger);
+			command.add("-c");
+			command.add("iptables -D INPUT -i " + intf + " -p tcp -m state --state NEW -m tcp --dport " + port + " -j DROP;" +
+				        "iptables -D INPUT -i " + intf + " -p tcp -m state --state NEW -m tcp --dport " + port + " -j HTTP;" +
+				        "iptables -D INPUT -i " + intf + " -p tcp -m state --state NEW -m tcp --dport " + "443" + " -j DROP;" +
+				        "iptables -D INPUT -i " + intf + " -p tcp -m state --state NEW -m tcp --dport " + "443" + " -j HTTP;" +
+				        "iptables -F HTTP;" +
+				        "iptables -X HTTP;" +
+				        "iptables -N HTTP;" +
+					    "iptables -I INPUT -i " + intf + " -p tcp -m state --state NEW -m tcp --dport " + port + " -j DROP;" +
+					    "iptables -I INPUT -i " + intf + " -p tcp -m state --state NEW -m tcp --dport " + "443" + " -j DROP;" +
+					    "iptables -I INPUT -i " + intf + " -p tcp -m state --state NEW -m tcp --dport " + port + " -j HTTP;" +
+			            "iptables -I INPUT -i " + intf + " -p tcp -m state --state NEW -m tcp --dport " + "443" + " -j HTTP;");
+
+			result = command.execute();
+			if (result != null) {
+				s_logger.warn("Error in opening up httpd port err=" + result );
+				return false;
+			}*/			
+
+            command = new Script("/bin/bash", s_logger);
+            command.add("-c");
+            command.add("if [ -d /etc/apache2 ] ; then service apache2 start; else service httpd start; fi ");
+            result = command.execute();
+            if (result != null) {
+                s_logger.warn("Error in starting httpd service err=" + result );
+                return false;
+            }
+        }
+
+        return true;
+    }
+}    

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/tools/devcloud/pom.xml
----------------------------------------------------------------------
diff --git a/tools/devcloud/pom.xml b/tools/devcloud/pom.xml
index d7b82c9..d32d84b 100644
--- a/tools/devcloud/pom.xml
+++ b/tools/devcloud/pom.xml
@@ -142,5 +142,38 @@
         </plugins>
       </build>
     </profile>
+    <profile>
+      <id>quicksvr</id>
+      <activation>
+        <property>
+          <name>quicksvr</name>
+        </property>
+      </activation>
+      <build> 
+        <plugins>
+          <plugin>
+         <groupId>org.codehaus.mojo</groupId>
+        <artifactId>exec-maven-plugin</artifactId>
+        <version>1.2.1</version>
+        <executions>
+          <execution>
+            <phase>package</phase>
+            <goals>
+              <goal>exec</goal>
+            </goals>
+          </execution>
+        </executions>
+        <configuration>
+          <executable>python</executable>
+          <arguments>
+            <argument>../marvin/marvin/deployDataCenter.py</argument>
+            <argument>-i</argument>
+            <argument>quickcloud.cfg</argument>
+          </arguments>
+        </configuration>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
   </profiles>
 </project>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/tools/devcloud/quickcloud.cfg
----------------------------------------------------------------------
diff --git a/tools/devcloud/quickcloud.cfg b/tools/devcloud/quickcloud.cfg
new file mode 100644
index 0000000..0e1fb4f
--- /dev/null
+++ b/tools/devcloud/quickcloud.cfg
@@ -0,0 +1,120 @@
+#  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.
+#
+
+{
+    "zones": [
+        {
+            "name": "QuickCloud00", 
+            "enabled" : "True",
+            "details" : [
+                    {"key" : "enable.secstorage.vm", "value": "False"},
+                    {"key" : "enable.consoleproxy.vm", "value": "False"}
+            ],
+            "physical_networks": [
+                {
+                    "broadcastdomainrange": "Zone", 
+                    "name": "test-network", 
+                    "traffictypes": [
+                        {
+                            "typ": "Guest"
+                        }, 
+                        {
+                            "typ": "Management"
+                        } 
+                    ], 
+                    "providers": [
+                        {
+                            "broadcastdomainrange": "ZONE", 
+                            "name": "VirtualRouter"
+                        },
+                        {
+                            "broadcastdomainrange": "Pod",
+                            "name": "SecurityGroupProvider"
+                        }
+                    ]
+                }
+            ],
+            "dns2": "4.4.4.4", 
+            "dns1": "8.8.8.8",
+            "securitygroupenabled": "true", 
+            "localstorageenabled": "true",
+            "networktype": "Basic", 
+            "pods": [
+                {
+                    "endip": "192.168.56.220", 
+                    "name": "test00", 
+                    "startip": "192.168.56.200", 
+                    "guestIpRanges": [
+                        {
+                            "startip": "192.168.56.100", 
+                            "endip": "192.168.56.199", 
+                            "netmask": "255.255.255.0", 
+                            "gateway": "192.168.56.1"
+                        }
+                    ], 
+                    "netmask": "255.255.255.0", 
+                    "clusters": [
+                        {
+                            "clustername": "test000", 
+                            "hypervisor": "XenServer", 
+                            "hosts": [
+                                {
+                                    "username": "root", 
+                                    "url": "http://192.168.56.10/", 
+                                    "password": "password"
+                                }
+                            ], 
+                            "clustertype": "CloudManaged"
+                        }
+                    ], 
+                    "gateway": "192.168.56.1"
+                }
+            ], 
+            "internaldns1": "192.168.56.1",
+            "secondaryStorages": [
+                {
+                    "url": "nfs://192.168.56.10:/opt/storage/secondary"
+                }
+            ]
+        }
+    ], 
+    "logger": [
+        {
+            "name": "TestClient", 
+            "file": "testclient.log"
+        }, 
+        {
+            "name": "TestCase", 
+            "file": "testcase.log"
+        }
+    ], 
+    "mgtSvr": [
+        {
+            "mgtSvrIp": "127.0.0.1", 
+            "port": 8096
+        }
+    ],
+    "dbSvr": 
+        {
+	    "dbSvr": "127.0.0.1",
+	    "port": 3306,
+	    "user": "cloud",
+	    "passwd": "cloud",
+	    "db": "cloud"
+        }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/tools/marvin/marvin/cloudstackConnection.py
----------------------------------------------------------------------
diff --git a/tools/marvin/marvin/cloudstackConnection.py b/tools/marvin/marvin/cloudstackConnection.py
index e8b861e..1caeef3 100644
--- a/tools/marvin/marvin/cloudstackConnection.py
+++ b/tools/marvin/marvin/cloudstackConnection.py
@@ -162,9 +162,9 @@ class cloudConnection(object):
                     else:
                         requests.pop(param)
                         i = 0
-                        for v in value:
-                            for key, val in v.iteritems():
-                                requests["%s[%d].%s"%(param,i,key)] = val
+                        for val in value:
+                            for k,v in val.iteritems():
+                                requests["%s[%d].%s"%(param,i,k)] = v
                             i = i + 1
         
         if self.logging is not None:

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7983b25/tools/marvin/marvin/deployDataCenter.py
----------------------------------------------------------------------
diff --git a/tools/marvin/marvin/deployDataCenter.py b/tools/marvin/marvin/deployDataCenter.py
index cec920c..42bc5f9 100644
--- a/tools/marvin/marvin/deployDataCenter.py
+++ b/tools/marvin/marvin/deployDataCenter.py
@@ -270,6 +270,12 @@ class deployDataCenters():
         zoneCmd.allocationstate = allocation_state
         return self.apiClient.updateZone(zoneCmd)
 
+    def updateZoneDetails(self, zoneid, details):
+        zoneCmd = updateZone.updateZoneCmd()
+        zoneCmd.id = zoneid
+        zoneCmd.details = details
+        return self.apiClient.updateZone(zoneCmd)
+
     def createZones(self, zones):
         for zone in zones:
             createzone = createZone.createZoneCmd()
@@ -320,7 +326,15 @@ class deployDataCenters():
                                         zoneId)
 
             self.createSecondaryStorages(zone.secondaryStorages, zoneId)
-            self.enableZone(zoneId, "Enabled")
+            
+            enabled = getattr(zone, 'enabled', 'True')
+            if enabled == 'True' or enabled == 'None':
+                self.enableZone(zoneId, "Enabled")
+            details = getattr(zone, 'details')
+            if details is not None:
+                det = [d.__dict__ for d in details]
+                self.updateZoneDetails(zoneId, det)
+
         return
     
     def isEipElbZone(self, zone):