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

[01/11] Moved the secondary storage service into its own server directory

Updated Branches:
  refs/heads/master aaa20947a -> 54f32a8e4


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4be3b993/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
deleted file mode 100755
index cdbc52d..0000000
--- a/services/secondary-storage/src/org/apache/cloudstack/storage/template/UploadManagerImpl.java
+++ /dev/null
@@ -1,550 +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 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.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 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.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.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;
-
-        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;
-        }
-
-        public TemplateUploader getTemplateUploader() {
-            return tu;
-        }
-
-        public void cleanup() {
-            if (tu != null) {
-                String upldPath = tu.getUploadLocalPath();
-                if (upldPath != null) {
-                    File f = new File(upldPath);
-                    f.delete();
-                }
-            }
-        }
-
-    }
-
-    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 final String extractMountPoint = "/mnt/SecStorage/extractmnt";
-    private StorageLayer _storage;
-    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();
-        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) {
-        return 0;
-    }
-
-    @SuppressWarnings("unchecked")
-    @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 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.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/4be3b993/services/secondary-storage/test/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResourceTest.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/test/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResourceTest.java b/services/secondary-storage/test/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResourceTest.java
deleted file mode 100644
index e0fcbae..0000000
--- a/services/secondary-storage/test/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResourceTest.java
+++ /dev/null
@@ -1,143 +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 org.apache.cloudstack.storage.resource;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.util.Map;
-import java.util.Properties;
-import java.util.UUID;
-
-import javax.naming.ConfigurationException;
-
-import junit.framework.Assert;
-import junit.framework.TestCase;
-
-import org.apache.log4j.Logger;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mockito;
-
-import org.apache.cloudstack.storage.command.CopyCmdAnswer;
-import org.apache.cloudstack.storage.command.CopyCommand;
-import org.apache.cloudstack.storage.command.DownloadCommand;
-import org.apache.cloudstack.storage.to.TemplateObjectTO;
-
-import com.cloud.agent.api.storage.DownloadAnswer;
-import com.cloud.agent.api.storage.ListTemplateAnswer;
-import com.cloud.agent.api.storage.ListTemplateCommand;
-import com.cloud.agent.api.to.DataObjectType;
-import com.cloud.agent.api.to.NfsTO;
-import com.cloud.agent.api.to.SwiftTO;
-import com.cloud.storage.DataStoreRole;
-import com.cloud.storage.Storage;
-import com.cloud.utils.PropertiesUtil;
-import com.cloud.utils.exception.CloudRuntimeException;
-
-public class LocalNfsSecondaryStorageResourceTest extends TestCase {
-    private static Map<String, Object> testParams;
-
-    private static final Logger s_logger = Logger.getLogger(LocalNfsSecondaryStorageResourceTest.class.getName());
-
-    LocalNfsSecondaryStorageResource resource;
-
-    @Before
-    @Override
-    public void setUp() throws ConfigurationException {
-        resource = new LocalNfsSecondaryStorageResource();
-        resource.setInSystemVM(true);
-
-        testParams = PropertiesUtil.toMap(loadProperties());
-        resource.configureStorageLayerClass(testParams);
-        Object testLocalRoot = testParams.get("testLocalRoot");
-        resource.setParentPath("/mnt");
-
-        if (testLocalRoot != null) {
-            resource.setParentPath((String)testLocalRoot);
-        }
-
-        System.setProperty("paths.script", "/Users/edison/develop/asf-master/script");
-        //resource.configure("test", new HashMap<String, Object>());
-    }
-
-    @Test
-    public void testExecuteRequest() throws Exception {
-        TemplateObjectTO template = Mockito.mock(TemplateObjectTO.class);
-        NfsTO cacheStore = Mockito.mock(NfsTO.class);
-        Mockito.when(cacheStore.getUrl()).thenReturn("nfs://nfs2.lab.vmops.com/export/home/edison/");
-        SwiftTO swift = Mockito.mock(SwiftTO.class);
-        Mockito.when(swift.getEndPoint()).thenReturn("https://objects.dreamhost.com/auth");
-        Mockito.when(swift.getAccount()).thenReturn("cloudstack");
-        Mockito.when(swift.getUserName()).thenReturn("images");
-        Mockito.when(swift.getKey()).thenReturn("oxvELQaOD1U5_VyosGfA-wpZ7uBWEff-CUBGCM0u");
-
-        Mockito.when(template.getDataStore()).thenReturn(swift);
-        Mockito.when(template.getPath()).thenReturn("template/1/1/");
-        Mockito.when(template.isRequiresHvm()).thenReturn(true);
-        Mockito.when(template.getId()).thenReturn(1L);
-        Mockito.when(template.getFormat()).thenReturn(Storage.ImageFormat.VHD);
-        Mockito.when(template.getOrigUrl()).thenReturn("http://nfs1.lab.vmops.com/templates/test.bz2");
-        Mockito.when(template.getName()).thenReturn(UUID.randomUUID().toString());
-        Mockito.when(template.getObjectType()).thenReturn(DataObjectType.TEMPLATE);
-
-        DownloadCommand cmd = new DownloadCommand(template, 100000L);
-        cmd.setCacheStore(cacheStore);
-        DownloadAnswer answer = (DownloadAnswer)resource.executeRequest(cmd);
-        Assert.assertTrue(answer.getResult());
-
-        Mockito.when(template.getPath()).thenReturn(answer.getInstallPath());
-        Mockito.when(template.getDataStore()).thenReturn(swift);
-        //download swift:
-        Mockito.when(cacheStore.getRole()).thenReturn(DataStoreRole.ImageCache);
-        TemplateObjectTO destTemplate = Mockito.mock(TemplateObjectTO.class);
-        Mockito.when(destTemplate.getPath()).thenReturn("template/1/2");
-        Mockito.when(destTemplate.getDataStore()).thenReturn(cacheStore);
-        Mockito.when(destTemplate.getObjectType()).thenReturn(DataObjectType.TEMPLATE);
-        CopyCommand cpyCmd = new CopyCommand(template, destTemplate, 10000, true);
-        CopyCmdAnswer copyCmdAnswer = (CopyCmdAnswer)resource.executeRequest(cpyCmd);
-        Assert.assertTrue(copyCmdAnswer.getResult());
-
-        //list template
-        ListTemplateCommand listCmd = new ListTemplateCommand(swift);
-        ListTemplateAnswer listAnswer = (ListTemplateAnswer)resource.executeRequest(listCmd);
-
-        Assert.assertTrue(listAnswer.getTemplateInfo().size() > 0);
-    }
-
-    public static Properties loadProperties() throws ConfigurationException {
-        Properties properties = new Properties();
-        final File file = PropertiesUtil.findConfigFile("agent.properties");
-        if (file == null) {
-            throw new ConfigurationException("Unable to find agent.properties.");
-        }
-
-        s_logger.info("agent.properties found at " + file.getAbsolutePath());
-
-        try {
-            properties.load(new FileInputStream(file));
-        } catch (final FileNotFoundException ex) {
-            throw new CloudRuntimeException("Cannot find the file: " + file.getAbsolutePath(), ex);
-        } catch (final IOException ex) {
-            throw new CloudRuntimeException("IOException in reading " + file.getAbsolutePath(), ex);
-        }
-        return properties;
-    }
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4be3b993/services/secondary-storage/test/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResourceTest.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/test/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResourceTest.java b/services/secondary-storage/test/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResourceTest.java
deleted file mode 100644
index e0ae4c5..0000000
--- a/services/secondary-storage/test/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResourceTest.java
+++ /dev/null
@@ -1,110 +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 org.apache.cloudstack.storage.resource;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.net.URI;
-import java.util.Map;
-import java.util.Properties;
-
-import javax.naming.ConfigurationException;
-
-import junit.framework.Assert;
-import junit.framework.TestCase;
-
-import org.apache.log4j.Level;
-import org.apache.log4j.Logger;
-import org.junit.Before;
-import org.junit.Test;
-
-import com.cloud.utils.PropertiesUtil;
-import com.cloud.utils.exception.CloudRuntimeException;
-
-public class NfsSecondaryStorageResourceTest extends TestCase {
-    private static Map<String, Object> testParams;
-
-    private static final Logger s_logger = Logger.getLogger(NfsSecondaryStorageResourceTest.class.getName());
-
-    NfsSecondaryStorageResource resource;
-
-    @Before
-    @Override
-    public void setUp() throws ConfigurationException {
-        s_logger.setLevel(Level.ALL);
-        resource = new NfsSecondaryStorageResource();
-        resource.setInSystemVM(true);
-        testParams = PropertiesUtil.toMap(loadProperties());
-        resource.configureStorageLayerClass(testParams);
-        Object testLocalRoot = testParams.get("testLocalRoot");
-        if (testLocalRoot != null) {
-            resource.setParentPath((String)testLocalRoot);
-        }
-    }
-
-    @Test
-    public void testMount() throws Exception {
-        String sampleUriStr = "cifs://192.168.1.128/CSHV3?user=administrator&password=1pass%40word1&foo=bar";
-        URI sampleUri = new URI(sampleUriStr);
-
-        s_logger.info("Check HostIp parsing");
-        String hostIpStr = resource.getUriHostIp(sampleUri);
-        Assert.assertEquals("Expected host IP " + sampleUri.getHost() + " and actual host IP " + hostIpStr + " differ.", sampleUri.getHost(), hostIpStr);
-
-        s_logger.info("Check option parsing");
-        String expected = "user=administrator,password=1pass@word1,foo=bar,";
-        String actualOpts = resource.parseCifsMountOptions(sampleUri);
-        Assert.assertEquals("Options should be " + expected + " and not " + actualOpts, expected, actualOpts);
-
-        // attempt a configured mount
-        final Map<String, Object> params = PropertiesUtil.toMap(loadProperties());
-        String sampleMount = (String)params.get("testCifsMount");
-        if (!sampleMount.isEmpty()) {
-            s_logger.info("functional test, mount " + sampleMount);
-            URI realMntUri = new URI(sampleMount);
-            String mntSubDir = resource.mountUri(realMntUri);
-            s_logger.info("functional test, umount " + mntSubDir);
-            resource.umount(resource.getMountingRoot() + mntSubDir, realMntUri);
-        } else {
-            s_logger.info("no entry for testCifsMount in " + "./conf/agent.properties - skip functional test");
-        }
-    }
-
-    public static Properties loadProperties() throws ConfigurationException {
-        Properties properties = new Properties();
-        final File file = PropertiesUtil.findConfigFile("agent.properties");
-        if (file == null) {
-            throw new ConfigurationException("Unable to find agent.properties.");
-        }
-
-        s_logger.info("agent.properties found at " + file.getAbsolutePath());
-
-        try {
-            properties.load(new FileInputStream(file));
-        } catch (final FileNotFoundException ex) {
-            throw new CloudRuntimeException("Cannot find the file: " + file.getAbsolutePath(), ex);
-        } catch (final IOException ex) {
-            throw new CloudRuntimeException("IOException in reading " + file.getAbsolutePath(), ex);
-        }
-        return properties;
-    }
-
-}


[09/11] git commit: updated refs/heads/master to 54f32a8

Posted by ah...@apache.org.
Removed some useless imports


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

Branch: refs/heads/master
Commit: 03a424e45abe753cd0227efb10eb21e2b9fab53c
Parents: 7f34282
Author: Alex Huang <al...@citrix.com>
Authored: Wed Jan 29 16:21:33 2014 +0000
Committer: Alex Huang <al...@citrix.com>
Committed: Wed Feb 5 01:39:16 2014 +0000

----------------------------------------------------------------------
 .../ConsoleProxyBalanceAllocator.java             |  3 ---
 .../consoleproxy/StaticConsoleProxyManager.java   | 18 ------------------
 2 files changed, 21 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/03a424e4/server/src/com/cloud/consoleproxy/ConsoleProxyBalanceAllocator.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyBalanceAllocator.java b/server/src/com/cloud/consoleproxy/ConsoleProxyBalanceAllocator.java
index 147063d..2cbd847 100644
--- a/server/src/com/cloud/consoleproxy/ConsoleProxyBalanceAllocator.java
+++ b/server/src/com/cloud/consoleproxy/ConsoleProxyBalanceAllocator.java
@@ -21,7 +21,6 @@ import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
 import java.util.Map;
-import java.util.Random;
 
 import javax.ejb.Local;
 import javax.naming.ConfigurationException;
@@ -32,8 +31,6 @@ import com.cloud.vm.ConsoleProxy;
 @Local(value = {ConsoleProxyAllocator.class})
 public class ConsoleProxyBalanceAllocator extends AdapterBase implements ConsoleProxyAllocator {
 
-    private final Random _rand = new Random(System.currentTimeMillis());
-
     @Override
     public Long allocProxy(List<? extends ConsoleProxy> candidates, final Map<Long, Integer> loadInfo, long dataCenterId) {
         List<ConsoleProxy> allocationList = new ArrayList<ConsoleProxy>(candidates);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/03a424e4/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 27bdcbe..8aa9b0d 100755
--- a/server/src/com/cloud/consoleproxy/StaticConsoleProxyManager.java
+++ b/server/src/com/cloud/consoleproxy/StaticConsoleProxyManager.java
@@ -18,23 +18,17 @@ 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.apache.log4j.Logger;
-
 import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.framework.security.keystore.KeystoreDao;
-import org.apache.cloudstack.framework.security.keystore.KeystoreManager;
 
 import com.cloud.agent.api.StartupCommand;
 import com.cloud.agent.api.StartupProxyCommand;
 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.resource.ResourceManager;
 import com.cloud.resource.ResourceStateAdapter;
@@ -43,11 +37,9 @@ 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, ResourceStateAdapter {
-    private static final Logger s_logger = Logger.getLogger(StaticConsoleProxyManager.class);
 
     @Inject
     ConsoleProxyDao _proxyDao;
@@ -55,16 +47,6 @@ public class StaticConsoleProxyManager extends AgentBasedConsoleProxyManager imp
     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;
 
     public StaticConsoleProxyManager() {


[05/11] Moved the secondary storage service into its own server directory

Posted by ah...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4be3b993/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/SecondaryStorageDiscoverer.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/SecondaryStorageDiscoverer.java b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/SecondaryStorageDiscoverer.java
new file mode 100755
index 0000000..ee50647
--- /dev/null
+++ b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/SecondaryStorageDiscoverer.java
@@ -0,0 +1,312 @@
+// 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.host.HostVO;
+import com.cloud.host.Status.Event;
+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.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 VMTemplateDao _tmpltDao = null;
+    @Inject
+    protected VMTemplateZoneDao _vmTemplateZoneDao = null;
+    @Inject
+    protected VMTemplateDao _vmTemplateDao = 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("cifs") && !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("cifs") || 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/4be3b993/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/SecondaryStorageResource.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/SecondaryStorageResource.java b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/SecondaryStorageResource.java
new file mode 100755
index 0000000..93fd8ea
--- /dev/null
+++ b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/SecondaryStorageResource.java
@@ -0,0 +1,29 @@
+// 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.resource.ServerResource;
+
+/**
+ *
+ * SecondaryStorageServerResource is a generic container to execute commands sent
+ */
+public interface SecondaryStorageResource extends ServerResource {
+
+    public String getRootDir(String cmd);
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4be3b993/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/SecondaryStorageResourceHandler.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/SecondaryStorageResourceHandler.java b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/SecondaryStorageResourceHandler.java
new file mode 100644
index 0000000..14ebc71
--- /dev/null
+++ b/services/secondary-storage/server/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/4be3b993/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/DownloadManager.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/DownloadManager.java b/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/DownloadManager.java
new file mode 100644
index 0000000..d0abe2c
--- /dev/null
+++ b/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/DownloadManager.java
@@ -0,0 +1,108 @@
+// 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.command.DownloadCommand;
+import org.apache.cloudstack.storage.command.DownloadCommand.ResourceType;
+import org.apache.cloudstack.storage.resource.SecondaryStorageResource;
+
+import com.cloud.agent.api.storage.DownloadAnswer;
+import com.cloud.agent.api.storage.Proxy;
+import com.cloud.agent.api.to.S3TO;
+import com.cloud.storage.Storage.ImageFormat;
+import com.cloud.storage.VMTemplateHostVO;
+import com.cloud.storage.template.TemplateDownloader;
+import com.cloud.storage.template.TemplateProp;
+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 templatePath, String userName, String passwd, long maxDownloadSizeInBytes, Proxy proxy, ResourceType resourceType);
+
+    public String downloadS3Template(S3TO s3, 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);
+
+    /**
+     * 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, TemplateProp> gatherTemplateInfo(String templateDir);
+
+    /**
+    /**
+     * @return list of volume info for installed volumes
+     */
+    public Map<Long, TemplateProp> gatherVolumeInfo(String volumeDir);
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4be3b993/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java b/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java
new file mode 100755
index 0000000..d45a6bb
--- /dev/null
+++ b/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java
@@ -0,0 +1,1080 @@
+// 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.log4j.Logger;
+
+import org.apache.cloudstack.storage.command.DownloadCommand;
+import org.apache.cloudstack.storage.command.DownloadCommand.ResourceType;
+import org.apache.cloudstack.storage.command.DownloadProgressCommand;
+import org.apache.cloudstack.storage.command.DownloadProgressCommand.RequestType;
+import org.apache.cloudstack.storage.resource.SecondaryStorageResource;
+
+import com.cloud.agent.api.storage.DownloadAnswer;
+import com.cloud.agent.api.storage.Proxy;
+import com.cloud.agent.api.to.DataStoreTO;
+import com.cloud.agent.api.to.NfsTO;
+import com.cloud.agent.api.to.S3TO;
+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.OVAProcessor;
+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.S3TemplateDownloader;
+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.TemplateLocation;
+import com.cloud.storage.template.TemplateProp;
+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 tmpltName;
+        private final boolean hvm;
+        private final ImageFormat format;
+        private String tmpltPath;
+        private final String description;
+        private String checksum;
+        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.tmpltName = tmpltName;
+            this.format = format;
+            this.hvm = hvm;
+            description = descr;
+            checksum = cksum;
+            this.installPathPrefix = installPathPrefix;
+            templatesize = 0;
+            this.id = id;
+            this.resourceType = resourceType;
+        }
+
+        public String getDescription() {
+            return description;
+        }
+
+        public String getChecksum() {
+            return checksum;
+        }
+
+        public TemplateDownloader getTemplateDownloader() {
+            return td;
+        }
+
+        public String getTmpltName() {
+            return tmpltName;
+        }
+
+        public ImageFormat getFormat() {
+            return format;
+        }
+
+        public boolean isHvm() {
+            return hvm;
+        }
+
+        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 ExecutorService threadPool;
+
+    private final Map<String, DownloadJob> jobs = new ConcurrentHashMap<String, DownloadJob>();
+    private String listTmpltScr;
+    private String listVolScr;
+    private int installTimeoutPerGig = 180 * 60 * 1000;
+
+    public void setThreadPool(ExecutorService threadPool) {
+        this.threadPool = threadPool;
+    }
+
+    public void setStorageLayer(StorageLayer storage) {
+        _storage = storage;
+    }
+
+    /**
+     * 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:
+            if (!(td instanceof S3TemplateDownloader)) {
+                // we currently only create template.properties for NFS by
+                // running some post download script
+                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()));
+                }
+            } else {
+                // for s3 and swift, we skip post download step and just set
+                // status to trigger callback.
+                td.setStatus(Status.POST_DOWNLOAD_FINISHED);
+                // set template size for S3
+                S3TemplateDownloader std = (S3TemplateDownloader)td;
+                long size = std.totalBytes;
+                DownloadJob dnld = jobs.get(jobId);
+                dnld.setTemplatesize(size);
+                dnld.setTemplatePhysicalSize(size);
+                dnld.setTmpltPath(std.getDownloadLocalPath()); // update template path to include file name.
+            }
+            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 = dnld.getInstallPathPrefix(); // path with mount
+        // directory
+        String finalResourcePath = dnld.getTmpltPath(); // template download
+        // path on secondary
+        // storage
+        ResourceType resourceType = dnld.getResourceType();
+
+        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();
+        }
+
+        // run script to mv the temporary template file to the final template
+        // file
+        String templateFilename = templateName + "." + extension;
+        dnld.setTmpltPath(finalResourcePath + "/" + templateFilename);
+        scr.add("-n", templateFilename);
+
+        scr.add("-t", resourcePath);
+        scr.add("-f", td.getDownloadLocalPath()); // this is the temporary
+        // template file downloaded
+        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 downloadS3Template(S3TO s3, 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();
+
+        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 S3TemplateDownloader(s3, url, installPathPrefix, new Completion(jobId), maxTemplateSizeInBytes, user, password, proxy, resourceType);
+            } 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);
+        dj.setTmpltPath(installPathPrefix);
+        jobs.put(jobId, dj);
+        threadPool.execute(td);
+
+        return jobId;
+    }
+
+    @Override
+    public String downloadPublicTemplate(long id, String url, String name, ImageFormat format, boolean hvm, Long accountId, String descr, String cksum,
+            String installPathPrefix, String templatePath, String user, String password, long maxTemplateSizeInBytes, Proxy proxy, ResourceType resourceType) {
+        UUID uuid = UUID.randomUUID();
+        String jobId = uuid.toString();
+        String tmpDir = installPathPrefix;
+
+        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") || uri.getScheme().equalsIgnoreCase("cifs")) {
+                            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);
+                    }
+                    // NOTE the difference between installPathPrefix and templatePath
+                    // here. instalPathPrefix is the absolute path for template
+                    // including mount directory
+                    // on ssvm, while templatePath is the final relative path on
+                    // secondary storage.
+                    DownloadJob dj = new DownloadJob(td, jobId, id, name, format, hvm, accountId, descr, cksum, installPathPrefix, resourceType);
+                    dj.setTmpltPath(templatePath);
+                    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);
+        }
+
+        DataStoreTO dstore = cmd.getDataStore();
+        String installPathPrefix = cmd.getInstallPath();
+        // for NFS, we need to get mounted path
+        if (dstore instanceof NfsTO) {
+            installPathPrefix = resource.getRootDir(((NfsTO)dstore).getUrl()) + File.separator + installPathPrefix;
+        }
+        String user = null;
+        String password = null;
+        if (cmd.getAuth() != null) {
+            user = cmd.getAuth().getUserName();
+            password = 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 = null;
+        if (dstore instanceof S3TO) {
+            jobId =
+                    downloadS3Template((S3TO)dstore, cmd.getId(), cmd.getUrl(), cmd.getName(), cmd.getFormat(), cmd.isHvm(), cmd.getAccountId(), cmd.getDescription(),
+                            cmd.getChecksum(), installPathPrefix, user, password, maxDownloadSizeInBytes, cmd.getProxy(), resourceType);
+        } else {
+            jobId =
+                    downloadPublicTemplate(cmd.getId(), cmd.getUrl(), cmd.getName(), cmd.getFormat(), cmd.isHvm(), cmd.getAccountId(), cmd.getDescription(),
+                            cmd.getChecksum(), installPathPrefix, cmd.getInstallPath(), 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", com.cloud.storage.VMTemplateStorageResourceAssoc.Status.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 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, TemplateProp> gatherTemplateInfo(String rootDir) {
+        Map<String, TemplateProp> result = new HashMap<String, TemplateProp>();
+        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;
+            }
+
+            TemplateProp tInfo = loc.getTemplateInfo();
+
+            if ((tInfo.getSize() == tInfo.getPhysicalSize()) && (tInfo.getInstallPath().endsWith(ImageFormat.OVA.getFileExtension()))) {
+                try {
+                    Processor processor = _processors.get("OVA Processor");
+                    OVAProcessor vmdkProcessor = (OVAProcessor)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, TemplateProp> gatherVolumeInfo(String rootDir) {
+        Map<Long, TemplateProp> result = new HashMap<Long, TemplateProp>();
+        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;
+            }
+
+            TemplateProp vInfo = loc.getTemplateInfo();
+
+            if ((vInfo.getSize() == vInfo.getPhysicalSize()) && (vInfo.getInstallPath().endsWith(ImageFormat.OVA.getFileExtension()))) {
+                try {
+                    Processor processor = _processors.get("OVA Processor");
+                    OVAProcessor vmdkProcessor = (OVAProcessor)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;
+    }
+
+    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 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");
+        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 OVAProcessor();
+        processor.configure("OVA Processor", params);
+        _processors.put("OVA 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/4be3b993/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/UploadManager.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/UploadManager.java b/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/UploadManager.java
new file mode 100755
index 0000000..be99fea
--- /dev/null
+++ b/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/UploadManager.java
@@ -0,0 +1,82 @@
+// 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);
+
+}


[02/11] Moved the secondary storage service into its own server directory

Posted by ah...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4be3b993/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
deleted file mode 100755
index ee50647..0000000
--- a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/SecondaryStorageDiscoverer.java
+++ /dev/null
@@ -1,312 +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 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.host.HostVO;
-import com.cloud.host.Status.Event;
-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.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 VMTemplateDao _tmpltDao = null;
-    @Inject
-    protected VMTemplateZoneDao _vmTemplateZoneDao = null;
-    @Inject
-    protected VMTemplateDao _vmTemplateDao = 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("cifs") && !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("cifs") || 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/4be3b993/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
deleted file mode 100755
index 93fd8ea..0000000
--- a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/SecondaryStorageResource.java
+++ /dev/null
@@ -1,29 +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 org.apache.cloudstack.storage.resource;
-
-import com.cloud.resource.ServerResource;
-
-/**
- *
- * SecondaryStorageServerResource is a generic container to execute commands sent
- */
-public interface SecondaryStorageResource extends ServerResource {
-
-    public String getRootDir(String cmd);
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4be3b993/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
deleted file mode 100644
index 14ebc71..0000000
--- a/services/secondary-storage/src/org/apache/cloudstack/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 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/4be3b993/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
deleted file mode 100644
index d0abe2c..0000000
--- a/services/secondary-storage/src/org/apache/cloudstack/storage/template/DownloadManager.java
+++ /dev/null
@@ -1,108 +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 org.apache.cloudstack.storage.template;
-
-import java.util.Map;
-
-import org.apache.cloudstack.storage.command.DownloadCommand;
-import org.apache.cloudstack.storage.command.DownloadCommand.ResourceType;
-import org.apache.cloudstack.storage.resource.SecondaryStorageResource;
-
-import com.cloud.agent.api.storage.DownloadAnswer;
-import com.cloud.agent.api.storage.Proxy;
-import com.cloud.agent.api.to.S3TO;
-import com.cloud.storage.Storage.ImageFormat;
-import com.cloud.storage.VMTemplateHostVO;
-import com.cloud.storage.template.TemplateDownloader;
-import com.cloud.storage.template.TemplateProp;
-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 templatePath, String userName, String passwd, long maxDownloadSizeInBytes, Proxy proxy, ResourceType resourceType);
-
-    public String downloadS3Template(S3TO s3, 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);
-
-    /**
-     * 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, TemplateProp> gatherTemplateInfo(String templateDir);
-
-    /**
-    /**
-     * @return list of volume info for installed volumes
-     */
-    public Map<Long, TemplateProp> gatherVolumeInfo(String volumeDir);
-
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4be3b993/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
deleted file mode 100755
index d45a6bb..0000000
--- a/services/secondary-storage/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java
+++ /dev/null
@@ -1,1080 +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 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.log4j.Logger;
-
-import org.apache.cloudstack.storage.command.DownloadCommand;
-import org.apache.cloudstack.storage.command.DownloadCommand.ResourceType;
-import org.apache.cloudstack.storage.command.DownloadProgressCommand;
-import org.apache.cloudstack.storage.command.DownloadProgressCommand.RequestType;
-import org.apache.cloudstack.storage.resource.SecondaryStorageResource;
-
-import com.cloud.agent.api.storage.DownloadAnswer;
-import com.cloud.agent.api.storage.Proxy;
-import com.cloud.agent.api.to.DataStoreTO;
-import com.cloud.agent.api.to.NfsTO;
-import com.cloud.agent.api.to.S3TO;
-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.OVAProcessor;
-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.S3TemplateDownloader;
-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.TemplateLocation;
-import com.cloud.storage.template.TemplateProp;
-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 tmpltName;
-        private final boolean hvm;
-        private final ImageFormat format;
-        private String tmpltPath;
-        private final String description;
-        private String checksum;
-        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.tmpltName = tmpltName;
-            this.format = format;
-            this.hvm = hvm;
-            description = descr;
-            checksum = cksum;
-            this.installPathPrefix = installPathPrefix;
-            templatesize = 0;
-            this.id = id;
-            this.resourceType = resourceType;
-        }
-
-        public String getDescription() {
-            return description;
-        }
-
-        public String getChecksum() {
-            return checksum;
-        }
-
-        public TemplateDownloader getTemplateDownloader() {
-            return td;
-        }
-
-        public String getTmpltName() {
-            return tmpltName;
-        }
-
-        public ImageFormat getFormat() {
-            return format;
-        }
-
-        public boolean isHvm() {
-            return hvm;
-        }
-
-        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 ExecutorService threadPool;
-
-    private final Map<String, DownloadJob> jobs = new ConcurrentHashMap<String, DownloadJob>();
-    private String listTmpltScr;
-    private String listVolScr;
-    private int installTimeoutPerGig = 180 * 60 * 1000;
-
-    public void setThreadPool(ExecutorService threadPool) {
-        this.threadPool = threadPool;
-    }
-
-    public void setStorageLayer(StorageLayer storage) {
-        _storage = storage;
-    }
-
-    /**
-     * 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:
-            if (!(td instanceof S3TemplateDownloader)) {
-                // we currently only create template.properties for NFS by
-                // running some post download script
-                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()));
-                }
-            } else {
-                // for s3 and swift, we skip post download step and just set
-                // status to trigger callback.
-                td.setStatus(Status.POST_DOWNLOAD_FINISHED);
-                // set template size for S3
-                S3TemplateDownloader std = (S3TemplateDownloader)td;
-                long size = std.totalBytes;
-                DownloadJob dnld = jobs.get(jobId);
-                dnld.setTemplatesize(size);
-                dnld.setTemplatePhysicalSize(size);
-                dnld.setTmpltPath(std.getDownloadLocalPath()); // update template path to include file name.
-            }
-            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 = dnld.getInstallPathPrefix(); // path with mount
-        // directory
-        String finalResourcePath = dnld.getTmpltPath(); // template download
-        // path on secondary
-        // storage
-        ResourceType resourceType = dnld.getResourceType();
-
-        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();
-        }
-
-        // run script to mv the temporary template file to the final template
-        // file
-        String templateFilename = templateName + "." + extension;
-        dnld.setTmpltPath(finalResourcePath + "/" + templateFilename);
-        scr.add("-n", templateFilename);
-
-        scr.add("-t", resourcePath);
-        scr.add("-f", td.getDownloadLocalPath()); // this is the temporary
-        // template file downloaded
-        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 downloadS3Template(S3TO s3, 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();
-
-        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 S3TemplateDownloader(s3, url, installPathPrefix, new Completion(jobId), maxTemplateSizeInBytes, user, password, proxy, resourceType);
-            } 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);
-        dj.setTmpltPath(installPathPrefix);
-        jobs.put(jobId, dj);
-        threadPool.execute(td);
-
-        return jobId;
-    }
-
-    @Override
-    public String downloadPublicTemplate(long id, String url, String name, ImageFormat format, boolean hvm, Long accountId, String descr, String cksum,
-            String installPathPrefix, String templatePath, String user, String password, long maxTemplateSizeInBytes, Proxy proxy, ResourceType resourceType) {
-        UUID uuid = UUID.randomUUID();
-        String jobId = uuid.toString();
-        String tmpDir = installPathPrefix;
-
-        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") || uri.getScheme().equalsIgnoreCase("cifs")) {
-                            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);
-                    }
-                    // NOTE the difference between installPathPrefix and templatePath
-                    // here. instalPathPrefix is the absolute path for template
-                    // including mount directory
-                    // on ssvm, while templatePath is the final relative path on
-                    // secondary storage.
-                    DownloadJob dj = new DownloadJob(td, jobId, id, name, format, hvm, accountId, descr, cksum, installPathPrefix, resourceType);
-                    dj.setTmpltPath(templatePath);
-                    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);
-        }
-
-        DataStoreTO dstore = cmd.getDataStore();
-        String installPathPrefix = cmd.getInstallPath();
-        // for NFS, we need to get mounted path
-        if (dstore instanceof NfsTO) {
-            installPathPrefix = resource.getRootDir(((NfsTO)dstore).getUrl()) + File.separator + installPathPrefix;
-        }
-        String user = null;
-        String password = null;
-        if (cmd.getAuth() != null) {
-            user = cmd.getAuth().getUserName();
-            password = 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 = null;
-        if (dstore instanceof S3TO) {
-            jobId =
-                    downloadS3Template((S3TO)dstore, cmd.getId(), cmd.getUrl(), cmd.getName(), cmd.getFormat(), cmd.isHvm(), cmd.getAccountId(), cmd.getDescription(),
-                            cmd.getChecksum(), installPathPrefix, user, password, maxDownloadSizeInBytes, cmd.getProxy(), resourceType);
-        } else {
-            jobId =
-                    downloadPublicTemplate(cmd.getId(), cmd.getUrl(), cmd.getName(), cmd.getFormat(), cmd.isHvm(), cmd.getAccountId(), cmd.getDescription(),
-                            cmd.getChecksum(), installPathPrefix, cmd.getInstallPath(), 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", com.cloud.storage.VMTemplateStorageResourceAssoc.Status.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 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, TemplateProp> gatherTemplateInfo(String rootDir) {
-        Map<String, TemplateProp> result = new HashMap<String, TemplateProp>();
-        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;
-            }
-
-            TemplateProp tInfo = loc.getTemplateInfo();
-
-            if ((tInfo.getSize() == tInfo.getPhysicalSize()) && (tInfo.getInstallPath().endsWith(ImageFormat.OVA.getFileExtension()))) {
-                try {
-                    Processor processor = _processors.get("OVA Processor");
-                    OVAProcessor vmdkProcessor = (OVAProcessor)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, TemplateProp> gatherVolumeInfo(String rootDir) {
-        Map<Long, TemplateProp> result = new HashMap<Long, TemplateProp>();
-        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;
-            }
-
-            TemplateProp vInfo = loc.getTemplateInfo();
-
-            if ((vInfo.getSize() == vInfo.getPhysicalSize()) && (vInfo.getInstallPath().endsWith(ImageFormat.OVA.getFileExtension()))) {
-                try {
-                    Processor processor = _processors.get("OVA Processor");
-                    OVAProcessor vmdkProcessor = (OVAProcessor)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;
-    }
-
-    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 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");
-        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 OVAProcessor();
-        processor.configure("OVA Processor", params);
-        _processors.put("OVA 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/4be3b993/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
deleted file mode 100755
index be99fea..0000000
--- a/services/secondary-storage/src/org/apache/cloudstack/storage/template/UploadManager.java
+++ /dev/null
@@ -1,82 +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 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);
-
-}


[11/11] git commit: updated refs/heads/master to 54f32a8

Posted by ah...@apache.org.
Moved the controlling logic for secondary storage vm into place


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

Branch: refs/heads/master
Commit: 54f32a8e46247e2f354a70f52fef4835159887fd
Parents: 03a424e
Author: Alex Huang <al...@citrix.com>
Authored: Wed Feb 5 01:38:04 2014 +0000
Committer: Alex Huang <al...@citrix.com>
Committed: Wed Feb 5 01:39:17 2014 +0000

----------------------------------------------------------------------
 client/pom.xml                                  |    5 +
 .../spring-server-core-managers-context.xml     |    6 -
 .../PremiumSecondaryStorageManagerImpl.java     |  185 ---
 .../secondary/SecondaryStorageManagerImpl.java  | 1386 -----------------
 .../ConsoleProxyThumbnailHandler.java           |    1 +
 ...econdary-storage-controller-core-context.xml |   33 +
 .../PremiumSecondaryStorageManagerImpl.java     |  186 +++
 .../SecondaryStorageManagerImpl.java            | 1388 ++++++++++++++++++
 8 files changed, 1613 insertions(+), 1577 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/54f32a8e/client/pom.xml
----------------------------------------------------------------------
diff --git a/client/pom.xml b/client/pom.xml
index 5215e0c..06a6db0 100644
--- a/client/pom.xml
+++ b/client/pom.xml
@@ -268,6 +268,11 @@
     </dependency>
     <dependency>
       <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-controller-secondary-storage</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.cloudstack</groupId>
       <artifactId>cloud-engine-storage-image</artifactId>
       <version>${project.version}</version>
     </dependency>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/54f32a8e/server/resources/META-INF/cloudstack/core/spring-server-core-managers-context.xml
----------------------------------------------------------------------
diff --git a/server/resources/META-INF/cloudstack/core/spring-server-core-managers-context.xml b/server/resources/META-INF/cloudstack/core/spring-server-core-managers-context.xml
index 53a294e..cf04cc3 100644
--- a/server/resources/META-INF/cloudstack/core/spring-server-core-managers-context.xml
+++ b/server/resources/META-INF/cloudstack/core/spring-server-core-managers-context.xml
@@ -86,12 +86,6 @@
 
     <bean id="securityGroupManagerImpl2" class="com.cloud.network.security.SecurityGroupManagerImpl2" />
 
-    <bean id="premiumSecondaryStorageManagerImpl"
-        class="com.cloud.secstorage.PremiumSecondaryStorageManagerImpl">
-        <property name="secondaryStorageVmAllocators"
-            value="#{secondaryStorageVmAllocatorsRegistry.registered}" />
-    </bean>
-
     <bean id="ipv6AddressManagerImpl" class="com.cloud.network.Ipv6AddressManagerImpl" />
 
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/54f32a8e/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
deleted file mode 100755
index ec2af2a..0000000
--- a/server/src/com/cloud/secstorage/PremiumSecondaryStorageManagerImpl.java
+++ /dev/null
@@ -1,185 +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.secstorage;
-
-import java.util.Date;
-import java.util.List;
-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.api.Command;
-import com.cloud.configuration.Config;
-import com.cloud.host.HostVO;
-import com.cloud.host.Status;
-import com.cloud.host.dao.HostDao;
-import com.cloud.resource.ResourceManager;
-import com.cloud.storage.secondary.SecondaryStorageManagerImpl;
-import com.cloud.storage.secondary.SecondaryStorageVmManager;
-import com.cloud.utils.DateUtil;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.Pair;
-import com.cloud.utils.db.JoinBuilder.JoinType;
-import com.cloud.utils.db.SearchBuilder;
-import com.cloud.utils.db.SearchCriteria;
-import com.cloud.utils.db.SearchCriteria.Op;
-import com.cloud.vm.SecondaryStorageVm;
-import com.cloud.vm.SecondaryStorageVmVO;
-import com.cloud.vm.SystemVmLoadScanner.AfterScanAction;
-import com.cloud.vm.VirtualMachine.State;
-import com.cloud.vm.dao.SecondaryStorageVmDao;
-
-@Local(value = {SecondaryStorageVmManager.class})
-public class PremiumSecondaryStorageManagerImpl extends SecondaryStorageManagerImpl {
-    private static final Logger s_logger = Logger.getLogger(PremiumSecondaryStorageManagerImpl.class);
-
-    private int _capacityPerSSVM = SecondaryStorageVmManager.DEFAULT_SS_VM_CAPACITY;
-    private int _standbyCapacity = SecondaryStorageVmManager.DEFAULT_STANDBY_CAPACITY;
-    private int _maxExecutionTimeMs = 1800000;
-
-    @Inject
-    SecondaryStorageVmDao _secStorageVmDao;
-    @Inject
-    CommandExecLogDao _cmdExecLogDao;
-    @Inject
-    HostDao _hostDao;
-    @Inject
-    ResourceManager _resourceMgr;
-    protected SearchBuilder<CommandExecLogVO> ActiveCommandSearch;
-    protected SearchBuilder<HostVO> HostSearch;
-
-    @Override
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-        super.configure(name, params);
-
-        _capacityPerSSVM = NumbersUtil.parseInt(_configDao.getValue(Config.SecStorageSessionMax.key()), DEFAULT_SS_VM_CAPACITY);
-        _standbyCapacity = NumbersUtil.parseInt(_configDao.getValue(Config.SecStorageCapacityStandby.key()), DEFAULT_STANDBY_CAPACITY);
-
-        int nMaxExecutionMinutes = NumbersUtil.parseInt(_configDao.getValue(Config.SecStorageCmdExecutionTimeMax.key()), 30);
-        _maxExecutionTimeMs = nMaxExecutionMinutes * 60 * 1000;
-
-        HostSearch = _hostDao.createSearchBuilder();
-        HostSearch.and("dc", HostSearch.entity().getDataCenterId(), Op.EQ);
-        HostSearch.and("status", HostSearch.entity().getStatus(), Op.EQ);
-
-        ActiveCommandSearch = _cmdExecLogDao.createSearchBuilder();
-        ActiveCommandSearch.and("created", ActiveCommandSearch.entity().getCreated(), Op.GTEQ);
-        ActiveCommandSearch.join("hostSearch", HostSearch, ActiveCommandSearch.entity().getInstanceId(), HostSearch.entity().getId(), JoinType.INNER);
-
-        HostSearch.done();
-        ActiveCommandSearch.done();
-        return true;
-    }
-
-    @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);
-
-        boolean suspendAutoLoading = !reserveStandbyCapacity();
-        if (!suspendAutoLoading) {
-            // this is a hacking, has nothing to do with console proxy, it is just a flag that primary storage is being under maintenance mode
-            String restart = _configDao.getValue("consoleproxy.restart");
-            if (restart != null && restart.equalsIgnoreCase("false")) {
-                s_logger.debug("Capacity scan disabled purposefully, consoleproxy.restart = false. This happens when the primarystorage is in maintenance mode");
-                suspendAutoLoading = true;
-            }
-        }
-
-        List<SecondaryStorageVmVO> alreadyRunning =
-            _secStorageVmDao.getSecStorageVmListInStates(SecondaryStorageVm.Role.templateProcessor, dataCenterId, State.Running, State.Migrating, State.Starting);
-        if (alreadyRunning.size() == 0) {
-            s_logger.info("No running secondary storage vms found in datacenter id=" + dataCenterId + ", starting one");
-
-            List<SecondaryStorageVmVO> stopped =
-                _secStorageVmDao.getSecStorageVmListInStates(SecondaryStorageVm.Role.templateProcessor, dataCenterId, State.Stopped, State.Stopping);
-            if (stopped.size() == 0 || !suspendAutoLoading) {
-                List<SecondaryStorageVmVO> stopping = _secStorageVmDao.getSecStorageVmListInStates(SecondaryStorageVm.Role.templateProcessor, State.Stopping);
-                if (stopping.size() > 0) {
-                    s_logger.info("Found SSVMs that are currently at stopping state, wait until they are settled");
-                    return new Pair<AfterScanAction, Object>(AfterScanAction.nop, null);
-                }
-
-                expandPool(pool, SecondaryStorageVm.Role.templateProcessor);
-            }
-        }
-
-        if (!suspendAutoLoading) {
-            // this is to avoid surprises that people may accidently see two SSVMs being launched, capacity expanding only happens when we have at least the primary SSVM is up
-            if (alreadyRunning.size() == 0) {
-                s_logger.info("Primary secondary storage is not even started, wait until next turn");
-                return new Pair<AfterScanAction, Object>(AfterScanAction.nop, null);
-            }
-
-            alreadyRunning = _secStorageVmDao.getSecStorageVmListInStates(null, dataCenterId, State.Running, State.Migrating, State.Starting);
-
-            List<CommandExecLogVO> activeCmds = listActiveCommands(dataCenterId, cutTime);
-            if (alreadyRunning.size() * _capacityPerSSVM - activeCmds.size() < _standbyCapacity) {
-                s_logger.info("secondary storage command execution standby capactiy low (running VMs: " + alreadyRunning.size() + ", active cmds: " + activeCmds.size() +
-                    "), starting a new one");
-                return new Pair<AfterScanAction, Object>(AfterScanAction.expand, SecondaryStorageVm.Role.commandExecutor);
-            }
-        }
-
-        return new Pair<AfterScanAction, Object>(AfterScanAction.nop, null);
-    }
-
-    @Override
-    public Pair<HostVO, SecondaryStorageVmVO> assignSecStorageVm(long zoneId, Command cmd) {
-
-        // TODO, need performance optimization
-        List<Long> vms = _secStorageVmDao.listRunningSecStorageOrderByLoad(null, zoneId);
-        for (Long vmId : vms) {
-            SecondaryStorageVmVO secStorageVm = _secStorageVmDao.findById(vmId);
-            HostVO host;
-            host = _resourceMgr.findHostByName(secStorageVm.getHostName());
-            if (host != null && host.getStatus() == Status.Up)
-                return new Pair<HostVO, SecondaryStorageVmVO>(host, secStorageVm);
-        }
-
-        return null;
-    }
-
-    private List<CommandExecLogVO> listActiveCommands(long dcId, Date cutTime) {
-        SearchCriteria<CommandExecLogVO> sc = ActiveCommandSearch.create();
-
-        sc.setParameters("created", cutTime);
-        sc.setJoinParameters("hostSearch", "dc", dcId);
-        sc.setJoinParameters("hostSearch", "status", Status.Up);
-
-        return _cmdExecLogDao.search(sc, null);
-    }
-
-    private boolean reserveStandbyCapacity() {
-        String value = _configDao.getValue(Config.SystemVMAutoReserveCapacity.key());
-        if (value != null && value.equalsIgnoreCase("true")) {
-            return true;
-        }
-
-        return false;
-    }
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/54f32a8e/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
deleted file mode 100755
index 484dfbd..0000000
--- a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java
+++ /dev/null
@@ -1,1386 +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.net.URI;
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.ejb.Local;
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.apache.cloudstack.config.ApiServiceConfiguration;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
-import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.framework.security.keystore.KeystoreManager;
-import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
-import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
-import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
-import org.apache.cloudstack.utils.identity.ManagementServerNode;
-import org.apache.log4j.Logger;
-
-import com.cloud.agent.AgentManager;
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.Command;
-import com.cloud.agent.api.RebootCommand;
-import com.cloud.agent.api.SecStorageFirewallCfgCommand;
-import com.cloud.agent.api.SecStorageSetupAnswer;
-import com.cloud.agent.api.SecStorageSetupCommand;
-import com.cloud.agent.api.SecStorageVMSetupCommand;
-import com.cloud.agent.api.StartupCommand;
-import com.cloud.agent.api.StartupSecondaryStorageCommand;
-import com.cloud.agent.api.check.CheckSshAnswer;
-import com.cloud.agent.api.check.CheckSshCommand;
-import com.cloud.agent.api.to.NfsTO;
-import com.cloud.agent.manager.Commands;
-import com.cloud.capacity.dao.CapacityDao;
-import com.cloud.cluster.ClusterManager;
-import com.cloud.configuration.Config;
-import com.cloud.configuration.ZoneConfig;
-import com.cloud.consoleproxy.ConsoleProxyManager;
-import com.cloud.dc.DataCenter;
-import com.cloud.dc.DataCenter.NetworkType;
-import com.cloud.dc.DataCenterVO;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.deploy.DataCenterDeployment;
-import com.cloud.deploy.DeployDestination;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientCapacityException;
-import com.cloud.exception.ResourceUnavailableException;
-import com.cloud.exception.StorageUnavailableException;
-import com.cloud.host.Host;
-import com.cloud.host.HostVO;
-import com.cloud.host.Status;
-import com.cloud.host.dao.HostDao;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.info.RunningHostCountInfo;
-import com.cloud.info.RunningHostInfoAgregator;
-import com.cloud.info.RunningHostInfoAgregator.ZoneHostInfo;
-import com.cloud.network.Network;
-import com.cloud.network.NetworkModel;
-import com.cloud.network.Networks.TrafficType;
-import com.cloud.network.dao.IPAddressDao;
-import com.cloud.network.dao.IPAddressVO;
-import com.cloud.network.dao.NetworkDao;
-import com.cloud.network.dao.NetworkVO;
-import com.cloud.network.rules.RulesManager;
-import com.cloud.offering.NetworkOffering;
-import com.cloud.offering.ServiceOffering;
-import com.cloud.offerings.dao.NetworkOfferingDao;
-import com.cloud.resource.ResourceManager;
-import com.cloud.resource.ResourceStateAdapter;
-import com.cloud.resource.ServerResource;
-import com.cloud.resource.UnableDeleteHostException;
-import com.cloud.service.ServiceOfferingVO;
-import com.cloud.service.dao.ServiceOfferingDao;
-import com.cloud.storage.UploadVO;
-import com.cloud.storage.VMTemplateVO;
-import com.cloud.storage.dao.SnapshotDao;
-import com.cloud.storage.dao.StoragePoolHostDao;
-import com.cloud.storage.dao.UploadDao;
-import com.cloud.storage.dao.VMTemplateDao;
-import com.cloud.storage.template.TemplateConstants;
-import com.cloud.template.TemplateManager;
-import com.cloud.user.Account;
-import com.cloud.user.AccountService;
-import com.cloud.utils.DateUtil;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.Pair;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.db.GlobalLock;
-import com.cloud.utils.db.QueryBuilder;
-import com.cloud.utils.db.SearchCriteria.Op;
-import com.cloud.utils.events.SubscriptionMgr;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.net.NetUtils;
-import com.cloud.vm.Nic;
-import com.cloud.vm.NicProfile;
-import com.cloud.vm.ReservationContext;
-import com.cloud.vm.SecondaryStorageVm;
-import com.cloud.vm.SecondaryStorageVmVO;
-import com.cloud.vm.SystemVmLoadScanHandler;
-import com.cloud.vm.SystemVmLoadScanner;
-import com.cloud.vm.SystemVmLoadScanner.AfterScanAction;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.VirtualMachine.State;
-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.SecondaryStorageVmDao;
-import com.cloud.vm.dao.UserVmDetailsDao;
-import com.cloud.vm.dao.VMInstanceDao;
-
-//
-// Possible secondary storage vm state transition cases
-//        Creating -> Destroyed
-//        Creating -> Stopped --> Starting -> Running
-//        HA -> Stopped -> Starting -> Running
-//        Migrating -> Running    (if previous state is Running before it enters into Migrating state
-//        Migrating -> Stopped    (if previous state is not Running before it enters into Migrating state)
-//        Running -> HA            (if agent lost connection)
-//        Stopped -> Destroyed
-//
-//        Creating state indicates of record creating and IP address allocation are ready, it is a transient
-//         state which will soon be switching towards Running if everything goes well.
-//        Stopped state indicates the readiness of being able to start (has storage and IP resources allocated)
-//        Starting state can only be entered from Stopped states
-//
-// Starting, HA, Migrating, Creating and Running state are all counted as "Open" for available capacity calculation
-// because sooner or later, it will be driven into Running state
-//
-@Local(value = {SecondaryStorageVmManager.class})
-public class SecondaryStorageManagerImpl extends ManagerBase implements SecondaryStorageVmManager, VirtualMachineGuru, SystemVmLoadScanHandler<Long>,
-        ResourceStateAdapter {
-    private static final Logger s_logger = Logger.getLogger(SecondaryStorageManagerImpl.class);
-
-    private static final int DEFAULT_CAPACITY_SCAN_INTERVAL = 30000; // 30
-    // seconds
-    private static final int ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_SYNC = 180; // 3
-    // minutes
-
-    private static final int STARTUP_DELAY = 60000; // 60 seconds
-
-    private int _mgmtPort = 8250;
-
-    private List<SecondaryStorageVmAllocator> _ssVmAllocators;
-
-    @Inject
-    protected SecondaryStorageVmDao _secStorageVmDao;
-    @Inject
-    private DataCenterDao _dcDao;
-    @Inject
-    private VMTemplateDao _templateDao;
-    @Inject
-    private HostDao _hostDao;
-    @Inject
-    private StoragePoolHostDao _storagePoolHostDao;
-    @Inject
-    private AgentManager _agentMgr;
-    @Inject
-    protected NetworkOrchestrationService _networkMgr;
-    @Inject
-    protected NetworkModel _networkModel;
-    @Inject
-    protected SnapshotDao _snapshotDao;
-    @Inject
-    private ClusterManager _clusterMgr;
-
-    private SecondaryStorageListener _listener;
-
-    private ServiceOfferingVO _serviceOffering;
-
-    @Inject
-    protected ConfigurationDao _configDao;
-    @Inject
-    private ServiceOfferingDao _offeringDao;
-    @Inject
-    private AccountService _accountMgr;
-    @Inject
-    private VirtualMachineManager _itMgr;
-    @Inject
-    protected VMInstanceDao _vmDao;
-    @Inject
-    protected CapacityDao _capacityDao;
-    @Inject
-    UserVmDetailsDao _vmDetailsDao;
-    @Inject
-    protected ResourceManager _resourceMgr;
-    @Inject
-    NetworkDao _networkDao;
-    @Inject
-    NetworkOfferingDao _networkOfferingDao;
-    @Inject
-    protected IPAddressDao _ipAddressDao = null;
-    @Inject
-    protected RulesManager _rulesMgr;
-    @Inject
-    TemplateManager templateMgr;
-    @Inject
-    UploadDao _uploadDao;
-
-    @Inject
-    KeystoreManager _keystoreMgr;
-    @Inject
-    DataStoreManager _dataStoreMgr;
-    @Inject
-    ImageStoreDao _imageStoreDao;
-    @Inject
-    TemplateDataStoreDao _tmplStoreDao;
-    private long _capacityScanInterval = DEFAULT_CAPACITY_SCAN_INTERVAL;
-    private int _secStorageVmMtuSize;
-
-    private String _instance;
-    private boolean _useLocalStorage;
-    private boolean _useSSlCopy;
-    private String _httpProxy;
-    private String _allowedInternalSites;
-    protected long _nodeId = ManagementServerNode.getManagementServerId();
-
-    private SystemVmLoadScanner<Long> _loadScanner;
-    private Map<Long, ZoneHostInfo> _zoneHostInfoMap; // map <zone id, info about running host in zone>
-
-    private final GlobalLock _allocLock = GlobalLock.getInternLock(getAllocLockName());
-
-    public SecondaryStorageManagerImpl() {
-    }
-
-    @Override
-    public SecondaryStorageVmVO startSecStorageVm(long secStorageVmId) {
-        try {
-            SecondaryStorageVmVO secStorageVm = _secStorageVmDao.findById(secStorageVmId);
-            _itMgr.advanceStart(secStorageVm.getUuid(), null, null);
-            return _secStorageVmDao.findById(secStorageVm.getId());
-        } catch (StorageUnavailableException e) {
-            s_logger.warn("Exception while trying to start secondary storage vm", e);
-            return null;
-        } catch (InsufficientCapacityException e) {
-            s_logger.warn("Exception while trying to start secondary storage vm", e);
-            return null;
-        } catch (ResourceUnavailableException e) {
-            s_logger.warn("Exception while trying to start secondary storage vm", e);
-            return null;
-        } catch (Exception e) {
-            s_logger.warn("Exception while trying to start secondary storage vm", e);
-            return null;
-        }
-    }
-
-    SecondaryStorageVmVO getSSVMfromHost(HostVO ssAHost) {
-        if (ssAHost.getType() == Host.Type.SecondaryStorageVM) {
-            return _secStorageVmDao.findByInstanceName(ssAHost.getName());
-        }
-        return null;
-    }
-
-    @Override
-    public boolean generateSetupCommand(Long ssHostId) {
-        HostVO cssHost = _hostDao.findById(ssHostId);
-        Long zoneId = cssHost.getDataCenterId();
-        if (cssHost.getType() == Host.Type.SecondaryStorageVM) {
-
-            SecondaryStorageVmVO secStorageVm = _secStorageVmDao.findByInstanceName(cssHost.getName());
-            if (secStorageVm == null) {
-                s_logger.warn("secondary storage VM " + cssHost.getName() + " doesn't exist");
-                return false;
-            }
-
-            List<DataStore> ssStores = _dataStoreMgr.getImageStoresByScope(new ZoneScope(zoneId));
-            for (DataStore ssStore : ssStores) {
-                if (!(ssStore.getTO() instanceof NfsTO)) {
-                    continue; // only do this for Nfs
-                }
-                String secUrl = ssStore.getUri();
-                SecStorageSetupCommand setupCmd = null;
-                if (!_useSSlCopy) {
-                    setupCmd = new SecStorageSetupCommand(ssStore.getTO(), secUrl, null);
-                } else {
-                    KeystoreManager.Certificates certs = _keystoreMgr.getCertificates(ConsoleProxyManager.CERTIFICATE_NAME);
-                    setupCmd = new SecStorageSetupCommand(ssStore.getTO(), secUrl, certs);
-                }
-
-                Answer answer = _agentMgr.easySend(ssHostId, setupCmd);
-                if (answer != null && answer.getResult()) {
-                    SecStorageSetupAnswer an = (SecStorageSetupAnswer)answer;
-                    if (an.get_dir() != null) {
-                        // update the parent path in image_store table for this image store
-                        ImageStoreVO svo = _imageStoreDao.findById(ssStore.getId());
-                        svo.setParent(an.get_dir());
-                        _imageStoreDao.update(ssStore.getId(), svo);
-                    }
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug("Successfully programmed secondary storage " + ssStore.getName() + " in secondary storage VM " + secStorageVm.getInstanceName());
-                    }
-                } else {
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug("Successfully programmed secondary storage " + ssStore.getName() + " in secondary storage VM " + secStorageVm.getInstanceName());
-                    }
-                    return false;
-                }
-            }
-        }
-        /* After removing SecondaryStorage entries from host table, control should never come here!!
-        else if( cssHost.getType() == Host.Type.SecondaryStorage ) {
-            List<SecondaryStorageVmVO> alreadyRunning = _secStorageVmDao.getSecStorageVmListInStates(SecondaryStorageVm.Role.templateProcessor, zoneId, State.Running);
-            String secUrl = cssHost.getStorageUrl();
-            SecStorageSetupCommand setupCmd = new SecStorageSetupCommand(secUrl, null);
-            for ( SecondaryStorageVmVO ssVm : alreadyRunning ) {
-                HostVO host = _resourceMgr.findHostByName(ssVm.getInstanceName());
-                Answer answer = _agentMgr.easySend(host.getId(), setupCmd);
-                if (answer != null && answer.getResult()) {
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug("Successfully programmed secondary storage " + host.getName() + " in secondary storage VM " + ssVm.getInstanceName());
-                    }
-                } else {
-                    if (s_logger.isDebugEnabled()) {
-                        s_logger.debug("Successfully programmed secondary storage " + host.getName() + " in secondary storage VM " + ssVm.getInstanceName());
-                    }
-                    return false;
-                }
-            }
-        }
-         */
-        return true;
-    }
-
-    @Override
-    public boolean generateVMSetupCommand(Long ssAHostId) {
-        HostVO ssAHost = _hostDao.findById(ssAHostId);
-        if (ssAHost.getType() != Host.Type.SecondaryStorageVM) {
-            return false;
-        }
-        SecondaryStorageVmVO secStorageVm = _secStorageVmDao.findByInstanceName(ssAHost.getName());
-        if (secStorageVm == null) {
-            s_logger.warn("secondary storage VM " + ssAHost.getName() + " doesn't exist");
-            return false;
-        }
-
-        SecStorageVMSetupCommand setupCmd = new SecStorageVMSetupCommand();
-        if (_allowedInternalSites != null) {
-            List<String> allowedCidrs = new ArrayList<String>();
-            String[] cidrs = _allowedInternalSites.split(",");
-            for (String cidr : cidrs) {
-                if (NetUtils.isValidCIDR(cidr) || NetUtils.isValidIp(cidr) || !cidr.startsWith("0.0.0.0")) {
-                    allowedCidrs.add(cidr);
-                }
-            }
-            List<? extends Nic> nics = _networkModel.getNicsForTraffic(secStorageVm.getId(), TrafficType.Management);
-            setupCmd.setAllowedInternalSites(allowedCidrs.toArray(new String[allowedCidrs.size()]));
-        }
-        String copyPasswd = _configDao.getValue("secstorage.copy.password");
-        setupCmd.setCopyPassword(copyPasswd);
-        setupCmd.setCopyUserName(TemplateConstants.DEFAULT_HTTP_AUTH_USER);
-        Answer answer = _agentMgr.easySend(ssAHostId, setupCmd);
-        if (answer != null && answer.getResult()) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Successfully programmed http auth into " + secStorageVm.getHostName());
-            }
-            return true;
-        } else {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("failed to program http auth into secondary storage vm : " + secStorageVm.getHostName());
-            }
-            return false;
-        }
-    }
-
-    @Override
-    public Pair<HostVO, SecondaryStorageVmVO> assignSecStorageVm(long zoneId, Command cmd) {
-        return null;
-    }
-
-    @Override
-    public boolean generateFirewallConfiguration(Long ssAHostId) {
-        if (ssAHostId == null) {
-            return true;
-        }
-        HostVO ssAHost = _hostDao.findById(ssAHostId);
-        SecondaryStorageVmVO thisSecStorageVm = _secStorageVmDao.findByInstanceName(ssAHost.getName());
-
-        if (thisSecStorageVm == null) {
-            s_logger.warn("secondary storage VM " + ssAHost.getName() + " doesn't exist");
-            return false;
-        }
-
-        String copyPort = _useSSlCopy ? "443" : Integer.toString(TemplateConstants.DEFAULT_TMPLT_COPY_PORT);
-        SecStorageFirewallCfgCommand thiscpc = new SecStorageFirewallCfgCommand(true);
-        thiscpc.addPortConfig(thisSecStorageVm.getPublicIpAddress(), copyPort, true, TemplateConstants.DEFAULT_TMPLT_COPY_INTF);
-
-        QueryBuilder<HostVO> sc = QueryBuilder.create(HostVO.class);
-        sc.and(sc.entity().getType(), Op.EQ, Host.Type.SecondaryStorageVM);
-        sc.and(sc.entity().getStatus(), Op.IN, Status.Up, Status.Connecting);
-        List<HostVO> ssvms = sc.list();
-        for (HostVO ssvm : ssvms) {
-            if (ssvm.getId() == ssAHostId) {
-                continue;
-            }
-            Answer answer = _agentMgr.easySend(ssvm.getId(), thiscpc);
-            if (answer != null && answer.getResult()) {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Successfully programmed firewall rules into SSVM " + ssvm.getName());
-                }
-            } else {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("failed to program firewall rules into secondary storage vm : " + ssvm.getName());
-                }
-                return false;
-            }
-        }
-
-        SecStorageFirewallCfgCommand allSSVMIpList = new SecStorageFirewallCfgCommand(false);
-        for (HostVO ssvm : ssvms) {
-            if (ssvm.getId() == ssAHostId) {
-                continue;
-            }
-            allSSVMIpList.addPortConfig(ssvm.getPublicIpAddress(), copyPort, true, TemplateConstants.DEFAULT_TMPLT_COPY_INTF);
-        }
-
-        Answer answer = _agentMgr.easySend(ssAHostId, allSSVMIpList);
-        if (answer != null && answer.getResult()) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Successfully programmed firewall rules into " + thisSecStorageVm.getHostName());
-            }
-        } else {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("failed to program firewall rules into secondary storage vm : " + thisSecStorageVm.getHostName());
-            }
-            return false;
-        }
-
-        return true;
-
-    }
-
-    protected boolean isSecondaryStorageVmRequired(long dcId) {
-        DataCenterVO dc = _dcDao.findById(dcId);
-        _dcDao.loadDetails(dc);
-        String ssvmReq = dc.getDetail(ZoneConfig.EnableSecStorageVm.key());
-        if (ssvmReq != null) {
-            return Boolean.parseBoolean(ssvmReq);
-        }
-        return true;
-    }
-
-    public SecondaryStorageVmVO startNew(long dataCenterId, SecondaryStorageVm.Role role) {
-
-        if (!isSecondaryStorageVmRequired(dataCenterId)) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Secondary storage vm not required in zone " + dataCenterId + " acc. to zone config");
-            }
-            return null;
-        }
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Assign secondary storage vm from a newly started instance for request from data center : " + dataCenterId);
-        }
-
-        Map<String, Object> context = createSecStorageVmInstance(dataCenterId, role);
-
-        long secStorageVmId = (Long)context.get("secStorageVmId");
-        if (secStorageVmId == 0) {
-            if (s_logger.isTraceEnabled()) {
-                s_logger.trace("Creating secondary storage vm instance failed, data center id : " + dataCenterId);
-            }
-
-            return null;
-        }
-
-        SecondaryStorageVmVO secStorageVm = _secStorageVmDao.findById(secStorageVmId);
-        // SecondaryStorageVmVO secStorageVm =
-        // allocSecStorageVmStorage(dataCenterId, secStorageVmId);
-        if (secStorageVm != null) {
-            SubscriptionMgr.getInstance().notifySubscribers(ALERT_SUBJECT, this,
-                new SecStorageVmAlertEventArgs(SecStorageVmAlertEventArgs.SSVM_CREATED, dataCenterId, secStorageVmId, secStorageVm, null));
-            return secStorageVm;
-        } else {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Unable to allocate secondary storage vm storage, remove the secondary storage vm record from DB, secondary storage vm id: " +
-                    secStorageVmId);
-            }
-
-            SubscriptionMgr.getInstance().notifySubscribers(ALERT_SUBJECT, this,
-                new SecStorageVmAlertEventArgs(SecStorageVmAlertEventArgs.SSVM_CREATE_FAILURE, dataCenterId, secStorageVmId, null, "Unable to allocate storage"));
-        }
-        return null;
-    }
-
-    protected Map<String, Object> createSecStorageVmInstance(long dataCenterId, SecondaryStorageVm.Role role) {
-        DataStore secStore = _dataStoreMgr.getImageStore(dataCenterId);
-        if (secStore == null) {
-            String msg = "No secondary storage available in zone " + dataCenterId + ", cannot create secondary storage vm";
-            s_logger.warn(msg);
-            throw new CloudRuntimeException(msg);
-        }
-
-        long id = _secStorageVmDao.getNextInSequence(Long.class, "id");
-        String name = VirtualMachineName.getSystemVmName(id, _instance, "s").intern();
-        Account systemAcct = _accountMgr.getSystemAccount();
-
-        DataCenterDeployment plan = new DataCenterDeployment(dataCenterId);
-        DataCenter dc = _dcDao.findById(plan.getDataCenterId());
-
-        NetworkVO defaultNetwork = null;
-        if (dc.getNetworkType() == NetworkType.Advanced && dc.isSecurityGroupEnabled()) {
-            List<NetworkVO> networks = _networkDao.listByZoneSecurityGroup(dataCenterId);
-            if (networks == null || networks.size() == 0) {
-                throw new CloudRuntimeException("Can not found security enabled network in SG Zone " + dc);
-            }
-            defaultNetwork = networks.get(0);
-        } else {
-            TrafficType defaultTrafficType = TrafficType.Public;
-
-            if (dc.getNetworkType() == NetworkType.Basic || dc.isSecurityGroupEnabled()) {
-                defaultTrafficType = TrafficType.Guest;
-            }
-            List<NetworkVO> defaultNetworks = _networkDao.listByZoneAndTrafficType(dataCenterId, defaultTrafficType);
-            // api should never allow this situation to happen
-            if (defaultNetworks.size() != 1) {
-                throw new CloudRuntimeException("Found " + defaultNetworks.size() + " networks of type " + defaultTrafficType + " when expect to find 1");
-            }
-            defaultNetwork = defaultNetworks.get(0);
-        }
-
-        List<? extends NetworkOffering> offerings =
-            _networkModel.getSystemAccountNetworkOfferings(NetworkOffering.SystemControlNetwork, NetworkOffering.SystemManagementNetwork,
-                NetworkOffering.SystemStorageNetwork);
-        LinkedHashMap<Network, NicProfile> networks = new LinkedHashMap<Network, NicProfile>(offerings.size() + 1);
-        NicProfile defaultNic = new NicProfile();
-        defaultNic.setDefaultNic(true);
-        defaultNic.setDeviceId(2);
-        try {
-            networks.put(_networkMgr.setupNetwork(systemAcct, _networkOfferingDao.findById(defaultNetwork.getNetworkOfferingId()), plan, null, null, false).get(0),
-                defaultNic);
-            for (NetworkOffering offering : offerings) {
-                networks.put(_networkMgr.setupNetwork(systemAcct, offering, plan, null, null, false).get(0), null);
-            }
-        } catch (ConcurrentOperationException e) {
-            s_logger.info("Unable to setup due to concurrent operation. " + e);
-            return new HashMap<String, Object>();
-        }
-
-        VMTemplateVO template = null;
-        HypervisorType availableHypervisor = _resourceMgr.getAvailableHypervisor(dataCenterId);
-        template = _templateDao.findSystemVMReadyTemplate(dataCenterId, availableHypervisor);
-        if (template == null) {
-            throw new CloudRuntimeException("Not able to find the System templates or not downloaded in zone " + dataCenterId);
-        }
-
-        SecondaryStorageVmVO secStorageVm =
-            new SecondaryStorageVmVO(id, _serviceOffering.getId(), name, template.getId(), template.getHypervisorType(), template.getGuestOSId(), dataCenterId,
-                systemAcct.getDomainId(), systemAcct.getId(), role, _serviceOffering.getOfferHA());
-        secStorageVm.setDynamicallyScalable(template.isDynamicallyScalable());
-        secStorageVm = _secStorageVmDao.persist(secStorageVm);
-        try {
-            _itMgr.allocate(name, template, _serviceOffering, networks, plan, null);
-            secStorageVm = _secStorageVmDao.findById(secStorageVm.getId());
-        } catch (InsufficientCapacityException e) {
-            s_logger.warn("InsufficientCapacity", e);
-            throw new CloudRuntimeException("Insufficient capacity exception", e);
-        }
-
-        Map<String, Object> context = new HashMap<String, Object>();
-        context.put("secStorageVmId", secStorageVm.getId());
-        return context;
-    }
-
-    private SecondaryStorageVmAllocator getCurrentAllocator() {
-
-        // for now, only one adapter is supported
-        if (_ssVmAllocators.size() > 0) {
-            return _ssVmAllocators.get(0);
-        }
-
-        return null;
-    }
-
-    protected String connect(String ipAddress, int port) {
-        return null;
-    }
-
-    public SecondaryStorageVmVO assignSecStorageVmFromRunningPool(long dataCenterId, SecondaryStorageVm.Role role) {
-
-        if (s_logger.isTraceEnabled()) {
-            s_logger.trace("Assign  secondary storage vm from running pool for request from data center : " + dataCenterId);
-        }
-
-        SecondaryStorageVmAllocator allocator = getCurrentAllocator();
-        assert (allocator != null);
-        List<SecondaryStorageVmVO> runningList = _secStorageVmDao.getSecStorageVmListInStates(role, dataCenterId, State.Running);
-        if (runningList != null && runningList.size() > 0) {
-            if (s_logger.isTraceEnabled()) {
-                s_logger.trace("Running secondary storage vm pool size : " + runningList.size());
-                for (SecondaryStorageVmVO secStorageVm : runningList) {
-                    s_logger.trace("Running secStorageVm instance : " + secStorageVm.getHostName());
-                }
-            }
-
-            Map<Long, Integer> loadInfo = new HashMap<Long, Integer>();
-
-            return allocator.allocSecondaryStorageVm(runningList, loadInfo, dataCenterId);
-        } else {
-            if (s_logger.isTraceEnabled()) {
-                s_logger.trace("Empty running secStorageVm pool for now in data center : " + dataCenterId);
-            }
-        }
-        return null;
-    }
-
-    public SecondaryStorageVmVO assignSecStorageVmFromStoppedPool(long dataCenterId, SecondaryStorageVm.Role role) {
-        List<SecondaryStorageVmVO> l = _secStorageVmDao.getSecStorageVmListInStates(role, dataCenterId, State.Starting, State.Stopped, State.Migrating);
-        if (l != null && l.size() > 0) {
-            return l.get(0);
-        }
-
-        return null;
-    }
-
-    private void allocCapacity(long dataCenterId, SecondaryStorageVm.Role role) {
-        if (s_logger.isTraceEnabled()) {
-            s_logger.trace("Allocate secondary storage vm standby capacity for data center : " + dataCenterId);
-        }
-
-        if (!isSecondaryStorageVmRequired(dataCenterId)) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Secondary storage vm not required in zone " + dataCenterId + " acc. to zone config");
-            }
-            return;
-        }
-
-        boolean secStorageVmFromStoppedPool = false;
-        SecondaryStorageVmVO secStorageVm = assignSecStorageVmFromStoppedPool(dataCenterId, role);
-        if (secStorageVm == null) {
-            if (s_logger.isInfoEnabled()) {
-                s_logger.info("No stopped secondary storage vm is available, need to allocate a new secondary storage vm");
-            }
-
-            if (_allocLock.lock(ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_SYNC)) {
-                try {
-                    secStorageVm = startNew(dataCenterId, role);
-                    for (UploadVO upload : _uploadDao.listAll()) {
-                        _uploadDao.expunge(upload.getId());
-                    }
-                } finally {
-                    _allocLock.unlock();
-                }
-            } else {
-                if (s_logger.isInfoEnabled()) {
-                    s_logger.info("Unable to acquire synchronization lock to allocate secStorageVm resource for standby capacity, wait for next scan");
-                }
-                return;
-            }
-        } else {
-            if (s_logger.isInfoEnabled()) {
-                s_logger.info("Found a stopped secondary storage vm, bring it up to running pool. secStorageVm vm id : " + secStorageVm.getId());
-            }
-            secStorageVmFromStoppedPool = true;
-        }
-
-        if (secStorageVm != null) {
-            long secStorageVmId = secStorageVm.getId();
-            GlobalLock secStorageVmLock = GlobalLock.getInternLock(getSecStorageVmLockName(secStorageVmId));
-            try {
-                if (secStorageVmLock.lock(ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_SYNC)) {
-                    try {
-                        secStorageVm = startSecStorageVm(secStorageVmId);
-                    } finally {
-                        secStorageVmLock.unlock();
-                    }
-                } else {
-                    if (s_logger.isInfoEnabled()) {
-                        s_logger.info("Unable to acquire synchronization lock to start secStorageVm for standby capacity, secStorageVm vm id : " + secStorageVm.getId());
-                    }
-                    return;
-                }
-            } finally {
-                secStorageVmLock.releaseRef();
-            }
-
-            if (secStorageVm == null) {
-                if (s_logger.isInfoEnabled()) {
-                    s_logger.info("Unable to start secondary storage vm for standby capacity, secStorageVm vm Id : " + secStorageVmId +
-                        ", will recycle it and start a new one");
-                }
-
-                if (secStorageVmFromStoppedPool) {
-                    destroySecStorageVm(secStorageVmId);
-                }
-            } else {
-                if (s_logger.isInfoEnabled()) {
-                    s_logger.info("Secondary storage vm " + secStorageVm.getHostName() + " is started");
-                }
-            }
-        }
-    }
-
-    public boolean isZoneReady(Map<Long, ZoneHostInfo> zoneHostInfoMap, long dataCenterId) {
-        ZoneHostInfo zoneHostInfo = zoneHostInfoMap.get(dataCenterId);
-        if (zoneHostInfo != null && (zoneHostInfo.getFlags() & RunningHostInfoAgregator.ZoneHostInfo.ROUTING_HOST_MASK) != 0) {
-            VMTemplateVO template = _templateDao.findSystemVMReadyTemplate(dataCenterId, HypervisorType.Any);
-            if (template == null) {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("System vm template is not ready at data center " + dataCenterId + ", wait until it is ready to launch secondary storage vm");
-                }
-                return false;
-            }
-
-            List<DataStore> stores = _dataStoreMgr.getImageStoresByScope(new ZoneScope(dataCenterId));
-            if (stores.size() < 1) {
-                s_logger.debug("No image store added  in zone " + dataCenterId + ", wait until it is ready to launch secondary storage vm");
-                return false;
-            }
-
-            DataStore store = templateMgr.getImageStore(dataCenterId, template.getId());
-            if (store == null) {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("No secondary storage available in zone " + dataCenterId + ", wait until it is ready to launch secondary storage vm");
-                }
-                return false;
-            }
-
-            List<Pair<Long, Integer>> l = _storagePoolHostDao.getDatacenterStoragePoolHostInfo(dataCenterId, !_useLocalStorage);
-            if (l != null && l.size() > 0 && l.get(0).second().intValue() > 0) {
-                return true;
-            } else {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Primary storage is not ready, wait until it is ready to launch secondary storage vm. dcId: " + dataCenterId +
-                        " system.vm.use.local.storage: " + _useLocalStorage +
-                        "If you want to use local storage to start ssvm, need to set system.vm.use.local.storage to true");
-                }
-            }
-
-        }
-        return false;
-    }
-
-    private synchronized Map<Long, ZoneHostInfo> getZoneHostInfo() {
-        Date cutTime = DateUtil.currentGMTTime();
-        List<RunningHostCountInfo> l = _hostDao.getRunningHostCounts(new Date(cutTime.getTime() - ClusterManager.HeartbeatThreshold.value()));
-
-        RunningHostInfoAgregator aggregator = new RunningHostInfoAgregator();
-        if (l.size() > 0) {
-            for (RunningHostCountInfo countInfo : l) {
-                aggregator.aggregate(countInfo);
-            }
-        }
-
-        return aggregator.getZoneHostInfoMap();
-    }
-
-    @Override
-    public boolean start() {
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Start secondary storage vm manager");
-        }
-
-        return true;
-    }
-
-    @Override
-    public boolean stop() {
-        _loadScanner.stop();
-        _allocLock.releaseRef();
-        _resourceMgr.unregisterResourceStateAdapter(this.getClass().getSimpleName());
-        return true;
-    }
-
-    @Override
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Start configuring secondary storage vm manager : " + name);
-        }
-
-        Map<String, String> configs = _configDao.getConfiguration("management-server", params);
-
-        _secStorageVmMtuSize = NumbersUtil.parseInt(configs.get("secstorage.vm.mtu.size"), DEFAULT_SS_VM_MTUSIZE);
-        String useServiceVM = _configDao.getValue("secondary.storage.vm");
-        boolean _useServiceVM = false;
-        if ("true".equalsIgnoreCase(useServiceVM)) {
-            _useServiceVM = true;
-        }
-
-        String sslcopy = _configDao.getValue("secstorage.encrypt.copy");
-        if ("true".equalsIgnoreCase(sslcopy)) {
-            _useSSlCopy = true;
-        }
-
-        _allowedInternalSites = _configDao.getValue("secstorage.allowed.internal.sites");
-
-        String value = configs.get("secstorage.capacityscan.interval");
-        _capacityScanInterval = NumbersUtil.parseLong(value, DEFAULT_CAPACITY_SCAN_INTERVAL);
-
-        _instance = configs.get("instance.name");
-        if (_instance == null) {
-            _instance = "DEFAULT";
-        }
-
-        Map<String, String> agentMgrConfigs = _configDao.getConfiguration("AgentManager", params);
-
-        value = agentMgrConfigs.get("port");
-        _mgmtPort = NumbersUtil.parseInt(value, 8250);
-
-        _listener = new SecondaryStorageListener(this);
-        _agentMgr.registerForHostEvents(_listener, true, false, true);
-
-        _itMgr.registerGuru(VirtualMachine.Type.SecondaryStorageVm, this);
-
-        //check if there is a default service offering configured
-        String ssvmSrvcOffIdStr = configs.get(Config.SecondaryStorageServiceOffering.key());
-        if (ssvmSrvcOffIdStr != null) {
-            Long ssvmSrvcOffId = Long.parseLong(ssvmSrvcOffIdStr);
-            _serviceOffering = _offeringDao.findById(ssvmSrvcOffId);
-            if (_serviceOffering == null || !_serviceOffering.getSystemUse()) {
-                String msg = "Can't find system service offering id=" + ssvmSrvcOffId + " for secondary storage vm";
-                s_logger.error(msg);
-                throw new ConfigurationException(msg);
-            }
-        } else {
-            int ramSize = NumbersUtil.parseInt(_configDao.getValue("ssvm.ram.size"), DEFAULT_SS_VM_RAMSIZE);
-            int cpuFreq = NumbersUtil.parseInt(_configDao.getValue("ssvm.cpu.mhz"), DEFAULT_SS_VM_CPUMHZ);
-            _useLocalStorage = Boolean.parseBoolean(configs.get(Config.SystemVMUseLocalStorage.key()));
-            _serviceOffering =
-                new ServiceOfferingVO("System Offering For Secondary Storage VM", 1, ramSize, cpuFreq, null, null, false, null, _useLocalStorage, true, null, true,
-                    VirtualMachine.Type.SecondaryStorageVm, true);
-            _serviceOffering.setUniqueName(ServiceOffering.ssvmDefaultOffUniqueName);
-            _serviceOffering = _offeringDao.persistSystemServiceOffering(_serviceOffering);
-
-            // this can sometimes happen, if DB is manually or programmatically manipulated
-            if (_serviceOffering == null) {
-                String msg = "Data integrity problem : System Offering For Secondary Storage VM has been removed?";
-                s_logger.error(msg);
-                throw new ConfigurationException(msg);
-            }
-        }
-
-        if (_useServiceVM) {
-            _loadScanner = new SystemVmLoadScanner<Long>(this);
-            _loadScanner.initScan(STARTUP_DELAY, _capacityScanInterval);
-        }
-
-        _httpProxy = configs.get(Config.SecStorageProxy.key());
-        if (_httpProxy != null) {
-            boolean valid = true;
-            String errMsg = null;
-            try {
-                URI uri = new URI(_httpProxy);
-                if (!"http".equalsIgnoreCase(uri.getScheme())) {
-                    errMsg = "Only support http proxy";
-                    valid = false;
-                } else if (uri.getHost() == null) {
-                    errMsg = "host can not be null";
-                    valid = false;
-                } else if (uri.getPort() == -1) {
-                    _httpProxy = _httpProxy + ":3128";
-                }
-            } catch (URISyntaxException e) {
-                errMsg = e.toString();
-            } finally {
-                if (!valid) {
-                    s_logger.debug("ssvm http proxy " + _httpProxy + " is invalid: " + errMsg);
-                    throw new ConfigurationException("ssvm http proxy " + _httpProxy + "is invalid: " + errMsg);
-                }
-            }
-        }
-        if (s_logger.isInfoEnabled()) {
-            s_logger.info("Secondary storage vm Manager is configured.");
-        }
-        _resourceMgr.registerResourceStateAdapter(this.getClass().getSimpleName(), this);
-        return true;
-    }
-
-    @Override
-    public boolean stopSecStorageVm(long secStorageVmId) {
-        SecondaryStorageVmVO secStorageVm = _secStorageVmDao.findById(secStorageVmId);
-        if (secStorageVm == null) {
-            String msg = "Stopping secondary storage vm failed: secondary storage vm " + secStorageVmId + " no longer exists";
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug(msg);
-            }
-            return false;
-        }
-        try {
-            if (secStorageVm.getHostId() != null) {
-                GlobalLock secStorageVmLock = GlobalLock.getInternLock(getSecStorageVmLockName(secStorageVm.getId()));
-                try {
-                    if (secStorageVmLock.lock(ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_SYNC)) {
-                        try {
-                            _itMgr.stop(secStorageVm.getUuid());
-                            return true;
-                        } finally {
-                            secStorageVmLock.unlock();
-                        }
-                    } else {
-                        String msg = "Unable to acquire secondary storage vm lock : " + secStorageVm.toString();
-                        s_logger.debug(msg);
-                        return false;
-                    }
-                } finally {
-                    secStorageVmLock.releaseRef();
-                }
-            }
-
-            // vm was already stopped, return true
-            return true;
-        } catch (ResourceUnavailableException e) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Stopping secondary storage vm " + secStorageVm.getHostName() + " faled : exception " + e.toString());
-            }
-            return false;
-        }
-    }
-
-    @Override
-    public boolean rebootSecStorageVm(long secStorageVmId) {
-        final SecondaryStorageVmVO secStorageVm = _secStorageVmDao.findById(secStorageVmId);
-
-        if (secStorageVm == null || secStorageVm.getState() == State.Destroyed) {
-            return false;
-        }
-
-        if (secStorageVm.getState() == State.Running && secStorageVm.getHostId() != null) {
-            final RebootCommand cmd = new RebootCommand(secStorageVm.getInstanceName());
-            final Answer answer = _agentMgr.easySend(secStorageVm.getHostId(), cmd);
-
-            if (answer != null && answer.getResult()) {
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug("Successfully reboot secondary storage vm " + secStorageVm.getHostName());
-                }
-
-                SubscriptionMgr.getInstance().notifySubscribers(ALERT_SUBJECT, this,
-                    new SecStorageVmAlertEventArgs(SecStorageVmAlertEventArgs.SSVM_REBOOTED, secStorageVm.getDataCenterId(), secStorageVm.getId(), secStorageVm, null));
-
-                return true;
-            } else {
-                String msg = "Rebooting Secondary Storage VM failed - " + secStorageVm.getHostName();
-                if (s_logger.isDebugEnabled()) {
-                    s_logger.debug(msg);
-                }
-                return false;
-            }
-        } else {
-            return startSecStorageVm(secStorageVmId) != null;
-        }
-    }
-
-    @Override
-    public boolean destroySecStorageVm(long vmId) {
-        SecondaryStorageVmVO ssvm = _secStorageVmDao.findById(vmId);
-
-        try {
-            _itMgr.expunge(ssvm.getUuid());
-            _secStorageVmDao.remove(ssvm.getId());
-            HostVO host = _hostDao.findByTypeNameAndZoneId(ssvm.getDataCenterId(), ssvm.getHostName(), Host.Type.SecondaryStorageVM);
-            if (host != null) {
-                s_logger.debug("Removing host entry for ssvm id=" + vmId);
-                _hostDao.remove(host.getId());
-            }
-
-            return true;
-        } catch (ResourceUnavailableException e) {
-            s_logger.warn("Unable to expunge " + ssvm, e);
-            return false;
-        }
-    }
-
-    @Override
-    public void onAgentConnect(Long dcId, StartupCommand cmd) {
-    }
-
-    private String getAllocLockName() {
-        // to improve security, it may be better to return a unique mashed
-        // name(for example MD5 hashed)
-        return "secStorageVm.alloc";
-    }
-
-    private String getSecStorageVmLockName(long id) {
-        return "secStorageVm." + id;
-    }
-
-    @Override
-    public boolean finalizeVirtualMachineProfile(VirtualMachineProfile profile, DeployDestination dest, ReservationContext context) {
-
-        SecondaryStorageVmVO vm = _secStorageVmDao.findById(profile.getId());
-        Map<String, String> details = _vmDetailsDao.listDetailsKeyPairs(vm.getId());
-        vm.setDetails(details);
-
-        DataStore secStore = _dataStoreMgr.getImageStore(dest.getDataCenter().getId());
-        assert (secStore != null);
-
-        StringBuilder buf = profile.getBootArgsBuilder();
-        buf.append(" template=domP type=secstorage");
-        buf.append(" host=").append(ApiServiceConfiguration.ManagementHostIPAdr.value());
-        buf.append(" port=").append(_mgmtPort);
-        buf.append(" name=").append(profile.getVirtualMachine().getHostName());
-
-        buf.append(" zone=").append(dest.getDataCenter().getId());
-        buf.append(" pod=").append(dest.getPod().getId());
-
-        buf.append(" guid=").append(profile.getVirtualMachine().getHostName());
-
-        if (_configDao.isPremium()) {
-            s_logger.debug("VmWare hypervisor configured, telling the ssvm to load the PremiumSecondaryStorageResource");
-            buf.append(" resource=com.cloud.storage.resource.PremiumSecondaryStorageResource");
-        } else {
-            buf.append(" resource=org.apache.cloudstack.storage.resource.NfsSecondaryStorageResource");
-        }
-        buf.append(" instance=SecStorage");
-        buf.append(" sslcopy=").append(Boolean.toString(_useSSlCopy));
-        buf.append(" role=").append(vm.getRole().toString());
-        buf.append(" mtu=").append(_secStorageVmMtuSize);
-
-        boolean externalDhcp = false;
-        String externalDhcpStr = _configDao.getValue("direct.attach.network.externalIpAllocator.enabled");
-        if (externalDhcpStr != null && externalDhcpStr.equalsIgnoreCase("true")) {
-            externalDhcp = true;
-        }
-
-        if (Boolean.valueOf(_configDao.getValue("system.vm.random.password"))) {
-            buf.append(" vmpassword=").append(_configDao.getValue("system.vm.password"));
-        }
-
-        for (NicProfile nic : profile.getNics()) {
-            int deviceId = nic.getDeviceId();
-            if (nic.getIp4Address() == null) {
-                buf.append(" eth").append(deviceId).append("mask=").append("0.0.0.0");
-                buf.append(" eth").append(deviceId).append("ip=").append("0.0.0.0");
-            } else {
-                buf.append(" eth").append(deviceId).append("ip=").append(nic.getIp4Address());
-                buf.append(" eth").append(deviceId).append("mask=").append(nic.getNetmask());
-            }
-
-            if (nic.isDefaultNic()) {
-                buf.append(" gateway=").append(nic.getGateway());
-            }
-            if (nic.getTrafficType() == TrafficType.Management) {
-                String mgmt_cidr = _configDao.getValue(Config.ManagementNetwork.key());
-                if (NetUtils.isValidCIDR(mgmt_cidr)) {
-                    buf.append(" mgmtcidr=").append(mgmt_cidr);
-                }
-                buf.append(" localgw=").append(dest.getPod().getGateway());
-                buf.append(" private.network.device=").append("eth").append(deviceId);
-            } else if (nic.getTrafficType() == TrafficType.Public) {
-                buf.append(" public.network.device=").append("eth").append(deviceId);
-            } else if (nic.getTrafficType() == TrafficType.Storage) {
-                buf.append(" storageip=").append(nic.getIp4Address());
-                buf.append(" storagenetmask=").append(nic.getNetmask());
-                buf.append(" storagegateway=").append(nic.getGateway());
-            }
-        }
-
-        /* External DHCP mode */
-        if (externalDhcp) {
-            buf.append(" bootproto=dhcp");
-        }
-
-        DataCenterVO dc = _dcDao.findById(profile.getVirtualMachine().getDataCenterId());
-        buf.append(" internaldns1=").append(dc.getInternalDns1());
-        if (dc.getInternalDns2() != null) {
-            buf.append(" internaldns2=").append(dc.getInternalDns2());
-        }
-        buf.append(" dns1=").append(dc.getDns1());
-        if (dc.getDns2() != null) {
-            buf.append(" dns2=").append(dc.getDns2());
-        }
-
-        String bootArgs = buf.toString();
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Boot Args for " + profile + ": " + bootArgs);
-        }
-
-        return true;
-    }
-
-    @Override
-    public boolean finalizeDeployment(Commands cmds, VirtualMachineProfile profile, DeployDestination dest, ReservationContext context) {
-
-        finalizeCommandsOnStart(cmds, profile);
-
-        SecondaryStorageVmVO secVm = _secStorageVmDao.findById(profile.getId());
-        DataCenter dc = dest.getDataCenter();
-        List<NicProfile> nics = profile.getNics();
-        for (NicProfile nic : nics) {
-            if ((nic.getTrafficType() == TrafficType.Public && dc.getNetworkType() == NetworkType.Advanced) ||
-                (nic.getTrafficType() == TrafficType.Guest && (dc.getNetworkType() == NetworkType.Basic || dc.isSecurityGroupEnabled()))) {
-                secVm.setPublicIpAddress(nic.getIp4Address());
-                secVm.setPublicNetmask(nic.getNetmask());
-                secVm.setPublicMacAddress(nic.getMacAddress());
-            } else if (nic.getTrafficType() == TrafficType.Management) {
-                secVm.setPrivateIpAddress(nic.getIp4Address());
-                secVm.setPrivateMacAddress(nic.getMacAddress());
-            }
-        }
-        _secStorageVmDao.update(secVm.getId(), secVm);
-        return true;
-    }
-
-    @Override
-    public boolean finalizeCommandsOnStart(Commands cmds, VirtualMachineProfile profile) {
-
-        NicProfile managementNic = null;
-        NicProfile controlNic = null;
-        for (NicProfile nic : profile.getNics()) {
-            if (nic.getTrafficType() == TrafficType.Management) {
-                managementNic = nic;
-            } else if (nic.getTrafficType() == TrafficType.Control && nic.getIp4Address() != null) {
-                controlNic = nic;
-            }
-        }
-
-        if (controlNic == null) {
-            if (managementNic == null) {
-                s_logger.error("Management network doesn't exist for the secondaryStorageVm " + profile.getVirtualMachine());
-                return false;
-            }
-            controlNic = managementNic;
-        }
-
-        // verify ssh access on management nic for system vm running on HyperV
-        if(profile.getHypervisorType() == HypervisorType.Hyperv) {
-            controlNic = managementNic;
-        }
-
-        CheckSshCommand check = new CheckSshCommand(profile.getInstanceName(), controlNic.getIp4Address(), 3922);
-        cmds.addCommand("checkSsh", check);
-
-        return true;
-    }
-
-    @Override
-    public boolean finalizeStart(VirtualMachineProfile profile, long hostId, Commands cmds, ReservationContext context) {
-        CheckSshAnswer answer = (CheckSshAnswer)cmds.getAnswer("checkSsh");
-        if (!answer.getResult()) {
-            s_logger.warn("Unable to ssh to the VM: " + answer.getDetails());
-            return false;
-        }
-
-        try {
-            //get system ip and create static nat rule for the vm in case of basic networking with EIP/ELB
-            _rulesMgr.getSystemIpAndEnableStaticNatForVm(profile.getVirtualMachine(), false);
-            IPAddressVO ipaddr = _ipAddressDao.findByAssociatedVmId(profile.getVirtualMachine().getId());
-            if (ipaddr != null && ipaddr.getSystem()) {
-                SecondaryStorageVmVO secVm = _secStorageVmDao.findById(profile.getId());
-                // override SSVM guest IP with EIP, so that download url's with be prepared with EIP
-                secVm.setPublicIpAddress(ipaddr.getAddress().addr());
-                _secStorageVmDao.update(secVm.getId(), secVm);
-            }
-        } catch (Exception ex) {
-            s_logger.warn("Failed to get system ip and enable static nat for the vm " + profile.getVirtualMachine() + " due to exception ", ex);
-            return false;
-        }
-
-        return true;
-    }
-
-    @Override
-    public void finalizeStop(VirtualMachineProfile profile, Answer answer) {
-        //release elastic IP here
-        IPAddressVO ip = _ipAddressDao.findByAssociatedVmId(profile.getId());
-        if (ip != null && ip.getSystem()) {
-            CallContext ctx = CallContext.current();
-            try {
-                _rulesMgr.disableStaticNat(ip.getId(), ctx.getCallingAccount(), ctx.getCallingUserId(), true);
-            } catch (Exception ex) {
-                s_logger.warn("Failed to disable static nat and release system ip " + ip + " as a part of vm " + profile.getVirtualMachine() + " stop due to exception ",
-                    ex);
-            }
-        }
-    }
-
-    @Override
-    public void finalizeExpunge(VirtualMachine vm) {
-        SecondaryStorageVmVO ssvm = _secStorageVmDao.findByUuid(vm.getUuid());
-
-        ssvm.setPublicIpAddress(null);
-        ssvm.setPublicMacAddress(null);
-        ssvm.setPublicNetmask(null);
-        _secStorageVmDao.update(ssvm.getId(), ssvm);
-    }
-
-    @Override
-    public String getScanHandlerName() {
-        return "secstorage";
-    }
-
-    @Override
-    public boolean canScan() {
-        return true;
-    }
-
-    @Override
-    public void onScanStart() {
-        _zoneHostInfoMap = getZoneHostInfo();
-    }
-
-    @Override
-    public Long[] getScannablePools() {
-        List<DataCenterVO> zones = _dcDao.listEnabledZones();
-
-        Long[] dcIdList = new Long[zones.size()];
-        int i = 0;
-        for (DataCenterVO dc : zones) {
-            dcIdList[i++] = dc.getId();
-        }
-
-        return dcIdList;
-    }
-
-    @Override
-    public boolean isPoolReadyForScan(Long pool) {
-        // pool is at zone basis
-        long dataCenterId = pool.longValue();
-
-        if (!isZoneReady(_zoneHostInfoMap, dataCenterId)) {
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Zone " + dataCenterId + " is not ready to launch secondary storage VM yet");
-            }
-            return false;
-        }
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Zone " + dataCenterId + " is ready to launch secondary storage VM");
-        }
-        return true;
-    }
-
-    @Override
-    public Pair<AfterScanAction, Object> scanPool(Long pool) {
-        long dataCenterId = pool.longValue();
-
-        List<SecondaryStorageVmVO> ssVms =
-            _secStorageVmDao.getSecStorageVmListInStates(SecondaryStorageVm.Role.templateProcessor, dataCenterId, State.Running, State.Migrating, State.Starting,
-                State.Stopped, State.Stopping);
-        int vmSize = (ssVms == null) ? 0 : ssVms.size();
-        List<DataStore> ssStores = _dataStoreMgr.getImageStoresByScope(new ZoneScope(dataCenterId));
-        int storeSize = (ssStores == null) ? 0 : ssStores.size();
-        if (storeSize > vmSize) {
-            s_logger.info("No secondary storage vms found in datacenter id=" + dataCenterId + ", starting a new one");
-            return new Pair<AfterScanAction, Object>(AfterScanAction.expand, SecondaryStorageVm.Role.templateProcessor);
-        }
-
-        return new Pair<AfterScanAction, Object>(AfterScanAction.nop, SecondaryStorageVm.Role.templateProcessor);
-    }
-
-    @Override
-    public void expandPool(Long pool, Object actionArgs) {
-        long dataCenterId = pool.longValue();
-        allocCapacity(dataCenterId, (SecondaryStorageVm.Role)actionArgs);
-    }
-
-    @Override
-    public void shrinkPool(Long pool, Object actionArgs) {
-    }
-
-    @Override
-    public void onScanEnd() {
-    }
-
-    @Override
-    public HostVO createHostVOForConnectedAgent(HostVO host, StartupCommand[] cmd) {
-        /* Called when Secondary Storage VM connected */
-        StartupCommand firstCmd = cmd[0];
-        if (!(firstCmd instanceof StartupSecondaryStorageCommand)) {
-            return null;
-        }
-
-        host.setType(com.cloud.host.Host.Type.SecondaryStorageVM);
-        return host;
-    }
-
-    @Override
-    public HostVO createHostVOForDirectConnectAgent(HostVO host, StartupCommand[] startup, ServerResource resource, Map<String, String> details, List<String> hostTags) {
-        // Used to be Called when add secondary storage on UI through DummySecondaryStorageResource to update that host entry for Secondary Storage.
-        // Now since we move secondary storage from host table, this code is not needed to be invoked anymore.
-        /*
-        StartupCommand firstCmd = startup[0];
-        if (!(firstCmd instanceof StartupStorageCommand)) {
-            return null;
-        }
-
-        com.cloud.host.Host.Type type = null;
-        StartupStorageCommand ssCmd = ((StartupStorageCommand) firstCmd);
-        if (ssCmd.getHostType() == Host.Type.SecondaryStorageCmdExecutor) {
-            type = ssCmd.getHostType();
-        } else {
-            if (ssCmd.getResourceType() == Storage.StorageResourceType.SECONDARY_STORAGE) {
-                type = Host.Type.SecondaryStorage;
-                if (resource != null && resource instanceof DummySecondaryStorageResource) {
-                    host.setResource(null);
-                }
-            } else if (ssCmd.getResourceType() == Storage.StorageResourceType.LOCAL_SECONDARY_STORAGE) {
-                type = Host.Type.LocalSecondaryStorage;
-            } else {
-                type = Host.Type.Storage;
-            }
-
-            final Map<String, String> hostDetails = ssCmd.getHostDetails();
-            if (hostDetails != null) {
-                if (details != null) {
-                    details.putAll(hostDetails);
-                } else {
-                    details = hostDetails;
-                }
-            }
-
-            host.setDetails(details);
-            host.setParent(ssCmd.getParent());
-            host.setTotalSize(ssCmd.getTotalSize());
-            host.setHypervisorType(HypervisorType.None);
-            host.setType(type);
-            if (ssCmd.getNfsShare() != null) {
-                host.setStorageUrl(ssCmd.getNfsShare());
-            }
-        }
-         */
-        return null; // no need to handle this event anymore since secondary storage is not in host table anymore.
-    }
-
-    @Override
-    public DeleteHostAnswer deleteHost(HostVO host, boolean isForced, boolean isForceDeleteStorage) throws UnableDeleteHostException {
-        // Since secondary storage is moved out of host table, this class should not handle delete secondary storage anymore.
-        return null;
-    }
-
-    @Override
-    public List<HostVO> listUpAndConnectingSecondaryStorageVmHost(Long dcId) {
-        QueryBuilder<HostVO> sc = QueryBuilder.create(HostVO.class);
-        if (dcId != null) {
-            sc.and(sc.entity().getDataCenterId(), Op.EQ, dcId);
-        }
-        sc.and(sc.entity().getState(), Op.IN, Status.Up, Status.Connecting);
-        sc.and(sc.entity().getType(), Op.EQ, Host.Type.SecondaryStorageVM);
-        return sc.list();
-    }
-
-    @Override
-    public HostVO pickSsvmHost(HostVO ssHost) {
-        if (ssHost.getType() == Host.Type.LocalSecondaryStorage) {
-            return ssHost;
-        } else if (ssHost.getType() == Host.Type.SecondaryStorage) {
-            Long dcId = ssHost.getDataCenterId();
-            List<HostVO> ssAHosts = listUpAndConnectingSecondaryStorageVmHost(dcId);
-            if (ssAHosts == null || ssAHosts.isEmpty()) {
-                return null;
-            }
-            Collections.shuffle(ssAHosts);
-            return ssAHosts.get(0);
-        }
-        return null;
-    }
-
-    @Override
-    public void prepareStop(VirtualMachineProfile profile) {
-
-    }
-
-    public List<SecondaryStorageVmAllocator> getSecondaryStorageVmAllocators() {
-        return _ssVmAllocators;
-    }
-
-    @Inject
-    public void setSecondaryStorageVmAllocators(List<SecondaryStorageVmAllocator> ssVmAllocators) {
-        _ssVmAllocators = ssVmAllocators;
-    }
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/54f32a8e/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyThumbnailHandler.java
----------------------------------------------------------------------
diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyThumbnailHandler.java b/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyThumbnailHandler.java
index 4a02968..06f21d3 100644
--- a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyThumbnailHandler.java
+++ b/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyThumbnailHandler.java
@@ -41,6 +41,7 @@ public class ConsoleProxyThumbnailHandler implements HttpHandler {
     }
 
     @Override
+    @SuppressWarnings("access")
     public void handle(HttpExchange t) throws IOException {
         try {
             Thread.currentThread().setName("JPG Thread " + Thread.currentThread().getId() + " " + t.getRemoteAddress());

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/54f32a8e/services/secondary-storage/controller/resources/META-INF/cloudstack/core/spring-services-secondary-storage-controller-core-context.xml
----------------------------------------------------------------------
diff --git a/services/secondary-storage/controller/resources/META-INF/cloudstack/core/spring-services-secondary-storage-controller-core-context.xml b/services/secondary-storage/controller/resources/META-INF/cloudstack/core/spring-services-secondary-storage-controller-core-context.xml
new file mode 100644
index 0000000..a62fede
--- /dev/null
+++ b/services/secondary-storage/controller/resources/META-INF/cloudstack/core/spring-services-secondary-storage-controller-core-context.xml
@@ -0,0 +1,33 @@
+<!--
+  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: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/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"
+                      >
+    <bean id="premiumSecondaryStorageManagerImpl" class="org.apache.cloudstack.secondarystorage.PremiumSecondaryStorageManagerImpl">
+            <property name="secondaryStorageVmAllocators"
+            value="#{secondaryStorageVmAllocatorsRegistry.registered}" />
+    </bean>
+</beans>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/54f32a8e/services/secondary-storage/controller/src/org/apache/cloudstack/secondarystorage/PremiumSecondaryStorageManagerImpl.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/controller/src/org/apache/cloudstack/secondarystorage/PremiumSecondaryStorageManagerImpl.java b/services/secondary-storage/controller/src/org/apache/cloudstack/secondarystorage/PremiumSecondaryStorageManagerImpl.java
new file mode 100755
index 0000000..af96ed2
--- /dev/null
+++ b/services/secondary-storage/controller/src/org/apache/cloudstack/secondarystorage/PremiumSecondaryStorageManagerImpl.java
@@ -0,0 +1,186 @@
+// 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.secondarystorage;
+
+import java.util.Date;
+import java.util.List;
+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.api.Command;
+import com.cloud.configuration.Config;
+import com.cloud.host.HostVO;
+import com.cloud.host.Status;
+import com.cloud.host.dao.HostDao;
+import com.cloud.resource.ResourceManager;
+import com.cloud.secstorage.CommandExecLogDao;
+import com.cloud.secstorage.CommandExecLogVO;
+import com.cloud.storage.secondary.SecondaryStorageVmManager;
+import com.cloud.utils.DateUtil;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.Pair;
+import com.cloud.utils.db.JoinBuilder.JoinType;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.SearchCriteria.Op;
+import com.cloud.vm.SecondaryStorageVm;
+import com.cloud.vm.SecondaryStorageVmVO;
+import com.cloud.vm.SystemVmLoadScanner.AfterScanAction;
+import com.cloud.vm.VirtualMachine.State;
+import com.cloud.vm.dao.SecondaryStorageVmDao;
+
+@Local(value = {SecondaryStorageVmManager.class})
+public class PremiumSecondaryStorageManagerImpl extends SecondaryStorageManagerImpl {
+    private static final Logger s_logger = Logger.getLogger(PremiumSecondaryStorageManagerImpl.class);
+
+    private int _capacityPerSSVM = SecondaryStorageVmManager.DEFAULT_SS_VM_CAPACITY;
+    private int _standbyCapacity = SecondaryStorageVmManager.DEFAULT_STANDBY_CAPACITY;
+    private int _maxExecutionTimeMs = 1800000;
+
+    @Inject
+    SecondaryStorageVmDao _secStorageVmDao;
+    @Inject
+    CommandExecLogDao _cmdExecLogDao;
+    @Inject
+    HostDao _hostDao;
+    @Inject
+    ResourceManager _resourceMgr;
+    protected SearchBuilder<CommandExecLogVO> ActiveCommandSearch;
+    protected SearchBuilder<HostVO> HostSearch;
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+        super.configure(name, params);
+
+        _capacityPerSSVM = NumbersUtil.parseInt(_configDao.getValue(Config.SecStorageSessionMax.key()), DEFAULT_SS_VM_CAPACITY);
+        _standbyCapacity = NumbersUtil.parseInt(_configDao.getValue(Config.SecStorageCapacityStandby.key()), DEFAULT_STANDBY_CAPACITY);
+
+        int nMaxExecutionMinutes = NumbersUtil.parseInt(_configDao.getValue(Config.SecStorageCmdExecutionTimeMax.key()), 30);
+        _maxExecutionTimeMs = nMaxExecutionMinutes * 60 * 1000;
+
+        HostSearch = _hostDao.createSearchBuilder();
+        HostSearch.and("dc", HostSearch.entity().getDataCenterId(), Op.EQ);
+        HostSearch.and("status", HostSearch.entity().getStatus(), Op.EQ);
+
+        ActiveCommandSearch = _cmdExecLogDao.createSearchBuilder();
+        ActiveCommandSearch.and("created", ActiveCommandSearch.entity().getCreated(), Op.GTEQ);
+        ActiveCommandSearch.join("hostSearch", HostSearch, ActiveCommandSearch.entity().getInstanceId(), HostSearch.entity().getId(), JoinType.INNER);
+
+        HostSearch.done();
+        ActiveCommandSearch.done();
+        return true;
+    }
+
+    @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);
+
+        boolean suspendAutoLoading = !reserveStandbyCapacity();
+        if (!suspendAutoLoading) {
+            // this is a hacking, has nothing to do with console proxy, it is just a flag that primary storage is being under maintenance mode
+            String restart = _configDao.getValue("consoleproxy.restart");
+            if (restart != null && restart.equalsIgnoreCase("false")) {
+                s_logger.debug("Capacity scan disabled purposefully, consoleproxy.restart = false. This happens when the primarystorage is in maintenance mode");
+                suspendAutoLoading = true;
+            }
+        }
+
+        List<SecondaryStorageVmVO> alreadyRunning =
+            _secStorageVmDao.getSecStorageVmListInStates(SecondaryStorageVm.Role.templateProcessor, dataCenterId, State.Running, State.Migrating, State.Starting);
+        if (alreadyRunning.size() == 0) {
+            s_logger.info("No running secondary storage vms found in datacenter id=" + dataCenterId + ", starting one");
+
+            List<SecondaryStorageVmVO> stopped =
+                _secStorageVmDao.getSecStorageVmListInStates(SecondaryStorageVm.Role.templateProcessor, dataCenterId, State.Stopped, State.Stopping);
+            if (stopped.size() == 0 || !suspendAutoLoading) {
+                List<SecondaryStorageVmVO> stopping = _secStorageVmDao.getSecStorageVmListInStates(SecondaryStorageVm.Role.templateProcessor, State.Stopping);
+                if (stopping.size() > 0) {
+                    s_logger.info("Found SSVMs that are currently at stopping state, wait until they are settled");
+                    return new Pair<AfterScanAction, Object>(AfterScanAction.nop, null);
+                }
+
+                expandPool(pool, SecondaryStorageVm.Role.templateProcessor);
+            }
+        }
+
+        if (!suspendAutoLoading) {
+            // this is to avoid surprises that people may accidently see two SSVMs being launched, capacity expanding only happens when we have at least the primary SSVM is up
+            if (alreadyRunning.size() == 0) {
+                s_logger.info("Primary secondary storage is not even started, wait until next turn");
+                return new Pair<AfterScanAction, Object>(AfterScanAction.nop, null);
+            }
+
+            alreadyRunning = _secStorageVmDao.getSecStorageVmListInStates(null, dataCenterId, State.Running, State.Migrating, State.Starting);
+
+            List<CommandExecLogVO> activeCmds = listActiveCommands(dataCenterId, cutTime);
+            if (alreadyRunning.size() * _capacityPerSSVM - activeCmds.size() < _standbyCapacity) {
+                s_logger.info("secondary storage command execution standby capactiy low (running VMs: " + alreadyRunning.size() + ", active cmds: " + activeCmds.size() +
+                    "), starting a new one");
+                return new Pair<AfterScanAction, Object>(AfterScanAction.expand, SecondaryStorageVm.Role.commandExecutor);
+            }
+        }
+
+        return new Pair<AfterScanAction, Object>(AfterScanAction.nop, null);
+    }
+
+    @Override
+    public Pair<HostVO, SecondaryStorageVmVO> assignSecStorageVm(long zoneId, Command cmd) {
+
+        // TODO, need performance optimization
+        List<Long> vms = _secStorageVmDao.listRunningSecStorageOrderByLoad(null, zoneId);
+        for (Long vmId : vms) {
+            SecondaryStorageVmVO secStorageVm = _secStorageVmDao.findById(vmId);
+            HostVO host;
+            host = _resourceMgr.findHostByName(secStorageVm.getHostName());
+            if (host != null && host.getStatus() == Status.Up)
+                return new Pair<HostVO, SecondaryStorageVmVO>(host, secStorageVm);
+        }
+
+        return null;
+    }
+
+    private List<CommandExecLogVO> listActiveCommands(long dcId, Date cutTime) {
+        SearchCriteria<CommandExecLogVO> sc = ActiveCommandSearch.create();
+
+        sc.setParameters("created", cutTime);
+        sc.setJoinParameters("hostSearch", "dc", dcId);
+        sc.setJoinParameters("hostSearch", "status", Status.Up);
+
+        return _cmdExecLogDao.search(sc, null);
+    }
+
+    private boolean reserveStandbyCapacity() {
+        String value = _configDao.getValue(Config.SystemVMAutoReserveCapacity.key());
+        if (value != null && value.equalsIgnoreCase("true")) {
+            return true;
+        }
+
+        return false;
+    }
+}


[04/11] Moved the secondary storage service into its own server directory

Posted by ah...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4be3b993/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/UploadManagerImpl.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/UploadManagerImpl.java b/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/UploadManagerImpl.java
new file mode 100755
index 0000000..cdbc52d
--- /dev/null
+++ b/services/secondary-storage/server/src/org/apache/cloudstack/storage/template/UploadManagerImpl.java
@@ -0,0 +1,550 @@
+// 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.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 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.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.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;
+
+        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;
+        }
+
+        public TemplateUploader getTemplateUploader() {
+            return tu;
+        }
+
+        public void cleanup() {
+            if (tu != null) {
+                String upldPath = tu.getUploadLocalPath();
+                if (upldPath != null) {
+                    File f = new File(upldPath);
+                    f.delete();
+                }
+            }
+        }
+
+    }
+
+    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 final String extractMountPoint = "/mnt/SecStorage/extractmnt";
+    private StorageLayer _storage;
+    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();
+        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) {
+        return 0;
+    }
+
+    @SuppressWarnings("unchecked")
+    @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 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.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/4be3b993/services/secondary-storage/server/test/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResourceTest.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/server/test/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResourceTest.java b/services/secondary-storage/server/test/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResourceTest.java
new file mode 100644
index 0000000..e0fcbae
--- /dev/null
+++ b/services/secondary-storage/server/test/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResourceTest.java
@@ -0,0 +1,143 @@
+/*
+ * 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.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.Map;
+import java.util.Properties;
+import java.util.UUID;
+
+import javax.naming.ConfigurationException;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+import org.apache.log4j.Logger;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import org.apache.cloudstack.storage.command.CopyCmdAnswer;
+import org.apache.cloudstack.storage.command.CopyCommand;
+import org.apache.cloudstack.storage.command.DownloadCommand;
+import org.apache.cloudstack.storage.to.TemplateObjectTO;
+
+import com.cloud.agent.api.storage.DownloadAnswer;
+import com.cloud.agent.api.storage.ListTemplateAnswer;
+import com.cloud.agent.api.storage.ListTemplateCommand;
+import com.cloud.agent.api.to.DataObjectType;
+import com.cloud.agent.api.to.NfsTO;
+import com.cloud.agent.api.to.SwiftTO;
+import com.cloud.storage.DataStoreRole;
+import com.cloud.storage.Storage;
+import com.cloud.utils.PropertiesUtil;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+public class LocalNfsSecondaryStorageResourceTest extends TestCase {
+    private static Map<String, Object> testParams;
+
+    private static final Logger s_logger = Logger.getLogger(LocalNfsSecondaryStorageResourceTest.class.getName());
+
+    LocalNfsSecondaryStorageResource resource;
+
+    @Before
+    @Override
+    public void setUp() throws ConfigurationException {
+        resource = new LocalNfsSecondaryStorageResource();
+        resource.setInSystemVM(true);
+
+        testParams = PropertiesUtil.toMap(loadProperties());
+        resource.configureStorageLayerClass(testParams);
+        Object testLocalRoot = testParams.get("testLocalRoot");
+        resource.setParentPath("/mnt");
+
+        if (testLocalRoot != null) {
+            resource.setParentPath((String)testLocalRoot);
+        }
+
+        System.setProperty("paths.script", "/Users/edison/develop/asf-master/script");
+        //resource.configure("test", new HashMap<String, Object>());
+    }
+
+    @Test
+    public void testExecuteRequest() throws Exception {
+        TemplateObjectTO template = Mockito.mock(TemplateObjectTO.class);
+        NfsTO cacheStore = Mockito.mock(NfsTO.class);
+        Mockito.when(cacheStore.getUrl()).thenReturn("nfs://nfs2.lab.vmops.com/export/home/edison/");
+        SwiftTO swift = Mockito.mock(SwiftTO.class);
+        Mockito.when(swift.getEndPoint()).thenReturn("https://objects.dreamhost.com/auth");
+        Mockito.when(swift.getAccount()).thenReturn("cloudstack");
+        Mockito.when(swift.getUserName()).thenReturn("images");
+        Mockito.when(swift.getKey()).thenReturn("oxvELQaOD1U5_VyosGfA-wpZ7uBWEff-CUBGCM0u");
+
+        Mockito.when(template.getDataStore()).thenReturn(swift);
+        Mockito.when(template.getPath()).thenReturn("template/1/1/");
+        Mockito.when(template.isRequiresHvm()).thenReturn(true);
+        Mockito.when(template.getId()).thenReturn(1L);
+        Mockito.when(template.getFormat()).thenReturn(Storage.ImageFormat.VHD);
+        Mockito.when(template.getOrigUrl()).thenReturn("http://nfs1.lab.vmops.com/templates/test.bz2");
+        Mockito.when(template.getName()).thenReturn(UUID.randomUUID().toString());
+        Mockito.when(template.getObjectType()).thenReturn(DataObjectType.TEMPLATE);
+
+        DownloadCommand cmd = new DownloadCommand(template, 100000L);
+        cmd.setCacheStore(cacheStore);
+        DownloadAnswer answer = (DownloadAnswer)resource.executeRequest(cmd);
+        Assert.assertTrue(answer.getResult());
+
+        Mockito.when(template.getPath()).thenReturn(answer.getInstallPath());
+        Mockito.when(template.getDataStore()).thenReturn(swift);
+        //download swift:
+        Mockito.when(cacheStore.getRole()).thenReturn(DataStoreRole.ImageCache);
+        TemplateObjectTO destTemplate = Mockito.mock(TemplateObjectTO.class);
+        Mockito.when(destTemplate.getPath()).thenReturn("template/1/2");
+        Mockito.when(destTemplate.getDataStore()).thenReturn(cacheStore);
+        Mockito.when(destTemplate.getObjectType()).thenReturn(DataObjectType.TEMPLATE);
+        CopyCommand cpyCmd = new CopyCommand(template, destTemplate, 10000, true);
+        CopyCmdAnswer copyCmdAnswer = (CopyCmdAnswer)resource.executeRequest(cpyCmd);
+        Assert.assertTrue(copyCmdAnswer.getResult());
+
+        //list template
+        ListTemplateCommand listCmd = new ListTemplateCommand(swift);
+        ListTemplateAnswer listAnswer = (ListTemplateAnswer)resource.executeRequest(listCmd);
+
+        Assert.assertTrue(listAnswer.getTemplateInfo().size() > 0);
+    }
+
+    public static Properties loadProperties() throws ConfigurationException {
+        Properties properties = new Properties();
+        final File file = PropertiesUtil.findConfigFile("agent.properties");
+        if (file == null) {
+            throw new ConfigurationException("Unable to find agent.properties.");
+        }
+
+        s_logger.info("agent.properties found at " + file.getAbsolutePath());
+
+        try {
+            properties.load(new FileInputStream(file));
+        } catch (final FileNotFoundException ex) {
+            throw new CloudRuntimeException("Cannot find the file: " + file.getAbsolutePath(), ex);
+        } catch (final IOException ex) {
+            throw new CloudRuntimeException("IOException in reading " + file.getAbsolutePath(), ex);
+        }
+        return properties;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4be3b993/services/secondary-storage/server/test/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResourceTest.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/server/test/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResourceTest.java b/services/secondary-storage/server/test/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResourceTest.java
new file mode 100644
index 0000000..e0ae4c5
--- /dev/null
+++ b/services/secondary-storage/server/test/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResourceTest.java
@@ -0,0 +1,110 @@
+/*
+ * 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.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.net.URI;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.naming.ConfigurationException;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+import org.apache.log4j.Level;
+import org.apache.log4j.Logger;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.cloud.utils.PropertiesUtil;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+public class NfsSecondaryStorageResourceTest extends TestCase {
+    private static Map<String, Object> testParams;
+
+    private static final Logger s_logger = Logger.getLogger(NfsSecondaryStorageResourceTest.class.getName());
+
+    NfsSecondaryStorageResource resource;
+
+    @Before
+    @Override
+    public void setUp() throws ConfigurationException {
+        s_logger.setLevel(Level.ALL);
+        resource = new NfsSecondaryStorageResource();
+        resource.setInSystemVM(true);
+        testParams = PropertiesUtil.toMap(loadProperties());
+        resource.configureStorageLayerClass(testParams);
+        Object testLocalRoot = testParams.get("testLocalRoot");
+        if (testLocalRoot != null) {
+            resource.setParentPath((String)testLocalRoot);
+        }
+    }
+
+    @Test
+    public void testMount() throws Exception {
+        String sampleUriStr = "cifs://192.168.1.128/CSHV3?user=administrator&password=1pass%40word1&foo=bar";
+        URI sampleUri = new URI(sampleUriStr);
+
+        s_logger.info("Check HostIp parsing");
+        String hostIpStr = resource.getUriHostIp(sampleUri);
+        Assert.assertEquals("Expected host IP " + sampleUri.getHost() + " and actual host IP " + hostIpStr + " differ.", sampleUri.getHost(), hostIpStr);
+
+        s_logger.info("Check option parsing");
+        String expected = "user=administrator,password=1pass@word1,foo=bar,";
+        String actualOpts = resource.parseCifsMountOptions(sampleUri);
+        Assert.assertEquals("Options should be " + expected + " and not " + actualOpts, expected, actualOpts);
+
+        // attempt a configured mount
+        final Map<String, Object> params = PropertiesUtil.toMap(loadProperties());
+        String sampleMount = (String)params.get("testCifsMount");
+        if (!sampleMount.isEmpty()) {
+            s_logger.info("functional test, mount " + sampleMount);
+            URI realMntUri = new URI(sampleMount);
+            String mntSubDir = resource.mountUri(realMntUri);
+            s_logger.info("functional test, umount " + mntSubDir);
+            resource.umount(resource.getMountingRoot() + mntSubDir, realMntUri);
+        } else {
+            s_logger.info("no entry for testCifsMount in " + "./conf/agent.properties - skip functional test");
+        }
+    }
+
+    public static Properties loadProperties() throws ConfigurationException {
+        Properties properties = new Properties();
+        final File file = PropertiesUtil.findConfigFile("agent.properties");
+        if (file == null) {
+            throw new ConfigurationException("Unable to find agent.properties.");
+        }
+
+        s_logger.info("agent.properties found at " + file.getAbsolutePath());
+
+        try {
+            properties.load(new FileInputStream(file));
+        } catch (final FileNotFoundException ex) {
+            throw new CloudRuntimeException("Cannot find the file: " + file.getAbsolutePath(), ex);
+        } catch (final IOException ex) {
+            throw new CloudRuntimeException("IOException in reading " + file.getAbsolutePath(), ex);
+        }
+        return properties;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4be3b993/services/secondary-storage/src/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResource.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResource.java b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResource.java
deleted file mode 100644
index 9393ee2..0000000
--- a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResource.java
+++ /dev/null
@@ -1,95 +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 org.apache.cloudstack.storage.resource;
-
-import java.net.URI;
-import java.util.concurrent.Executors;
-
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
-import org.apache.cloudstack.storage.template.DownloadManagerImpl;
-
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.Command;
-import com.cloud.storage.JavaStorageLayer;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.script.Script;
-
-@Component
-public class LocalNfsSecondaryStorageResource extends NfsSecondaryStorageResource {
-
-    private static final Logger s_logger = Logger.getLogger(LocalNfsSecondaryStorageResource.class);
-
-    public LocalNfsSecondaryStorageResource() {
-        this._dlMgr = new DownloadManagerImpl();
-        ((DownloadManagerImpl)_dlMgr).setThreadPool(Executors.newFixedThreadPool(10));
-        _storage = new JavaStorageLayer();
-        this._inSystemVM = false;
-    }
-
-    @Override
-    public void setParentPath(String path) {
-        this._parent = path;
-    }
-
-    @Override
-    public Answer executeRequest(Command cmd) {
-        return super.executeRequest(cmd);
-    }
-
-    @Override
-    synchronized public String getRootDir(String secUrl) {
-        try {
-            URI uri = new URI(secUrl);
-            String dir = mountUri(uri);
-            return _parent + "/" + dir;
-        } catch (Exception e) {
-            String msg = "GetRootDir for " + secUrl + " failed due to " + e.toString();
-            s_logger.error(msg, e);
-            throw new CloudRuntimeException(msg);
-        }
-    }
-
-    @Override
-    protected void mount(String localRootPath, String remoteDevice, URI uri) {
-        ensureLocalRootPathExists(localRootPath, uri);
-
-        if (mountExists(localRootPath, uri)) {
-            return;
-        }
-
-        attemptMount(localRootPath, remoteDevice, uri);
-
-        // Change permissions for the mountpoint - seems to bypass authentication
-        Script script = new Script(true, "chmod", _timeout, s_logger);
-        script.add("777", localRootPath);
-        String result = script.execute();
-        if (result != null) {
-            String errMsg = "Unable to set permissions for " + localRootPath + " due to " + result;
-            s_logger.error(errMsg);
-            throw new CloudRuntimeException(errMsg);
-        }
-        s_logger.debug("Successfully set 777 permission for " + localRootPath);
-
-        // XXX: Adding the check for creation of snapshots dir here. Might have
-        // to move it somewhere more logical later.
-        checkForSnapshotsDir(localRootPath);
-        checkForVolumesDir(localRootPath);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4be3b993/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
deleted file mode 100644
index bdfe7e8..0000000
--- a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/LocalSecondaryStorageResource.java
+++ /dev/null
@@ -1,240 +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 org.apache.cloudstack.storage.resource;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.naming.ConfigurationException;
-
-import org.apache.log4j.Logger;
-
-import org.apache.cloudstack.storage.command.DownloadCommand;
-import org.apache.cloudstack.storage.command.DownloadProgressCommand;
-import org.apache.cloudstack.storage.template.DownloadManager;
-import org.apache.cloudstack.storage.template.DownloadManagerImpl;
-
-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.ListTemplateAnswer;
-import com.cloud.agent.api.storage.ListTemplateCommand;
-import com.cloud.agent.api.to.NfsTO;
-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.TemplateProp;
-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(String url) {
-        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, TemplateProp> templateInfos = _dlMgr.gatherTemplateInfo(root);
-        return new ListTemplateAnswer(((NfsTO)cmd.getDataStore()).getUrl(), 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
-
-    }
-}


[08/11] git commit: updated refs/heads/master to 54f32a8

Posted by ah...@apache.org.
Removed references to secondarystoragevmmanager from code that doesn't use it.


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

Branch: refs/heads/master
Commit: 7f34282dfa276909a537bd4a65155e99a1e2f04f
Parents: 4be3b99
Author: Alex Huang <al...@citrix.com>
Authored: Wed Jan 15 17:56:57 2014 -0800
Committer: Alex Huang <al...@citrix.com>
Committed: Wed Feb 5 01:39:15 2014 +0000

----------------------------------------------------------------------
 .../storage/test/ChildTestConfiguration.java    |   6 -
 .../com/cloud/hypervisor/guru/VMwareGuru.java   |  36 ++--
 .../vmware/manager/VmwareManagerImpl.java       |  94 ++++------
 .../vmware/VmwareDatacenterApiUnitTest.java     |   6 -
 .../IntegrationTestConfiguration.java           |   6 -
 .../com/cloud/resource/ResourceManagerImpl.java |  66 ++++---
 .../com/cloud/server/ManagementServerImpl.java  |  40 ++---
 .../com/cloud/storage/VolumeApiServiceImpl.java | 178 ++++---------------
 .../storage/download/DownloadMonitorImpl.java   |  29 +--
 .../secondary/SecondaryStorageListener.java     |   5 +-
 .../secondary/SecondaryStorageManagerImpl.java  |   5 +-
 .../storage/snapshot/SnapshotManagerImpl.java   |  66 +++----
 .../cloud/storage/upload/UploadMonitorImpl.java |  27 ++-
 .../com/cloud/template/TemplateManagerImpl.java | 133 ++++----------
 .../networkoffering/ChildTestConfiguration.java |   6 -
 15 files changed, 207 insertions(+), 496 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7f34282d/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/ChildTestConfiguration.java
----------------------------------------------------------------------
diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/ChildTestConfiguration.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/ChildTestConfiguration.java
index 69d60c2..3af7df7 100644
--- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/ChildTestConfiguration.java
+++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/ChildTestConfiguration.java
@@ -79,7 +79,6 @@ import com.cloud.storage.dao.VMTemplateZoneDaoImpl;
 import com.cloud.storage.dao.VolumeDaoImpl;
 import com.cloud.storage.dao.VolumeHostDaoImpl;
 import com.cloud.storage.download.DownloadMonitorImpl;
-import com.cloud.storage.secondary.SecondaryStorageVmManager;
 import com.cloud.tags.dao.ResourceTagsDaoImpl;
 import com.cloud.template.TemplateManager;
 import com.cloud.user.AccountManager;
@@ -111,11 +110,6 @@ import com.cloud.vm.snapshot.dao.VMSnapshotDaoImpl;
 public class ChildTestConfiguration extends TestConfiguration {
 
     @Bean
-    public SecondaryStorageVmManager secondaryStoreageMgr() {
-        return Mockito.mock(SecondaryStorageVmManager.class);
-    }
-
-    @Bean
     public HostDao hostDao() {
         return Mockito.spy(new HostDaoImpl());
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7f34282d/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java
index d72787c..9a30f18 100644
--- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java
+++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java
@@ -27,8 +27,6 @@ import java.util.UUID;
 import javax.ejb.Local;
 import javax.inject.Inject;
 
-import com.cloud.dc.dao.ClusterDao;
-import com.cloud.vm.dao.VMInstanceDao;
 import org.apache.log4j.Logger;
 
 import org.apache.cloudstack.framework.config.ConfigKey;
@@ -71,7 +69,6 @@ import com.cloud.network.Networks.BroadcastDomainType;
 import com.cloud.network.Networks.TrafficType;
 import com.cloud.network.dao.NetworkDao;
 import com.cloud.network.dao.NetworkVO;
-import com.cloud.network.dao.PhysicalNetworkDao;
 import com.cloud.network.dao.PhysicalNetworkTrafficTypeDao;
 import com.cloud.network.dao.PhysicalNetworkTrafficTypeVO;
 import com.cloud.secstorage.CommandExecLogDao;
@@ -95,41 +92,38 @@ import com.cloud.vm.VirtualMachine;
 import com.cloud.vm.VirtualMachineProfile;
 import com.cloud.vm.VmDetailConstants;
 import com.cloud.vm.dao.NicDao;
+import com.cloud.vm.dao.VMInstanceDao;
 
 @Local(value = HypervisorGuru.class)
 public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Configurable {
     private static final Logger s_logger = Logger.getLogger(VMwareGuru.class);
 
     @Inject
-    NetworkDao _networkDao;
-    @Inject
-    GuestOSDao _guestOsDao;
-    @Inject
-    HostDao _hostDao;
+    private NetworkDao _networkDao;
     @Inject
-    HostDetailsDao _hostDetailsDao;
+    private GuestOSDao _guestOsDao;
     @Inject
-    CommandExecLogDao _cmdExecLogDao;
+    private HostDao _hostDao;
     @Inject
-    VmwareManager _vmwareMgr;
+    private HostDetailsDao _hostDetailsDao;
     @Inject
-    SecondaryStorageVmManager _secStorageMgr;
+    private CommandExecLogDao _cmdExecLogDao;
     @Inject
-    NetworkModel _networkMgr;
+    private VmwareManager _vmwareMgr;
     @Inject
-    ConfigurationDao _configDao;
+    private SecondaryStorageVmManager _secStorageMgr;
     @Inject
-    NicDao _nicDao;
+    private NetworkModel _networkMgr;
     @Inject
-    PhysicalNetworkDao _physicalNetworkDao;
+    private ConfigurationDao _configDao;
     @Inject
-    PhysicalNetworkTrafficTypeDao _physicalNetworkTrafficTypeDao;
+    private NicDao _nicDao;
     @Inject
-    VMInstanceDao _vmDao;
+    private PhysicalNetworkTrafficTypeDao _physicalNetworkTrafficTypeDao;
     @Inject
-    ClusterDao _clusterDao;
+    private VMInstanceDao _vmDao;
     @Inject
-    ClusterManager _clusterMgr;
+    private ClusterManager _clusterMgr;
 
     protected VMwareGuru() {
         super();
@@ -204,7 +198,7 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Co
             }
         }
 
-        long clusterId = this.getClusterId(vm.getId());
+        long clusterId = getClusterId(vm.getId());
         details.put(Config.VmwareReserveCpu.key(), VmwareReserveCpu.valueIn(clusterId).toString());
         details.put(Config.VmwareReserveMem.key(), VmwareReserveMemory.valueIn(clusterId).toString());
         to.setDetails(details);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7f34282d/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java
index 482e8a6..4f443bb 100755
--- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java
+++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java
@@ -38,7 +38,6 @@ import javax.naming.ConfigurationException;
 
 import org.apache.log4j.Logger;
 
-import com.google.gson.Gson;
 import com.vmware.vim25.AboutInfo;
 import com.vmware.vim25.ManagedObjectReference;
 
@@ -75,7 +74,6 @@ import com.cloud.exception.InvalidParameterValueException;
 import com.cloud.exception.ResourceInUseException;
 import com.cloud.host.Host;
 import com.cloud.host.Status;
-import com.cloud.host.dao.HostDao;
 import com.cloud.hypervisor.Hypervisor.HypervisorType;
 import com.cloud.hypervisor.dao.HypervisorCapabilitiesDao;
 import com.cloud.hypervisor.vmware.LegacyZoneVO;
@@ -104,11 +102,9 @@ import com.cloud.network.Networks.BroadcastDomainType;
 import com.cloud.network.dao.CiscoNexusVSMDeviceDao;
 import com.cloud.org.Cluster.ClusterType;
 import com.cloud.secstorage.CommandExecLogDao;
-import com.cloud.serializer.GsonHelper;
 import com.cloud.server.ConfigurationServer;
 import com.cloud.storage.JavaStorageLayer;
 import com.cloud.storage.StorageLayer;
-import com.cloud.storage.secondary.SecondaryStorageVmManager;
 import com.cloud.utils.FileUtil;
 import com.cloud.utils.NumbersUtil;
 import com.cloud.utils.Pair;
@@ -132,85 +128,77 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
     private static final long DEFAULT_HOST_SCAN_INTERVAL = 600000;     // every 10 minutes
 
     private long _hostScanInterval = DEFAULT_HOST_SCAN_INTERVAL;
-    int _timeout;
+    private int _timeout;
 
     private String _instance;
 
     @Inject
-    AgentManager _agentMgr;
+    private AgentManager _agentMgr;
     @Inject
-    protected NetworkModel _netMgr;
+    private NetworkModel _netMgr;
     @Inject
-    HostDao _hostDao;
+    private ClusterDao _clusterDao;
     @Inject
-    ClusterDao _clusterDao;
+    private ClusterDetailsDao _clusterDetailsDao;
     @Inject
-    ClusterDetailsDao _clusterDetailsDao;
+    private CommandExecLogDao _cmdExecLogDao;
     @Inject
-    CommandExecLogDao _cmdExecLogDao;
+    private DataStoreManager _dataStoreMgr;
     @Inject
-    SecondaryStorageVmManager _ssvmMgr;
+    private CiscoNexusVSMDeviceDao _nexusDao;
     @Inject
-    DataStoreManager _dataStoreMgr;
+    private ClusterVSMMapDao _vsmMapDao;
     @Inject
-    CiscoNexusVSMDeviceDao _nexusDao;
+    private ConfigurationDao _configDao;
     @Inject
-    ClusterVSMMapDao _vsmMapDao;
+    private ConfigurationServer _configServer;
     @Inject
-    ConfigurationDao _configDao;
+    private HypervisorCapabilitiesDao _hvCapabilitiesDao;
     @Inject
-    ConfigurationServer _configServer;
+    private DataCenterDao _dcDao;
     @Inject
-    HypervisorCapabilitiesDao _hvCapabilitiesDao;
+    private VmwareDatacenterDao _vmwareDcDao;
     @Inject
-    DataCenterDao _dcDao;
+    private VmwareDatacenterZoneMapDao _vmwareDcZoneMapDao;
     @Inject
-    VmwareDatacenterDao _vmwareDcDao;
+    private LegacyZoneDao _legacyZoneDao;
     @Inject
-    VmwareDatacenterZoneMapDao _vmwareDcZoneMapDao;
+    private ManagementServerHostPeerDao _mshostPeerDao;
     @Inject
-    LegacyZoneDao _legacyZoneDao;
-    @Inject
-    ManagementServerHostPeerDao _mshostPeerDao;
-    @Inject
-    ClusterManager _clusterMgr;
+    private ClusterManager _clusterMgr;
 
-    String _mountParent;
-    StorageLayer _storage;
-    String _privateNetworkVSwitchName = "vSwitch0";
+    private String _mountParent;
+    private StorageLayer _storage;
+    private final String _privateNetworkVSwitchName = "vSwitch0";
 
-    int _portsPerDvPortGroup = 256;
-    boolean _nexusVSwitchActive;
-    boolean _fullCloneFlag;
-    boolean _instanceNameFlag;
-    String _serviceConsoleName;
-    String _managemetPortGroupName;
-    String _defaultSystemVmNicAdapterType = VirtualEthernetCardType.E1000.toString();
-    String _recycleHungWorker = "false";
-    long _hungWorkerTimeout = 7200000;        // 2 hour
-    int _additionalPortRangeStart;
-    int _additionalPortRangeSize;
-    int _routerExtraPublicNics = 2;
-    int _vCenterSessionTimeout = 1200000; // Timeout in milliseconds
+    private int _portsPerDvPortGroup = 256;
+    private boolean _fullCloneFlag;
+    private boolean _instanceNameFlag;
+    private String _serviceConsoleName;
+    private String _managemetPortGroupName;
+    private String _defaultSystemVmNicAdapterType = VirtualEthernetCardType.E1000.toString();
+    private String _recycleHungWorker = "false";
+    private int _additionalPortRangeStart;
+    private int _additionalPortRangeSize;
+    private int _routerExtraPublicNics = 2;
+    private int _vCenterSessionTimeout = 1200000; // Timeout in milliseconds
 
-    String _reserveCpu = "false";
+    private String _reserveCpu = "false";
 
-    String _reserveMem = "false";
+    private String _reserveMem = "false";
 
-    String _rootDiskController = DiskControllerType.ide.toString();
+    private String _rootDiskController = DiskControllerType.ide.toString();
 
-    Map<String, String> _storageMounts = new HashMap<String, String>();
+    private final Map<String, String> _storageMounts = new HashMap<String, String>();
 
-    Random _rand = new Random(System.currentTimeMillis());
-    Gson _gson;
+    private final Random _rand = new Random(System.currentTimeMillis());
 
-    VmwareStorageManager _storageMgr;
-    GlobalLock _exclusiveOpLock = GlobalLock.getInternLock("vmware.exclusive.op");
+    private final VmwareStorageManager _storageMgr;
+    private final GlobalLock _exclusiveOpLock = GlobalLock.getInternLock("vmware.exclusive.op");
 
     private final ScheduledExecutorService _hostScanScheduler = Executors.newScheduledThreadPool(1, new NamedThreadFactory("Vmware-Host-Scan"));
 
     public VmwareManagerImpl() {
-        _gson = GsonHelper.getGsonLogger();
         _storageMgr = new VmwareStorageManagerImpl(this);
     }
 
@@ -310,10 +298,6 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
             _recycleHungWorker = "false";
         }
 
-        value = _configDao.getValue(Config.VmwareHungWorkerTimeout.key());
-        if (value != null)
-            _hungWorkerTimeout = Long.parseLong(value) * 1000;
-
         _rootDiskController = _configDao.getValue(Config.VmwareRootDiskControllerType.key());
         if (_rootDiskController == null || _rootDiskController.isEmpty()) {
             _rootDiskController = DiskControllerType.ide.toString();

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7f34282d/plugins/hypervisors/vmware/test/com/cloud/hypervisor/vmware/VmwareDatacenterApiUnitTest.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/vmware/test/com/cloud/hypervisor/vmware/VmwareDatacenterApiUnitTest.java b/plugins/hypervisors/vmware/test/com/cloud/hypervisor/vmware/VmwareDatacenterApiUnitTest.java
index 4a00489..c2002ff 100644
--- a/plugins/hypervisors/vmware/test/com/cloud/hypervisor/vmware/VmwareDatacenterApiUnitTest.java
+++ b/plugins/hypervisors/vmware/test/com/cloud/hypervisor/vmware/VmwareDatacenterApiUnitTest.java
@@ -85,7 +85,6 @@ import com.cloud.org.Cluster.ClusterType;
 import com.cloud.org.Managed.ManagedState;
 import com.cloud.secstorage.CommandExecLogDao;
 import com.cloud.server.ConfigurationServer;
-import com.cloud.storage.secondary.SecondaryStorageVmManager;
 import com.cloud.user.Account;
 import com.cloud.user.AccountManager;
 import com.cloud.user.AccountService;
@@ -364,11 +363,6 @@ public class VmwareDatacenterApiUnitTest {
         }
 
         @Bean
-        public SecondaryStorageVmManager secondaryStorageVmManager() {
-            return Mockito.mock(SecondaryStorageVmManager.class);
-        }
-
-        @Bean
         public CommandExecLogDao commandExecLogDao() {
             return Mockito.mock(CommandExecLogDao.class);
         }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7f34282d/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/IntegrationTestConfiguration.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/IntegrationTestConfiguration.java b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/IntegrationTestConfiguration.java
index 1a53c17..954a37e 100644
--- a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/IntegrationTestConfiguration.java
+++ b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/IntegrationTestConfiguration.java
@@ -259,7 +259,6 @@ import com.cloud.storage.dao.VMTemplateHostDaoImpl;
 import com.cloud.storage.dao.VMTemplateZoneDaoImpl;
 import com.cloud.storage.dao.VolumeDaoImpl;
 import com.cloud.storage.dao.VolumeHostDaoImpl;
-import com.cloud.storage.secondary.SecondaryStorageVmManager;
 import com.cloud.storage.snapshot.SnapshotApiService;
 import com.cloud.storage.snapshot.SnapshotManager;
 import com.cloud.tags.dao.ResourceTagDao;
@@ -624,11 +623,6 @@ public class IntegrationTestConfiguration {
     }
 
     @Bean
-    public SecondaryStorageVmManager secondaryStorageVmManager() {
-        return Mockito.mock(SecondaryStorageVmManager.class);
-    }
-
-    @Bean
     public Site2SiteVpnManager site2SiteVpnManager() {
         return Mockito.mock(Site2SiteVpnManager.class);
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7f34282d/server/src/com/cloud/resource/ResourceManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/resource/ResourceManagerImpl.java b/server/src/com/cloud/resource/ResourceManagerImpl.java
index c9e2e7a..79eb1cb 100755
--- a/server/src/com/cloud/resource/ResourceManagerImpl.java
+++ b/server/src/com/cloud/resource/ResourceManagerImpl.java
@@ -47,7 +47,6 @@ import org.apache.cloudstack.api.command.admin.host.UpdateHostCmd;
 import org.apache.cloudstack.api.command.admin.host.UpdateHostPasswordCmd;
 import org.apache.cloudstack.context.CallContext;
 import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.region.dao.RegionDao;
 import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
 import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
 import org.apache.cloudstack.utils.identity.ManagementServerNode;
@@ -129,7 +128,6 @@ import com.cloud.storage.VMTemplateVO;
 import com.cloud.storage.dao.GuestOSCategoryDao;
 import com.cloud.storage.dao.StoragePoolHostDao;
 import com.cloud.storage.dao.VMTemplateDao;
-import com.cloud.storage.secondary.SecondaryStorageVmManager;
 import com.cloud.user.Account;
 import com.cloud.user.AccountManager;
 import com.cloud.user.User;
@@ -168,55 +166,51 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
     Gson _gson;
 
     @Inject
-    AccountManager _accountMgr;
+    private AccountManager _accountMgr;
     @Inject
-    AgentManager _agentMgr;
+    private AgentManager _agentMgr;
     @Inject
-    StorageManager _storageMgr;
+    private StorageManager _storageMgr;
     @Inject
-    protected SecondaryStorageVmManager _secondaryStorageMgr;
+    private DataCenterDao _dcDao;
     @Inject
-    protected RegionDao _regionDao;
+    private HostPodDao _podDao;
     @Inject
-    protected DataCenterDao _dcDao;
+    private ClusterDetailsDao _clusterDetailsDao;
     @Inject
-    protected HostPodDao _podDao;
+    private ClusterDao _clusterDao;
     @Inject
-    protected ClusterDetailsDao _clusterDetailsDao;
+    private CapacityDao _capacityDao;
     @Inject
-    protected ClusterDao _clusterDao;
+    private HostDao _hostDao;
     @Inject
-    protected CapacityDao _capacityDao;
+    private HostDetailsDao _hostDetailsDao;
     @Inject
-    protected HostDao _hostDao;
+    private ConfigurationDao _configDao;
     @Inject
-    protected HostDetailsDao _hostDetailsDao;
+    private HostTagsDao _hostTagsDao;
     @Inject
-    protected ConfigurationDao _configDao;
+    private GuestOSCategoryDao _guestOSCategoryDao;
     @Inject
-    protected HostTagsDao _hostTagsDao;
+    private PrimaryDataStoreDao _storagePoolDao;
     @Inject
-    protected GuestOSCategoryDao _guestOSCategoryDao;
+    private DataCenterIpAddressDao _privateIPAddressDao;
     @Inject
-    protected PrimaryDataStoreDao _storagePoolDao;
+    private IPAddressDao _publicIPAddressDao;
     @Inject
-    protected DataCenterIpAddressDao _privateIPAddressDao;
+    private VirtualMachineManager _vmMgr;
     @Inject
-    protected IPAddressDao _publicIPAddressDao;
+    private VMInstanceDao _vmDao;
     @Inject
-    protected VirtualMachineManager _vmMgr;
+    private HighAvailabilityManager _haMgr;
     @Inject
-    protected VMInstanceDao _vmDao;
-    @Inject
-    protected HighAvailabilityManager _haMgr;
-    @Inject
-    protected StorageService _storageSvr;
+    private StorageService _storageSvr;
     @Inject
     PlannerHostReservationDao _plannerHostReserveDao;
     @Inject
-    protected DedicatedResourceDao _dedicatedDao;
+    private DedicatedResourceDao _dedicatedDao;
 
-    protected List<? extends Discoverer> _discoverers;
+    private List<? extends Discoverer> _discoverers;
 
     public List<? extends Discoverer> getDiscoverers() {
         return _discoverers;
@@ -227,22 +221,22 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
     }
 
     @Inject
-    protected ClusterManager _clusterMgr;
+    private ClusterManager _clusterMgr;
     @Inject
-    protected StoragePoolHostDao _storagePoolHostDao;
+    private StoragePoolHostDao _storagePoolHostDao;
 
     @Inject
-    protected VMTemplateDao _templateDao;
+    private VMTemplateDao _templateDao;
     @Inject
-    protected ConfigurationManager _configMgr;
+    private ConfigurationManager _configMgr;
     @Inject
-    protected ClusterVSMMapDao _clusterVSMMapDao;
+    private ClusterVSMMapDao _clusterVSMMapDao;
 
-    protected long _nodeId = ManagementServerNode.getManagementServerId();
+    private final long _nodeId = ManagementServerNode.getManagementServerId();
 
-    protected HashMap<String, ResourceStateAdapter> _resourceStateAdapters = new HashMap<String, ResourceStateAdapter>();
+    private final HashMap<String, ResourceStateAdapter> _resourceStateAdapters = new HashMap<String, ResourceStateAdapter>();
 
-    protected HashMap<Integer, List<ResourceListener>> _lifeCycleListeners = new HashMap<Integer, List<ResourceListener>>();
+    private final HashMap<Integer, List<ResourceListener>> _lifeCycleListeners = new HashMap<Integer, List<ResourceListener>>();
     private HypervisorType _defaultSystemVMHypervisor;
 
     private static final int ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION = 30; // seconds

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7f34282d/server/src/com/cloud/server/ManagementServerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java
index 9dc9dda..ec40411 100755
--- a/server/src/com/cloud/server/ManagementServerImpl.java
+++ b/server/src/com/cloud/server/ManagementServerImpl.java
@@ -40,6 +40,9 @@ import javax.crypto.spec.SecretKeySpec;
 import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
+import org.apache.commons.codec.binary.Base64;
+import org.apache.log4j.Logger;
+
 import org.apache.cloudstack.acl.ControlledEntity;
 import org.apache.cloudstack.acl.SecurityChecker.AccessType;
 import org.apache.cloudstack.affinity.AffinityGroupProcessor;
@@ -438,7 +441,6 @@ import org.apache.cloudstack.context.CallContext;
 import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
 import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
 import org.apache.cloudstack.framework.config.ConfigDepot;
 import org.apache.cloudstack.framework.config.ConfigKey;
 import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
@@ -450,8 +452,6 @@ import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
 import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
 import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
 import org.apache.cloudstack.utils.identity.ManagementServerNode;
-import org.apache.commons.codec.binary.Base64;
-import org.apache.log4j.Logger;
 
 import com.cloud.agent.AgentManager;
 import com.cloud.agent.api.GetVncPortAnswer;
@@ -468,7 +468,6 @@ import com.cloud.capacity.dao.CapacityDao;
 import com.cloud.capacity.dao.CapacityDaoImpl.SummedCapacity;
 import com.cloud.cluster.ClusterManager;
 import com.cloud.configuration.Config;
-import com.cloud.configuration.ConfigurationManager;
 import com.cloud.consoleproxy.ConsoleProxyManagementState;
 import com.cloud.consoleproxy.ConsoleProxyManager;
 import com.cloud.dc.AccountVlanMapVO;
@@ -553,7 +552,6 @@ import com.cloud.storage.dao.GuestOSDao;
 import com.cloud.storage.dao.VMTemplateDao;
 import com.cloud.storage.dao.VolumeDao;
 import com.cloud.storage.secondary.SecondaryStorageVmManager;
-import com.cloud.storage.snapshot.SnapshotManager;
 import com.cloud.tags.ResourceTagVO;
 import com.cloud.tags.dao.ResourceTagDao;
 import com.cloud.template.TemplateManager;
@@ -699,38 +697,28 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
     private ImageStoreDao _imgStoreDao;
 
     @Inject
-    ProjectManager _projectMgr;
-    @Inject
-    ResourceManager _resourceMgr;
-    @Inject
-    SnapshotManager _snapshotMgr;
-    @Inject
-    HighAvailabilityManager _haMgr;
-    @Inject
-    TemplateManager templateMgr;
-    @Inject
-    DataStoreManager dataStoreMgr;
+    private ProjectManager _projectMgr;
     @Inject
-    HostTagsDao _hostTagsDao;
+    private ResourceManager _resourceMgr;
     @Inject
-    ConfigurationServer _configServer;
+    private HighAvailabilityManager _haMgr;
     @Inject
-    ConfigDepot _configDepot;
+    private DataStoreManager dataStoreMgr;
     @Inject
-    UserVmManager _userVmMgr;
+    private HostTagsDao _hostTagsDao;
     @Inject
-    VolumeDataFactory _volFactory;
+    private ConfigDepot _configDepot;
     @Inject
-    AccountService _accountService;
+    private UserVmManager _userVmMgr;
     @Inject
-    ConfigurationManager _configMgr;
+    private AccountService _accountService;
     @Inject
-    ServiceOfferingDao _offeringDao;
+    private ServiceOfferingDao _offeringDao;
 
     @Inject
-    DeploymentPlanningManager _dpMgr;
+    private DeploymentPlanningManager _dpMgr;
 
-    LockMasterListener _lockMasterListener;
+    private LockMasterListener _lockMasterListener;
 
     private final ScheduledExecutorService _eventExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("EventChecker"));
     private final ScheduledExecutorService _alertExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("AlertChecker"));

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7f34282d/server/src/com/cloud/storage/VolumeApiServiceImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/com/cloud/storage/VolumeApiServiceImpl.java
index d4fa8c1..252d925 100644
--- a/server/src/com/cloud/storage/VolumeApiServiceImpl.java
+++ b/server/src/com/cloud/storage/VolumeApiServiceImpl.java
@@ -26,6 +26,8 @@ import java.util.concurrent.ExecutionException;
 
 import javax.inject.Inject;
 
+import org.apache.log4j.Logger;
+
 import org.apache.cloudstack.api.command.user.volume.AttachVolumeCmd;
 import org.apache.cloudstack.api.command.user.volume.CreateVolumeCmd;
 import org.apache.cloudstack.api.command.user.volume.DetachVolumeCmd;
@@ -38,14 +40,10 @@ import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationSer
 import org.apache.cloudstack.engine.subsystem.api.storage.ChapInfo;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProviderManager;
 import org.apache.cloudstack.engine.subsystem.api.storage.HostScope;
 import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo;
 import org.apache.cloudstack.engine.subsystem.api.storage.Scope;
-import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory;
-import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotService;
 import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator;
-import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory;
 import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
 import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
 import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService;
@@ -68,37 +66,27 @@ import org.apache.cloudstack.storage.command.DettachCommand;
 import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
 import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao;
 import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
-import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
 import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao;
 import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO;
 import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity;
 import org.apache.cloudstack.utils.identity.ManagementServerNode;
-import org.apache.log4j.Logger;
 
 import com.cloud.agent.AgentManager;
 import com.cloud.agent.api.Answer;
 import com.cloud.agent.api.to.DataTO;
 import com.cloud.agent.api.to.DiskTO;
-import com.cloud.alert.AlertManager;
 import com.cloud.api.ApiDBUtils;
-import com.cloud.capacity.CapacityManager;
-import com.cloud.capacity.dao.CapacityDao;
 import com.cloud.configuration.Config;
 import com.cloud.configuration.ConfigurationManager;
 import com.cloud.configuration.Resource.ResourceType;
-import com.cloud.consoleproxy.ConsoleProxyManager;
 import com.cloud.dc.ClusterVO;
 import com.cloud.dc.DataCenter;
 import com.cloud.dc.DataCenterVO;
-import com.cloud.dc.dao.ClusterDao;
 import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.dc.dao.HostPodDao;
 import com.cloud.domain.Domain;
-import com.cloud.domain.dao.DomainDao;
 import com.cloud.event.ActionEvent;
 import com.cloud.event.EventTypes;
 import com.cloud.event.UsageEventUtils;
-import com.cloud.event.dao.EventDao;
 import com.cloud.exception.ConcurrentOperationException;
 import com.cloud.exception.InvalidParameterValueException;
 import com.cloud.exception.PermissionDeniedException;
@@ -108,29 +96,15 @@ import com.cloud.host.HostVO;
 import com.cloud.host.dao.HostDao;
 import com.cloud.hypervisor.Hypervisor.HypervisorType;
 import com.cloud.hypervisor.HypervisorCapabilitiesVO;
-import com.cloud.hypervisor.HypervisorGuruManager;
 import com.cloud.hypervisor.dao.HypervisorCapabilitiesDao;
-import com.cloud.network.NetworkModel;
 import com.cloud.org.Grouping;
-import com.cloud.resource.ResourceManager;
-import com.cloud.server.ManagementServer;
-import com.cloud.service.dao.ServiceOfferingDao;
 import com.cloud.storage.Storage.ImageFormat;
 import com.cloud.storage.dao.DiskOfferingDao;
 import com.cloud.storage.dao.SnapshotDao;
-import com.cloud.storage.dao.SnapshotPolicyDao;
-import com.cloud.storage.dao.StoragePoolHostDao;
-import com.cloud.storage.dao.StoragePoolWorkDao;
 import com.cloud.storage.dao.VMTemplateDao;
-import com.cloud.storage.dao.VMTemplatePoolDao;
 import com.cloud.storage.dao.VolumeDao;
-import com.cloud.storage.dao.VolumeDetailsDao;
-import com.cloud.storage.download.DownloadMonitor;
-import com.cloud.storage.secondary.SecondaryStorageVmManager;
 import com.cloud.storage.snapshot.SnapshotApiService;
 import com.cloud.storage.snapshot.SnapshotManager;
-import com.cloud.storage.snapshot.SnapshotScheduler;
-import com.cloud.tags.dao.ResourceTagDao;
 import com.cloud.template.TemplateManager;
 import com.cloud.user.Account;
 import com.cloud.user.AccountManager;
@@ -138,7 +112,6 @@ import com.cloud.user.ResourceLimitService;
 import com.cloud.user.User;
 import com.cloud.user.VmDiskStatisticsVO;
 import com.cloud.user.dao.AccountDao;
-import com.cloud.user.dao.UserDao;
 import com.cloud.user.dao.VmDiskStatisticsDao;
 import com.cloud.utils.EnumUtils;
 import com.cloud.utils.NumbersUtil;
@@ -155,20 +128,15 @@ import com.cloud.utils.db.UUIDManager;
 import com.cloud.utils.exception.CloudRuntimeException;
 import com.cloud.utils.fsm.NoTransitionException;
 import com.cloud.utils.fsm.StateMachine2;
-import com.cloud.vm.UserVmManager;
 import com.cloud.vm.UserVmVO;
 import com.cloud.vm.VMInstanceVO;
 import com.cloud.vm.VirtualMachine;
 import com.cloud.vm.VirtualMachine.State;
-import com.cloud.vm.VirtualMachineManager;
 import com.cloud.vm.VmWork;
 import com.cloud.vm.VmWorkConstants;
 import com.cloud.vm.VmWorkJobHandler;
 import com.cloud.vm.VmWorkJobHandlerProxy;
 import com.cloud.vm.VmWorkSerializer;
-import com.cloud.vm.dao.ConsoleProxyDao;
-import com.cloud.vm.dao.DomainRouterDao;
-import com.cloud.vm.dao.SecondaryStorageVmDao;
 import com.cloud.vm.dao.UserVmDao;
 import com.cloud.vm.dao.VMInstanceDao;
 import com.cloud.vm.snapshot.VMSnapshotVO;
@@ -180,153 +148,73 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
     public static final String VM_WORK_JOB_HANDLER = VolumeApiServiceImpl.class.getSimpleName();
 
     @Inject
-    VolumeOrchestrationService _volumeMgr;
+    private VolumeOrchestrationService _volumeMgr;
 
     @Inject
-    EntityManager _entityMgr;
-    @Inject
-    protected UserVmManager _userVmMgr;
-    @Inject
-    protected AgentManager _agentMgr;
-    @Inject
-    protected TemplateManager _tmpltMgr;
-    @Inject
-    protected AsyncJobManager _asyncMgr;
-    @Inject
-    protected SnapshotManager _snapshotMgr;
-    @Inject
-    protected SnapshotScheduler _snapshotScheduler;
-    @Inject
-    protected AccountManager _accountMgr;
-    @Inject
-    protected ConfigurationManager _configMgr;
+    private EntityManager _entityMgr;
     @Inject
-    protected ConsoleProxyManager _consoleProxyMgr;
+    private AgentManager _agentMgr;
     @Inject
-    protected SecondaryStorageVmManager _secStorageMgr;
+    private TemplateManager _tmpltMgr;
     @Inject
-    protected NetworkModel _networkMgr;
+    private AsyncJobManager _asyncMgr;
     @Inject
-    protected ServiceOfferingDao _serviceOfferingDao;
+    private SnapshotManager _snapshotMgr;
     @Inject
-    protected VolumeDao _volsDao;
+    private AccountManager _accountMgr;
     @Inject
-    protected HostDao _hostDao;
+    private ConfigurationManager _configMgr;
     @Inject
-    protected ConsoleProxyDao _consoleProxyDao;
+    private VolumeDao _volsDao;
     @Inject
-    protected SnapshotDao _snapshotDao;
+    private HostDao _hostDao;
     @Inject
-    protected SnapshotManager _snapMgr;
-    @Inject
-    protected SnapshotPolicyDao _snapshotPolicyDao;
-    @Inject
-    protected StoragePoolHostDao _storagePoolHostDao;
+    private SnapshotDao _snapshotDao;
     @Inject
     StoragePoolDetailsDao storagePoolDetailsDao;
     @Inject
-    protected AlertManager _alertMgr;
-    @Inject
-    protected TemplateDataStoreDao _vmTemplateStoreDao = null;
-    @Inject
-    protected VMTemplatePoolDao _vmTemplatePoolDao = null;
-    @Inject
-    protected VMTemplateDao _vmTemplateDao = null;
-    @Inject
-    protected StoragePoolHostDao _poolHostDao = null;
-    @Inject
-    protected UserVmDao _userVmDao;
+    private UserVmDao _userVmDao;
     @Inject
     VolumeDataStoreDao _volumeStoreDao;
     @Inject
-    protected VMInstanceDao _vmInstanceDao;
-    @Inject
-    protected PrimaryDataStoreDao _storagePoolDao = null;
-    @Inject
-    protected CapacityDao _capacityDao;
-    @Inject
-    protected CapacityManager _capacityMgr;
-    @Inject
-    protected DiskOfferingDao _diskOfferingDao;
+    private VMInstanceDao _vmInstanceDao;
     @Inject
-    protected AccountDao _accountDao;
+    private final PrimaryDataStoreDao _storagePoolDao = null;
     @Inject
-    protected EventDao _eventDao = null;
+    private DiskOfferingDao _diskOfferingDao;
     @Inject
-    protected DataCenterDao _dcDao = null;
+    private AccountDao _accountDao;
     @Inject
-    protected HostPodDao _podDao = null;
+    private final DataCenterDao _dcDao = null;
     @Inject
-    protected VMTemplateDao _templateDao;
+    private VMTemplateDao _templateDao;
     @Inject
-    protected ServiceOfferingDao _offeringDao;
+    private VolumeDao _volumeDao;
     @Inject
-    protected DomainDao _domainDao;
+    private ResourceLimitService _resourceLimitMgr;
     @Inject
-    protected UserDao _userDao;
+    private VmDiskStatisticsDao _vmDiskStatsDao;
     @Inject
-    protected ClusterDao _clusterDao;
+    private VMSnapshotDao _vmSnapshotDao;
+    private List<StoragePoolAllocator> _storagePoolAllocators;
     @Inject
-    protected VirtualMachineManager _vmMgr;
+    private ConfigurationDao _configDao;
     @Inject
-    protected DomainRouterDao _domrDao;
+    private DataStoreManager dataStoreMgr;
     @Inject
-    protected SecondaryStorageVmDao _secStrgDao;
+    private VolumeService volService;
     @Inject
-    protected StoragePoolWorkDao _storagePoolWorkDao;
+    private VolumeDataFactory volFactory;
     @Inject
-    protected HypervisorGuruManager _hvGuruMgr;
+    private SnapshotApiService snapshotMgr;
     @Inject
-    protected VolumeDao _volumeDao;
-    @Inject
-    protected OCFS2Manager _ocfs2Mgr;
-    @Inject
-    protected ResourceLimitService _resourceLimitMgr;
-    @Inject
-    protected SecondaryStorageVmManager _ssvmMgr;
-    @Inject
-    protected ResourceManager _resourceMgr;
-    @Inject
-    protected DownloadMonitor _downloadMonitor;
-    @Inject
-    protected ResourceTagDao _resourceTagDao;
-    @Inject
-    protected VmDiskStatisticsDao _vmDiskStatsDao;
-    @Inject
-    protected VMSnapshotDao _vmSnapshotDao;
-    protected List<StoragePoolAllocator> _storagePoolAllocators;
-    @Inject
-    ConfigurationDao _configDao;
-    @Inject
-    VolumeDetailsDao _volDetailDao;
-    @Inject
-    ManagementServer _msServer;
-    @Inject
-    DataStoreManager dataStoreMgr;
-    @Inject
-    DataStoreProviderManager dataStoreProviderMgr;
-    @Inject
-    VolumeService volService;
-    @Inject
-    VolumeDataFactory volFactory;
-    @Inject
-    TemplateDataFactory tmplFactory;
-    @Inject
-    SnapshotDataFactory snapshotFactory;
-    @Inject
-    SnapshotApiService snapshotMgr;
-    @Inject
-    SnapshotService snapshotSrv;
-    @Inject
-    UUIDManager _uuidMgr;
+    private UUIDManager _uuidMgr;
 
     @Inject
-    protected HypervisorCapabilitiesDao _hypervisorCapabilitiesDao;
-    @Inject
-    StorageManager storageMgr;
+    private HypervisorCapabilitiesDao _hypervisorCapabilitiesDao;
 
     @Inject
-    protected AsyncJobManager _jobMgr;
+    private AsyncJobManager _jobMgr;
 
     @Inject
     protected VmWorkJobDao _workJobDao;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7f34282d/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 33278af..1b44a12 100755
--- a/server/src/com/cloud/storage/download/DownloadMonitorImpl.java
+++ b/server/src/com/cloud/storage/download/DownloadMonitorImpl.java
@@ -31,10 +31,8 @@ import org.springframework.stereotype.Component;
 
 import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
 import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
 import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
-import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory;
 import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
 import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
 import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
@@ -42,7 +40,6 @@ import org.apache.cloudstack.storage.command.DownloadCommand;
 import org.apache.cloudstack.storage.command.DownloadCommand.ResourceType;
 import org.apache.cloudstack.storage.command.DownloadProgressCommand;
 import org.apache.cloudstack.storage.command.DownloadProgressCommand.RequestType;
-import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
 import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
 import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
 import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao;
@@ -60,7 +57,6 @@ import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
 import com.cloud.storage.Volume;
 import com.cloud.storage.dao.VMTemplateDao;
 import com.cloud.storage.dao.VolumeDao;
-import com.cloud.storage.secondary.SecondaryStorageVmManager;
 import com.cloud.storage.template.TemplateConstants;
 import com.cloud.storage.upload.UploadListener;
 import com.cloud.template.VirtualMachineTemplate;
@@ -74,39 +70,28 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor
     static final Logger s_logger = Logger.getLogger(DownloadMonitorImpl.class);
 
     @Inject
-    TemplateDataStoreDao _vmTemplateStoreDao;
+    private TemplateDataStoreDao _vmTemplateStoreDao;
     @Inject
-    ImageStoreDao _imageStoreDao;
+    private VolumeDao _volumeDao;
     @Inject
-    VolumeDao _volumeDao;
+    private VolumeDataStoreDao _volumeStoreDao;
     @Inject
-    VolumeDataStoreDao _volumeStoreDao;
-    @Inject
-    VMTemplateDao _templateDao = null;
+    private final VMTemplateDao _templateDao = null;
     @Inject
     private AgentManager _agentMgr;
     @Inject
-    SecondaryStorageVmManager _secMgr;
-    @Inject
-    ConfigurationDao _configDao;
-    @Inject
-    EndPointSelector _epSelector;
+    private ConfigurationDao _configDao;
     @Inject
-    TemplateDataFactory tmplFactory;
+    private EndPointSelector _epSelector;
 
-    private Boolean _sslCopy = new Boolean(false);
     private String _copyAuthPasswd;
     private String _proxy = null;
 
-    Timer _timer;
-
-    @Inject
-    DataStoreManager storeMgr;
+    private Timer _timer;
 
     @Override
     public boolean configure(String name, Map<String, Object> params) {
         final Map<String, String> configs = _configDao.getConfiguration("management-server", params);
-        _sslCopy = Boolean.parseBoolean(configs.get("secstorage.encrypt.copy"));
         _proxy = configs.get(Config.SecStorageProxy.key());
 
         String cert = configs.get("secstorage.ssl.cert.domain");

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7f34282d/server/src/com/cloud/storage/secondary/SecondaryStorageListener.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/secondary/SecondaryStorageListener.java b/server/src/com/cloud/storage/secondary/SecondaryStorageListener.java
index 4215fa6..43613e7 100755
--- a/server/src/com/cloud/storage/secondary/SecondaryStorageListener.java
+++ b/server/src/com/cloud/storage/secondary/SecondaryStorageListener.java
@@ -18,7 +18,6 @@ package com.cloud.storage.secondary;
 
 import org.apache.log4j.Logger;
 
-import com.cloud.agent.AgentManager;
 import com.cloud.agent.Listener;
 import com.cloud.agent.api.AgentControlAnswer;
 import com.cloud.agent.api.AgentControlCommand;
@@ -35,11 +34,9 @@ public class SecondaryStorageListener implements Listener {
     private final static Logger s_logger = Logger.getLogger(SecondaryStorageListener.class);
 
     SecondaryStorageVmManager _ssVmMgr = null;
-    AgentManager _agentMgr = null;
 
-    public SecondaryStorageListener(SecondaryStorageVmManager ssVmMgr, AgentManager agentMgr) {
+    public SecondaryStorageListener(SecondaryStorageVmManager ssVmMgr) {
         _ssVmMgr = ssVmMgr;
-        _agentMgr = agentMgr;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7f34282d/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 a5d3d4c..484dfbd 100755
--- a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java
+++ b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java
@@ -211,8 +211,6 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar
     UserVmDetailsDao _vmDetailsDao;
     @Inject
     protected ResourceManager _resourceMgr;
-    //@Inject            // TODO this is a very strange usage, a singleton class need to inject itself?
-    protected SecondaryStorageVmManager _ssvmMgr;
     @Inject
     NetworkDao _networkDao;
     @Inject
@@ -250,7 +248,6 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar
     private final GlobalLock _allocLock = GlobalLock.getInternLock(getAllocLockName());
 
     public SecondaryStorageManagerImpl() {
-        _ssvmMgr = this;
     }
 
     @Override
@@ -825,7 +822,7 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar
         value = agentMgrConfigs.get("port");
         _mgmtPort = NumbersUtil.parseInt(value, 8250);
 
-        _listener = new SecondaryStorageListener(this, _agentMgr);
+        _listener = new SecondaryStorageListener(this);
         _agentMgr.registerForHostEvents(_listener, true, false, true);
 
         _itMgr.registerGuru(VirtualMachine.Type.SecondaryStorageVm, this);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7f34282d/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java
index a9eae7d..821f43a 100755
--- a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java
+++ b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java
@@ -34,7 +34,6 @@ import org.apache.cloudstack.api.command.user.snapshot.DeleteSnapshotPoliciesCmd
 import org.apache.cloudstack.api.command.user.snapshot.ListSnapshotPoliciesCmd;
 import org.apache.cloudstack.api.command.user.snapshot.ListSnapshotsCmd;
 import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
 import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
 import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
@@ -54,7 +53,6 @@ import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao;
 import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
 import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
 
-import com.cloud.agent.AgentManager;
 import com.cloud.agent.api.Answer;
 import com.cloud.agent.api.Command;
 import com.cloud.agent.api.DeleteSnapshotsDirCommand;
@@ -64,7 +62,6 @@ import com.cloud.configuration.Config;
 import com.cloud.configuration.Resource.ResourceType;
 import com.cloud.dc.ClusterVO;
 import com.cloud.dc.dao.ClusterDao;
-import com.cloud.dc.dao.DataCenterDao;
 import com.cloud.domain.dao.DomainDao;
 import com.cloud.event.ActionEvent;
 import com.cloud.event.ActionEventUtils;
@@ -94,17 +91,14 @@ import com.cloud.storage.StoragePool;
 import com.cloud.storage.VMTemplateVO;
 import com.cloud.storage.Volume;
 import com.cloud.storage.VolumeVO;
-import com.cloud.storage.dao.DiskOfferingDao;
 import com.cloud.storage.dao.SnapshotDao;
 import com.cloud.storage.dao.SnapshotPolicyDao;
 import com.cloud.storage.dao.SnapshotScheduleDao;
 import com.cloud.storage.dao.VMTemplateDao;
 import com.cloud.storage.dao.VolumeDao;
-import com.cloud.storage.secondary.SecondaryStorageVmManager;
 import com.cloud.storage.template.TemplateConstants;
 import com.cloud.tags.ResourceTagVO;
 import com.cloud.tags.dao.ResourceTagDao;
-import com.cloud.template.TemplateManager;
 import com.cloud.user.Account;
 import com.cloud.user.AccountManager;
 import com.cloud.user.AccountVO;
@@ -138,46 +132,38 @@ import com.cloud.vm.snapshot.dao.VMSnapshotDao;
 public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, SnapshotApiService {
     private static final Logger s_logger = Logger.getLogger(SnapshotManagerImpl.class);
     @Inject
-    protected VMTemplateDao _templateDao;
+    private VMTemplateDao _templateDao;
     @Inject
-    protected UserVmDao _vmDao;
+    private UserVmDao _vmDao;
     @Inject
-    protected VolumeDao _volsDao;
+    private VolumeDao _volsDao;
     @Inject
-    protected AccountDao _accountDao;
+    private AccountDao _accountDao;
     @Inject
-    protected DataCenterDao _dcDao;
+    private SnapshotDao _snapshotDao;
     @Inject
-    protected DiskOfferingDao _diskOfferingDao;
+    private SnapshotDataStoreDao _snapshotStoreDao;
     @Inject
-    protected SnapshotDao _snapshotDao;
+    private PrimaryDataStoreDao _storagePoolDao;
     @Inject
-    protected SnapshotDataStoreDao _snapshotStoreDao;
+    private final SnapshotPolicyDao _snapshotPolicyDao = null;
     @Inject
-    protected PrimaryDataStoreDao _storagePoolDao;
+    private SnapshotScheduleDao _snapshotScheduleDao;
     @Inject
-    protected SnapshotPolicyDao _snapshotPolicyDao = null;
+    private DomainDao _domainDao;
     @Inject
-    protected SnapshotScheduleDao _snapshotScheduleDao;
+    private StorageManager _storageMgr;
     @Inject
-    protected DomainDao _domainDao;
+    private SnapshotScheduler _snapSchedMgr;
     @Inject
-    protected StorageManager _storageMgr;
-    @Inject
-    protected AgentManager _agentMgr;
-    @Inject
-    protected SnapshotScheduler _snapSchedMgr;
-    @Inject
-    protected AccountManager _accountMgr;
+    private AccountManager _accountMgr;
     @Inject
     private AlertManager _alertMgr;
     @Inject
-    protected ClusterDao _clusterDao;
+    private ClusterDao _clusterDao;
     @Inject
     private ResourceLimitService _resourceLimitMgr;
     @Inject
-    private SecondaryStorageVmManager _ssvmMgr;
-    @Inject
     private DomainManager _domainMgr;
     @Inject
     private ResourceTagDao _resourceTagDao;
@@ -185,33 +171,23 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager,
     private ConfigurationDao _configDao;
     @Inject
     private VMSnapshotDao _vmSnapshotDao;
-    String _name;
     @Inject
-    TemplateManager templateMgr;
+    private DataStoreManager dataStoreMgr;
     @Inject
-    VolumeOrchestrationService volumeMgr;
+    private SnapshotService snapshotSrv;
     @Inject
-    DataStoreManager dataStoreMgr;
+    private VolumeDataFactory volFactory;
     @Inject
-    SnapshotService snapshotSrv;
+    private SnapshotDataFactory snapshotFactory;
     @Inject
-    VolumeDataFactory volFactory;
-    @Inject
-    SnapshotDataFactory snapshotFactory;
-    @Inject
-    EndPointSelector _epSelector;
+    private EndPointSelector _epSelector;
     @Inject
     private ResourceManager _resourceMgr;
     @Inject
-    StorageStrategyFactory _storageStrategyFactory;
+    private StorageStrategyFactory _storageStrategyFactory;
 
     private int _totalRetries;
     private int _pauseInterval;
-    private int _backupsnapshotwait;
-    Boolean backup;
-
-    protected SearchBuilder<SnapshotVO> PolicySnapshotSearch;
-    protected SearchBuilder<SnapshotPolicyVO> PoliciesForSnapSearch;
 
     @Override
     public Answer sendToPool(Volume vol, Command cmd) {
@@ -970,8 +946,6 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager,
     public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
 
         String value = _configDao.getValue(Config.BackupSnapshotWait.toString());
-        _backupsnapshotwait = NumbersUtil.parseInt(value, Integer.parseInt(Config.BackupSnapshotWait.getDefaultValue()));
-        backup = Boolean.parseBoolean(_configDao.getValue(Config.BackupSnapshotAfterTakingSnapshot.toString()));
 
         Type.HOURLY.setMax(NumbersUtil.parseInt(_configDao.getValue("snapshot.max.hourly"), HOURLYMAX));
         Type.DAILY.setMax(NumbersUtil.parseInt(_configDao.getValue("snapshot.max.daily"), DAILYMAX));

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7f34282d/server/src/com/cloud/storage/upload/UploadMonitorImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/upload/UploadMonitorImpl.java b/server/src/com/cloud/storage/upload/UploadMonitorImpl.java
index 6f1f5e9..8a997b2 100755
--- a/server/src/com/cloud/storage/upload/UploadMonitorImpl.java
+++ b/server/src/com/cloud/storage/upload/UploadMonitorImpl.java
@@ -67,8 +67,6 @@ import com.cloud.storage.UploadVO;
 import com.cloud.storage.VMTemplateVO;
 import com.cloud.storage.VolumeVO;
 import com.cloud.storage.dao.UploadDao;
-import com.cloud.storage.dao.VMTemplateDao;
-import com.cloud.storage.secondary.SecondaryStorageVmManager;
 import com.cloud.utils.NumbersUtil;
 import com.cloud.utils.component.ManagerBase;
 import com.cloud.utils.concurrency.NamedThreadFactory;
@@ -89,35 +87,30 @@ public class UploadMonitorImpl extends ManagerBase implements UploadMonitor {
     static final Logger s_logger = Logger.getLogger(UploadMonitorImpl.class);
 
     @Inject
-    UploadDao _uploadDao;
+    private UploadDao _uploadDao;
     @Inject
-    SecondaryStorageVmDao _secStorageVmDao;
+    private SecondaryStorageVmDao _secStorageVmDao;
 
     @Inject
-    HostDao _serverDao = null;
-    @Inject
-    VMTemplateDao _templateDao = null;
+    private final HostDao _serverDao = null;
     @Inject
     private AgentManager _agentMgr;
     @Inject
-    ConfigurationDao _configDao;
-    @Inject
-    ResourceManager _resourceMgr;
+    private ConfigurationDao _configDao;
     @Inject
-    SecondaryStorageVmManager _ssvmMgr;
+    private ResourceManager _resourceMgr;
     @Inject
-    EndPointSelector _epSelector;
+    private EndPointSelector _epSelector;
     @Inject
-    DataStoreManager storeMgr;
+    private DataStoreManager storeMgr;
 
-    private String _name;
     private Boolean _sslCopy = new Boolean(false);
     private String _ssvmUrlDomain;
     private ScheduledExecutorService _executor = null;
 
-    Timer _timer;
-    int _cleanupInterval;
-    int _urlExpirationInterval;
+    private Timer _timer;
+    private int _cleanupInterval;
+    private int _urlExpirationInterval;
 
     final Map<UploadVO, UploadListener> _listenerMap = new ConcurrentHashMap<UploadVO, UploadListener>();
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7f34282d/server/src/com/cloud/template/TemplateManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java
index 93e3c59..70e4a49 100755
--- a/server/src/com/cloud/template/TemplateManagerImpl.java
+++ b/server/src/com/cloud/template/TemplateManagerImpl.java
@@ -72,12 +72,10 @@ import org.apache.cloudstack.framework.async.AsyncCallFuture;
 import org.apache.cloudstack.framework.config.ConfigKey;
 import org.apache.cloudstack.framework.config.Configurable;
 import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.framework.jobs.AsyncJobManager;
 import org.apache.cloudstack.managed.context.ManagedContextRunnable;
 import org.apache.cloudstack.storage.command.AttachCommand;
 import org.apache.cloudstack.storage.command.CommandResult;
 import org.apache.cloudstack.storage.command.DettachCommand;
-import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
 import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
 import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
 import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
@@ -99,7 +97,6 @@ import com.cloud.configuration.Config;
 import com.cloud.configuration.Resource.ResourceType;
 import com.cloud.dc.DataCenter;
 import com.cloud.dc.DataCenterVO;
-import com.cloud.dc.dao.ClusterDao;
 import com.cloud.dc.dao.DataCenterDao;
 import com.cloud.domain.Domain;
 import com.cloud.domain.dao.DomainDao;
@@ -107,7 +104,6 @@ import com.cloud.event.ActionEvent;
 import com.cloud.event.EventTypes;
 import com.cloud.event.UsageEventUtils;
 import com.cloud.event.UsageEventVO;
-import com.cloud.event.dao.EventDao;
 import com.cloud.event.dao.UsageEventDao;
 import com.cloud.exception.InvalidParameterValueException;
 import com.cloud.exception.PermissionDeniedException;
@@ -117,11 +113,8 @@ import com.cloud.host.HostVO;
 import com.cloud.host.dao.HostDao;
 import com.cloud.hypervisor.Hypervisor;
 import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.hypervisor.HypervisorGuruManager;
 import com.cloud.projects.Project;
 import com.cloud.projects.ProjectManager;
-import com.cloud.resource.ResourceManager;
-import com.cloud.server.ConfigurationServer;
 import com.cloud.storage.DataStoreRole;
 import com.cloud.storage.GuestOSVO;
 import com.cloud.storage.LaunchPermissionVO;
@@ -148,16 +141,10 @@ import com.cloud.storage.dao.GuestOSDao;
 import com.cloud.storage.dao.LaunchPermissionDao;
 import com.cloud.storage.dao.SnapshotDao;
 import com.cloud.storage.dao.StoragePoolHostDao;
-import com.cloud.storage.dao.UploadDao;
 import com.cloud.storage.dao.VMTemplateDao;
-import com.cloud.storage.dao.VMTemplateDetailsDao;
-import com.cloud.storage.dao.VMTemplateHostDao;
 import com.cloud.storage.dao.VMTemplatePoolDao;
 import com.cloud.storage.dao.VMTemplateZoneDao;
 import com.cloud.storage.dao.VolumeDao;
-import com.cloud.storage.download.DownloadMonitor;
-import com.cloud.storage.secondary.SecondaryStorageVmManager;
-import com.cloud.storage.upload.UploadMonitor;
 import com.cloud.template.TemplateAdapter.TemplateAdapterType;
 import com.cloud.user.Account;
 import com.cloud.user.AccountManager;
@@ -166,11 +153,8 @@ import com.cloud.user.AccountVO;
 import com.cloud.user.ResourceLimitService;
 import com.cloud.user.User;
 import com.cloud.user.dao.AccountDao;
-import com.cloud.user.dao.UserAccountDao;
-import com.cloud.user.dao.UserDao;
 import com.cloud.uservm.UserVm;
 import com.cloud.utils.EnumUtils;
-import com.cloud.utils.NumbersUtil;
 import com.cloud.utils.Pair;
 import com.cloud.utils.component.AdapterBase;
 import com.cloud.utils.component.ManagerBase;
@@ -180,12 +164,10 @@ import com.cloud.utils.db.Transaction;
 import com.cloud.utils.db.TransactionCallbackNoReturn;
 import com.cloud.utils.db.TransactionStatus;
 import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.vm.UserVmManager;
 import com.cloud.vm.UserVmVO;
 import com.cloud.vm.VMInstanceVO;
 import com.cloud.vm.VirtualMachine.State;
 import com.cloud.vm.dao.UserVmDao;
-import com.cloud.vm.dao.UserVmDetailsDao;
 import com.cloud.vm.dao.VMInstanceDao;
 
 @Local(value = {TemplateManager.class, TemplateApiService.class})
@@ -193,116 +175,78 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
     private final static Logger s_logger = Logger.getLogger(TemplateManagerImpl.class);
 
     @Inject
-    VMTemplateDao _tmpltDao;
+    private VMTemplateDao _tmpltDao;
     @Inject
-    TemplateDataStoreDao _tmplStoreDao;
+    private TemplateDataStoreDao _tmplStoreDao;
     @Inject
-    VMTemplatePoolDao _tmpltPoolDao;
+    private VMTemplatePoolDao _tmpltPoolDao;
     @Inject
-    VMTemplateZoneDao _tmpltZoneDao;
+    private VMTemplateZoneDao _tmpltZoneDao;
     @Inject
-    protected UserVmDetailsDao _vmDetailsDao;
+    private VMInstanceDao _vmInstanceDao;
     @Inject
-    protected VMTemplateDetailsDao _templateDetailsDao;
+    private PrimaryDataStoreDao _poolDao;
     @Inject
-    VMInstanceDao _vmInstanceDao;
+    private StoragePoolHostDao _poolHostDao;
     @Inject
-    PrimaryDataStoreDao _poolDao;
+    private AccountDao _accountDao;
     @Inject
-    StoragePoolHostDao _poolHostDao;
+    private AgentManager _agentMgr;
     @Inject
-    EventDao _eventDao;
+    private AccountManager _accountMgr;
     @Inject
-    DownloadMonitor _downloadMonitor;
+    private HostDao _hostDao;
     @Inject
-    UploadMonitor _uploadMonitor;
+    private DataCenterDao _dcDao;
     @Inject
-    UserAccountDao _userAccountDao;
+    private UserVmDao _userVmDao;
     @Inject
-    AccountDao _accountDao;
+    private VolumeDao _volumeDao;
     @Inject
-    UserDao _userDao;
+    private SnapshotDao _snapshotDao;
     @Inject
-    AgentManager _agentMgr;
+    private ConfigurationDao _configDao;
     @Inject
-    AccountManager _accountMgr;
+    private DomainDao _domainDao;
     @Inject
-    HostDao _hostDao;
+    private GuestOSDao _guestOSDao;
     @Inject
-    DataCenterDao _dcDao;
+    private StorageManager _storageMgr;
     @Inject
-    UserVmDao _userVmDao;
+    private UsageEventDao _usageEventDao;
     @Inject
-    VolumeDao _volumeDao;
+    private AccountService _accountService;
     @Inject
-    SnapshotDao _snapshotDao;
+    private ResourceLimitService _resourceLimitMgr;
     @Inject
-    ConfigurationDao _configDao;
+    private LaunchPermissionDao _launchPermissionDao;
     @Inject
-    ClusterDao _clusterDao;
+    private ProjectManager _projectMgr;
     @Inject
-    DomainDao _domainDao;
+    private VolumeDataFactory _volFactory;
     @Inject
-    UploadDao _uploadDao;
+    private TemplateDataFactory _tmplFactory;
     @Inject
-    protected GuestOSDao _guestOSDao;
+    private SnapshotDataFactory _snapshotFactory;
     @Inject
-    StorageManager _storageMgr;
+    private TemplateService _tmpltSvr;
     @Inject
-    AsyncJobManager _asyncMgr;
+    private DataStoreManager _dataStoreMgr;
     @Inject
-    UserVmManager _vmMgr;
+    private VolumeOrchestrationService _volumeMgr;
     @Inject
-    UsageEventDao _usageEventDao;
+    private EndPointSelector _epSelector;
     @Inject
-    HypervisorGuruManager _hvGuruMgr;
-    @Inject
-    AccountService _accountService;
-    @Inject
-    ResourceLimitService _resourceLimitMgr;
-    @Inject
-    SecondaryStorageVmManager _ssvmMgr;
-    @Inject
-    LaunchPermissionDao _launchPermissionDao;
-    @Inject
-    ProjectManager _projectMgr;
-    @Inject
-    VolumeDataFactory _volFactory;
-    @Inject
-    TemplateDataFactory _tmplFactory;
-    @Inject
-    SnapshotDataFactory _snapshotFactory;
-    @Inject
-    TemplateService _tmpltSvr;
-    @Inject
-    DataStoreManager _dataStoreMgr;
-    @Inject
-    protected ResourceManager _resourceMgr;
-    @Inject
-    VolumeOrchestrationService _volumeMgr;
-    @Inject
-    ImageStoreDao _imageStoreDao;
-    @Inject
-    EndPointSelector _epSelector;
-    @Inject
-    UserVmJoinDao _userVmJoinDao;
-    @Inject
-    VMTemplateHostDao _vmTemplateHostDao;
-
-    @Inject
-    ConfigurationServer _configServer;
-
-    int _primaryStorageDownloadWait;
-    int _storagePoolMaxWaitSeconds = 3600;
-    boolean _disableExtraction = false;
-    ExecutorService _preloadExecutor;
+    private UserVmJoinDao _userVmJoinDao;
+    private boolean _disableExtraction = false;
+    private ExecutorService _preloadExecutor;
 
-    protected List<TemplateAdapter> _adapters;
+    private List<TemplateAdapter> _adapters;
 
     @Inject
-    StorageCacheManager cacheMgr;
+    private StorageCacheManager cacheMgr;
     @Inject
-    EndPointSelector selector;
+    private EndPointSelector selector;
 
     private TemplateAdapter getAdapter(HypervisorType type) {
         TemplateAdapter adapter = null;
@@ -842,13 +786,10 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
 
     @Override
     public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-        String value = _configDao.getValue(Config.PrimaryStorageDownloadWait.toString());
-        _primaryStorageDownloadWait = NumbersUtil.parseInt(value, Integer.parseInt(Config.PrimaryStorageDownloadWait.getDefaultValue()));
 
         String disableExtraction = _configDao.getValue(Config.DisableExtraction.toString());
         _disableExtraction = (disableExtraction == null) ? false : Boolean.parseBoolean(disableExtraction);
 
-        _storagePoolMaxWaitSeconds = NumbersUtil.parseInt(_configDao.getValue(Config.StoragePoolMaxWaitSeconds.key()), 3600);
         _preloadExecutor = Executors.newFixedThreadPool(8, new NamedThreadFactory("Template-Preloader"));
 
         return true;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7f34282d/server/test/org/apache/cloudstack/networkoffering/ChildTestConfiguration.java
----------------------------------------------------------------------
diff --git a/server/test/org/apache/cloudstack/networkoffering/ChildTestConfiguration.java b/server/test/org/apache/cloudstack/networkoffering/ChildTestConfiguration.java
index 58d02fa..22516c0 100644
--- a/server/test/org/apache/cloudstack/networkoffering/ChildTestConfiguration.java
+++ b/server/test/org/apache/cloudstack/networkoffering/ChildTestConfiguration.java
@@ -106,7 +106,6 @@ import com.cloud.storage.dao.DiskOfferingDaoImpl;
 import com.cloud.storage.dao.SnapshotDaoImpl;
 import com.cloud.storage.dao.StoragePoolDetailsDaoImpl;
 import com.cloud.storage.dao.VolumeDaoImpl;
-import com.cloud.storage.secondary.SecondaryStorageVmManager;
 import com.cloud.tags.dao.ResourceTagsDaoImpl;
 import com.cloud.user.AccountDetailsDao;
 import com.cloud.user.AccountManager;
@@ -181,11 +180,6 @@ public class ChildTestConfiguration {
     }
 
     @Bean
-    public SecondaryStorageVmManager ssvmMgr() {
-        return Mockito.mock(SecondaryStorageVmManager.class);
-    }
-
-    @Bean
     public VpcManager vpcMgr() {
         return Mockito.mock(VpcManager.class);
     }


[06/11] Moved the secondary storage service into its own server directory

Posted by ah...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4be3b993/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
new file mode 100755
index 0000000..9782c2e
--- /dev/null
+++ b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
@@ -0,0 +1,2430 @@
+// 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.mputFile;
+import static com.cloud.utils.S3Utils.putFile;
+import static com.cloud.utils.StringUtils.join;
+import static java.lang.String.format;
+import static java.util.Arrays.asList;
+import static org.apache.commons.lang.StringUtils.substringAfterLast;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.math.BigInteger;
+import java.net.InetAddress;
+import java.net.URI;
+import java.net.UnknownHostException;
+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 javax.naming.ConfigurationException;
+
+import org.apache.commons.codec.digest.DigestUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.utils.URLEncodedUtils;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.log4j.Logger;
+
+import com.amazonaws.services.s3.model.S3ObjectSummary;
+
+import org.apache.cloudstack.framework.security.keystore.KeystoreManager;
+import org.apache.cloudstack.storage.command.CopyCmdAnswer;
+import org.apache.cloudstack.storage.command.CopyCommand;
+import org.apache.cloudstack.storage.command.DeleteCommand;
+import org.apache.cloudstack.storage.command.DownloadCommand;
+import org.apache.cloudstack.storage.command.DownloadProgressCommand;
+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.cloudstack.storage.to.SnapshotObjectTO;
+import org.apache.cloudstack.storage.to.TemplateObjectTO;
+import org.apache.cloudstack.storage.to.VolumeObjectTO;
+
+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.DeleteSnapshotsDirCommand;
+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.SecStorageVMSetupCommand;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.StartupSecondaryStorageCommand;
+import com.cloud.agent.api.storage.CreateEntityDownloadURLCommand;
+import com.cloud.agent.api.storage.DeleteEntityDownloadURLCommand;
+import com.cloud.agent.api.storage.DownloadAnswer;
+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.to.DataObjectType;
+import com.cloud.agent.api.to.DataStoreTO;
+import com.cloud.agent.api.to.DataTO;
+import com.cloud.agent.api.to.NfsTO;
+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.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.resource.ServerResourceBase;
+import com.cloud.storage.DataStoreRole;
+import com.cloud.storage.Storage.ImageFormat;
+import com.cloud.storage.StorageLayer;
+import com.cloud.storage.VMTemplateStorageResourceAssoc;
+import com.cloud.storage.template.OVAProcessor;
+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.TemplateLocation;
+import com.cloud.storage.template.TemplateProp;
+import com.cloud.storage.template.VhdProcessor;
+import com.cloud.storage.template.VmdkProcessor;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.S3Utils;
+import com.cloud.utils.S3Utils.FileNamingStrategy;
+import com.cloud.utils.SwiftUtil;
+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 VOLUME_ROOT_DIR = "volumes";
+
+    int _timeout;
+
+    public int getTimeout() {
+        return _timeout;
+    }
+
+    public void setTimeout(int timeout) {
+        _timeout = timeout;
+    }
+
+    String _instance;
+    String _dc;
+    String _pod;
+    String _guid;
+    String _role;
+    Map<String, Object> _params;
+    protected StorageLayer _storage;
+    protected boolean _inSystemVM = false;
+    boolean _sslCopy = false;
+
+    protected DownloadManager _dlMgr;
+    protected 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>();
+    protected String _parent = "/mnt/SecStorage";
+    final private String _tmpltpp = "template.properties";
+    protected String createTemplateFromSnapshotXenScript;
+
+    public void setParentPath(String path) {
+        _parent = path;
+    }
+
+    public String getMountingRoot() {
+        return _parent;
+    }
+
+    @Override
+    public void disconnected() {
+    }
+
+    public void setInSystemVM(boolean inSystemVM) {
+        _inSystemVM = inSystemVM;
+    }
+
+    @Override
+    public Answer executeRequest(Command cmd) {
+        if (cmd instanceof DownloadProgressCommand) {
+            return _dlMgr.handleDownloadCommand(this, (DownloadProgressCommand)cmd);
+        } else if (cmd instanceof DownloadCommand) {
+            return execute((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 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 DeleteSnapshotsDirCommand) {
+            return execute((DeleteSnapshotsDirCommand)cmd);
+        } else if (cmd instanceof CopyCommand) {
+            return execute((CopyCommand)cmd);
+        } else if (cmd instanceof DeleteCommand) {
+            return execute((DeleteCommand)cmd);
+        } else {
+            return Answer.createUnsupportedCommandAnswer(cmd);
+        }
+    }
+
+    protected CopyCmdAnswer postProcessing(File destFile, String downloadPath, String destPath, DataTO srcData, DataTO destData) throws ConfigurationException {
+        if (destData.getObjectType() == DataObjectType.SNAPSHOT) {
+            SnapshotObjectTO snapshot = new SnapshotObjectTO();
+            snapshot.setPath(destPath + File.separator + destFile.getName());
+
+            CopyCmdAnswer answer = new CopyCmdAnswer(snapshot);
+            return answer;
+        }
+        // do post processing to unzip the file if it is compressed
+        String scriptsDir = "scripts/storage/secondary";
+        String 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);
+        String 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);
+        String script = srcData.getObjectType() == DataObjectType.TEMPLATE ? createTmpltScr : createVolScr;
+
+        int installTimeoutPerGig = 180 * 60 * 1000;
+        long imgSizeGigs = (long)Math.ceil(destFile.length() * 1.0d / (1024 * 1024 * 1024));
+        imgSizeGigs++; // add one just in case
+        long timeout = imgSizeGigs * installTimeoutPerGig;
+
+        String origPath = destFile.getAbsolutePath();
+        String extension = null;
+        if (srcData.getObjectType() == DataObjectType.TEMPLATE) {
+            extension = ((TemplateObjectTO)srcData).getFormat().getFileExtension();
+        } else if (srcData.getObjectType() == DataObjectType.VOLUME) {
+            extension = ((VolumeObjectTO)srcData).getFormat().getFileExtension();
+        }
+
+        String templateName = UUID.randomUUID().toString();
+        String templateFilename = templateName + "." + extension;
+        Script scr = new Script(script, timeout, s_logger);
+        scr.add("-s", Long.toString(imgSizeGigs)); // not used for now
+        scr.add("-n", templateFilename);
+
+        scr.add("-t", downloadPath);
+        scr.add("-f", origPath); // this is the temporary
+        // template file downloaded
+        String result;
+        result = scr.execute();
+
+        if (result != null) {
+            // script execution failure
+            throw new CloudRuntimeException("Failed to run script " + script);
+        }
+
+        String finalFileName = templateFilename;
+        String finalDownloadPath = destPath + File.separator + templateFilename;
+        // compute the size of
+        long size = _storage.getSize(downloadPath + File.separator + templateFilename);
+
+        DataTO newDestTO = null;
+
+        if (destData.getObjectType() == DataObjectType.TEMPLATE) {
+            TemplateObjectTO newTemplTO = new TemplateObjectTO();
+            newTemplTO.setPath(finalDownloadPath);
+            newTemplTO.setName(finalFileName);
+            newTemplTO.setSize(size);
+            newTemplTO.setPhysicalSize(size);
+            newDestTO = newTemplTO;
+        } else {
+            VolumeObjectTO newVolTO = new VolumeObjectTO();
+            newVolTO.setPath(finalDownloadPath);
+            newVolTO.setName(finalFileName);
+            newVolTO.setSize(size);
+            newDestTO = newVolTO;
+        }
+
+        return new CopyCmdAnswer(newDestTO);
+    }
+
+    protected Answer copyFromSwiftToNfs(CopyCommand cmd, DataTO srcData, SwiftTO swiftTO, DataTO destData, NfsTO destImageStore) {
+        final String storagePath = destImageStore.getUrl();
+        final String destPath = destData.getPath();
+        try {
+            String downloadPath = determineStorageTemplatePath(storagePath, destPath);
+            final File downloadDirectory = _storage.getFile(downloadPath);
+            if (!downloadDirectory.mkdirs()) {
+                return new CopyCmdAnswer("Failed to create download directory " + downloadPath);
+            }
+            File destFile = SwiftUtil.getObject(swiftTO, downloadDirectory, srcData.getPath());
+            return postProcessing(destFile, downloadPath, destPath, srcData, destData);
+        } catch (Exception e) {
+            s_logger.debug("Failed to copy swift to nfs", e);
+            return new CopyCmdAnswer(e.toString());
+        }
+    }
+
+    protected Answer copyFromS3ToNfs(CopyCommand cmd, DataTO srcData, S3TO s3, DataTO destData, NfsTO destImageStore) {
+        final String storagePath = destImageStore.getUrl();
+        final String destPath = destData.getPath();
+
+        try {
+
+            String downloadPath = determineStorageTemplatePath(storagePath, destPath);
+            final File downloadDirectory = _storage.getFile(downloadPath);
+
+            if (!downloadDirectory.mkdirs()) {
+                final String errMsg = "Unable to create directory " + downloadPath + " to copy from S3 to cache.";
+                s_logger.error(errMsg);
+                return new CopyCmdAnswer(errMsg);
+            } else {
+                s_logger.debug("Directory " + downloadPath + " already exists");
+            }
+
+            File destFile = S3Utils.getFile(s3, s3.getBucketName(), srcData.getPath(), downloadDirectory, new FileNamingStrategy() {
+                @Override
+                public String determineFileName(final String key) {
+                    return substringAfterLast(key, S3Utils.SEPARATOR);
+                }
+            });
+
+            if (destFile == null) {
+                return new CopyCmdAnswer("Can't find template");
+            }
+
+            return postProcessing(destFile, downloadPath, destPath, srcData, destData);
+        } catch (Exception e) {
+
+            final String errMsg = format("Failed to download" + "due to $2%s", e.getMessage());
+            s_logger.error(errMsg, e);
+            return new CopyCmdAnswer(errMsg);
+        }
+    }
+
+    protected Answer copySnapshotToTemplateFromNfsToNfsXenserver(CopyCommand cmd, SnapshotObjectTO srcData, NfsTO srcDataStore, TemplateObjectTO destData,
+            NfsTO destDataStore) {
+        String srcMountPoint = getRootDir(srcDataStore.getUrl());
+        String snapshotPath = srcData.getPath();
+        int index = snapshotPath.lastIndexOf("/");
+        String snapshotName = snapshotPath.substring(index + 1);
+        if (!snapshotName.startsWith("VHD-") && !snapshotName.endsWith(".vhd")) {
+            snapshotName = snapshotName + ".vhd";
+        }
+        snapshotPath = snapshotPath.substring(0, index);
+
+        snapshotPath = srcMountPoint + File.separator + snapshotPath;
+        String destMountPoint = getRootDir(destDataStore.getUrl());
+        String destPath = destMountPoint + File.separator + destData.getPath();
+
+        String errMsg = null;
+        try {
+            _storage.mkdir(destPath);
+
+            String templateUuid = UUID.randomUUID().toString();
+            String templateName = templateUuid + ".vhd";
+            Script command = new Script(createTemplateFromSnapshotXenScript, cmd.getWait() * 1000, s_logger);
+            command.add("-p", snapshotPath);
+            command.add("-s", snapshotName);
+            command.add("-n", templateName);
+            command.add("-t", destPath);
+            String result = command.execute();
+
+            if (result != null && !result.equalsIgnoreCase("")) {
+                return new CopyCmdAnswer(result);
+            }
+
+            Map<String, Object> params = new HashMap<String, Object>();
+            params.put(StorageLayer.InstanceConfigKey, _storage);
+            Processor processor = new VhdProcessor();
+
+            processor.configure("Vhd Processor", params);
+            FormatInfo info = processor.process(destPath, null, templateUuid);
+
+            TemplateLocation loc = new TemplateLocation(_storage, destPath);
+            loc.create(1, true, templateUuid);
+            loc.addFormat(info);
+            loc.save();
+            TemplateProp prop = loc.getTemplateInfo();
+            TemplateObjectTO newTemplate = new TemplateObjectTO();
+            newTemplate.setPath(destData.getPath() + File.separator + templateName);
+            newTemplate.setFormat(ImageFormat.VHD);
+            newTemplate.setSize(prop.getSize());
+            newTemplate.setPhysicalSize(prop.getPhysicalSize());
+            newTemplate.setName(templateUuid);
+            return new CopyCmdAnswer(newTemplate);
+        } catch (ConfigurationException e) {
+            s_logger.debug("Failed to create template from snapshot: " + e.toString());
+            errMsg = e.toString();
+        } catch (InternalErrorException e) {
+            s_logger.debug("Failed to create template from snapshot: " + e.toString());
+            errMsg = e.toString();
+        } catch (IOException e) {
+            s_logger.debug("Failed to create template from snapshot: " + e.toString());
+            errMsg = e.toString();
+        }
+
+        return new CopyCmdAnswer(errMsg);
+    }
+
+    protected Answer copySnapshotToTemplateFromNfsToNfs(CopyCommand cmd, SnapshotObjectTO srcData, NfsTO srcDataStore, TemplateObjectTO destData, NfsTO destDataStore) {
+
+        if (srcData.getHypervisorType() == HypervisorType.XenServer) {
+            return copySnapshotToTemplateFromNfsToNfsXenserver(cmd, srcData, srcDataStore, destData, destDataStore);
+        } else if (srcData.getHypervisorType() == HypervisorType.KVM) {
+            File srcFile = getFile(srcData.getPath(), srcDataStore.getUrl());
+            File destFile = getFile(destData.getPath(), destDataStore.getUrl());
+
+            VolumeObjectTO volumeObjectTO = srcData.getVolume();
+            ImageFormat srcFormat = null;
+            //TODO: the image format should be stored in snapshot table, instead of getting from volume
+            if (volumeObjectTO != null) {
+                srcFormat = volumeObjectTO.getFormat();
+            } else {
+                srcFormat = ImageFormat.QCOW2;
+            }
+
+            // get snapshot file name
+            String templateName = srcFile.getName();
+            // add kvm file extension for copied template name
+            String fileName = templateName + "." + srcFormat.getFileExtension();
+            String destFileFullPath = destFile.getAbsolutePath() + File.separator + fileName;
+            s_logger.debug("copy snapshot " + srcFile.getAbsolutePath() + " to template " + destFileFullPath);
+            Script.runSimpleBashScript("cp " + srcFile.getAbsolutePath() + " " + destFileFullPath);
+            try {
+                // generate template.properties file
+                String metaFileName = destFile.getAbsolutePath() + File.separator + "template.properties";
+                _storage.create(destFile.getAbsolutePath(), "template.properties");
+                File metaFile = new File(metaFileName);
+                FileWriter writer = new FileWriter(metaFile);
+                BufferedWriter bufferWriter = new BufferedWriter(writer);
+                // KVM didn't change template unique name, just used the template name passed from orchestration layer, so no need
+                // to send template name back.
+                bufferWriter.write("uniquename=" + destData.getName());
+                bufferWriter.write("\n");
+                bufferWriter.write("filename=" + fileName);
+                bufferWriter.write("\n");
+                long size = _storage.getSize(destFileFullPath);
+                bufferWriter.write("size=" + size);
+                bufferWriter.close();
+                writer.close();
+
+                /**
+                 * Snapshots might be in either QCOW2 or RAW image format
+                 *
+                 * For example RBD snapshots are in RAW format
+                 */
+                Processor processor = null;
+                if (srcFormat == ImageFormat.QCOW2) {
+                    processor = new QCOW2Processor();
+                } else if (srcFormat == ImageFormat.RAW) {
+                    processor = new RawImageProcessor();
+                } else {
+                    throw new ConfigurationException("Unknown image format " + srcFormat.toString());
+                }
+
+                Map<String, Object> params = new HashMap<String, Object>();
+                params.put(StorageLayer.InstanceConfigKey, _storage);
+
+                processor.configure("template processor", params);
+                String destPath = destFile.getAbsolutePath();
+
+                FormatInfo info = processor.process(destPath, null, templateName);
+                TemplateLocation loc = new TemplateLocation(_storage, destPath);
+                loc.create(1, true, destData.getName());
+                loc.addFormat(info);
+                loc.save();
+
+                TemplateProp prop = loc.getTemplateInfo();
+                TemplateObjectTO newTemplate = new TemplateObjectTO();
+                newTemplate.setPath(destData.getPath() + File.separator + fileName);
+                newTemplate.setFormat(srcFormat);
+                newTemplate.setSize(prop.getSize());
+                newTemplate.setPhysicalSize(prop.getPhysicalSize());
+                return new CopyCmdAnswer(newTemplate);
+            } catch (ConfigurationException e) {
+                s_logger.debug("Failed to create template:" + e.toString());
+                return new CopyCmdAnswer(e.toString());
+            } catch (IOException e) {
+                s_logger.debug("Failed to create template:" + e.toString());
+                return new CopyCmdAnswer(e.toString());
+            } catch (InternalErrorException e) {
+                s_logger.debug("Failed to create template:" + e.toString());
+                return new CopyCmdAnswer(e.toString());
+            }
+        }
+
+        return new CopyCmdAnswer("");
+    }
+
+    protected File getFile(String path, String nfsPath) {
+        String filePath = getRootDir(nfsPath) + File.separator + path;
+        File f = new File(filePath);
+        if (!f.exists()) {
+            _storage.mkdirs(filePath);
+            f = new File(filePath);
+        }
+        return f;
+    }
+
+    protected Answer createTemplateFromSnapshot(CopyCommand cmd) {
+        DataTO srcData = cmd.getSrcTO();
+        DataTO destData = cmd.getDestTO();
+        DataStoreTO srcDataStore = srcData.getDataStore();
+        DataStoreTO destDataStore = destData.getDataStore();
+        if (srcDataStore.getRole() == DataStoreRole.Image || srcDataStore.getRole() == DataStoreRole.ImageCache || srcDataStore.getRole() == DataStoreRole.Primary) {
+            if (!(srcDataStore instanceof NfsTO)) {
+                s_logger.debug("only support nfs storage as src, when create template from snapshot");
+                return Answer.createUnsupportedCommandAnswer(cmd);
+            }
+
+            if (destDataStore instanceof NfsTO) {
+                return copySnapshotToTemplateFromNfsToNfs(cmd, (SnapshotObjectTO)srcData, (NfsTO)srcDataStore, (TemplateObjectTO)destData, (NfsTO)destDataStore);
+            } else if (destDataStore instanceof SwiftTO) {
+                //create template on the same data store
+                CopyCmdAnswer answer =
+                        (CopyCmdAnswer)copySnapshotToTemplateFromNfsToNfs(cmd, (SnapshotObjectTO)srcData, (NfsTO)srcDataStore, (TemplateObjectTO)destData,
+                                (NfsTO)srcDataStore);
+                if (!answer.getResult()) {
+                    return answer;
+                }
+                s_logger.debug("starting copy template to swift");
+                DataTO newTemplate = answer.getNewData();
+                File templateFile = getFile(newTemplate.getPath(), ((NfsTO)srcDataStore).getUrl());
+                SwiftTO swift = (SwiftTO)destDataStore;
+                String containterName = SwiftUtil.getContainerName(destData.getObjectType().toString(), destData.getId());
+                String swiftPath = SwiftUtil.putObject(swift, templateFile, containterName, templateFile.getName());
+                //upload template.properties
+                File properties = new File(templateFile.getParent() + File.separator + _tmpltpp);
+                if (properties.exists()) {
+                    SwiftUtil.putObject(swift, properties, containterName, _tmpltpp);
+                }
+
+                //clean up template data on staging area
+                try {
+                    DeleteCommand deleteCommand = new DeleteCommand(newTemplate);
+                    execute(deleteCommand);
+                } catch (Exception e) {
+                    s_logger.debug("Failed to clean up staging area:", e);
+                }
+
+                TemplateObjectTO template = new TemplateObjectTO();
+                template.setPath(swiftPath);
+                template.setSize(templateFile.length());
+                template.setPhysicalSize(template.getSize());
+                SnapshotObjectTO snapshot = (SnapshotObjectTO)srcData;
+                template.setFormat(snapshot.getVolume().getFormat());
+                return new CopyCmdAnswer(template);
+            } else if (destDataStore instanceof S3TO) {
+                //create template on the same data store
+                CopyCmdAnswer answer =
+                        (CopyCmdAnswer)copySnapshotToTemplateFromNfsToNfs(cmd, (SnapshotObjectTO)srcData, (NfsTO)srcDataStore, (TemplateObjectTO)destData,
+                                (NfsTO)srcDataStore);
+                if (!answer.getResult()) {
+                    return answer;
+                }
+                TemplateObjectTO newTemplate = (TemplateObjectTO)answer.getNewData();
+                newTemplate.setDataStore(srcDataStore);
+                CopyCommand newCpyCmd = new CopyCommand(newTemplate, destData, cmd.getWait(), cmd.executeInSequence());
+                Answer result = copyFromNfsToS3(newCpyCmd);
+                //clean up template data on staging area
+                try {
+                    DeleteCommand deleteCommand = new DeleteCommand(newTemplate);
+                    execute(deleteCommand);
+                } catch (Exception e) {
+                    s_logger.debug("Failed to clean up staging area:", e);
+                }
+                return result;
+            }
+        }
+        s_logger.debug("Failed to create templat from snapshot");
+        return new CopyCmdAnswer("Unsupported prototcol");
+    }
+
+    protected Answer copyFromNfsToImage(CopyCommand cmd) {
+        DataTO destData = cmd.getDestTO();
+        DataStoreTO destDataStore = destData.getDataStore();
+
+        if (destDataStore instanceof S3TO) {
+            return copyFromNfsToS3(cmd);
+        } else {
+            return new CopyCmdAnswer("unsupported ");
+        }
+    }
+
+    protected Answer execute(CopyCommand cmd) {
+        DataTO srcData = cmd.getSrcTO();
+        DataTO destData = cmd.getDestTO();
+        DataStoreTO srcDataStore = srcData.getDataStore();
+        DataStoreTO destDataStore = destData.getDataStore();
+
+        if (srcData.getObjectType() == DataObjectType.SNAPSHOT && destData.getObjectType() == DataObjectType.TEMPLATE) {
+            return createTemplateFromSnapshot(cmd);
+        }
+
+        if (destDataStore instanceof NfsTO && destDataStore.getRole() == DataStoreRole.ImageCache) {
+            NfsTO destImageStore = (NfsTO)destDataStore;
+            if (srcDataStore instanceof S3TO) {
+                S3TO s3 = (S3TO)srcDataStore;
+                return copyFromS3ToNfs(cmd, srcData, s3, destData, destImageStore);
+            } else if (srcDataStore instanceof SwiftTO) {
+                return copyFromSwiftToNfs(cmd, srcData, (SwiftTO)srcDataStore, destData, destImageStore);
+            }
+        }
+
+        if (srcDataStore.getRole() == DataStoreRole.ImageCache && destDataStore.getRole() == DataStoreRole.Image) {
+            return copyFromNfsToImage(cmd);
+        }
+
+        return Answer.createUnsupportedCommandAnswer(cmd);
+    }
+
+    @SuppressWarnings("unchecked")
+    protected String determineS3TemplateDirectory(final Long accountId, final Long templateId, final String templateUniqueName) {
+        return join(asList(TEMPLATE_ROOT_DIR, accountId, templateId, templateUniqueName), S3Utils.SEPARATOR);
+    }
+
+    private String determineS3TemplateNameFromKey(String key) {
+        return StringUtils.substringAfterLast(StringUtils.substringBeforeLast(key, S3Utils.SEPARATOR), S3Utils.SEPARATOR);
+    }
+
+    @SuppressWarnings("unchecked")
+    protected String determineS3VolumeDirectory(final Long accountId, final Long volId) {
+        return join(asList(VOLUME_ROOT_DIR, accountId, volId), S3Utils.SEPARATOR);
+    }
+
+    protected Long determineS3VolumeIdFromKey(String key) {
+        return Long.parseLong(StringUtils.substringAfterLast(StringUtils.substringBeforeLast(key, S3Utils.SEPARATOR), S3Utils.SEPARATOR));
+    }
+
+    private String determineStorageTemplatePath(final String storagePath, String dataPath) {
+        return join(asList(getRootDir(storagePath), dataPath), File.separator);
+    }
+
+    protected File downloadFromUrlToNfs(String url, NfsTO nfs, String path, String name) {
+        HttpClient client = new DefaultHttpClient();
+        HttpGet get = new HttpGet(url);
+        try {
+            HttpResponse response = client.execute(get);
+            HttpEntity entity = response.getEntity();
+            if (entity == null) {
+                s_logger.debug("Faled to get entity");
+                throw new CloudRuntimeException("Failed to get url: " + url);
+            }
+
+            String nfsMountPath = getRootDir(nfs.getUrl());
+
+            String filePath = nfsMountPath + File.separator + path;
+            File directory = new File(filePath);
+            if (!directory.exists()) {
+                _storage.mkdirs(filePath);
+            }
+            File destFile = new File(filePath + File.separator + name);
+            if (!destFile.createNewFile()) {
+                s_logger.warn("Reusing existing file " + destFile.getPath());
+            }
+            FileOutputStream outputStream = new FileOutputStream(destFile);
+            entity.writeTo(outputStream);
+            return new File(destFile.getAbsolutePath());
+        } catch (IOException e) {
+            s_logger.debug("Faild to get url:" + url + ", due to " + e.toString());
+            throw new CloudRuntimeException(e);
+        }
+    }
+
+    protected Answer registerTemplateOnSwift(DownloadCommand cmd) {
+        SwiftTO swiftTO = (SwiftTO)cmd.getDataStore();
+        String path = cmd.getInstallPath();
+        DataStoreTO cacheStore = cmd.getCacheStore();
+        if (cacheStore == null || !(cacheStore instanceof NfsTO)) {
+            return new DownloadAnswer("cache store can't be null", VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR);
+        }
+
+        File file = null;
+        try {
+            NfsTO nfsCacheStore = (NfsTO)cacheStore;
+            String fileName = cmd.getName() + "." + cmd.getFormat().getFileExtension();
+            file = downloadFromUrlToNfs(cmd.getUrl(), nfsCacheStore, path, fileName);
+            String container = "T-" + cmd.getId();
+            String swiftPath = SwiftUtil.putObject(swiftTO, file, container, null);
+
+            //put metda file
+            File uniqDir = _storage.createUniqDir();
+            String metaFileName = uniqDir.getAbsolutePath() + File.separator + "template.properties";
+            _storage.create(uniqDir.getAbsolutePath(), "template.properties");
+            File metaFile = new File(metaFileName);
+            FileWriter writer = new FileWriter(metaFile);
+            BufferedWriter bufferWriter = new BufferedWriter(writer);
+            bufferWriter.write("uniquename=" + cmd.getName());
+            bufferWriter.write("\n");
+            bufferWriter.write("filename=" + fileName);
+            bufferWriter.write("\n");
+            bufferWriter.write("size=" + file.length());
+            bufferWriter.close();
+            writer.close();
+
+            SwiftUtil.putObject(swiftTO, metaFile, container, "template.properties");
+            metaFile.delete();
+            uniqDir.delete();
+            String md5sum = null;
+            try {
+                md5sum = DigestUtils.md5Hex(new FileInputStream(file));
+            } catch (IOException e) {
+                s_logger.debug("Failed to get md5sum: " + file.getAbsoluteFile());
+            }
+
+            DownloadAnswer answer =
+                    new DownloadAnswer(null, 100, null, VMTemplateStorageResourceAssoc.Status.DOWNLOADED, swiftPath, swiftPath, file.length(), file.length(), md5sum);
+            return answer;
+        } catch (IOException e) {
+            s_logger.debug("Failed to register template into swift", e);
+            return new DownloadAnswer(e.toString(), VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR);
+        } finally {
+            if (file != null) {
+                file.delete();
+            }
+        }
+    }
+
+    private Answer execute(DownloadCommand cmd) {
+        DataStoreTO dstore = cmd.getDataStore();
+        if (dstore instanceof NfsTO || dstore instanceof S3TO) {
+            return _dlMgr.handleDownloadCommand(this, cmd);
+        } else if (dstore instanceof SwiftTO) {
+            return registerTemplateOnSwift(cmd);
+        } else {
+            return new Answer(cmd, false, "Unsupported image data store: " + dstore);
+        }
+
+    }
+
+    private ImageFormat getTemplateFormat(String filePath) {
+        String ext = null;
+        int extensionPos = filePath.lastIndexOf('.');
+        int lastSeparator = Math.max(filePath.lastIndexOf('/'), filePath.lastIndexOf('\\'));
+        int i = lastSeparator > extensionPos ? -1 : extensionPos;
+        if (i > 0) {
+            ext = filePath.substring(i + 1);
+        }
+        if (ext != null) {
+            if (ext.equalsIgnoreCase("vhd")) {
+                return ImageFormat.VHD;
+            } else if (ext.equalsIgnoreCase("vhdx")) {
+                return ImageFormat.VHDX;
+            } else if (ext.equalsIgnoreCase("qcow2")) {
+                return ImageFormat.QCOW2;
+            } else if (ext.equalsIgnoreCase("ova")) {
+                return ImageFormat.OVA;
+            } else if (ext.equalsIgnoreCase("tar")) {
+                return ImageFormat.TAR;
+            } else if (ext.equalsIgnoreCase("img") || ext.equalsIgnoreCase("raw")) {
+                return ImageFormat.RAW;
+            } else if (ext.equalsIgnoreCase("vmdk")) {
+                return ImageFormat.VMDK;
+            } else if (ext.equalsIgnoreCase("vdi")) {
+                return ImageFormat.VDI;
+            }
+        }
+
+        return null;
+
+    }
+
+    protected Long getVirtualSize(File file, ImageFormat format) {
+        Processor processor = null;
+        try {
+            if (format == null) {
+                return file.length();
+            } else if (format == ImageFormat.QCOW2) {
+                processor = new QCOW2Processor();
+            } else if (format == ImageFormat.OVA) {
+                processor = new OVAProcessor();
+            } else if (format == ImageFormat.VHD) {
+                processor = new VhdProcessor();
+            } else if (format == ImageFormat.RAW) {
+                processor = new RawImageProcessor();
+            } else if (format == ImageFormat.VMDK) {
+                processor = new VmdkProcessor();
+            }
+
+            if (processor == null) {
+                return file.length();
+            }
+
+            processor.configure("template processor", new HashMap<String, Object>());
+            return processor.getVirtualSize(file);
+        } catch (Exception e) {
+            s_logger.debug("Failed to get virtual size:", e);
+        }
+        return file.length();
+    }
+
+    protected Answer copyFromNfsToS3(CopyCommand cmd) {
+        final DataTO srcData = cmd.getSrcTO();
+        final DataTO destData = cmd.getDestTO();
+        DataStoreTO srcDataStore = srcData.getDataStore();
+        NfsTO srcStore = (NfsTO)srcDataStore;
+        DataStoreTO destDataStore = destData.getDataStore();
+
+        final S3TO s3 = (S3TO)destDataStore;
+
+        try {
+            final String templatePath = determineStorageTemplatePath(srcStore.getUrl(), srcData.getPath());
+
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Found " + srcData.getObjectType() + " from directory " + templatePath + " to upload to S3.");
+            }
+
+            final String bucket = s3.getBucketName();
+            File srcFile = _storage.getFile(templatePath);
+            // guard the case where templatePath does not have file extension, since we are not completely sure
+            // about hypervisor, so we check each extension
+            if (!srcFile.exists()) {
+                srcFile = _storage.getFile(templatePath + ".qcow2");
+                if (!srcFile.exists()) {
+                    srcFile = _storage.getFile(templatePath + ".vhd");
+                    if (!srcFile.exists()) {
+                        srcFile = _storage.getFile(templatePath + ".ova");
+                        if (!srcFile.exists()) {
+                            srcFile = _storage.getFile(templatePath + ".vmdk");
+                            if (!srcFile.exists()) {
+                                return new CopyCmdAnswer("Can't find src file:" + templatePath);
+                            }
+                        }
+                    }
+                }
+            }
+
+            long srcSize = srcFile.length();
+            ImageFormat format = getTemplateFormat(srcFile.getName());
+            String key = destData.getPath() + S3Utils.SEPARATOR + srcFile.getName();
+            if (!s3.getSingleUpload(srcSize)) {
+                mputFile(s3, srcFile, bucket, key);
+            } else {
+                putFile(s3, srcFile, bucket, key);
+            }
+
+            DataTO retObj = null;
+            if (destData.getObjectType() == DataObjectType.TEMPLATE) {
+                TemplateObjectTO newTemplate = new TemplateObjectTO();
+                newTemplate.setPath(key);
+                newTemplate.setSize(getVirtualSize(srcFile, format));
+                newTemplate.setPhysicalSize(srcFile.length());
+                newTemplate.setFormat(format);
+                retObj = newTemplate;
+            } else if (destData.getObjectType() == DataObjectType.VOLUME) {
+                VolumeObjectTO newVol = new VolumeObjectTO();
+                newVol.setPath(key);
+                newVol.setSize(srcFile.length());
+                retObj = newVol;
+            } else if (destData.getObjectType() == DataObjectType.SNAPSHOT) {
+                SnapshotObjectTO newSnapshot = new SnapshotObjectTO();
+                newSnapshot.setPath(key);
+                retObj = newSnapshot;
+            }
+
+            return new CopyCmdAnswer(retObj);
+        } catch (Exception e) {
+            s_logger.error("failed to upload" + srcData.getPath(), e);
+            return new CopyCmdAnswer("failed to upload" + srcData.getPath() + e.toString());
+        }
+    }
+
+    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=" + parser.getLines();
+                    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=" + parser.getLines();
+                    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=" + parser.getLines();
+                        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=" + parser.getLines();
+                    s_logger.warn(errMsg);
+                    return errMsg;
+                }
+            }
+        }
+        return null;
+    }
+
+    public Answer execute(DeleteSnapshotsDirCommand cmd) {
+        DataStoreTO dstore = cmd.getDataStore();
+        if (dstore instanceof NfsTO) {
+            NfsTO nfs = (NfsTO)dstore;
+            String relativeSnapshotPath = cmd.getDirectory();
+            String parent = getRootDir(nfs.getUrl());
+
+            if (relativeSnapshotPath.startsWith(File.separator)) {
+                relativeSnapshotPath = relativeSnapshotPath.substring(1);
+            }
+
+            if (!parent.endsWith(File.separator)) {
+                parent += File.separator;
+            }
+            String absoluteSnapshotPath = parent + relativeSnapshotPath;
+            File snapshotDir = new File(absoluteSnapshotPath);
+            String details = null;
+            if (!snapshotDir.exists()) {
+                details = "snapshot directory " + snapshotDir.getName() + " doesn't exist";
+                s_logger.debug(details);
+                return new Answer(cmd, true, details);
+            }
+            // delete all files in the directory
+            String lPath = absoluteSnapshotPath + "/*";
+            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);
+            }
+            // delete the directory
+            if (!snapshotDir.delete()) {
+                details = "Unable to delete directory " + snapshotDir.getName() + " under snapshot path " + relativeSnapshotPath;
+                s_logger.debug(details);
+                return new Answer(cmd, false, details);
+            }
+            return new Answer(cmd, true, null);
+        } else if (dstore instanceof S3TO) {
+            final S3TO s3 = (S3TO)dstore;
+            final String path = cmd.getDirectory();
+            final String bucket = s3.getBucketName();
+            try {
+                S3Utils.deleteDirectory(s3, bucket, path);
+                return new Answer(cmd, true, String.format("Deleted snapshot %1%s from bucket %2$s.", path, bucket));
+            } catch (Exception e) {
+                final String errorMessage =
+                        String.format("Failed to delete snapshot %1$s from bucket %2$s due to the following error: %3$s", path, bucket, e.getMessage());
+                s_logger.error(errorMessage, e);
+                return new Answer(cmd, false, errorMessage);
+            }
+        } else if (dstore instanceof SwiftTO) {
+            String path = cmd.getDirectory();
+            String volumeId = StringUtils.substringAfterLast(path, "/"); // assuming
+            // that
+            // the
+            // filename
+            // is
+            // the
+            // last
+            // section
+            // in
+            // the
+            // path
+            String result = swiftDelete((SwiftTO)dstore, "V-" + volumeId.toString(), "");
+            if (result != null) {
+                String errMsg = "failed to delete snapshot for volume " + volumeId + " , err=" + result;
+                s_logger.warn(errMsg);
+                return new Answer(cmd, false, errMsg);
+            }
+            return new Answer(cmd, true, "Deleted snapshot " + path + " from swift");
+        } else {
+            return new Answer(cmd, false, "Unsupported image data store: " + dstore);
+        }
+    }
+
+    private Answer execute(ComputeChecksumCommand cmd) {
+
+        String relativeTemplatePath = cmd.getTemplatePath();
+        DataStoreTO store = cmd.getStore();
+        if (!(store instanceof NfsTO)) {
+            return new Answer(cmd, false, "can't handle non nfs data store");
+        }
+        NfsTO nfsStore = (NfsTO)store;
+        String parent = getRootDir(nfsStore.getUrl());
+
+        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(KeystoreManager.Certificates certs) {
+        if (certs == null) {
+            configureSSL();
+        } else {
+            String prvKey = certs.getPrivKey();
+            String pubCert = certs.getPrivCert();
+
+            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);
+        }
+        DataStoreTO dStore = cmd.getDataStore();
+        if (dStore instanceof NfsTO) {
+            String secUrl = cmd.getSecUrl();
+            try {
+                URI uri = new URI(secUrl);
+                String nfsHostIp = getUriHostIp(uri);
+
+                addRouteToInternalIpOrCidr(_storageGateway, _storageIp, _storageNetmask, nfsHostIp);
+                String dir = mountUri(uri);
+
+                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);
+
+            }
+        } else {
+            // TODO: what do we need to setup for S3/Swift, maybe need to mount
+            // to some cache storage
+            return new Answer(cmd, true, null);
+        }
+    }
+
+    protected Answer deleteSnapshot(final DeleteCommand cmd) {
+        DataTO obj = cmd.getData();
+        DataStoreTO dstore = obj.getDataStore();
+        if (dstore instanceof NfsTO) {
+            NfsTO nfs = (NfsTO)dstore;
+            String parent = getRootDir(nfs.getUrl());
+            if (!parent.endsWith(File.separator)) {
+                parent += File.separator;
+            }
+            String snapshotPath = obj.getPath();
+            if (snapshotPath.startsWith(File.separator)) {
+                snapshotPath = snapshotPath.substring(1);
+            }
+            // check if the passed snapshot path is a directory or not. For ImageCache, path is stored as a directory instead of
+            // snapshot file name. If so, since backupSnapshot process has already deleted snapshot in cache, so we just do nothing
+            // and return true.
+            String fullSnapPath = parent + snapshotPath;
+            File snapDir = new File(fullSnapPath);
+            if (snapDir.exists() && snapDir.isDirectory()) {
+                s_logger.debug("snapshot path " + snapshotPath + " is a directory, already deleted during backup snapshot, so no need to delete");
+                return new Answer(cmd, true, null);
+            }
+            // passed snapshot path is a snapshot file path, then get snapshot directory first
+            int index = snapshotPath.lastIndexOf("/");
+            String snapshotName = snapshotPath.substring(index + 1);
+            snapshotPath = snapshotPath.substring(0, index);
+            String absoluteSnapshotPath = parent + snapshotPath;
+            // check if snapshot directory exists
+            File snapshotDir = new File(absoluteSnapshotPath);
+            String details = null;
+            if (!snapshotDir.exists()) {
+                details = "snapshot directory " + snapshotDir.getName() + " doesn't exist";
+                s_logger.debug(details);
+                return new Answer(cmd, false, details);
+            }
+            // delete snapshot in the directory if exists
+            String lPath = absoluteSnapshotPath + "/*" + snapshotName + "*";
+            String result = deleteLocalFile(lPath);
+            if (result != null) {
+                details = "failed to delete snapshot " + lPath + " , err=" + result;
+                s_logger.warn(details);
+                return new Answer(cmd, false, details);
+            }
+            return new Answer(cmd, true, null);
+        } else if (dstore instanceof S3TO) {
+            final S3TO s3 = (S3TO)dstore;
+            final String path = obj.getPath();
+            final String bucket = s3.getBucketName();
+            try {
+                S3Utils.deleteObject(s3, bucket, path);
+                return new Answer(cmd, true, String.format("Deleted snapshot %1%s from bucket %2$s.", path, bucket));
+            } catch (Exception e) {
+                final String errorMessage =
+                        String.format("Failed to delete snapshot %1$s from bucket %2$s due to the following error: %3$s", path, bucket, e.getMessage());
+                s_logger.error(errorMessage, e);
+                return new Answer(cmd, false, errorMessage);
+            }
+        } else if (dstore instanceof SwiftTO) {
+            SwiftTO swiftTO = (SwiftTO)dstore;
+            String path = obj.getPath();
+            SwiftUtil.deleteObject(swiftTO, path);
+
+            return new Answer(cmd, true, "Deleted snapshot " + path + " from swift");
+        } else {
+            return new Answer(cmd, false, "Unsupported image data store: " + dstore);
+        }
+
+    }
+
+    Map<String, TemplateProp> swiftListTemplate(SwiftTO swift) {
+        String[] containers = SwiftUtil.list(swift, "", null);
+        if (containers == null) {
+            return null;
+        }
+        Map<String, TemplateProp> tmpltInfos = new HashMap<String, TemplateProp>();
+        for (String container : containers) {
+            if (container.startsWith("T-")) {
+                String[] files = SwiftUtil.list(swift, container, "template.properties");
+                if (files.length != 1) {
+                    continue;
+                }
+                try {
+                    File tempFile = File.createTempFile("template", ".tmp");
+                    File tmpFile = SwiftUtil.getObject(swift, tempFile, container + File.separator + "template.properties");
+                    if (tmpFile == null) {
+                        continue;
+                    }
+                    FileReader fr = new FileReader(tmpFile);
+                    BufferedReader brf = new BufferedReader(fr);
+                    String line = null;
+                    String uniqName = null;
+                    Long size = null;
+                    String name = null;
+                    while ((line = brf.readLine()) != null) {
+                        if (line.startsWith("uniquename=")) {
+                            uniqName = line.split("=")[1];
+                        } else if (line.startsWith("size=")) {
+                            size = Long.parseLong(line.split("=")[1]);
+                        } else if (line.startsWith("filename=")) {
+                            name = line.split("=")[1];
+                        }
+                    }
+                    brf.close();
+                    tempFile.delete();
+                    if (uniqName != null) {
+                        TemplateProp prop = new TemplateProp(uniqName, container + File.separator + name, size, size, true, false);
+                        tmpltInfos.put(uniqName, prop);
+                    }
+
+                } catch (IOException e) {
+                    s_logger.debug("Failed to create templ file:" + e.toString());
+                    continue;
+                } catch (Exception e) {
+                    s_logger.debug("Failed to get properties: " + e.toString());
+                    continue;
+                }
+            }
+        }
+        return tmpltInfos;
+
+    }
+
+    Map<String, TemplateProp> s3ListTemplate(S3TO s3) {
+        String bucket = s3.getBucketName();
+        // List the objects in the source directory on S3
+        final List<S3ObjectSummary> objectSummaries = S3Utils.getDirectory(s3, bucket, TEMPLATE_ROOT_DIR);
+        if (objectSummaries == null) {
+            return null;
+        }
+        Map<String, TemplateProp> tmpltInfos = new HashMap<String, TemplateProp>();
+        for (S3ObjectSummary objectSummary : objectSummaries) {
+            String key = objectSummary.getKey();
+            // String installPath = StringUtils.substringBeforeLast(key,
+            // S3Utils.SEPARATOR);
+            String uniqueName = determineS3TemplateNameFromKey(key);
+            // TODO: isPublic value, where to get?
+            TemplateProp tInfo = new TemplateProp(uniqueName, key, objectSummary.getSize(), objectSummary.getSize(), true, false);
+            tmpltInfos.put(uniqueName, tInfo);
+        }
+        return tmpltInfos;
+
+    }
+
+    Map<Long, TemplateProp> s3ListVolume(S3TO s3) {
+        String bucket = s3.getBucketName();
+        // List the objects in the source directory on S3
+        final List<S3ObjectSummary> objectSummaries = S3Utils.getDirectory(s3, bucket, VOLUME_ROOT_DIR);
+        if (objectSummaries == null) {
+            return null;
+        }
+        Map<Long, TemplateProp> tmpltInfos = new HashMap<Long, TemplateProp>();
+        for (S3ObjectSummary objectSummary : objectSummaries) {
+            String key = objectSummary.getKey();
+            // String installPath = StringUtils.substringBeforeLast(key,
+            // S3Utils.SEPARATOR);
+            Long id = determineS3VolumeIdFromKey(key);
+            // TODO: how to get volume template name
+            TemplateProp tInfo = new TemplateProp(id.toString(), key, objectSummary.getSize(), objectSummary.getSize(), true, false);
+            tmpltInfos.put(id, tInfo);
+        }
+        return tmpltInfos;
+
+    }
+
+    private Answer execute(ListTemplateCommand cmd) {
+        if (!_inSystemVM) {
+            return new ListTemplateAnswer(null, null);
+        }
+
+        DataStoreTO store = cmd.getDataStore();
+        if (store instanceof NfsTO) {
+            NfsTO nfs = (NfsTO)store;
+            String secUrl = nfs.getUrl();
+            String root = getRootDir(secUrl);
+            Map<String, TemplateProp> templateInfos = _dlMgr.gatherTemplateInfo(root);
+            return new ListTemplateAnswer(secUrl, templateInfos);
+        } else if (store instanceof SwiftTO) {
+            SwiftTO swift = (SwiftTO)store;
+            Map<String, TemplateProp> templateInfos = swiftListTemplate(swift);
+            return new ListTemplateAnswer(swift.toString(), templateInfos);
+        } else if (store instanceof S3TO) {
+            S3TO s3 = (S3TO)store;
+            Map<String, TemplateProp> templateInfos = s3ListTemplate(s3);
+            return new ListTemplateAnswer(s3.getBucketName(), templateInfos);
+        } else {
+            return new Answer(cmd, false, "Unsupported image data store: " + store);
+        }
+    }
+
+    private Answer execute(ListVolumeCommand cmd) {
+        if (!_inSystemVM) {
+            return new ListVolumeAnswer(cmd.getSecUrl(), null);
+        }
+        DataStoreTO store = cmd.getDataStore();
+        if (store instanceof NfsTO) {
+            String root = getRootDir(cmd.getSecUrl());
+            Map<Long, TemplateProp> templateInfos = _dlMgr.gatherVolumeInfo(root);
+            return new ListVolumeAnswer(cmd.getSecUrl(), templateInfos);
+        } else if (store instanceof S3TO) {
+            S3TO s3 = (S3TO)store;
+            Map<Long, TemplateProp> templateInfos = s3ListVolume(s3);
+            return new ListVolumeAnswer(s3.getBucketName(), templateInfos);
+        } else {
+            return new Answer(cmd, false, "Unsupported image data store: " + store);
+        }
+
+    }
+
+    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 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) {
+        DataStoreTO store = cmd.getStore();
+        if (store instanceof S3TO || store instanceof SwiftTO) {
+            long infinity = Integer.MAX_VALUE;
+            return new GetStorageStatsAnswer(cmd, infinity, 0L);
+        }
+
+        String rootDir = getRootDir(((NfsTO)store).getUrl());
+        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 DeleteCommand cmd) {
+        DataTO obj = cmd.getData();
+        DataObjectType objType = obj.getObjectType();
+        if (obj.getPath() == null) {
+            // account for those fake entries for NFS migration to object store
+            return new Answer(cmd, true, "Object with null install path does not exist on image store , no need to delete");
+        }
+        switch (objType) {
+        case TEMPLATE:
+            return deleteTemplate(cmd);
+        case VOLUME:
+            return deleteVolume(cmd);
+        case SNAPSHOT:
+            return deleteSnapshot(cmd);
+        }
+        return Answer.createUnsupportedCommandAnswer(cmd);
+    }
+
+    protected Answer deleteTemplate(DeleteCommand cmd) {
+        DataTO obj = cmd.getData();
+        DataStoreTO dstore = obj.getDataStore();
+        if (dstore instanceof NfsTO) {
+            NfsTO nfs = (NfsTO)dstore;
+            String relativeTemplatePath = obj.getPath();
+            String parent = getRootDir(nfs.getUrl());
+
+            if (relativeTemplatePath.startsWith(File.separator)) {
+                relativeTemplatePath = relativeTemplatePath.substring(1);
+            }
+
+            if (!parent.endsWith(File.separator)) {
+                parent += File.separator;
+            }
+            String absoluteTemplatePath = parent + relativeTemplatePath;
+            File tmpltPath = new File(absoluteTemplatePath);
+            File tmpltParent = null;
+            if(tmpltPath.exists() && tmpltPath.isDirectory()) {
+                tmpltParent = tmpltPath;
+            } else {
+                tmpltParent = tmpltPath.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;
+                    }
+
+                    // KVM HA monitor makes a mess in the templates with its
+                    // heartbeat tests
+                    // Don't let this stop us from cleaning up the template
+                    if (f.isDirectory() && f.getName().equals("KVMHA")) {
+                        s_logger.debug("Deleting KVMHA directory contents from template location");
+                        File[] haFiles = f.listFiles();
+                        for (File haFile : haFiles) {
+                            haFile.delete();
+                        }
+                    }
+
+                    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);
+        } else if (dstore instanceof S3TO) {
+            final S3TO s3 = (S3TO)dstore;
+            final String path = obj.getPath();
+            final String bucket = s3.getBucketName();
+            try {
+                S3Utils.deleteDirectory(s3, bucket, path);
+                return new Answer(cmd, true, String.format("Deleted template %1$s from bucket %2$s.", path, bucket));
+            } catch (Exception e) {
+                final String errorMessage =
+                        String.format("Failed to delete template %1$s from bucket %2$s due to the following error: %3$s", path, bucket, e.getMessage());
+                s_logger.error(errorMessage, e);
+                return new Answer(cmd, false, errorMessage);
+            }
+        } else if (dstore instanceof SwiftTO) {
+            SwiftTO swift = (SwiftTO)dstore;
+            String container = "T-" + obj.getId();
+            String 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);
+            }
+        } else {
+            return new Answer(cmd, false, "Unsupported image data store: " + dstore);
+        }
+    }
+
+    protected Answer deleteVolume(final DeleteCommand cmd) {
+        DataTO obj = cmd.getData();
+        DataStoreTO dstore = obj.getDataStore();
+        if (dstore instanceof NfsTO) {
+            NfsTO nfs = (NfsTO)dstore;
+            String relativeVolumePath = obj.getPath();
+            String parent = getRootDir(nfs.getUrl());
+
+            if (relativeVolumePath.startsWith(File.separator)) {
+                relativeVolumePath = relativeVolumePath.substring(1);
+            }
+
+            if (!parent.endsWith(File.separator)) {
+                parent += File.separator;
+            }
+            String absoluteVolumePath = parent + relativeVolumePath;
+            File volPath = new File(absoluteVolumePath);
+            File tmpltParent = null;
+            if (volPath.exists() && volPath.isDirectory()) {
+                // for vmware, absoluteVolumePath represents a directory where volume files are located.
+                tmpltParent = volPath;
+            } else {
+                // for other hypervisors, the volume .vhd or .qcow2 file path is passed
+                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;
+                    }
+
+                    // KVM HA monitor makes a mess in the templates with its
+                    // heartbeat tests
+                    // Don't let this stop us from cleaning up the template
+                    if (f.isDirectory() && f.getName().equals("KVMHA")) {
+                        s_logger.debug("Deleting KVMHA directory contents from template location");
+                        File[] haFiles = f.listFiles();
+                        for (File haFile : haFiles) {
+                            haFile.delete();
+                        }
+                    }
+
+                    if (!f.delete()) {
+                        return new Answer(cmd, false, "Unable to delete file " + f.getName() + " under Volume path " + tmpltParent.getPath());
+                    }
+                }
+                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 " + tmpltParent.getPath();
+                s_logger.debug(details);
+                return new Answer(cmd, false, details);
+            }
+            return new Answer(cmd, true, null);
+        } else if (dstore instanceof S3TO) {
+            final S3TO s3 = (S3TO)dstore;
+            final String path = obj.getPath();
+            final String bucket = s3.getBucketName();
+            try {
+                S3Utils.deleteDirectory(s3, bucket, path);
+                return new Answer(cmd, true, String.format("Deleted volume %1%s from bucket %2$s.", path, bucket));
+            } catch (Exception e) {
+                final String errorMessage = String.format("Failed to delete volume %1$s from bucket %2$s due to the following error: %3$s", path, bucket, e.getMessage());
+                s_logger.error(errorMessage, e);
+                return new Answer(cmd, false, errorMessage);
+            }
+        } else if (dstore instanceof SwiftTO) {
+            Long volumeId = obj.getId();
+            String path = obj.getPath();
+            String filename = StringUtils.substringAfterLast(path, "/"); // assuming
+            // that
+            // the
+            // filename
+            // is
+            // the
+            // last
+            // section
+            // in
+            // the
+            // path
+            String result = swiftDelete((SwiftTO)dstore, "V-" + volumeId.toString(), filename);
+            if (result != null) {
+                String errMsg = "failed to delete volume " + filename + " , err=" + result;
+                s_logger.warn(errMsg);
+                return new Answer(cmd, false, errMsg);
+            }
+            return new Answer(cmd, true, "Deleted volume " + path + " from swift");
+        } else {
+            return new Answer(cmd, false, "Unsupported image data store: " + dstore);
+        }
+
+    }
+
+    @Override
+    synchronized public String getRootDir(String secUrl) {
+        if (!_inSystemVM) {
+            return _parent;
+        }
+        try {
+            URI uri = new URI(secUrl);
+            String dir = mountUri(uri);
+            return _parent + "/" + dir;
+        } catch (Exception e) {
+            String msg = "GetRootDir for " + secUrl + " failed due to " + e.toString();
+            s_logger.error(msg, e);
+            throw new CloudRuntimeException(msg);
+        }
+    }
+
+    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("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");
+        }
+        _publicIp = (String)params.get("eth2ip");
+        _hostname = (String)params.get("name");
+
+        String inSystemVM = (String)params.get("secondary.storage.vm");
+        if (inSystemVM == null || "true".equalsIgnoreCase(inSystemVM)) {
+            s_logger.debug("conf secondary.storage.vm is true, act as if executing in SSVM");
+            _inSystemVM = true;
+        }
+
+        _storageIp = (String)params.get("storageip");
+        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");
+        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);
+        configureStorageLayerClass(params);
+
+        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);
+        }
+
+        createTemplateFromSnapshotXenScript = Script.findScript(getDefaultScriptsDir(), "create_privatetemplate_from_snapshot_xen.sh");
+        if (createTemplateFromSnapshotXenScript == null) {
+            throw new ConfigurationException("create_privatetemplate_from_snapshot_xen.sh not found in " + getDefaultScriptsDir());
+        }
+
+        _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;
+    }
+
+    protected void configureStorageLayerClass(Map<String, Object> params) throws ConfigurationException {
+        String value;
+        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();
+            

<TRUNCATED>

[10/11] Moved the controlling logic for secondary storage vm into place

Posted by ah...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/54f32a8e/services/secondary-storage/controller/src/org/apache/cloudstack/secondarystorage/SecondaryStorageManagerImpl.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/controller/src/org/apache/cloudstack/secondarystorage/SecondaryStorageManagerImpl.java b/services/secondary-storage/controller/src/org/apache/cloudstack/secondarystorage/SecondaryStorageManagerImpl.java
new file mode 100755
index 0000000..4a59d8f
--- /dev/null
+++ b/services/secondary-storage/controller/src/org/apache/cloudstack/secondarystorage/SecondaryStorageManagerImpl.java
@@ -0,0 +1,1388 @@
+// 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.secondarystorage;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.ejb.Local;
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.config.ApiServiceConfiguration;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
+import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.cloudstack.framework.security.keystore.KeystoreManager;
+import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
+import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
+import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
+import org.apache.cloudstack.utils.identity.ManagementServerNode;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.RebootCommand;
+import com.cloud.agent.api.SecStorageFirewallCfgCommand;
+import com.cloud.agent.api.SecStorageSetupAnswer;
+import com.cloud.agent.api.SecStorageSetupCommand;
+import com.cloud.agent.api.SecStorageVMSetupCommand;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.StartupSecondaryStorageCommand;
+import com.cloud.agent.api.check.CheckSshAnswer;
+import com.cloud.agent.api.check.CheckSshCommand;
+import com.cloud.agent.api.to.NfsTO;
+import com.cloud.agent.manager.Commands;
+import com.cloud.capacity.dao.CapacityDao;
+import com.cloud.cluster.ClusterManager;
+import com.cloud.configuration.Config;
+import com.cloud.configuration.ZoneConfig;
+import com.cloud.consoleproxy.ConsoleProxyManager;
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.DataCenter.NetworkType;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.deploy.DataCenterDeployment;
+import com.cloud.deploy.DeployDestination;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.exception.StorageUnavailableException;
+import com.cloud.host.Host;
+import com.cloud.host.HostVO;
+import com.cloud.host.Status;
+import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.info.RunningHostCountInfo;
+import com.cloud.info.RunningHostInfoAgregator;
+import com.cloud.info.RunningHostInfoAgregator.ZoneHostInfo;
+import com.cloud.network.Network;
+import com.cloud.network.NetworkModel;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.dao.IPAddressDao;
+import com.cloud.network.dao.IPAddressVO;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.rules.RulesManager;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.offering.ServiceOffering;
+import com.cloud.offerings.dao.NetworkOfferingDao;
+import com.cloud.resource.ResourceManager;
+import com.cloud.resource.ResourceStateAdapter;
+import com.cloud.resource.ServerResource;
+import com.cloud.resource.UnableDeleteHostException;
+import com.cloud.service.ServiceOfferingVO;
+import com.cloud.service.dao.ServiceOfferingDao;
+import com.cloud.storage.UploadVO;
+import com.cloud.storage.VMTemplateVO;
+import com.cloud.storage.dao.SnapshotDao;
+import com.cloud.storage.dao.StoragePoolHostDao;
+import com.cloud.storage.dao.UploadDao;
+import com.cloud.storage.dao.VMTemplateDao;
+import com.cloud.storage.secondary.SecStorageVmAlertEventArgs;
+import com.cloud.storage.secondary.SecondaryStorageListener;
+import com.cloud.storage.secondary.SecondaryStorageVmAllocator;
+import com.cloud.storage.secondary.SecondaryStorageVmManager;
+import com.cloud.storage.template.TemplateConstants;
+import com.cloud.template.TemplateManager;
+import com.cloud.user.Account;
+import com.cloud.user.AccountService;
+import com.cloud.utils.DateUtil;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.Pair;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.db.GlobalLock;
+import com.cloud.utils.db.QueryBuilder;
+import com.cloud.utils.db.SearchCriteria.Op;
+import com.cloud.utils.events.SubscriptionMgr;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.vm.Nic;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.ReservationContext;
+import com.cloud.vm.SecondaryStorageVm;
+import com.cloud.vm.SecondaryStorageVmVO;
+import com.cloud.vm.SystemVmLoadScanHandler;
+import com.cloud.vm.SystemVmLoadScanner;
+import com.cloud.vm.SystemVmLoadScanner.AfterScanAction;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachine.State;
+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.SecondaryStorageVmDao;
+import com.cloud.vm.dao.UserVmDetailsDao;
+import com.cloud.vm.dao.VMInstanceDao;
+
+//
+// Possible secondary storage vm state transition cases
+//        Creating -> Destroyed
+//        Creating -> Stopped --> Starting -> Running
+//        HA -> Stopped -> Starting -> Running
+//        Migrating -> Running    (if previous state is Running before it enters into Migrating state
+//        Migrating -> Stopped    (if previous state is not Running before it enters into Migrating state)
+//        Running -> HA            (if agent lost connection)
+//        Stopped -> Destroyed
+//
+//        Creating state indicates of record creating and IP address allocation are ready, it is a transient
+//         state which will soon be switching towards Running if everything goes well.
+//        Stopped state indicates the readiness of being able to start (has storage and IP resources allocated)
+//        Starting state can only be entered from Stopped states
+//
+// Starting, HA, Migrating, Creating and Running state are all counted as "Open" for available capacity calculation
+// because sooner or later, it will be driven into Running state
+//
+@Local(value = {SecondaryStorageVmManager.class})
+public class SecondaryStorageManagerImpl extends ManagerBase implements SecondaryStorageVmManager, VirtualMachineGuru, SystemVmLoadScanHandler<Long>,
+        ResourceStateAdapter {
+    private static final Logger s_logger = Logger.getLogger(SecondaryStorageManagerImpl.class);
+
+    private static final int DEFAULT_CAPACITY_SCAN_INTERVAL = 30000; // 30
+    // seconds
+    private static final int ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_SYNC = 180; // 3
+    // minutes
+
+    private static final int STARTUP_DELAY = 60000; // 60 seconds
+
+    private int _mgmtPort = 8250;
+
+    private List<SecondaryStorageVmAllocator> _ssVmAllocators;
+
+    @Inject
+    protected SecondaryStorageVmDao _secStorageVmDao;
+    @Inject
+    private DataCenterDao _dcDao;
+    @Inject
+    private VMTemplateDao _templateDao;
+    @Inject
+    private HostDao _hostDao;
+    @Inject
+    private StoragePoolHostDao _storagePoolHostDao;
+    @Inject
+    private AgentManager _agentMgr;
+    @Inject
+    protected NetworkOrchestrationService _networkMgr;
+    @Inject
+    protected NetworkModel _networkModel;
+    @Inject
+    protected SnapshotDao _snapshotDao;
+    private SecondaryStorageListener _listener;
+
+    private ServiceOfferingVO _serviceOffering;
+
+    @Inject
+    protected ConfigurationDao _configDao;
+    @Inject
+    private ServiceOfferingDao _offeringDao;
+    @Inject
+    private AccountService _accountMgr;
+    @Inject
+    private VirtualMachineManager _itMgr;
+    @Inject
+    protected VMInstanceDao _vmDao;
+    @Inject
+    protected CapacityDao _capacityDao;
+    @Inject
+    UserVmDetailsDao _vmDetailsDao;
+    @Inject
+    protected ResourceManager _resourceMgr;
+    @Inject
+    NetworkDao _networkDao;
+    @Inject
+    NetworkOfferingDao _networkOfferingDao;
+    @Inject
+    protected IPAddressDao _ipAddressDao = null;
+    @Inject
+    protected RulesManager _rulesMgr;
+    @Inject
+    TemplateManager templateMgr;
+    @Inject
+    UploadDao _uploadDao;
+
+    @Inject
+    KeystoreManager _keystoreMgr;
+    @Inject
+    DataStoreManager _dataStoreMgr;
+    @Inject
+    ImageStoreDao _imageStoreDao;
+    @Inject
+    TemplateDataStoreDao _tmplStoreDao;
+    private long _capacityScanInterval = DEFAULT_CAPACITY_SCAN_INTERVAL;
+    private int _secStorageVmMtuSize;
+
+    private String _instance;
+    private boolean _useLocalStorage;
+    private boolean _useSSlCopy;
+    private String _httpProxy;
+    private String _allowedInternalSites;
+    protected long _nodeId = ManagementServerNode.getManagementServerId();
+
+    private SystemVmLoadScanner<Long> _loadScanner;
+    private Map<Long, ZoneHostInfo> _zoneHostInfoMap; // map <zone id, info about running host in zone>
+
+    private final GlobalLock _allocLock = GlobalLock.getInternLock(getAllocLockName());
+
+    public SecondaryStorageManagerImpl() {
+    }
+
+    @Override
+    public SecondaryStorageVmVO startSecStorageVm(long secStorageVmId) {
+        try {
+            SecondaryStorageVmVO secStorageVm = _secStorageVmDao.findById(secStorageVmId);
+            _itMgr.advanceStart(secStorageVm.getUuid(), null, null);
+            return _secStorageVmDao.findById(secStorageVm.getId());
+        } catch (StorageUnavailableException e) {
+            s_logger.warn("Exception while trying to start secondary storage vm", e);
+            return null;
+        } catch (InsufficientCapacityException e) {
+            s_logger.warn("Exception while trying to start secondary storage vm", e);
+            return null;
+        } catch (ResourceUnavailableException e) {
+            s_logger.warn("Exception while trying to start secondary storage vm", e);
+            return null;
+        } catch (Exception e) {
+            s_logger.warn("Exception while trying to start secondary storage vm", e);
+            return null;
+        }
+    }
+
+    SecondaryStorageVmVO getSSVMfromHost(HostVO ssAHost) {
+        if (ssAHost.getType() == Host.Type.SecondaryStorageVM) {
+            return _secStorageVmDao.findByInstanceName(ssAHost.getName());
+        }
+        return null;
+    }
+
+    @Override
+    public boolean generateSetupCommand(Long ssHostId) {
+        HostVO cssHost = _hostDao.findById(ssHostId);
+        Long zoneId = cssHost.getDataCenterId();
+        if (cssHost.getType() == Host.Type.SecondaryStorageVM) {
+
+            SecondaryStorageVmVO secStorageVm = _secStorageVmDao.findByInstanceName(cssHost.getName());
+            if (secStorageVm == null) {
+                s_logger.warn("secondary storage VM " + cssHost.getName() + " doesn't exist");
+                return false;
+            }
+
+            List<DataStore> ssStores = _dataStoreMgr.getImageStoresByScope(new ZoneScope(zoneId));
+            for (DataStore ssStore : ssStores) {
+                if (!(ssStore.getTO() instanceof NfsTO)) {
+                    continue; // only do this for Nfs
+                }
+                String secUrl = ssStore.getUri();
+                SecStorageSetupCommand setupCmd = null;
+                if (!_useSSlCopy) {
+                    setupCmd = new SecStorageSetupCommand(ssStore.getTO(), secUrl, null);
+                } else {
+                    KeystoreManager.Certificates certs = _keystoreMgr.getCertificates(ConsoleProxyManager.CERTIFICATE_NAME);
+                    setupCmd = new SecStorageSetupCommand(ssStore.getTO(), secUrl, certs);
+                }
+
+                Answer answer = _agentMgr.easySend(ssHostId, setupCmd);
+                if (answer != null && answer.getResult()) {
+                    SecStorageSetupAnswer an = (SecStorageSetupAnswer)answer;
+                    if (an.get_dir() != null) {
+                        // update the parent path in image_store table for this image store
+                        ImageStoreVO svo = _imageStoreDao.findById(ssStore.getId());
+                        svo.setParent(an.get_dir());
+                        _imageStoreDao.update(ssStore.getId(), svo);
+                    }
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Successfully programmed secondary storage " + ssStore.getName() + " in secondary storage VM " + secStorageVm.getInstanceName());
+                    }
+                } else {
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Successfully programmed secondary storage " + ssStore.getName() + " in secondary storage VM " + secStorageVm.getInstanceName());
+                    }
+                    return false;
+                }
+            }
+        }
+        /* After removing SecondaryStorage entries from host table, control should never come here!!
+        else if( cssHost.getType() == Host.Type.SecondaryStorage ) {
+            List<SecondaryStorageVmVO> alreadyRunning = _secStorageVmDao.getSecStorageVmListInStates(SecondaryStorageVm.Role.templateProcessor, zoneId, State.Running);
+            String secUrl = cssHost.getStorageUrl();
+            SecStorageSetupCommand setupCmd = new SecStorageSetupCommand(secUrl, null);
+            for ( SecondaryStorageVmVO ssVm : alreadyRunning ) {
+                HostVO host = _resourceMgr.findHostByName(ssVm.getInstanceName());
+                Answer answer = _agentMgr.easySend(host.getId(), setupCmd);
+                if (answer != null && answer.getResult()) {
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Successfully programmed secondary storage " + host.getName() + " in secondary storage VM " + ssVm.getInstanceName());
+                    }
+                } else {
+                    if (s_logger.isDebugEnabled()) {
+                        s_logger.debug("Successfully programmed secondary storage " + host.getName() + " in secondary storage VM " + ssVm.getInstanceName());
+                    }
+                    return false;
+                }
+            }
+        }
+         */
+        return true;
+    }
+
+    @Override
+    public boolean generateVMSetupCommand(Long ssAHostId) {
+        HostVO ssAHost = _hostDao.findById(ssAHostId);
+        if (ssAHost.getType() != Host.Type.SecondaryStorageVM) {
+            return false;
+        }
+        SecondaryStorageVmVO secStorageVm = _secStorageVmDao.findByInstanceName(ssAHost.getName());
+        if (secStorageVm == null) {
+            s_logger.warn("secondary storage VM " + ssAHost.getName() + " doesn't exist");
+            return false;
+        }
+
+        SecStorageVMSetupCommand setupCmd = new SecStorageVMSetupCommand();
+        if (_allowedInternalSites != null) {
+            List<String> allowedCidrs = new ArrayList<String>();
+            String[] cidrs = _allowedInternalSites.split(",");
+            for (String cidr : cidrs) {
+                if (NetUtils.isValidCIDR(cidr) || NetUtils.isValidIp(cidr) || !cidr.startsWith("0.0.0.0")) {
+                    allowedCidrs.add(cidr);
+                }
+            }
+            List<? extends Nic> nics = _networkModel.getNicsForTraffic(secStorageVm.getId(), TrafficType.Management);
+            setupCmd.setAllowedInternalSites(allowedCidrs.toArray(new String[allowedCidrs.size()]));
+        }
+        String copyPasswd = _configDao.getValue("secstorage.copy.password");
+        setupCmd.setCopyPassword(copyPasswd);
+        setupCmd.setCopyUserName(TemplateConstants.DEFAULT_HTTP_AUTH_USER);
+        Answer answer = _agentMgr.easySend(ssAHostId, setupCmd);
+        if (answer != null && answer.getResult()) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Successfully programmed http auth into " + secStorageVm.getHostName());
+            }
+            return true;
+        } else {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("failed to program http auth into secondary storage vm : " + secStorageVm.getHostName());
+            }
+            return false;
+        }
+    }
+
+    @Override
+    public Pair<HostVO, SecondaryStorageVmVO> assignSecStorageVm(long zoneId, Command cmd) {
+        return null;
+    }
+
+    @Override
+    public boolean generateFirewallConfiguration(Long ssAHostId) {
+        if (ssAHostId == null) {
+            return true;
+        }
+        HostVO ssAHost = _hostDao.findById(ssAHostId);
+        SecondaryStorageVmVO thisSecStorageVm = _secStorageVmDao.findByInstanceName(ssAHost.getName());
+
+        if (thisSecStorageVm == null) {
+            s_logger.warn("secondary storage VM " + ssAHost.getName() + " doesn't exist");
+            return false;
+        }
+
+        String copyPort = _useSSlCopy ? "443" : Integer.toString(TemplateConstants.DEFAULT_TMPLT_COPY_PORT);
+        SecStorageFirewallCfgCommand thiscpc = new SecStorageFirewallCfgCommand(true);
+        thiscpc.addPortConfig(thisSecStorageVm.getPublicIpAddress(), copyPort, true, TemplateConstants.DEFAULT_TMPLT_COPY_INTF);
+
+        QueryBuilder<HostVO> sc = QueryBuilder.create(HostVO.class);
+        sc.and(sc.entity().getType(), Op.EQ, Host.Type.SecondaryStorageVM);
+        sc.and(sc.entity().getStatus(), Op.IN, Status.Up, Status.Connecting);
+        List<HostVO> ssvms = sc.list();
+        for (HostVO ssvm : ssvms) {
+            if (ssvm.getId() == ssAHostId) {
+                continue;
+            }
+            Answer answer = _agentMgr.easySend(ssvm.getId(), thiscpc);
+            if (answer != null && answer.getResult()) {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Successfully programmed firewall rules into SSVM " + ssvm.getName());
+                }
+            } else {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("failed to program firewall rules into secondary storage vm : " + ssvm.getName());
+                }
+                return false;
+            }
+        }
+
+        SecStorageFirewallCfgCommand allSSVMIpList = new SecStorageFirewallCfgCommand(false);
+        for (HostVO ssvm : ssvms) {
+            if (ssvm.getId() == ssAHostId) {
+                continue;
+            }
+            allSSVMIpList.addPortConfig(ssvm.getPublicIpAddress(), copyPort, true, TemplateConstants.DEFAULT_TMPLT_COPY_INTF);
+        }
+
+        Answer answer = _agentMgr.easySend(ssAHostId, allSSVMIpList);
+        if (answer != null && answer.getResult()) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Successfully programmed firewall rules into " + thisSecStorageVm.getHostName());
+            }
+        } else {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("failed to program firewall rules into secondary storage vm : " + thisSecStorageVm.getHostName());
+            }
+            return false;
+        }
+
+        return true;
+
+    }
+
+    protected boolean isSecondaryStorageVmRequired(long dcId) {
+        DataCenterVO dc = _dcDao.findById(dcId);
+        _dcDao.loadDetails(dc);
+        String ssvmReq = dc.getDetail(ZoneConfig.EnableSecStorageVm.key());
+        if (ssvmReq != null) {
+            return Boolean.parseBoolean(ssvmReq);
+        }
+        return true;
+    }
+
+    public SecondaryStorageVmVO startNew(long dataCenterId, SecondaryStorageVm.Role role) {
+
+        if (!isSecondaryStorageVmRequired(dataCenterId)) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Secondary storage vm not required in zone " + dataCenterId + " acc. to zone config");
+            }
+            return null;
+        }
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Assign secondary storage vm from a newly started instance for request from data center : " + dataCenterId);
+        }
+
+        Map<String, Object> context = createSecStorageVmInstance(dataCenterId, role);
+
+        long secStorageVmId = (Long)context.get("secStorageVmId");
+        if (secStorageVmId == 0) {
+            if (s_logger.isTraceEnabled()) {
+                s_logger.trace("Creating secondary storage vm instance failed, data center id : " + dataCenterId);
+            }
+
+            return null;
+        }
+
+        SecondaryStorageVmVO secStorageVm = _secStorageVmDao.findById(secStorageVmId);
+        // SecondaryStorageVmVO secStorageVm =
+        // allocSecStorageVmStorage(dataCenterId, secStorageVmId);
+        if (secStorageVm != null) {
+            SubscriptionMgr.getInstance().notifySubscribers(ALERT_SUBJECT, this,
+                new SecStorageVmAlertEventArgs(SecStorageVmAlertEventArgs.SSVM_CREATED, dataCenterId, secStorageVmId, secStorageVm, null));
+            return secStorageVm;
+        } else {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Unable to allocate secondary storage vm storage, remove the secondary storage vm record from DB, secondary storage vm id: " +
+                    secStorageVmId);
+            }
+
+            SubscriptionMgr.getInstance().notifySubscribers(ALERT_SUBJECT, this,
+                new SecStorageVmAlertEventArgs(SecStorageVmAlertEventArgs.SSVM_CREATE_FAILURE, dataCenterId, secStorageVmId, null, "Unable to allocate storage"));
+        }
+        return null;
+    }
+
+    protected Map<String, Object> createSecStorageVmInstance(long dataCenterId, SecondaryStorageVm.Role role) {
+        DataStore secStore = _dataStoreMgr.getImageStore(dataCenterId);
+        if (secStore == null) {
+            String msg = "No secondary storage available in zone " + dataCenterId + ", cannot create secondary storage vm";
+            s_logger.warn(msg);
+            throw new CloudRuntimeException(msg);
+        }
+
+        long id = _secStorageVmDao.getNextInSequence(Long.class, "id");
+        String name = VirtualMachineName.getSystemVmName(id, _instance, "s").intern();
+        Account systemAcct = _accountMgr.getSystemAccount();
+
+        DataCenterDeployment plan = new DataCenterDeployment(dataCenterId);
+        DataCenter dc = _dcDao.findById(plan.getDataCenterId());
+
+        NetworkVO defaultNetwork = null;
+        if (dc.getNetworkType() == NetworkType.Advanced && dc.isSecurityGroupEnabled()) {
+            List<NetworkVO> networks = _networkDao.listByZoneSecurityGroup(dataCenterId);
+            if (networks == null || networks.size() == 0) {
+                throw new CloudRuntimeException("Can not found security enabled network in SG Zone " + dc);
+            }
+            defaultNetwork = networks.get(0);
+        } else {
+            TrafficType defaultTrafficType = TrafficType.Public;
+
+            if (dc.getNetworkType() == NetworkType.Basic || dc.isSecurityGroupEnabled()) {
+                defaultTrafficType = TrafficType.Guest;
+            }
+            List<NetworkVO> defaultNetworks = _networkDao.listByZoneAndTrafficType(dataCenterId, defaultTrafficType);
+            // api should never allow this situation to happen
+            if (defaultNetworks.size() != 1) {
+                throw new CloudRuntimeException("Found " + defaultNetworks.size() + " networks of type " + defaultTrafficType + " when expect to find 1");
+            }
+            defaultNetwork = defaultNetworks.get(0);
+        }
+
+        List<? extends NetworkOffering> offerings =
+            _networkModel.getSystemAccountNetworkOfferings(NetworkOffering.SystemControlNetwork, NetworkOffering.SystemManagementNetwork,
+                NetworkOffering.SystemStorageNetwork);
+        LinkedHashMap<Network, NicProfile> networks = new LinkedHashMap<Network, NicProfile>(offerings.size() + 1);
+        NicProfile defaultNic = new NicProfile();
+        defaultNic.setDefaultNic(true);
+        defaultNic.setDeviceId(2);
+        try {
+            networks.put(_networkMgr.setupNetwork(systemAcct, _networkOfferingDao.findById(defaultNetwork.getNetworkOfferingId()), plan, null, null, false).get(0),
+                defaultNic);
+            for (NetworkOffering offering : offerings) {
+                networks.put(_networkMgr.setupNetwork(systemAcct, offering, plan, null, null, false).get(0), null);
+            }
+        } catch (ConcurrentOperationException e) {
+            s_logger.info("Unable to setup due to concurrent operation. " + e);
+            return new HashMap<String, Object>();
+        }
+
+        VMTemplateVO template = null;
+        HypervisorType availableHypervisor = _resourceMgr.getAvailableHypervisor(dataCenterId);
+        template = _templateDao.findSystemVMReadyTemplate(dataCenterId, availableHypervisor);
+        if (template == null) {
+            throw new CloudRuntimeException("Not able to find the System templates or not downloaded in zone " + dataCenterId);
+        }
+
+        SecondaryStorageVmVO secStorageVm =
+            new SecondaryStorageVmVO(id, _serviceOffering.getId(), name, template.getId(), template.getHypervisorType(), template.getGuestOSId(), dataCenterId,
+                systemAcct.getDomainId(), systemAcct.getId(), role, _serviceOffering.getOfferHA());
+        secStorageVm.setDynamicallyScalable(template.isDynamicallyScalable());
+        secStorageVm = _secStorageVmDao.persist(secStorageVm);
+        try {
+            _itMgr.allocate(name, template, _serviceOffering, networks, plan, null);
+            secStorageVm = _secStorageVmDao.findById(secStorageVm.getId());
+        } catch (InsufficientCapacityException e) {
+            s_logger.warn("InsufficientCapacity", e);
+            throw new CloudRuntimeException("Insufficient capacity exception", e);
+        }
+
+        Map<String, Object> context = new HashMap<String, Object>();
+        context.put("secStorageVmId", secStorageVm.getId());
+        return context;
+    }
+
+    private SecondaryStorageVmAllocator getCurrentAllocator() {
+
+        // for now, only one adapter is supported
+        if (_ssVmAllocators.size() > 0) {
+            return _ssVmAllocators.get(0);
+        }
+
+        return null;
+    }
+
+    protected String connect(String ipAddress, int port) {
+        return null;
+    }
+
+    public SecondaryStorageVmVO assignSecStorageVmFromRunningPool(long dataCenterId, SecondaryStorageVm.Role role) {
+
+        if (s_logger.isTraceEnabled()) {
+            s_logger.trace("Assign  secondary storage vm from running pool for request from data center : " + dataCenterId);
+        }
+
+        SecondaryStorageVmAllocator allocator = getCurrentAllocator();
+        assert (allocator != null);
+        List<SecondaryStorageVmVO> runningList = _secStorageVmDao.getSecStorageVmListInStates(role, dataCenterId, State.Running);
+        if (runningList != null && runningList.size() > 0) {
+            if (s_logger.isTraceEnabled()) {
+                s_logger.trace("Running secondary storage vm pool size : " + runningList.size());
+                for (SecondaryStorageVmVO secStorageVm : runningList) {
+                    s_logger.trace("Running secStorageVm instance : " + secStorageVm.getHostName());
+                }
+            }
+
+            Map<Long, Integer> loadInfo = new HashMap<Long, Integer>();
+
+            return allocator.allocSecondaryStorageVm(runningList, loadInfo, dataCenterId);
+        } else {
+            if (s_logger.isTraceEnabled()) {
+                s_logger.trace("Empty running secStorageVm pool for now in data center : " + dataCenterId);
+            }
+        }
+        return null;
+    }
+
+    public SecondaryStorageVmVO assignSecStorageVmFromStoppedPool(long dataCenterId, SecondaryStorageVm.Role role) {
+        List<SecondaryStorageVmVO> l = _secStorageVmDao.getSecStorageVmListInStates(role, dataCenterId, State.Starting, State.Stopped, State.Migrating);
+        if (l != null && l.size() > 0) {
+            return l.get(0);
+        }
+
+        return null;
+    }
+
+    private void allocCapacity(long dataCenterId, SecondaryStorageVm.Role role) {
+        if (s_logger.isTraceEnabled()) {
+            s_logger.trace("Allocate secondary storage vm standby capacity for data center : " + dataCenterId);
+        }
+
+        if (!isSecondaryStorageVmRequired(dataCenterId)) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Secondary storage vm not required in zone " + dataCenterId + " acc. to zone config");
+            }
+            return;
+        }
+
+        boolean secStorageVmFromStoppedPool = false;
+        SecondaryStorageVmVO secStorageVm = assignSecStorageVmFromStoppedPool(dataCenterId, role);
+        if (secStorageVm == null) {
+            if (s_logger.isInfoEnabled()) {
+                s_logger.info("No stopped secondary storage vm is available, need to allocate a new secondary storage vm");
+            }
+
+            if (_allocLock.lock(ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_SYNC)) {
+                try {
+                    secStorageVm = startNew(dataCenterId, role);
+                    for (UploadVO upload : _uploadDao.listAll()) {
+                        _uploadDao.expunge(upload.getId());
+                    }
+                } finally {
+                    _allocLock.unlock();
+                }
+            } else {
+                if (s_logger.isInfoEnabled()) {
+                    s_logger.info("Unable to acquire synchronization lock to allocate secStorageVm resource for standby capacity, wait for next scan");
+                }
+                return;
+            }
+        } else {
+            if (s_logger.isInfoEnabled()) {
+                s_logger.info("Found a stopped secondary storage vm, bring it up to running pool. secStorageVm vm id : " + secStorageVm.getId());
+            }
+            secStorageVmFromStoppedPool = true;
+        }
+
+        if (secStorageVm != null) {
+            long secStorageVmId = secStorageVm.getId();
+            GlobalLock secStorageVmLock = GlobalLock.getInternLock(getSecStorageVmLockName(secStorageVmId));
+            try {
+                if (secStorageVmLock.lock(ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_SYNC)) {
+                    try {
+                        secStorageVm = startSecStorageVm(secStorageVmId);
+                    } finally {
+                        secStorageVmLock.unlock();
+                    }
+                } else {
+                    if (s_logger.isInfoEnabled()) {
+                        s_logger.info("Unable to acquire synchronization lock to start secStorageVm for standby capacity, secStorageVm vm id : " + secStorageVm.getId());
+                    }
+                    return;
+                }
+            } finally {
+                secStorageVmLock.releaseRef();
+            }
+
+            if (secStorageVm == null) {
+                if (s_logger.isInfoEnabled()) {
+                    s_logger.info("Unable to start secondary storage vm for standby capacity, secStorageVm vm Id : " + secStorageVmId +
+                        ", will recycle it and start a new one");
+                }
+
+                if (secStorageVmFromStoppedPool) {
+                    destroySecStorageVm(secStorageVmId);
+                }
+            } else {
+                if (s_logger.isInfoEnabled()) {
+                    s_logger.info("Secondary storage vm " + secStorageVm.getHostName() + " is started");
+                }
+            }
+        }
+    }
+
+    public boolean isZoneReady(Map<Long, ZoneHostInfo> zoneHostInfoMap, long dataCenterId) {
+        ZoneHostInfo zoneHostInfo = zoneHostInfoMap.get(dataCenterId);
+        if (zoneHostInfo != null && (zoneHostInfo.getFlags() & RunningHostInfoAgregator.ZoneHostInfo.ROUTING_HOST_MASK) != 0) {
+            VMTemplateVO template = _templateDao.findSystemVMReadyTemplate(dataCenterId, HypervisorType.Any);
+            if (template == null) {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("System vm template is not ready at data center " + dataCenterId + ", wait until it is ready to launch secondary storage vm");
+                }
+                return false;
+            }
+
+            List<DataStore> stores = _dataStoreMgr.getImageStoresByScope(new ZoneScope(dataCenterId));
+            if (stores.size() < 1) {
+                s_logger.debug("No image store added  in zone " + dataCenterId + ", wait until it is ready to launch secondary storage vm");
+                return false;
+            }
+
+            DataStore store = templateMgr.getImageStore(dataCenterId, template.getId());
+            if (store == null) {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("No secondary storage available in zone " + dataCenterId + ", wait until it is ready to launch secondary storage vm");
+                }
+                return false;
+            }
+
+            List<Pair<Long, Integer>> l = _storagePoolHostDao.getDatacenterStoragePoolHostInfo(dataCenterId, !_useLocalStorage);
+            if (l != null && l.size() > 0 && l.get(0).second().intValue() > 0) {
+                return true;
+            } else {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Primary storage is not ready, wait until it is ready to launch secondary storage vm. dcId: " + dataCenterId +
+                        " system.vm.use.local.storage: " + _useLocalStorage +
+                        "If you want to use local storage to start ssvm, need to set system.vm.use.local.storage to true");
+                }
+            }
+
+        }
+        return false;
+    }
+
+    private synchronized Map<Long, ZoneHostInfo> getZoneHostInfo() {
+        Date cutTime = DateUtil.currentGMTTime();
+        List<RunningHostCountInfo> l = _hostDao.getRunningHostCounts(new Date(cutTime.getTime() - ClusterManager.HeartbeatThreshold.value()));
+
+        RunningHostInfoAgregator aggregator = new RunningHostInfoAgregator();
+        if (l.size() > 0) {
+            for (RunningHostCountInfo countInfo : l) {
+                aggregator.aggregate(countInfo);
+            }
+        }
+
+        return aggregator.getZoneHostInfoMap();
+    }
+
+    @Override
+    public boolean start() {
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Start secondary storage vm manager");
+        }
+
+        return true;
+    }
+
+    @Override
+    public boolean stop() {
+        _loadScanner.stop();
+        _allocLock.releaseRef();
+        _resourceMgr.unregisterResourceStateAdapter(this.getClass().getSimpleName());
+        return true;
+    }
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Start configuring secondary storage vm manager : " + name);
+        }
+
+        Map<String, String> configs = _configDao.getConfiguration("management-server", params);
+
+        _secStorageVmMtuSize = NumbersUtil.parseInt(configs.get("secstorage.vm.mtu.size"), DEFAULT_SS_VM_MTUSIZE);
+        String useServiceVM = _configDao.getValue("secondary.storage.vm");
+        boolean _useServiceVM = false;
+        if ("true".equalsIgnoreCase(useServiceVM)) {
+            _useServiceVM = true;
+        }
+
+        String sslcopy = _configDao.getValue("secstorage.encrypt.copy");
+        if ("true".equalsIgnoreCase(sslcopy)) {
+            _useSSlCopy = true;
+        }
+
+        _allowedInternalSites = _configDao.getValue("secstorage.allowed.internal.sites");
+
+        String value = configs.get("secstorage.capacityscan.interval");
+        _capacityScanInterval = NumbersUtil.parseLong(value, DEFAULT_CAPACITY_SCAN_INTERVAL);
+
+        _instance = configs.get("instance.name");
+        if (_instance == null) {
+            _instance = "DEFAULT";
+        }
+
+        Map<String, String> agentMgrConfigs = _configDao.getConfiguration("AgentManager", params);
+
+        value = agentMgrConfigs.get("port");
+        _mgmtPort = NumbersUtil.parseInt(value, 8250);
+
+        _listener = new SecondaryStorageListener(this);
+        _agentMgr.registerForHostEvents(_listener, true, false, true);
+
+        _itMgr.registerGuru(VirtualMachine.Type.SecondaryStorageVm, this);
+
+        //check if there is a default service offering configured
+        String ssvmSrvcOffIdStr = configs.get(Config.SecondaryStorageServiceOffering.key());
+        if (ssvmSrvcOffIdStr != null) {
+            Long ssvmSrvcOffId = Long.parseLong(ssvmSrvcOffIdStr);
+            _serviceOffering = _offeringDao.findById(ssvmSrvcOffId);
+            if (_serviceOffering == null || !_serviceOffering.getSystemUse()) {
+                String msg = "Can't find system service offering id=" + ssvmSrvcOffId + " for secondary storage vm";
+                s_logger.error(msg);
+                throw new ConfigurationException(msg);
+            }
+        } else {
+            int ramSize = NumbersUtil.parseInt(_configDao.getValue("ssvm.ram.size"), DEFAULT_SS_VM_RAMSIZE);
+            int cpuFreq = NumbersUtil.parseInt(_configDao.getValue("ssvm.cpu.mhz"), DEFAULT_SS_VM_CPUMHZ);
+            _useLocalStorage = Boolean.parseBoolean(configs.get(Config.SystemVMUseLocalStorage.key()));
+            _serviceOffering =
+                new ServiceOfferingVO("System Offering For Secondary Storage VM", 1, ramSize, cpuFreq, null, null, false, null, _useLocalStorage, true, null, true,
+                    VirtualMachine.Type.SecondaryStorageVm, true);
+            _serviceOffering.setUniqueName(ServiceOffering.ssvmDefaultOffUniqueName);
+            _serviceOffering = _offeringDao.persistSystemServiceOffering(_serviceOffering);
+
+            // this can sometimes happen, if DB is manually or programmatically manipulated
+            if (_serviceOffering == null) {
+                String msg = "Data integrity problem : System Offering For Secondary Storage VM has been removed?";
+                s_logger.error(msg);
+                throw new ConfigurationException(msg);
+            }
+        }
+
+        if (_useServiceVM) {
+            _loadScanner = new SystemVmLoadScanner<Long>(this);
+            _loadScanner.initScan(STARTUP_DELAY, _capacityScanInterval);
+        }
+
+        _httpProxy = configs.get(Config.SecStorageProxy.key());
+        if (_httpProxy != null) {
+            boolean valid = true;
+            String errMsg = null;
+            try {
+                URI uri = new URI(_httpProxy);
+                if (!"http".equalsIgnoreCase(uri.getScheme())) {
+                    errMsg = "Only support http proxy";
+                    valid = false;
+                } else if (uri.getHost() == null) {
+                    errMsg = "host can not be null";
+                    valid = false;
+                } else if (uri.getPort() == -1) {
+                    _httpProxy = _httpProxy + ":3128";
+                }
+            } catch (URISyntaxException e) {
+                errMsg = e.toString();
+            } finally {
+                if (!valid) {
+                    s_logger.debug("ssvm http proxy " + _httpProxy + " is invalid: " + errMsg);
+                    throw new ConfigurationException("ssvm http proxy " + _httpProxy + "is invalid: " + errMsg);
+                }
+            }
+        }
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Secondary storage vm Manager is configured.");
+        }
+        _resourceMgr.registerResourceStateAdapter(this.getClass().getSimpleName(), this);
+        return true;
+    }
+
+    @Override
+    public boolean stopSecStorageVm(long secStorageVmId) {
+        SecondaryStorageVmVO secStorageVm = _secStorageVmDao.findById(secStorageVmId);
+        if (secStorageVm == null) {
+            String msg = "Stopping secondary storage vm failed: secondary storage vm " + secStorageVmId + " no longer exists";
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug(msg);
+            }
+            return false;
+        }
+        try {
+            if (secStorageVm.getHostId() != null) {
+                GlobalLock secStorageVmLock = GlobalLock.getInternLock(getSecStorageVmLockName(secStorageVm.getId()));
+                try {
+                    if (secStorageVmLock.lock(ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_SYNC)) {
+                        try {
+                            _itMgr.stop(secStorageVm.getUuid());
+                            return true;
+                        } finally {
+                            secStorageVmLock.unlock();
+                        }
+                    } else {
+                        String msg = "Unable to acquire secondary storage vm lock : " + secStorageVm.toString();
+                        s_logger.debug(msg);
+                        return false;
+                    }
+                } finally {
+                    secStorageVmLock.releaseRef();
+                }
+            }
+
+            // vm was already stopped, return true
+            return true;
+        } catch (ResourceUnavailableException e) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Stopping secondary storage vm " + secStorageVm.getHostName() + " faled : exception " + e.toString());
+            }
+            return false;
+        }
+    }
+
+    @Override
+    public boolean rebootSecStorageVm(long secStorageVmId) {
+        final SecondaryStorageVmVO secStorageVm = _secStorageVmDao.findById(secStorageVmId);
+
+        if (secStorageVm == null || secStorageVm.getState() == State.Destroyed) {
+            return false;
+        }
+
+        if (secStorageVm.getState() == State.Running && secStorageVm.getHostId() != null) {
+            final RebootCommand cmd = new RebootCommand(secStorageVm.getInstanceName());
+            final Answer answer = _agentMgr.easySend(secStorageVm.getHostId(), cmd);
+
+            if (answer != null && answer.getResult()) {
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug("Successfully reboot secondary storage vm " + secStorageVm.getHostName());
+                }
+
+                SubscriptionMgr.getInstance().notifySubscribers(ALERT_SUBJECT, this,
+                    new SecStorageVmAlertEventArgs(SecStorageVmAlertEventArgs.SSVM_REBOOTED, secStorageVm.getDataCenterId(), secStorageVm.getId(), secStorageVm, null));
+
+                return true;
+            } else {
+                String msg = "Rebooting Secondary Storage VM failed - " + secStorageVm.getHostName();
+                if (s_logger.isDebugEnabled()) {
+                    s_logger.debug(msg);
+                }
+                return false;
+            }
+        } else {
+            return startSecStorageVm(secStorageVmId) != null;
+        }
+    }
+
+    @Override
+    public boolean destroySecStorageVm(long vmId) {
+        SecondaryStorageVmVO ssvm = _secStorageVmDao.findById(vmId);
+
+        try {
+            _itMgr.expunge(ssvm.getUuid());
+            _secStorageVmDao.remove(ssvm.getId());
+            HostVO host = _hostDao.findByTypeNameAndZoneId(ssvm.getDataCenterId(), ssvm.getHostName(), Host.Type.SecondaryStorageVM);
+            if (host != null) {
+                s_logger.debug("Removing host entry for ssvm id=" + vmId);
+                _hostDao.remove(host.getId());
+            }
+
+            return true;
+        } catch (ResourceUnavailableException e) {
+            s_logger.warn("Unable to expunge " + ssvm, e);
+            return false;
+        }
+    }
+
+    @Override
+    public void onAgentConnect(Long dcId, StartupCommand cmd) {
+    }
+
+    private String getAllocLockName() {
+        // to improve security, it may be better to return a unique mashed
+        // name(for example MD5 hashed)
+        return "secStorageVm.alloc";
+    }
+
+    private String getSecStorageVmLockName(long id) {
+        return "secStorageVm." + id;
+    }
+
+    @Override
+    public boolean finalizeVirtualMachineProfile(VirtualMachineProfile profile, DeployDestination dest, ReservationContext context) {
+
+        SecondaryStorageVmVO vm = _secStorageVmDao.findById(profile.getId());
+        Map<String, String> details = _vmDetailsDao.listDetailsKeyPairs(vm.getId());
+        vm.setDetails(details);
+
+        DataStore secStore = _dataStoreMgr.getImageStore(dest.getDataCenter().getId());
+        assert (secStore != null);
+
+        StringBuilder buf = profile.getBootArgsBuilder();
+        buf.append(" template=domP type=secstorage");
+        buf.append(" host=").append(ApiServiceConfiguration.ManagementHostIPAdr.value());
+        buf.append(" port=").append(_mgmtPort);
+        buf.append(" name=").append(profile.getVirtualMachine().getHostName());
+
+        buf.append(" zone=").append(dest.getDataCenter().getId());
+        buf.append(" pod=").append(dest.getPod().getId());
+
+        buf.append(" guid=").append(profile.getVirtualMachine().getHostName());
+
+        if (_configDao.isPremium()) {
+            s_logger.debug("VmWare hypervisor configured, telling the ssvm to load the PremiumSecondaryStorageResource");
+            buf.append(" resource=com.cloud.storage.resource.PremiumSecondaryStorageResource");
+        } else {
+            buf.append(" resource=org.apache.cloudstack.storage.resource.NfsSecondaryStorageResource");
+        }
+        buf.append(" instance=SecStorage");
+        buf.append(" sslcopy=").append(Boolean.toString(_useSSlCopy));
+        buf.append(" role=").append(vm.getRole().toString());
+        buf.append(" mtu=").append(_secStorageVmMtuSize);
+
+        boolean externalDhcp = false;
+        String externalDhcpStr = _configDao.getValue("direct.attach.network.externalIpAllocator.enabled");
+        if (externalDhcpStr != null && externalDhcpStr.equalsIgnoreCase("true")) {
+            externalDhcp = true;
+        }
+
+        if (Boolean.valueOf(_configDao.getValue("system.vm.random.password"))) {
+            buf.append(" vmpassword=").append(_configDao.getValue("system.vm.password"));
+        }
+
+        for (NicProfile nic : profile.getNics()) {
+            int deviceId = nic.getDeviceId();
+            if (nic.getIp4Address() == null) {
+                buf.append(" eth").append(deviceId).append("mask=").append("0.0.0.0");
+                buf.append(" eth").append(deviceId).append("ip=").append("0.0.0.0");
+            } else {
+                buf.append(" eth").append(deviceId).append("ip=").append(nic.getIp4Address());
+                buf.append(" eth").append(deviceId).append("mask=").append(nic.getNetmask());
+            }
+
+            if (nic.isDefaultNic()) {
+                buf.append(" gateway=").append(nic.getGateway());
+            }
+            if (nic.getTrafficType() == TrafficType.Management) {
+                String mgmt_cidr = _configDao.getValue(Config.ManagementNetwork.key());
+                if (NetUtils.isValidCIDR(mgmt_cidr)) {
+                    buf.append(" mgmtcidr=").append(mgmt_cidr);
+                }
+                buf.append(" localgw=").append(dest.getPod().getGateway());
+                buf.append(" private.network.device=").append("eth").append(deviceId);
+            } else if (nic.getTrafficType() == TrafficType.Public) {
+                buf.append(" public.network.device=").append("eth").append(deviceId);
+            } else if (nic.getTrafficType() == TrafficType.Storage) {
+                buf.append(" storageip=").append(nic.getIp4Address());
+                buf.append(" storagenetmask=").append(nic.getNetmask());
+                buf.append(" storagegateway=").append(nic.getGateway());
+            }
+        }
+
+        /* External DHCP mode */
+        if (externalDhcp) {
+            buf.append(" bootproto=dhcp");
+        }
+
+        DataCenterVO dc = _dcDao.findById(profile.getVirtualMachine().getDataCenterId());
+        buf.append(" internaldns1=").append(dc.getInternalDns1());
+        if (dc.getInternalDns2() != null) {
+            buf.append(" internaldns2=").append(dc.getInternalDns2());
+        }
+        buf.append(" dns1=").append(dc.getDns1());
+        if (dc.getDns2() != null) {
+            buf.append(" dns2=").append(dc.getDns2());
+        }
+
+        String bootArgs = buf.toString();
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Boot Args for " + profile + ": " + bootArgs);
+        }
+
+        return true;
+    }
+
+    @Override
+    public boolean finalizeDeployment(Commands cmds, VirtualMachineProfile profile, DeployDestination dest, ReservationContext context) {
+
+        finalizeCommandsOnStart(cmds, profile);
+
+        SecondaryStorageVmVO secVm = _secStorageVmDao.findById(profile.getId());
+        DataCenter dc = dest.getDataCenter();
+        List<NicProfile> nics = profile.getNics();
+        for (NicProfile nic : nics) {
+            if ((nic.getTrafficType() == TrafficType.Public && dc.getNetworkType() == NetworkType.Advanced) ||
+                (nic.getTrafficType() == TrafficType.Guest && (dc.getNetworkType() == NetworkType.Basic || dc.isSecurityGroupEnabled()))) {
+                secVm.setPublicIpAddress(nic.getIp4Address());
+                secVm.setPublicNetmask(nic.getNetmask());
+                secVm.setPublicMacAddress(nic.getMacAddress());
+            } else if (nic.getTrafficType() == TrafficType.Management) {
+                secVm.setPrivateIpAddress(nic.getIp4Address());
+                secVm.setPrivateMacAddress(nic.getMacAddress());
+            }
+        }
+        _secStorageVmDao.update(secVm.getId(), secVm);
+        return true;
+    }
+
+    @Override
+    public boolean finalizeCommandsOnStart(Commands cmds, VirtualMachineProfile profile) {
+
+        NicProfile managementNic = null;
+        NicProfile controlNic = null;
+        for (NicProfile nic : profile.getNics()) {
+            if (nic.getTrafficType() == TrafficType.Management) {
+                managementNic = nic;
+            } else if (nic.getTrafficType() == TrafficType.Control && nic.getIp4Address() != null) {
+                controlNic = nic;
+            }
+        }
+
+        if (controlNic == null) {
+            if (managementNic == null) {
+                s_logger.error("Management network doesn't exist for the secondaryStorageVm " + profile.getVirtualMachine());
+                return false;
+            }
+            controlNic = managementNic;
+        }
+
+        // verify ssh access on management nic for system vm running on HyperV
+        if(profile.getHypervisorType() == HypervisorType.Hyperv) {
+            controlNic = managementNic;
+        }
+
+        CheckSshCommand check = new CheckSshCommand(profile.getInstanceName(), controlNic.getIp4Address(), 3922);
+        cmds.addCommand("checkSsh", check);
+
+        return true;
+    }
+
+    @Override
+    public boolean finalizeStart(VirtualMachineProfile profile, long hostId, Commands cmds, ReservationContext context) {
+        CheckSshAnswer answer = (CheckSshAnswer)cmds.getAnswer("checkSsh");
+        if (!answer.getResult()) {
+            s_logger.warn("Unable to ssh to the VM: " + answer.getDetails());
+            return false;
+        }
+
+        try {
+            //get system ip and create static nat rule for the vm in case of basic networking with EIP/ELB
+            _rulesMgr.getSystemIpAndEnableStaticNatForVm(profile.getVirtualMachine(), false);
+            IPAddressVO ipaddr = _ipAddressDao.findByAssociatedVmId(profile.getVirtualMachine().getId());
+            if (ipaddr != null && ipaddr.getSystem()) {
+                SecondaryStorageVmVO secVm = _secStorageVmDao.findById(profile.getId());
+                // override SSVM guest IP with EIP, so that download url's with be prepared with EIP
+                secVm.setPublicIpAddress(ipaddr.getAddress().addr());
+                _secStorageVmDao.update(secVm.getId(), secVm);
+            }
+        } catch (Exception ex) {
+            s_logger.warn("Failed to get system ip and enable static nat for the vm " + profile.getVirtualMachine() + " due to exception ", ex);
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public void finalizeStop(VirtualMachineProfile profile, Answer answer) {
+        //release elastic IP here
+        IPAddressVO ip = _ipAddressDao.findByAssociatedVmId(profile.getId());
+        if (ip != null && ip.getSystem()) {
+            CallContext ctx = CallContext.current();
+            try {
+                _rulesMgr.disableStaticNat(ip.getId(), ctx.getCallingAccount(), ctx.getCallingUserId(), true);
+            } catch (Exception ex) {
+                s_logger.warn("Failed to disable static nat and release system ip " + ip + " as a part of vm " + profile.getVirtualMachine() + " stop due to exception ",
+                    ex);
+            }
+        }
+    }
+
+    @Override
+    public void finalizeExpunge(VirtualMachine vm) {
+        SecondaryStorageVmVO ssvm = _secStorageVmDao.findByUuid(vm.getUuid());
+
+        ssvm.setPublicIpAddress(null);
+        ssvm.setPublicMacAddress(null);
+        ssvm.setPublicNetmask(null);
+        _secStorageVmDao.update(ssvm.getId(), ssvm);
+    }
+
+    @Override
+    public String getScanHandlerName() {
+        return "secstorage";
+    }
+
+    @Override
+    public boolean canScan() {
+        return true;
+    }
+
+    @Override
+    public void onScanStart() {
+        _zoneHostInfoMap = getZoneHostInfo();
+    }
+
+    @Override
+    public Long[] getScannablePools() {
+        List<DataCenterVO> zones = _dcDao.listEnabledZones();
+
+        Long[] dcIdList = new Long[zones.size()];
+        int i = 0;
+        for (DataCenterVO dc : zones) {
+            dcIdList[i++] = dc.getId();
+        }
+
+        return dcIdList;
+    }
+
+    @Override
+    public boolean isPoolReadyForScan(Long pool) {
+        // pool is at zone basis
+        long dataCenterId = pool.longValue();
+
+        if (!isZoneReady(_zoneHostInfoMap, dataCenterId)) {
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("Zone " + dataCenterId + " is not ready to launch secondary storage VM yet");
+            }
+            return false;
+        }
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Zone " + dataCenterId + " is ready to launch secondary storage VM");
+        }
+        return true;
+    }
+
+    @Override
+    public Pair<AfterScanAction, Object> scanPool(Long pool) {
+        long dataCenterId = pool.longValue();
+
+        List<SecondaryStorageVmVO> ssVms =
+            _secStorageVmDao.getSecStorageVmListInStates(SecondaryStorageVm.Role.templateProcessor, dataCenterId, State.Running, State.Migrating, State.Starting,
+                State.Stopped, State.Stopping);
+        int vmSize = (ssVms == null) ? 0 : ssVms.size();
+        List<DataStore> ssStores = _dataStoreMgr.getImageStoresByScope(new ZoneScope(dataCenterId));
+        int storeSize = (ssStores == null) ? 0 : ssStores.size();
+        if (storeSize > vmSize) {
+            s_logger.info("No secondary storage vms found in datacenter id=" + dataCenterId + ", starting a new one");
+            return new Pair<AfterScanAction, Object>(AfterScanAction.expand, SecondaryStorageVm.Role.templateProcessor);
+        }
+
+        return new Pair<AfterScanAction, Object>(AfterScanAction.nop, SecondaryStorageVm.Role.templateProcessor);
+    }
+
+    @Override
+    public void expandPool(Long pool, Object actionArgs) {
+        long dataCenterId = pool.longValue();
+        allocCapacity(dataCenterId, (SecondaryStorageVm.Role)actionArgs);
+    }
+
+    @Override
+    public void shrinkPool(Long pool, Object actionArgs) {
+    }
+
+    @Override
+    public void onScanEnd() {
+    }
+
+    @Override
+    public HostVO createHostVOForConnectedAgent(HostVO host, StartupCommand[] cmd) {
+        /* Called when Secondary Storage VM connected */
+        StartupCommand firstCmd = cmd[0];
+        if (!(firstCmd instanceof StartupSecondaryStorageCommand)) {
+            return null;
+        }
+
+        host.setType(com.cloud.host.Host.Type.SecondaryStorageVM);
+        return host;
+    }
+
+    @Override
+    public HostVO createHostVOForDirectConnectAgent(HostVO host, StartupCommand[] startup, ServerResource resource, Map<String, String> details, List<String> hostTags) {
+        // Used to be Called when add secondary storage on UI through DummySecondaryStorageResource to update that host entry for Secondary Storage.
+        // Now since we move secondary storage from host table, this code is not needed to be invoked anymore.
+        /*
+        StartupCommand firstCmd = startup[0];
+        if (!(firstCmd instanceof StartupStorageCommand)) {
+            return null;
+        }
+
+        com.cloud.host.Host.Type type = null;
+        StartupStorageCommand ssCmd = ((StartupStorageCommand) firstCmd);
+        if (ssCmd.getHostType() == Host.Type.SecondaryStorageCmdExecutor) {
+            type = ssCmd.getHostType();
+        } else {
+            if (ssCmd.getResourceType() == Storage.StorageResourceType.SECONDARY_STORAGE) {
+                type = Host.Type.SecondaryStorage;
+                if (resource != null && resource instanceof DummySecondaryStorageResource) {
+                    host.setResource(null);
+                }
+            } else if (ssCmd.getResourceType() == Storage.StorageResourceType.LOCAL_SECONDARY_STORAGE) {
+                type = Host.Type.LocalSecondaryStorage;
+            } else {
+                type = Host.Type.Storage;
+            }
+
+            final Map<String, String> hostDetails = ssCmd.getHostDetails();
+            if (hostDetails != null) {
+                if (details != null) {
+                    details.putAll(hostDetails);
+                } else {
+                    details = hostDetails;
+                }
+            }
+
+            host.setDetails(details);
+            host.setParent(ssCmd.getParent());
+            host.setTotalSize(ssCmd.getTotalSize());
+            host.setHypervisorType(HypervisorType.None);
+            host.setType(type);
+            if (ssCmd.getNfsShare() != null) {
+                host.setStorageUrl(ssCmd.getNfsShare());
+            }
+        }
+         */
+        return null; // no need to handle this event anymore since secondary storage is not in host table anymore.
+    }
+
+    @Override
+    public DeleteHostAnswer deleteHost(HostVO host, boolean isForced, boolean isForceDeleteStorage) throws UnableDeleteHostException {
+        // Since secondary storage is moved out of host table, this class should not handle delete secondary storage anymore.
+        return null;
+    }
+
+    @Override
+    public List<HostVO> listUpAndConnectingSecondaryStorageVmHost(Long dcId) {
+        QueryBuilder<HostVO> sc = QueryBuilder.create(HostVO.class);
+        if (dcId != null) {
+            sc.and(sc.entity().getDataCenterId(), Op.EQ, dcId);
+        }
+        sc.and(sc.entity().getState(), Op.IN, Status.Up, Status.Connecting);
+        sc.and(sc.entity().getType(), Op.EQ, Host.Type.SecondaryStorageVM);
+        return sc.list();
+    }
+
+    @Override
+    public HostVO pickSsvmHost(HostVO ssHost) {
+        if (ssHost.getType() == Host.Type.LocalSecondaryStorage) {
+            return ssHost;
+        } else if (ssHost.getType() == Host.Type.SecondaryStorage) {
+            Long dcId = ssHost.getDataCenterId();
+            List<HostVO> ssAHosts = listUpAndConnectingSecondaryStorageVmHost(dcId);
+            if (ssAHosts == null || ssAHosts.isEmpty()) {
+                return null;
+            }
+            Collections.shuffle(ssAHosts);
+            return ssAHosts.get(0);
+        }
+        return null;
+    }
+
+    @Override
+    public void prepareStop(VirtualMachineProfile profile) {
+
+    }
+
+    public List<SecondaryStorageVmAllocator> getSecondaryStorageVmAllocators() {
+        return _ssVmAllocators;
+    }
+
+    @Inject
+    public void setSecondaryStorageVmAllocators(List<SecondaryStorageVmAllocator> ssVmAllocators) {
+        _ssVmAllocators = ssVmAllocators;
+    }
+}


[03/11] Moved the secondary storage service into its own server directory

Posted by ah...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4be3b993/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
deleted file mode 100755
index 9782c2e..0000000
--- a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
+++ /dev/null
@@ -1,2430 +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 org.apache.cloudstack.storage.resource;
-
-import static com.cloud.utils.S3Utils.mputFile;
-import static com.cloud.utils.S3Utils.putFile;
-import static com.cloud.utils.StringUtils.join;
-import static java.lang.String.format;
-import static java.util.Arrays.asList;
-import static org.apache.commons.lang.StringUtils.substringAfterLast;
-
-import java.io.BufferedReader;
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.FileReader;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.InputStream;
-import java.math.BigInteger;
-import java.net.InetAddress;
-import java.net.URI;
-import java.net.UnknownHostException;
-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 javax.naming.ConfigurationException;
-
-import org.apache.commons.codec.digest.DigestUtils;
-import org.apache.commons.lang.StringUtils;
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpResponse;
-import org.apache.http.NameValuePair;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.client.utils.URLEncodedUtils;
-import org.apache.http.impl.client.DefaultHttpClient;
-import org.apache.log4j.Logger;
-
-import com.amazonaws.services.s3.model.S3ObjectSummary;
-
-import org.apache.cloudstack.framework.security.keystore.KeystoreManager;
-import org.apache.cloudstack.storage.command.CopyCmdAnswer;
-import org.apache.cloudstack.storage.command.CopyCommand;
-import org.apache.cloudstack.storage.command.DeleteCommand;
-import org.apache.cloudstack.storage.command.DownloadCommand;
-import org.apache.cloudstack.storage.command.DownloadProgressCommand;
-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.cloudstack.storage.to.SnapshotObjectTO;
-import org.apache.cloudstack.storage.to.TemplateObjectTO;
-import org.apache.cloudstack.storage.to.VolumeObjectTO;
-
-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.DeleteSnapshotsDirCommand;
-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.SecStorageVMSetupCommand;
-import com.cloud.agent.api.StartupCommand;
-import com.cloud.agent.api.StartupSecondaryStorageCommand;
-import com.cloud.agent.api.storage.CreateEntityDownloadURLCommand;
-import com.cloud.agent.api.storage.DeleteEntityDownloadURLCommand;
-import com.cloud.agent.api.storage.DownloadAnswer;
-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.to.DataObjectType;
-import com.cloud.agent.api.to.DataStoreTO;
-import com.cloud.agent.api.to.DataTO;
-import com.cloud.agent.api.to.NfsTO;
-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.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.resource.ServerResourceBase;
-import com.cloud.storage.DataStoreRole;
-import com.cloud.storage.Storage.ImageFormat;
-import com.cloud.storage.StorageLayer;
-import com.cloud.storage.VMTemplateStorageResourceAssoc;
-import com.cloud.storage.template.OVAProcessor;
-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.TemplateLocation;
-import com.cloud.storage.template.TemplateProp;
-import com.cloud.storage.template.VhdProcessor;
-import com.cloud.storage.template.VmdkProcessor;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.S3Utils;
-import com.cloud.utils.S3Utils.FileNamingStrategy;
-import com.cloud.utils.SwiftUtil;
-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 VOLUME_ROOT_DIR = "volumes";
-
-    int _timeout;
-
-    public int getTimeout() {
-        return _timeout;
-    }
-
-    public void setTimeout(int timeout) {
-        _timeout = timeout;
-    }
-
-    String _instance;
-    String _dc;
-    String _pod;
-    String _guid;
-    String _role;
-    Map<String, Object> _params;
-    protected StorageLayer _storage;
-    protected boolean _inSystemVM = false;
-    boolean _sslCopy = false;
-
-    protected DownloadManager _dlMgr;
-    protected 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>();
-    protected String _parent = "/mnt/SecStorage";
-    final private String _tmpltpp = "template.properties";
-    protected String createTemplateFromSnapshotXenScript;
-
-    public void setParentPath(String path) {
-        _parent = path;
-    }
-
-    public String getMountingRoot() {
-        return _parent;
-    }
-
-    @Override
-    public void disconnected() {
-    }
-
-    public void setInSystemVM(boolean inSystemVM) {
-        _inSystemVM = inSystemVM;
-    }
-
-    @Override
-    public Answer executeRequest(Command cmd) {
-        if (cmd instanceof DownloadProgressCommand) {
-            return _dlMgr.handleDownloadCommand(this, (DownloadProgressCommand)cmd);
-        } else if (cmd instanceof DownloadCommand) {
-            return execute((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 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 DeleteSnapshotsDirCommand) {
-            return execute((DeleteSnapshotsDirCommand)cmd);
-        } else if (cmd instanceof CopyCommand) {
-            return execute((CopyCommand)cmd);
-        } else if (cmd instanceof DeleteCommand) {
-            return execute((DeleteCommand)cmd);
-        } else {
-            return Answer.createUnsupportedCommandAnswer(cmd);
-        }
-    }
-
-    protected CopyCmdAnswer postProcessing(File destFile, String downloadPath, String destPath, DataTO srcData, DataTO destData) throws ConfigurationException {
-        if (destData.getObjectType() == DataObjectType.SNAPSHOT) {
-            SnapshotObjectTO snapshot = new SnapshotObjectTO();
-            snapshot.setPath(destPath + File.separator + destFile.getName());
-
-            CopyCmdAnswer answer = new CopyCmdAnswer(snapshot);
-            return answer;
-        }
-        // do post processing to unzip the file if it is compressed
-        String scriptsDir = "scripts/storage/secondary";
-        String 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);
-        String 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);
-        String script = srcData.getObjectType() == DataObjectType.TEMPLATE ? createTmpltScr : createVolScr;
-
-        int installTimeoutPerGig = 180 * 60 * 1000;
-        long imgSizeGigs = (long)Math.ceil(destFile.length() * 1.0d / (1024 * 1024 * 1024));
-        imgSizeGigs++; // add one just in case
-        long timeout = imgSizeGigs * installTimeoutPerGig;
-
-        String origPath = destFile.getAbsolutePath();
-        String extension = null;
-        if (srcData.getObjectType() == DataObjectType.TEMPLATE) {
-            extension = ((TemplateObjectTO)srcData).getFormat().getFileExtension();
-        } else if (srcData.getObjectType() == DataObjectType.VOLUME) {
-            extension = ((VolumeObjectTO)srcData).getFormat().getFileExtension();
-        }
-
-        String templateName = UUID.randomUUID().toString();
-        String templateFilename = templateName + "." + extension;
-        Script scr = new Script(script, timeout, s_logger);
-        scr.add("-s", Long.toString(imgSizeGigs)); // not used for now
-        scr.add("-n", templateFilename);
-
-        scr.add("-t", downloadPath);
-        scr.add("-f", origPath); // this is the temporary
-        // template file downloaded
-        String result;
-        result = scr.execute();
-
-        if (result != null) {
-            // script execution failure
-            throw new CloudRuntimeException("Failed to run script " + script);
-        }
-
-        String finalFileName = templateFilename;
-        String finalDownloadPath = destPath + File.separator + templateFilename;
-        // compute the size of
-        long size = _storage.getSize(downloadPath + File.separator + templateFilename);
-
-        DataTO newDestTO = null;
-
-        if (destData.getObjectType() == DataObjectType.TEMPLATE) {
-            TemplateObjectTO newTemplTO = new TemplateObjectTO();
-            newTemplTO.setPath(finalDownloadPath);
-            newTemplTO.setName(finalFileName);
-            newTemplTO.setSize(size);
-            newTemplTO.setPhysicalSize(size);
-            newDestTO = newTemplTO;
-        } else {
-            VolumeObjectTO newVolTO = new VolumeObjectTO();
-            newVolTO.setPath(finalDownloadPath);
-            newVolTO.setName(finalFileName);
-            newVolTO.setSize(size);
-            newDestTO = newVolTO;
-        }
-
-        return new CopyCmdAnswer(newDestTO);
-    }
-
-    protected Answer copyFromSwiftToNfs(CopyCommand cmd, DataTO srcData, SwiftTO swiftTO, DataTO destData, NfsTO destImageStore) {
-        final String storagePath = destImageStore.getUrl();
-        final String destPath = destData.getPath();
-        try {
-            String downloadPath = determineStorageTemplatePath(storagePath, destPath);
-            final File downloadDirectory = _storage.getFile(downloadPath);
-            if (!downloadDirectory.mkdirs()) {
-                return new CopyCmdAnswer("Failed to create download directory " + downloadPath);
-            }
-            File destFile = SwiftUtil.getObject(swiftTO, downloadDirectory, srcData.getPath());
-            return postProcessing(destFile, downloadPath, destPath, srcData, destData);
-        } catch (Exception e) {
-            s_logger.debug("Failed to copy swift to nfs", e);
-            return new CopyCmdAnswer(e.toString());
-        }
-    }
-
-    protected Answer copyFromS3ToNfs(CopyCommand cmd, DataTO srcData, S3TO s3, DataTO destData, NfsTO destImageStore) {
-        final String storagePath = destImageStore.getUrl();
-        final String destPath = destData.getPath();
-
-        try {
-
-            String downloadPath = determineStorageTemplatePath(storagePath, destPath);
-            final File downloadDirectory = _storage.getFile(downloadPath);
-
-            if (!downloadDirectory.mkdirs()) {
-                final String errMsg = "Unable to create directory " + downloadPath + " to copy from S3 to cache.";
-                s_logger.error(errMsg);
-                return new CopyCmdAnswer(errMsg);
-            } else {
-                s_logger.debug("Directory " + downloadPath + " already exists");
-            }
-
-            File destFile = S3Utils.getFile(s3, s3.getBucketName(), srcData.getPath(), downloadDirectory, new FileNamingStrategy() {
-                @Override
-                public String determineFileName(final String key) {
-                    return substringAfterLast(key, S3Utils.SEPARATOR);
-                }
-            });
-
-            if (destFile == null) {
-                return new CopyCmdAnswer("Can't find template");
-            }
-
-            return postProcessing(destFile, downloadPath, destPath, srcData, destData);
-        } catch (Exception e) {
-
-            final String errMsg = format("Failed to download" + "due to $2%s", e.getMessage());
-            s_logger.error(errMsg, e);
-            return new CopyCmdAnswer(errMsg);
-        }
-    }
-
-    protected Answer copySnapshotToTemplateFromNfsToNfsXenserver(CopyCommand cmd, SnapshotObjectTO srcData, NfsTO srcDataStore, TemplateObjectTO destData,
-            NfsTO destDataStore) {
-        String srcMountPoint = getRootDir(srcDataStore.getUrl());
-        String snapshotPath = srcData.getPath();
-        int index = snapshotPath.lastIndexOf("/");
-        String snapshotName = snapshotPath.substring(index + 1);
-        if (!snapshotName.startsWith("VHD-") && !snapshotName.endsWith(".vhd")) {
-            snapshotName = snapshotName + ".vhd";
-        }
-        snapshotPath = snapshotPath.substring(0, index);
-
-        snapshotPath = srcMountPoint + File.separator + snapshotPath;
-        String destMountPoint = getRootDir(destDataStore.getUrl());
-        String destPath = destMountPoint + File.separator + destData.getPath();
-
-        String errMsg = null;
-        try {
-            _storage.mkdir(destPath);
-
-            String templateUuid = UUID.randomUUID().toString();
-            String templateName = templateUuid + ".vhd";
-            Script command = new Script(createTemplateFromSnapshotXenScript, cmd.getWait() * 1000, s_logger);
-            command.add("-p", snapshotPath);
-            command.add("-s", snapshotName);
-            command.add("-n", templateName);
-            command.add("-t", destPath);
-            String result = command.execute();
-
-            if (result != null && !result.equalsIgnoreCase("")) {
-                return new CopyCmdAnswer(result);
-            }
-
-            Map<String, Object> params = new HashMap<String, Object>();
-            params.put(StorageLayer.InstanceConfigKey, _storage);
-            Processor processor = new VhdProcessor();
-
-            processor.configure("Vhd Processor", params);
-            FormatInfo info = processor.process(destPath, null, templateUuid);
-
-            TemplateLocation loc = new TemplateLocation(_storage, destPath);
-            loc.create(1, true, templateUuid);
-            loc.addFormat(info);
-            loc.save();
-            TemplateProp prop = loc.getTemplateInfo();
-            TemplateObjectTO newTemplate = new TemplateObjectTO();
-            newTemplate.setPath(destData.getPath() + File.separator + templateName);
-            newTemplate.setFormat(ImageFormat.VHD);
-            newTemplate.setSize(prop.getSize());
-            newTemplate.setPhysicalSize(prop.getPhysicalSize());
-            newTemplate.setName(templateUuid);
-            return new CopyCmdAnswer(newTemplate);
-        } catch (ConfigurationException e) {
-            s_logger.debug("Failed to create template from snapshot: " + e.toString());
-            errMsg = e.toString();
-        } catch (InternalErrorException e) {
-            s_logger.debug("Failed to create template from snapshot: " + e.toString());
-            errMsg = e.toString();
-        } catch (IOException e) {
-            s_logger.debug("Failed to create template from snapshot: " + e.toString());
-            errMsg = e.toString();
-        }
-
-        return new CopyCmdAnswer(errMsg);
-    }
-
-    protected Answer copySnapshotToTemplateFromNfsToNfs(CopyCommand cmd, SnapshotObjectTO srcData, NfsTO srcDataStore, TemplateObjectTO destData, NfsTO destDataStore) {
-
-        if (srcData.getHypervisorType() == HypervisorType.XenServer) {
-            return copySnapshotToTemplateFromNfsToNfsXenserver(cmd, srcData, srcDataStore, destData, destDataStore);
-        } else if (srcData.getHypervisorType() == HypervisorType.KVM) {
-            File srcFile = getFile(srcData.getPath(), srcDataStore.getUrl());
-            File destFile = getFile(destData.getPath(), destDataStore.getUrl());
-
-            VolumeObjectTO volumeObjectTO = srcData.getVolume();
-            ImageFormat srcFormat = null;
-            //TODO: the image format should be stored in snapshot table, instead of getting from volume
-            if (volumeObjectTO != null) {
-                srcFormat = volumeObjectTO.getFormat();
-            } else {
-                srcFormat = ImageFormat.QCOW2;
-            }
-
-            // get snapshot file name
-            String templateName = srcFile.getName();
-            // add kvm file extension for copied template name
-            String fileName = templateName + "." + srcFormat.getFileExtension();
-            String destFileFullPath = destFile.getAbsolutePath() + File.separator + fileName;
-            s_logger.debug("copy snapshot " + srcFile.getAbsolutePath() + " to template " + destFileFullPath);
-            Script.runSimpleBashScript("cp " + srcFile.getAbsolutePath() + " " + destFileFullPath);
-            try {
-                // generate template.properties file
-                String metaFileName = destFile.getAbsolutePath() + File.separator + "template.properties";
-                _storage.create(destFile.getAbsolutePath(), "template.properties");
-                File metaFile = new File(metaFileName);
-                FileWriter writer = new FileWriter(metaFile);
-                BufferedWriter bufferWriter = new BufferedWriter(writer);
-                // KVM didn't change template unique name, just used the template name passed from orchestration layer, so no need
-                // to send template name back.
-                bufferWriter.write("uniquename=" + destData.getName());
-                bufferWriter.write("\n");
-                bufferWriter.write("filename=" + fileName);
-                bufferWriter.write("\n");
-                long size = _storage.getSize(destFileFullPath);
-                bufferWriter.write("size=" + size);
-                bufferWriter.close();
-                writer.close();
-
-                /**
-                 * Snapshots might be in either QCOW2 or RAW image format
-                 *
-                 * For example RBD snapshots are in RAW format
-                 */
-                Processor processor = null;
-                if (srcFormat == ImageFormat.QCOW2) {
-                    processor = new QCOW2Processor();
-                } else if (srcFormat == ImageFormat.RAW) {
-                    processor = new RawImageProcessor();
-                } else {
-                    throw new ConfigurationException("Unknown image format " + srcFormat.toString());
-                }
-
-                Map<String, Object> params = new HashMap<String, Object>();
-                params.put(StorageLayer.InstanceConfigKey, _storage);
-
-                processor.configure("template processor", params);
-                String destPath = destFile.getAbsolutePath();
-
-                FormatInfo info = processor.process(destPath, null, templateName);
-                TemplateLocation loc = new TemplateLocation(_storage, destPath);
-                loc.create(1, true, destData.getName());
-                loc.addFormat(info);
-                loc.save();
-
-                TemplateProp prop = loc.getTemplateInfo();
-                TemplateObjectTO newTemplate = new TemplateObjectTO();
-                newTemplate.setPath(destData.getPath() + File.separator + fileName);
-                newTemplate.setFormat(srcFormat);
-                newTemplate.setSize(prop.getSize());
-                newTemplate.setPhysicalSize(prop.getPhysicalSize());
-                return new CopyCmdAnswer(newTemplate);
-            } catch (ConfigurationException e) {
-                s_logger.debug("Failed to create template:" + e.toString());
-                return new CopyCmdAnswer(e.toString());
-            } catch (IOException e) {
-                s_logger.debug("Failed to create template:" + e.toString());
-                return new CopyCmdAnswer(e.toString());
-            } catch (InternalErrorException e) {
-                s_logger.debug("Failed to create template:" + e.toString());
-                return new CopyCmdAnswer(e.toString());
-            }
-        }
-
-        return new CopyCmdAnswer("");
-    }
-
-    protected File getFile(String path, String nfsPath) {
-        String filePath = getRootDir(nfsPath) + File.separator + path;
-        File f = new File(filePath);
-        if (!f.exists()) {
-            _storage.mkdirs(filePath);
-            f = new File(filePath);
-        }
-        return f;
-    }
-
-    protected Answer createTemplateFromSnapshot(CopyCommand cmd) {
-        DataTO srcData = cmd.getSrcTO();
-        DataTO destData = cmd.getDestTO();
-        DataStoreTO srcDataStore = srcData.getDataStore();
-        DataStoreTO destDataStore = destData.getDataStore();
-        if (srcDataStore.getRole() == DataStoreRole.Image || srcDataStore.getRole() == DataStoreRole.ImageCache || srcDataStore.getRole() == DataStoreRole.Primary) {
-            if (!(srcDataStore instanceof NfsTO)) {
-                s_logger.debug("only support nfs storage as src, when create template from snapshot");
-                return Answer.createUnsupportedCommandAnswer(cmd);
-            }
-
-            if (destDataStore instanceof NfsTO) {
-                return copySnapshotToTemplateFromNfsToNfs(cmd, (SnapshotObjectTO)srcData, (NfsTO)srcDataStore, (TemplateObjectTO)destData, (NfsTO)destDataStore);
-            } else if (destDataStore instanceof SwiftTO) {
-                //create template on the same data store
-                CopyCmdAnswer answer =
-                        (CopyCmdAnswer)copySnapshotToTemplateFromNfsToNfs(cmd, (SnapshotObjectTO)srcData, (NfsTO)srcDataStore, (TemplateObjectTO)destData,
-                                (NfsTO)srcDataStore);
-                if (!answer.getResult()) {
-                    return answer;
-                }
-                s_logger.debug("starting copy template to swift");
-                DataTO newTemplate = answer.getNewData();
-                File templateFile = getFile(newTemplate.getPath(), ((NfsTO)srcDataStore).getUrl());
-                SwiftTO swift = (SwiftTO)destDataStore;
-                String containterName = SwiftUtil.getContainerName(destData.getObjectType().toString(), destData.getId());
-                String swiftPath = SwiftUtil.putObject(swift, templateFile, containterName, templateFile.getName());
-                //upload template.properties
-                File properties = new File(templateFile.getParent() + File.separator + _tmpltpp);
-                if (properties.exists()) {
-                    SwiftUtil.putObject(swift, properties, containterName, _tmpltpp);
-                }
-
-                //clean up template data on staging area
-                try {
-                    DeleteCommand deleteCommand = new DeleteCommand(newTemplate);
-                    execute(deleteCommand);
-                } catch (Exception e) {
-                    s_logger.debug("Failed to clean up staging area:", e);
-                }
-
-                TemplateObjectTO template = new TemplateObjectTO();
-                template.setPath(swiftPath);
-                template.setSize(templateFile.length());
-                template.setPhysicalSize(template.getSize());
-                SnapshotObjectTO snapshot = (SnapshotObjectTO)srcData;
-                template.setFormat(snapshot.getVolume().getFormat());
-                return new CopyCmdAnswer(template);
-            } else if (destDataStore instanceof S3TO) {
-                //create template on the same data store
-                CopyCmdAnswer answer =
-                        (CopyCmdAnswer)copySnapshotToTemplateFromNfsToNfs(cmd, (SnapshotObjectTO)srcData, (NfsTO)srcDataStore, (TemplateObjectTO)destData,
-                                (NfsTO)srcDataStore);
-                if (!answer.getResult()) {
-                    return answer;
-                }
-                TemplateObjectTO newTemplate = (TemplateObjectTO)answer.getNewData();
-                newTemplate.setDataStore(srcDataStore);
-                CopyCommand newCpyCmd = new CopyCommand(newTemplate, destData, cmd.getWait(), cmd.executeInSequence());
-                Answer result = copyFromNfsToS3(newCpyCmd);
-                //clean up template data on staging area
-                try {
-                    DeleteCommand deleteCommand = new DeleteCommand(newTemplate);
-                    execute(deleteCommand);
-                } catch (Exception e) {
-                    s_logger.debug("Failed to clean up staging area:", e);
-                }
-                return result;
-            }
-        }
-        s_logger.debug("Failed to create templat from snapshot");
-        return new CopyCmdAnswer("Unsupported prototcol");
-    }
-
-    protected Answer copyFromNfsToImage(CopyCommand cmd) {
-        DataTO destData = cmd.getDestTO();
-        DataStoreTO destDataStore = destData.getDataStore();
-
-        if (destDataStore instanceof S3TO) {
-            return copyFromNfsToS3(cmd);
-        } else {
-            return new CopyCmdAnswer("unsupported ");
-        }
-    }
-
-    protected Answer execute(CopyCommand cmd) {
-        DataTO srcData = cmd.getSrcTO();
-        DataTO destData = cmd.getDestTO();
-        DataStoreTO srcDataStore = srcData.getDataStore();
-        DataStoreTO destDataStore = destData.getDataStore();
-
-        if (srcData.getObjectType() == DataObjectType.SNAPSHOT && destData.getObjectType() == DataObjectType.TEMPLATE) {
-            return createTemplateFromSnapshot(cmd);
-        }
-
-        if (destDataStore instanceof NfsTO && destDataStore.getRole() == DataStoreRole.ImageCache) {
-            NfsTO destImageStore = (NfsTO)destDataStore;
-            if (srcDataStore instanceof S3TO) {
-                S3TO s3 = (S3TO)srcDataStore;
-                return copyFromS3ToNfs(cmd, srcData, s3, destData, destImageStore);
-            } else if (srcDataStore instanceof SwiftTO) {
-                return copyFromSwiftToNfs(cmd, srcData, (SwiftTO)srcDataStore, destData, destImageStore);
-            }
-        }
-
-        if (srcDataStore.getRole() == DataStoreRole.ImageCache && destDataStore.getRole() == DataStoreRole.Image) {
-            return copyFromNfsToImage(cmd);
-        }
-
-        return Answer.createUnsupportedCommandAnswer(cmd);
-    }
-
-    @SuppressWarnings("unchecked")
-    protected String determineS3TemplateDirectory(final Long accountId, final Long templateId, final String templateUniqueName) {
-        return join(asList(TEMPLATE_ROOT_DIR, accountId, templateId, templateUniqueName), S3Utils.SEPARATOR);
-    }
-
-    private String determineS3TemplateNameFromKey(String key) {
-        return StringUtils.substringAfterLast(StringUtils.substringBeforeLast(key, S3Utils.SEPARATOR), S3Utils.SEPARATOR);
-    }
-
-    @SuppressWarnings("unchecked")
-    protected String determineS3VolumeDirectory(final Long accountId, final Long volId) {
-        return join(asList(VOLUME_ROOT_DIR, accountId, volId), S3Utils.SEPARATOR);
-    }
-
-    protected Long determineS3VolumeIdFromKey(String key) {
-        return Long.parseLong(StringUtils.substringAfterLast(StringUtils.substringBeforeLast(key, S3Utils.SEPARATOR), S3Utils.SEPARATOR));
-    }
-
-    private String determineStorageTemplatePath(final String storagePath, String dataPath) {
-        return join(asList(getRootDir(storagePath), dataPath), File.separator);
-    }
-
-    protected File downloadFromUrlToNfs(String url, NfsTO nfs, String path, String name) {
-        HttpClient client = new DefaultHttpClient();
-        HttpGet get = new HttpGet(url);
-        try {
-            HttpResponse response = client.execute(get);
-            HttpEntity entity = response.getEntity();
-            if (entity == null) {
-                s_logger.debug("Faled to get entity");
-                throw new CloudRuntimeException("Failed to get url: " + url);
-            }
-
-            String nfsMountPath = getRootDir(nfs.getUrl());
-
-            String filePath = nfsMountPath + File.separator + path;
-            File directory = new File(filePath);
-            if (!directory.exists()) {
-                _storage.mkdirs(filePath);
-            }
-            File destFile = new File(filePath + File.separator + name);
-            if (!destFile.createNewFile()) {
-                s_logger.warn("Reusing existing file " + destFile.getPath());
-            }
-            FileOutputStream outputStream = new FileOutputStream(destFile);
-            entity.writeTo(outputStream);
-            return new File(destFile.getAbsolutePath());
-        } catch (IOException e) {
-            s_logger.debug("Faild to get url:" + url + ", due to " + e.toString());
-            throw new CloudRuntimeException(e);
-        }
-    }
-
-    protected Answer registerTemplateOnSwift(DownloadCommand cmd) {
-        SwiftTO swiftTO = (SwiftTO)cmd.getDataStore();
-        String path = cmd.getInstallPath();
-        DataStoreTO cacheStore = cmd.getCacheStore();
-        if (cacheStore == null || !(cacheStore instanceof NfsTO)) {
-            return new DownloadAnswer("cache store can't be null", VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR);
-        }
-
-        File file = null;
-        try {
-            NfsTO nfsCacheStore = (NfsTO)cacheStore;
-            String fileName = cmd.getName() + "." + cmd.getFormat().getFileExtension();
-            file = downloadFromUrlToNfs(cmd.getUrl(), nfsCacheStore, path, fileName);
-            String container = "T-" + cmd.getId();
-            String swiftPath = SwiftUtil.putObject(swiftTO, file, container, null);
-
-            //put metda file
-            File uniqDir = _storage.createUniqDir();
-            String metaFileName = uniqDir.getAbsolutePath() + File.separator + "template.properties";
-            _storage.create(uniqDir.getAbsolutePath(), "template.properties");
-            File metaFile = new File(metaFileName);
-            FileWriter writer = new FileWriter(metaFile);
-            BufferedWriter bufferWriter = new BufferedWriter(writer);
-            bufferWriter.write("uniquename=" + cmd.getName());
-            bufferWriter.write("\n");
-            bufferWriter.write("filename=" + fileName);
-            bufferWriter.write("\n");
-            bufferWriter.write("size=" + file.length());
-            bufferWriter.close();
-            writer.close();
-
-            SwiftUtil.putObject(swiftTO, metaFile, container, "template.properties");
-            metaFile.delete();
-            uniqDir.delete();
-            String md5sum = null;
-            try {
-                md5sum = DigestUtils.md5Hex(new FileInputStream(file));
-            } catch (IOException e) {
-                s_logger.debug("Failed to get md5sum: " + file.getAbsoluteFile());
-            }
-
-            DownloadAnswer answer =
-                    new DownloadAnswer(null, 100, null, VMTemplateStorageResourceAssoc.Status.DOWNLOADED, swiftPath, swiftPath, file.length(), file.length(), md5sum);
-            return answer;
-        } catch (IOException e) {
-            s_logger.debug("Failed to register template into swift", e);
-            return new DownloadAnswer(e.toString(), VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR);
-        } finally {
-            if (file != null) {
-                file.delete();
-            }
-        }
-    }
-
-    private Answer execute(DownloadCommand cmd) {
-        DataStoreTO dstore = cmd.getDataStore();
-        if (dstore instanceof NfsTO || dstore instanceof S3TO) {
-            return _dlMgr.handleDownloadCommand(this, cmd);
-        } else if (dstore instanceof SwiftTO) {
-            return registerTemplateOnSwift(cmd);
-        } else {
-            return new Answer(cmd, false, "Unsupported image data store: " + dstore);
-        }
-
-    }
-
-    private ImageFormat getTemplateFormat(String filePath) {
-        String ext = null;
-        int extensionPos = filePath.lastIndexOf('.');
-        int lastSeparator = Math.max(filePath.lastIndexOf('/'), filePath.lastIndexOf('\\'));
-        int i = lastSeparator > extensionPos ? -1 : extensionPos;
-        if (i > 0) {
-            ext = filePath.substring(i + 1);
-        }
-        if (ext != null) {
-            if (ext.equalsIgnoreCase("vhd")) {
-                return ImageFormat.VHD;
-            } else if (ext.equalsIgnoreCase("vhdx")) {
-                return ImageFormat.VHDX;
-            } else if (ext.equalsIgnoreCase("qcow2")) {
-                return ImageFormat.QCOW2;
-            } else if (ext.equalsIgnoreCase("ova")) {
-                return ImageFormat.OVA;
-            } else if (ext.equalsIgnoreCase("tar")) {
-                return ImageFormat.TAR;
-            } else if (ext.equalsIgnoreCase("img") || ext.equalsIgnoreCase("raw")) {
-                return ImageFormat.RAW;
-            } else if (ext.equalsIgnoreCase("vmdk")) {
-                return ImageFormat.VMDK;
-            } else if (ext.equalsIgnoreCase("vdi")) {
-                return ImageFormat.VDI;
-            }
-        }
-
-        return null;
-
-    }
-
-    protected Long getVirtualSize(File file, ImageFormat format) {
-        Processor processor = null;
-        try {
-            if (format == null) {
-                return file.length();
-            } else if (format == ImageFormat.QCOW2) {
-                processor = new QCOW2Processor();
-            } else if (format == ImageFormat.OVA) {
-                processor = new OVAProcessor();
-            } else if (format == ImageFormat.VHD) {
-                processor = new VhdProcessor();
-            } else if (format == ImageFormat.RAW) {
-                processor = new RawImageProcessor();
-            } else if (format == ImageFormat.VMDK) {
-                processor = new VmdkProcessor();
-            }
-
-            if (processor == null) {
-                return file.length();
-            }
-
-            processor.configure("template processor", new HashMap<String, Object>());
-            return processor.getVirtualSize(file);
-        } catch (Exception e) {
-            s_logger.debug("Failed to get virtual size:", e);
-        }
-        return file.length();
-    }
-
-    protected Answer copyFromNfsToS3(CopyCommand cmd) {
-        final DataTO srcData = cmd.getSrcTO();
-        final DataTO destData = cmd.getDestTO();
-        DataStoreTO srcDataStore = srcData.getDataStore();
-        NfsTO srcStore = (NfsTO)srcDataStore;
-        DataStoreTO destDataStore = destData.getDataStore();
-
-        final S3TO s3 = (S3TO)destDataStore;
-
-        try {
-            final String templatePath = determineStorageTemplatePath(srcStore.getUrl(), srcData.getPath());
-
-            if (s_logger.isDebugEnabled()) {
-                s_logger.debug("Found " + srcData.getObjectType() + " from directory " + templatePath + " to upload to S3.");
-            }
-
-            final String bucket = s3.getBucketName();
-            File srcFile = _storage.getFile(templatePath);
-            // guard the case where templatePath does not have file extension, since we are not completely sure
-            // about hypervisor, so we check each extension
-            if (!srcFile.exists()) {
-                srcFile = _storage.getFile(templatePath + ".qcow2");
-                if (!srcFile.exists()) {
-                    srcFile = _storage.getFile(templatePath + ".vhd");
-                    if (!srcFile.exists()) {
-                        srcFile = _storage.getFile(templatePath + ".ova");
-                        if (!srcFile.exists()) {
-                            srcFile = _storage.getFile(templatePath + ".vmdk");
-                            if (!srcFile.exists()) {
-                                return new CopyCmdAnswer("Can't find src file:" + templatePath);
-                            }
-                        }
-                    }
-                }
-            }
-
-            long srcSize = srcFile.length();
-            ImageFormat format = getTemplateFormat(srcFile.getName());
-            String key = destData.getPath() + S3Utils.SEPARATOR + srcFile.getName();
-            if (!s3.getSingleUpload(srcSize)) {
-                mputFile(s3, srcFile, bucket, key);
-            } else {
-                putFile(s3, srcFile, bucket, key);
-            }
-
-            DataTO retObj = null;
-            if (destData.getObjectType() == DataObjectType.TEMPLATE) {
-                TemplateObjectTO newTemplate = new TemplateObjectTO();
-                newTemplate.setPath(key);
-                newTemplate.setSize(getVirtualSize(srcFile, format));
-                newTemplate.setPhysicalSize(srcFile.length());
-                newTemplate.setFormat(format);
-                retObj = newTemplate;
-            } else if (destData.getObjectType() == DataObjectType.VOLUME) {
-                VolumeObjectTO newVol = new VolumeObjectTO();
-                newVol.setPath(key);
-                newVol.setSize(srcFile.length());
-                retObj = newVol;
-            } else if (destData.getObjectType() == DataObjectType.SNAPSHOT) {
-                SnapshotObjectTO newSnapshot = new SnapshotObjectTO();
-                newSnapshot.setPath(key);
-                retObj = newSnapshot;
-            }
-
-            return new CopyCmdAnswer(retObj);
-        } catch (Exception e) {
-            s_logger.error("failed to upload" + srcData.getPath(), e);
-            return new CopyCmdAnswer("failed to upload" + srcData.getPath() + e.toString());
-        }
-    }
-
-    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=" + parser.getLines();
-                    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=" + parser.getLines();
-                    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=" + parser.getLines();
-                        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=" + parser.getLines();
-                    s_logger.warn(errMsg);
-                    return errMsg;
-                }
-            }
-        }
-        return null;
-    }
-
-    public Answer execute(DeleteSnapshotsDirCommand cmd) {
-        DataStoreTO dstore = cmd.getDataStore();
-        if (dstore instanceof NfsTO) {
-            NfsTO nfs = (NfsTO)dstore;
-            String relativeSnapshotPath = cmd.getDirectory();
-            String parent = getRootDir(nfs.getUrl());
-
-            if (relativeSnapshotPath.startsWith(File.separator)) {
-                relativeSnapshotPath = relativeSnapshotPath.substring(1);
-            }
-
-            if (!parent.endsWith(File.separator)) {
-                parent += File.separator;
-            }
-            String absoluteSnapshotPath = parent + relativeSnapshotPath;
-            File snapshotDir = new File(absoluteSnapshotPath);
-            String details = null;
-            if (!snapshotDir.exists()) {
-                details = "snapshot directory " + snapshotDir.getName() + " doesn't exist";
-                s_logger.debug(details);
-                return new Answer(cmd, true, details);
-            }
-            // delete all files in the directory
-            String lPath = absoluteSnapshotPath + "/*";
-            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);
-            }
-            // delete the directory
-            if (!snapshotDir.delete()) {
-                details = "Unable to delete directory " + snapshotDir.getName() + " under snapshot path " + relativeSnapshotPath;
-                s_logger.debug(details);
-                return new Answer(cmd, false, details);
-            }
-            return new Answer(cmd, true, null);
-        } else if (dstore instanceof S3TO) {
-            final S3TO s3 = (S3TO)dstore;
-            final String path = cmd.getDirectory();
-            final String bucket = s3.getBucketName();
-            try {
-                S3Utils.deleteDirectory(s3, bucket, path);
-                return new Answer(cmd, true, String.format("Deleted snapshot %1%s from bucket %2$s.", path, bucket));
-            } catch (Exception e) {
-                final String errorMessage =
-                        String.format("Failed to delete snapshot %1$s from bucket %2$s due to the following error: %3$s", path, bucket, e.getMessage());
-                s_logger.error(errorMessage, e);
-                return new Answer(cmd, false, errorMessage);
-            }
-        } else if (dstore instanceof SwiftTO) {
-            String path = cmd.getDirectory();
-            String volumeId = StringUtils.substringAfterLast(path, "/"); // assuming
-            // that
-            // the
-            // filename
-            // is
-            // the
-            // last
-            // section
-            // in
-            // the
-            // path
-            String result = swiftDelete((SwiftTO)dstore, "V-" + volumeId.toString(), "");
-            if (result != null) {
-                String errMsg = "failed to delete snapshot for volume " + volumeId + " , err=" + result;
-                s_logger.warn(errMsg);
-                return new Answer(cmd, false, errMsg);
-            }
-            return new Answer(cmd, true, "Deleted snapshot " + path + " from swift");
-        } else {
-            return new Answer(cmd, false, "Unsupported image data store: " + dstore);
-        }
-    }
-
-    private Answer execute(ComputeChecksumCommand cmd) {
-
-        String relativeTemplatePath = cmd.getTemplatePath();
-        DataStoreTO store = cmd.getStore();
-        if (!(store instanceof NfsTO)) {
-            return new Answer(cmd, false, "can't handle non nfs data store");
-        }
-        NfsTO nfsStore = (NfsTO)store;
-        String parent = getRootDir(nfsStore.getUrl());
-
-        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(KeystoreManager.Certificates certs) {
-        if (certs == null) {
-            configureSSL();
-        } else {
-            String prvKey = certs.getPrivKey();
-            String pubCert = certs.getPrivCert();
-
-            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);
-        }
-        DataStoreTO dStore = cmd.getDataStore();
-        if (dStore instanceof NfsTO) {
-            String secUrl = cmd.getSecUrl();
-            try {
-                URI uri = new URI(secUrl);
-                String nfsHostIp = getUriHostIp(uri);
-
-                addRouteToInternalIpOrCidr(_storageGateway, _storageIp, _storageNetmask, nfsHostIp);
-                String dir = mountUri(uri);
-
-                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);
-
-            }
-        } else {
-            // TODO: what do we need to setup for S3/Swift, maybe need to mount
-            // to some cache storage
-            return new Answer(cmd, true, null);
-        }
-    }
-
-    protected Answer deleteSnapshot(final DeleteCommand cmd) {
-        DataTO obj = cmd.getData();
-        DataStoreTO dstore = obj.getDataStore();
-        if (dstore instanceof NfsTO) {
-            NfsTO nfs = (NfsTO)dstore;
-            String parent = getRootDir(nfs.getUrl());
-            if (!parent.endsWith(File.separator)) {
-                parent += File.separator;
-            }
-            String snapshotPath = obj.getPath();
-            if (snapshotPath.startsWith(File.separator)) {
-                snapshotPath = snapshotPath.substring(1);
-            }
-            // check if the passed snapshot path is a directory or not. For ImageCache, path is stored as a directory instead of
-            // snapshot file name. If so, since backupSnapshot process has already deleted snapshot in cache, so we just do nothing
-            // and return true.
-            String fullSnapPath = parent + snapshotPath;
-            File snapDir = new File(fullSnapPath);
-            if (snapDir.exists() && snapDir.isDirectory()) {
-                s_logger.debug("snapshot path " + snapshotPath + " is a directory, already deleted during backup snapshot, so no need to delete");
-                return new Answer(cmd, true, null);
-            }
-            // passed snapshot path is a snapshot file path, then get snapshot directory first
-            int index = snapshotPath.lastIndexOf("/");
-            String snapshotName = snapshotPath.substring(index + 1);
-            snapshotPath = snapshotPath.substring(0, index);
-            String absoluteSnapshotPath = parent + snapshotPath;
-            // check if snapshot directory exists
-            File snapshotDir = new File(absoluteSnapshotPath);
-            String details = null;
-            if (!snapshotDir.exists()) {
-                details = "snapshot directory " + snapshotDir.getName() + " doesn't exist";
-                s_logger.debug(details);
-                return new Answer(cmd, false, details);
-            }
-            // delete snapshot in the directory if exists
-            String lPath = absoluteSnapshotPath + "/*" + snapshotName + "*";
-            String result = deleteLocalFile(lPath);
-            if (result != null) {
-                details = "failed to delete snapshot " + lPath + " , err=" + result;
-                s_logger.warn(details);
-                return new Answer(cmd, false, details);
-            }
-            return new Answer(cmd, true, null);
-        } else if (dstore instanceof S3TO) {
-            final S3TO s3 = (S3TO)dstore;
-            final String path = obj.getPath();
-            final String bucket = s3.getBucketName();
-            try {
-                S3Utils.deleteObject(s3, bucket, path);
-                return new Answer(cmd, true, String.format("Deleted snapshot %1%s from bucket %2$s.", path, bucket));
-            } catch (Exception e) {
-                final String errorMessage =
-                        String.format("Failed to delete snapshot %1$s from bucket %2$s due to the following error: %3$s", path, bucket, e.getMessage());
-                s_logger.error(errorMessage, e);
-                return new Answer(cmd, false, errorMessage);
-            }
-        } else if (dstore instanceof SwiftTO) {
-            SwiftTO swiftTO = (SwiftTO)dstore;
-            String path = obj.getPath();
-            SwiftUtil.deleteObject(swiftTO, path);
-
-            return new Answer(cmd, true, "Deleted snapshot " + path + " from swift");
-        } else {
-            return new Answer(cmd, false, "Unsupported image data store: " + dstore);
-        }
-
-    }
-
-    Map<String, TemplateProp> swiftListTemplate(SwiftTO swift) {
-        String[] containers = SwiftUtil.list(swift, "", null);
-        if (containers == null) {
-            return null;
-        }
-        Map<String, TemplateProp> tmpltInfos = new HashMap<String, TemplateProp>();
-        for (String container : containers) {
-            if (container.startsWith("T-")) {
-                String[] files = SwiftUtil.list(swift, container, "template.properties");
-                if (files.length != 1) {
-                    continue;
-                }
-                try {
-                    File tempFile = File.createTempFile("template", ".tmp");
-                    File tmpFile = SwiftUtil.getObject(swift, tempFile, container + File.separator + "template.properties");
-                    if (tmpFile == null) {
-                        continue;
-                    }
-                    FileReader fr = new FileReader(tmpFile);
-                    BufferedReader brf = new BufferedReader(fr);
-                    String line = null;
-                    String uniqName = null;
-                    Long size = null;
-                    String name = null;
-                    while ((line = brf.readLine()) != null) {
-                        if (line.startsWith("uniquename=")) {
-                            uniqName = line.split("=")[1];
-                        } else if (line.startsWith("size=")) {
-                            size = Long.parseLong(line.split("=")[1]);
-                        } else if (line.startsWith("filename=")) {
-                            name = line.split("=")[1];
-                        }
-                    }
-                    brf.close();
-                    tempFile.delete();
-                    if (uniqName != null) {
-                        TemplateProp prop = new TemplateProp(uniqName, container + File.separator + name, size, size, true, false);
-                        tmpltInfos.put(uniqName, prop);
-                    }
-
-                } catch (IOException e) {
-                    s_logger.debug("Failed to create templ file:" + e.toString());
-                    continue;
-                } catch (Exception e) {
-                    s_logger.debug("Failed to get properties: " + e.toString());
-                    continue;
-                }
-            }
-        }
-        return tmpltInfos;
-
-    }
-
-    Map<String, TemplateProp> s3ListTemplate(S3TO s3) {
-        String bucket = s3.getBucketName();
-        // List the objects in the source directory on S3
-        final List<S3ObjectSummary> objectSummaries = S3Utils.getDirectory(s3, bucket, TEMPLATE_ROOT_DIR);
-        if (objectSummaries == null) {
-            return null;
-        }
-        Map<String, TemplateProp> tmpltInfos = new HashMap<String, TemplateProp>();
-        for (S3ObjectSummary objectSummary : objectSummaries) {
-            String key = objectSummary.getKey();
-            // String installPath = StringUtils.substringBeforeLast(key,
-            // S3Utils.SEPARATOR);
-            String uniqueName = determineS3TemplateNameFromKey(key);
-            // TODO: isPublic value, where to get?
-            TemplateProp tInfo = new TemplateProp(uniqueName, key, objectSummary.getSize(), objectSummary.getSize(), true, false);
-            tmpltInfos.put(uniqueName, tInfo);
-        }
-        return tmpltInfos;
-
-    }
-
-    Map<Long, TemplateProp> s3ListVolume(S3TO s3) {
-        String bucket = s3.getBucketName();
-        // List the objects in the source directory on S3
-        final List<S3ObjectSummary> objectSummaries = S3Utils.getDirectory(s3, bucket, VOLUME_ROOT_DIR);
-        if (objectSummaries == null) {
-            return null;
-        }
-        Map<Long, TemplateProp> tmpltInfos = new HashMap<Long, TemplateProp>();
-        for (S3ObjectSummary objectSummary : objectSummaries) {
-            String key = objectSummary.getKey();
-            // String installPath = StringUtils.substringBeforeLast(key,
-            // S3Utils.SEPARATOR);
-            Long id = determineS3VolumeIdFromKey(key);
-            // TODO: how to get volume template name
-            TemplateProp tInfo = new TemplateProp(id.toString(), key, objectSummary.getSize(), objectSummary.getSize(), true, false);
-            tmpltInfos.put(id, tInfo);
-        }
-        return tmpltInfos;
-
-    }
-
-    private Answer execute(ListTemplateCommand cmd) {
-        if (!_inSystemVM) {
-            return new ListTemplateAnswer(null, null);
-        }
-
-        DataStoreTO store = cmd.getDataStore();
-        if (store instanceof NfsTO) {
-            NfsTO nfs = (NfsTO)store;
-            String secUrl = nfs.getUrl();
-            String root = getRootDir(secUrl);
-            Map<String, TemplateProp> templateInfos = _dlMgr.gatherTemplateInfo(root);
-            return new ListTemplateAnswer(secUrl, templateInfos);
-        } else if (store instanceof SwiftTO) {
-            SwiftTO swift = (SwiftTO)store;
-            Map<String, TemplateProp> templateInfos = swiftListTemplate(swift);
-            return new ListTemplateAnswer(swift.toString(), templateInfos);
-        } else if (store instanceof S3TO) {
-            S3TO s3 = (S3TO)store;
-            Map<String, TemplateProp> templateInfos = s3ListTemplate(s3);
-            return new ListTemplateAnswer(s3.getBucketName(), templateInfos);
-        } else {
-            return new Answer(cmd, false, "Unsupported image data store: " + store);
-        }
-    }
-
-    private Answer execute(ListVolumeCommand cmd) {
-        if (!_inSystemVM) {
-            return new ListVolumeAnswer(cmd.getSecUrl(), null);
-        }
-        DataStoreTO store = cmd.getDataStore();
-        if (store instanceof NfsTO) {
-            String root = getRootDir(cmd.getSecUrl());
-            Map<Long, TemplateProp> templateInfos = _dlMgr.gatherVolumeInfo(root);
-            return new ListVolumeAnswer(cmd.getSecUrl(), templateInfos);
-        } else if (store instanceof S3TO) {
-            S3TO s3 = (S3TO)store;
-            Map<Long, TemplateProp> templateInfos = s3ListVolume(s3);
-            return new ListVolumeAnswer(s3.getBucketName(), templateInfos);
-        } else {
-            return new Answer(cmd, false, "Unsupported image data store: " + store);
-        }
-
-    }
-
-    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 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) {
-        DataStoreTO store = cmd.getStore();
-        if (store instanceof S3TO || store instanceof SwiftTO) {
-            long infinity = Integer.MAX_VALUE;
-            return new GetStorageStatsAnswer(cmd, infinity, 0L);
-        }
-
-        String rootDir = getRootDir(((NfsTO)store).getUrl());
-        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 DeleteCommand cmd) {
-        DataTO obj = cmd.getData();
-        DataObjectType objType = obj.getObjectType();
-        if (obj.getPath() == null) {
-            // account for those fake entries for NFS migration to object store
-            return new Answer(cmd, true, "Object with null install path does not exist on image store , no need to delete");
-        }
-        switch (objType) {
-        case TEMPLATE:
-            return deleteTemplate(cmd);
-        case VOLUME:
-            return deleteVolume(cmd);
-        case SNAPSHOT:
-            return deleteSnapshot(cmd);
-        }
-        return Answer.createUnsupportedCommandAnswer(cmd);
-    }
-
-    protected Answer deleteTemplate(DeleteCommand cmd) {
-        DataTO obj = cmd.getData();
-        DataStoreTO dstore = obj.getDataStore();
-        if (dstore instanceof NfsTO) {
-            NfsTO nfs = (NfsTO)dstore;
-            String relativeTemplatePath = obj.getPath();
-            String parent = getRootDir(nfs.getUrl());
-
-            if (relativeTemplatePath.startsWith(File.separator)) {
-                relativeTemplatePath = relativeTemplatePath.substring(1);
-            }
-
-            if (!parent.endsWith(File.separator)) {
-                parent += File.separator;
-            }
-            String absoluteTemplatePath = parent + relativeTemplatePath;
-            File tmpltPath = new File(absoluteTemplatePath);
-            File tmpltParent = null;
-            if(tmpltPath.exists() && tmpltPath.isDirectory()) {
-                tmpltParent = tmpltPath;
-            } else {
-                tmpltParent = tmpltPath.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;
-                    }
-
-                    // KVM HA monitor makes a mess in the templates with its
-                    // heartbeat tests
-                    // Don't let this stop us from cleaning up the template
-                    if (f.isDirectory() && f.getName().equals("KVMHA")) {
-                        s_logger.debug("Deleting KVMHA directory contents from template location");
-                        File[] haFiles = f.listFiles();
-                        for (File haFile : haFiles) {
-                            haFile.delete();
-                        }
-                    }
-
-                    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);
-        } else if (dstore instanceof S3TO) {
-            final S3TO s3 = (S3TO)dstore;
-            final String path = obj.getPath();
-            final String bucket = s3.getBucketName();
-            try {
-                S3Utils.deleteDirectory(s3, bucket, path);
-                return new Answer(cmd, true, String.format("Deleted template %1$s from bucket %2$s.", path, bucket));
-            } catch (Exception e) {
-                final String errorMessage =
-                        String.format("Failed to delete template %1$s from bucket %2$s due to the following error: %3$s", path, bucket, e.getMessage());
-                s_logger.error(errorMessage, e);
-                return new Answer(cmd, false, errorMessage);
-            }
-        } else if (dstore instanceof SwiftTO) {
-            SwiftTO swift = (SwiftTO)dstore;
-            String container = "T-" + obj.getId();
-            String 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);
-            }
-        } else {
-            return new Answer(cmd, false, "Unsupported image data store: " + dstore);
-        }
-    }
-
-    protected Answer deleteVolume(final DeleteCommand cmd) {
-        DataTO obj = cmd.getData();
-        DataStoreTO dstore = obj.getDataStore();
-        if (dstore instanceof NfsTO) {
-            NfsTO nfs = (NfsTO)dstore;
-            String relativeVolumePath = obj.getPath();
-            String parent = getRootDir(nfs.getUrl());
-
-            if (relativeVolumePath.startsWith(File.separator)) {
-                relativeVolumePath = relativeVolumePath.substring(1);
-            }
-
-            if (!parent.endsWith(File.separator)) {
-                parent += File.separator;
-            }
-            String absoluteVolumePath = parent + relativeVolumePath;
-            File volPath = new File(absoluteVolumePath);
-            File tmpltParent = null;
-            if (volPath.exists() && volPath.isDirectory()) {
-                // for vmware, absoluteVolumePath represents a directory where volume files are located.
-                tmpltParent = volPath;
-            } else {
-                // for other hypervisors, the volume .vhd or .qcow2 file path is passed
-                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;
-                    }
-
-                    // KVM HA monitor makes a mess in the templates with its
-                    // heartbeat tests
-                    // Don't let this stop us from cleaning up the template
-                    if (f.isDirectory() && f.getName().equals("KVMHA")) {
-                        s_logger.debug("Deleting KVMHA directory contents from template location");
-                        File[] haFiles = f.listFiles();
-                        for (File haFile : haFiles) {
-                            haFile.delete();
-                        }
-                    }
-
-                    if (!f.delete()) {
-                        return new Answer(cmd, false, "Unable to delete file " + f.getName() + " under Volume path " + tmpltParent.getPath());
-                    }
-                }
-                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 " + tmpltParent.getPath();
-                s_logger.debug(details);
-                return new Answer(cmd, false, details);
-            }
-            return new Answer(cmd, true, null);
-        } else if (dstore instanceof S3TO) {
-            final S3TO s3 = (S3TO)dstore;
-            final String path = obj.getPath();
-            final String bucket = s3.getBucketName();
-            try {
-                S3Utils.deleteDirectory(s3, bucket, path);
-                return new Answer(cmd, true, String.format("Deleted volume %1%s from bucket %2$s.", path, bucket));
-            } catch (Exception e) {
-                final String errorMessage = String.format("Failed to delete volume %1$s from bucket %2$s due to the following error: %3$s", path, bucket, e.getMessage());
-                s_logger.error(errorMessage, e);
-                return new Answer(cmd, false, errorMessage);
-            }
-        } else if (dstore instanceof SwiftTO) {
-            Long volumeId = obj.getId();
-            String path = obj.getPath();
-            String filename = StringUtils.substringAfterLast(path, "/"); // assuming
-            // that
-            // the
-            // filename
-            // is
-            // the
-            // last
-            // section
-            // in
-            // the
-            // path
-            String result = swiftDelete((SwiftTO)dstore, "V-" + volumeId.toString(), filename);
-            if (result != null) {
-                String errMsg = "failed to delete volume " + filename + " , err=" + result;
-                s_logger.warn(errMsg);
-                return new Answer(cmd, false, errMsg);
-            }
-            return new Answer(cmd, true, "Deleted volume " + path + " from swift");
-        } else {
-            return new Answer(cmd, false, "Unsupported image data store: " + dstore);
-        }
-
-    }
-
-    @Override
-    synchronized public String getRootDir(String secUrl) {
-        if (!_inSystemVM) {
-            return _parent;
-        }
-        try {
-            URI uri = new URI(secUrl);
-            String dir = mountUri(uri);
-            return _parent + "/" + dir;
-        } catch (Exception e) {
-            String msg = "GetRootDir for " + secUrl + " failed due to " + e.toString();
-            s_logger.error(msg, e);
-            throw new CloudRuntimeException(msg);
-        }
-    }
-
-    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("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");
-        }
-        _publicIp = (String)params.get("eth2ip");
-        _hostname = (String)params.get("name");
-
-        String inSystemVM = (String)params.get("secondary.storage.vm");
-        if (inSystemVM == null || "true".equalsIgnoreCase(inSystemVM)) {
-            s_logger.debug("conf secondary.storage.vm is true, act as if executing in SSVM");
-            _inSystemVM = true;
-        }
-
-        _storageIp = (String)params.get("storageip");
-        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");
-        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);
-        configureStorageLayerClass(params);
-
-        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);
-        }
-
-        createTemplateFromSnapshotXenScript = Script.findScript(getDefaultScriptsDir(), "create_privatetemplate_from_snapshot_xen.sh");
-        if (createTemplateFromSnapshotXenScript == null) {
-            throw new ConfigurationException("create_privatetemplate_from_snapshot_xen.sh not found in " + getDefaultScriptsDir());
-        }
-
-        _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;
-    }
-
-    protected void configureStorageLayerClass(Map<String, Object> params) throws ConfigurationException {
-        String value;
-        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("

<TRUNCATED>

[07/11] git commit: updated refs/heads/master to 54f32a8

Posted by ah...@apache.org.
Moved the secondary storage service into its own server directory


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

Branch: refs/heads/master
Commit: 4be3b9933760c7713380112dff6f997cbe127def
Parents: aaa2094
Author: Alex Huang <al...@citrix.com>
Authored: Wed Jan 15 17:37:15 2014 -0800
Committer: Alex Huang <al...@citrix.com>
Committed: Wed Feb 5 01:38:24 2014 +0000

----------------------------------------------------------------------
 services/secondary-storage/controller/pom.xml   |   50 +
 services/secondary-storage/pom.xml              |   85 +-
 .../module.properties                           |   18 -
 ...ing-secondary-storage-discoverer-context.xml |   36 -
 services/secondary-storage/server/pom.xml       |  105 +
 .../module.properties                           |   18 +
 ...ing-secondary-storage-discoverer-context.xml |   36 +
 .../LocalNfsSecondaryStorageResource.java       |   95 +
 .../resource/LocalSecondaryStorageResource.java |  240 ++
 .../resource/NfsSecondaryStorageResource.java   | 2430 ++++++++++++++++++
 .../resource/SecondaryStorageDiscoverer.java    |  312 +++
 .../resource/SecondaryStorageResource.java      |   29 +
 .../SecondaryStorageResourceHandler.java        |   24 +
 .../storage/template/DownloadManager.java       |  108 +
 .../storage/template/DownloadManagerImpl.java   | 1080 ++++++++
 .../storage/template/UploadManager.java         |   82 +
 .../storage/template/UploadManagerImpl.java     |  550 ++++
 .../LocalNfsSecondaryStorageResourceTest.java   |  143 ++
 .../NfsSecondaryStorageResourceTest.java        |  110 +
 .../LocalNfsSecondaryStorageResource.java       |   95 -
 .../resource/LocalSecondaryStorageResource.java |  240 --
 .../resource/NfsSecondaryStorageResource.java   | 2430 ------------------
 .../resource/SecondaryStorageDiscoverer.java    |  312 ---
 .../resource/SecondaryStorageResource.java      |   29 -
 .../SecondaryStorageResourceHandler.java        |   24 -
 .../storage/template/DownloadManager.java       |  108 -
 .../storage/template/DownloadManagerImpl.java   | 1080 --------
 .../storage/template/UploadManager.java         |   82 -
 .../storage/template/UploadManagerImpl.java     |  550 ----
 .../LocalNfsSecondaryStorageResourceTest.java   |  143 --
 .../NfsSecondaryStorageResourceTest.java        |  110 -
 31 files changed, 5419 insertions(+), 5335 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4be3b993/services/secondary-storage/controller/pom.xml
----------------------------------------------------------------------
diff --git a/services/secondary-storage/controller/pom.xml b/services/secondary-storage/controller/pom.xml
new file mode 100644
index 0000000..47a730d
--- /dev/null
+++ b/services/secondary-storage/controller/pom.xml
@@ -0,0 +1,50 @@
+<!--
+  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-controller-secondary-storage</artifactId>
+  <name>Apache CloudStack Secondary Storage Controller</name>
+  <parent>
+    <groupId>org.apache.cloudstack</groupId>
+    <artifactId>cloudstack-service-secondary-storage</artifactId>
+    <version>4.4.0-SNAPSHOT</version>
+    <relativePath>../pom.xml</relativePath>
+  </parent>
+  <dependencies>
+    <dependency>
+      <groupId>commons-codec</groupId>
+      <artifactId>commons-codec</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-api</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-utils</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-server</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+  </dependencies>
+</project>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4be3b993/services/secondary-storage/pom.xml
----------------------------------------------------------------------
diff --git a/services/secondary-storage/pom.xml b/services/secondary-storage/pom.xml
index 2798584..61077a0 100644
--- a/services/secondary-storage/pom.xml
+++ b/services/secondary-storage/pom.xml
@@ -18,88 +18,17 @@
 -->
 <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>
+  <artifactId>cloudstack-service-secondary-storage</artifactId>
+  <name>Apache CloudStack Secondary Storage</name>
+  <packaging>pom</packaging>
   <parent>
     <groupId>org.apache.cloudstack</groupId>
     <artifactId>cloudstack-services</artifactId>
     <version>4.4.0-SNAPSHOT</version>
     <relativePath>../pom.xml</relativePath>
   </parent>
-    <properties>
-    <skipTests>true</skipTests>
-  </properties>
-    <dependencies>
-    <dependency>
-      <groupId>log4j</groupId>
-      <artifactId>log4j</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.google.code.gson</groupId>
-      <artifactId>gson</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>commons-codec</groupId>
-      <artifactId>commons-codec</artifactId>
-    </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-server</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-  </dependencies>
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-surefire-plugin</artifactId>
-        <configuration>
-         <skipTests>${skipTests}</skipTests>
-         <systemPropertyVariables>
-            <log4j.configuration>file:${project.build.testSourceDirectory}/../conf/log4j.xml</log4j.configuration>
-        </systemPropertyVariables>
-        </configuration>
-      </plugin>
-      <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>
-            <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>
-      </plugin>
-    </plugins>
-  </build>
+  <modules>
+    <module>controller</module>
+    <module>server</module>
+  </modules>
 </project>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4be3b993/services/secondary-storage/resources/META-INF/cloudstack/secondary-storage-discoverer/module.properties
----------------------------------------------------------------------
diff --git a/services/secondary-storage/resources/META-INF/cloudstack/secondary-storage-discoverer/module.properties b/services/secondary-storage/resources/META-INF/cloudstack/secondary-storage-discoverer/module.properties
deleted file mode 100644
index 7ff8a3a..0000000
--- a/services/secondary-storage/resources/META-INF/cloudstack/secondary-storage-discoverer/module.properties
+++ /dev/null
@@ -1,18 +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.
-name=secondary-storage-discoverer
-parent=discoverer
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4be3b993/services/secondary-storage/resources/META-INF/cloudstack/secondary-storage-discoverer/spring-secondary-storage-discoverer-context.xml
----------------------------------------------------------------------
diff --git a/services/secondary-storage/resources/META-INF/cloudstack/secondary-storage-discoverer/spring-secondary-storage-discoverer-context.xml b/services/secondary-storage/resources/META-INF/cloudstack/secondary-storage-discoverer/spring-secondary-storage-discoverer-context.xml
deleted file mode 100644
index 30521aa..0000000
--- a/services/secondary-storage/resources/META-INF/cloudstack/secondary-storage-discoverer/spring-secondary-storage-discoverer-context.xml
+++ /dev/null
@@ -1,36 +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: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/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"
-                      >
-
-    <bean id="SecondaryStorageDiscoverer"
-        class="org.apache.cloudstack.storage.resource.SecondaryStorageDiscoverer">
-        <property name="name" value="SecondaryStorage" />
-    </bean>
-
-    
-</beans>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4be3b993/services/secondary-storage/server/pom.xml
----------------------------------------------------------------------
diff --git a/services/secondary-storage/server/pom.xml b/services/secondary-storage/server/pom.xml
new file mode 100644
index 0000000..29fd7c7
--- /dev/null
+++ b/services/secondary-storage/server/pom.xml
@@ -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.
+-->
+<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>cloudstack-service-secondary-storage</artifactId>
+    <version>4.4.0-SNAPSHOT</version>
+    <relativePath>../pom.xml</relativePath>
+  </parent>
+    <properties>
+    <skipTests>true</skipTests>
+  </properties>
+    <dependencies>
+    <dependency>
+      <groupId>log4j</groupId>
+      <artifactId>log4j</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.google.code.gson</groupId>
+      <artifactId>gson</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>commons-codec</groupId>
+      <artifactId>commons-codec</artifactId>
+    </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-server</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+  </dependencies>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <configuration>
+         <skipTests>${skipTests}</skipTests>
+         <systemPropertyVariables>
+            <log4j.configuration>file:${project.build.testSourceDirectory}/../conf/log4j.xml</log4j.configuration>
+        </systemPropertyVariables>
+        </configuration>
+      </plugin>
+      <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>
+            <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>
+      </plugin>
+    </plugins>
+  </build>
+</project>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4be3b993/services/secondary-storage/server/resources/META-INF/cloudstack/secondary-storage-discoverer/module.properties
----------------------------------------------------------------------
diff --git a/services/secondary-storage/server/resources/META-INF/cloudstack/secondary-storage-discoverer/module.properties b/services/secondary-storage/server/resources/META-INF/cloudstack/secondary-storage-discoverer/module.properties
new file mode 100644
index 0000000..7ff8a3a
--- /dev/null
+++ b/services/secondary-storage/server/resources/META-INF/cloudstack/secondary-storage-discoverer/module.properties
@@ -0,0 +1,18 @@
+# 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.
+name=secondary-storage-discoverer
+parent=discoverer
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4be3b993/services/secondary-storage/server/resources/META-INF/cloudstack/secondary-storage-discoverer/spring-secondary-storage-discoverer-context.xml
----------------------------------------------------------------------
diff --git a/services/secondary-storage/server/resources/META-INF/cloudstack/secondary-storage-discoverer/spring-secondary-storage-discoverer-context.xml b/services/secondary-storage/server/resources/META-INF/cloudstack/secondary-storage-discoverer/spring-secondary-storage-discoverer-context.xml
new file mode 100644
index 0000000..30521aa
--- /dev/null
+++ b/services/secondary-storage/server/resources/META-INF/cloudstack/secondary-storage-discoverer/spring-secondary-storage-discoverer-context.xml
@@ -0,0 +1,36 @@
+<!--
+  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: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/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"
+                      >
+
+    <bean id="SecondaryStorageDiscoverer"
+        class="org.apache.cloudstack.storage.resource.SecondaryStorageDiscoverer">
+        <property name="name" value="SecondaryStorage" />
+    </bean>
+
+    
+</beans>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4be3b993/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResource.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResource.java b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResource.java
new file mode 100644
index 0000000..9393ee2
--- /dev/null
+++ b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResource.java
@@ -0,0 +1,95 @@
+// 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.net.URI;
+import java.util.concurrent.Executors;
+
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import org.apache.cloudstack.storage.template.DownloadManagerImpl;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
+import com.cloud.storage.JavaStorageLayer;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.script.Script;
+
+@Component
+public class LocalNfsSecondaryStorageResource extends NfsSecondaryStorageResource {
+
+    private static final Logger s_logger = Logger.getLogger(LocalNfsSecondaryStorageResource.class);
+
+    public LocalNfsSecondaryStorageResource() {
+        this._dlMgr = new DownloadManagerImpl();
+        ((DownloadManagerImpl)_dlMgr).setThreadPool(Executors.newFixedThreadPool(10));
+        _storage = new JavaStorageLayer();
+        this._inSystemVM = false;
+    }
+
+    @Override
+    public void setParentPath(String path) {
+        this._parent = path;
+    }
+
+    @Override
+    public Answer executeRequest(Command cmd) {
+        return super.executeRequest(cmd);
+    }
+
+    @Override
+    synchronized public String getRootDir(String secUrl) {
+        try {
+            URI uri = new URI(secUrl);
+            String dir = mountUri(uri);
+            return _parent + "/" + dir;
+        } catch (Exception e) {
+            String msg = "GetRootDir for " + secUrl + " failed due to " + e.toString();
+            s_logger.error(msg, e);
+            throw new CloudRuntimeException(msg);
+        }
+    }
+
+    @Override
+    protected void mount(String localRootPath, String remoteDevice, URI uri) {
+        ensureLocalRootPathExists(localRootPath, uri);
+
+        if (mountExists(localRootPath, uri)) {
+            return;
+        }
+
+        attemptMount(localRootPath, remoteDevice, uri);
+
+        // Change permissions for the mountpoint - seems to bypass authentication
+        Script script = new Script(true, "chmod", _timeout, s_logger);
+        script.add("777", localRootPath);
+        String result = script.execute();
+        if (result != null) {
+            String errMsg = "Unable to set permissions for " + localRootPath + " due to " + result;
+            s_logger.error(errMsg);
+            throw new CloudRuntimeException(errMsg);
+        }
+        s_logger.debug("Successfully set 777 permission for " + localRootPath);
+
+        // XXX: Adding the check for creation of snapshots dir here. Might have
+        // to move it somewhere more logical later.
+        checkForSnapshotsDir(localRootPath);
+        checkForVolumesDir(localRootPath);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4be3b993/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/LocalSecondaryStorageResource.java
----------------------------------------------------------------------
diff --git a/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/LocalSecondaryStorageResource.java b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/LocalSecondaryStorageResource.java
new file mode 100644
index 0000000..bdfe7e8
--- /dev/null
+++ b/services/secondary-storage/server/src/org/apache/cloudstack/storage/resource/LocalSecondaryStorageResource.java
@@ -0,0 +1,240 @@
+// 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.log4j.Logger;
+
+import org.apache.cloudstack.storage.command.DownloadCommand;
+import org.apache.cloudstack.storage.command.DownloadProgressCommand;
+import org.apache.cloudstack.storage.template.DownloadManager;
+import org.apache.cloudstack.storage.template.DownloadManagerImpl;
+
+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.ListTemplateAnswer;
+import com.cloud.agent.api.storage.ListTemplateCommand;
+import com.cloud.agent.api.to.NfsTO;
+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.TemplateProp;
+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(String url) {
+        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, TemplateProp> templateInfos = _dlMgr.gatherTemplateInfo(root);
+        return new ListTemplateAnswer(((NfsTO)cmd.getDataStore()).getUrl(), 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
+
+    }
+}