cloudstack-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ahu...@apache.org
Subject [37/50] [abbrv] Merged
Date Fri, 10 May 2013 23:33:20 GMT
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/30479293/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
----------------------------------------------------------------------
diff --cc services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
index 0000000,e7fa5b2..6099382
mode 000000,100755..100755
--- a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
+++ b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java
@@@ -1,0 -1,1904 +1,2128 @@@
+ // Licensed to the Apache Software Foundation (ASF) under one
+ // or more contributor license agreements.  See the NOTICE file
+ // distributed with this work for additional information
+ // regarding copyright ownership.  The ASF licenses this file
+ // to you under the Apache License, Version 2.0 (the
+ // "License"); you may not use this file except in compliance
+ // with the License.  You may obtain a copy of the License at
+ //
+ //   http://www.apache.org/licenses/LICENSE-2.0
+ //
+ // Unless required by applicable law or agreed to in writing,
+ // software distributed under the License is distributed on an
+ // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ // KIND, either express or implied.  See the License for the
+ // specific language governing permissions and limitations
+ // under the License.
+ package org.apache.cloudstack.storage.resource;
+ 
 -import static com.cloud.utils.S3Utils.deleteDirectory;
+ import static com.cloud.utils.S3Utils.getDirectory;
 -import static com.cloud.utils.S3Utils.putDirectory;
+ import static com.cloud.utils.StringUtils.join;
+ import static com.cloud.utils.db.GlobalLock.executeWithNoWaitLock;
+ import static java.lang.String.format;
+ import static java.util.Arrays.asList;
+ import static org.apache.commons.lang.StringUtils.substringAfterLast;
+ 
+ import java.io.BufferedWriter;
+ import java.io.File;
+ import java.io.FileInputStream;
+ import java.io.FileWriter;
 -import java.io.FilenameFilter;
+ import java.io.IOException;
+ import java.io.InputStream;
+ import java.math.BigInteger;
+ import java.net.InetAddress;
+ import java.net.URI;
+ import java.security.MessageDigest;
+ import java.security.NoSuchAlgorithmException;
+ import java.util.ArrayList;
+ import java.util.HashMap;
+ import java.util.List;
+ import java.util.Map;
+ import java.util.UUID;
+ import java.util.concurrent.Callable;
+ 
+ import javax.naming.ConfigurationException;
+ 
++import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType;
++import org.apache.cloudstack.engine.subsystem.api.storage.DataTO;
++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.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.commons.lang.StringUtils;
+ import org.apache.log4j.Logger;
+ 
++import com.amazonaws.services.s3.model.S3ObjectSummary;
+ import com.cloud.agent.api.Answer;
+ import com.cloud.agent.api.CheckHealthAnswer;
+ import com.cloud.agent.api.CheckHealthCommand;
+ import com.cloud.agent.api.CleanupSnapshotBackupCommand;
+ import com.cloud.agent.api.Command;
+ import com.cloud.agent.api.ComputeChecksumCommand;
 -import com.cloud.agent.api.DeleteObjectFromSwiftCommand;
+ import com.cloud.agent.api.DeleteSnapshotBackupCommand;
+ import com.cloud.agent.api.DeleteSnapshotsDirCommand;
 -import com.cloud.agent.api.DeleteTemplateFromS3Command;
+ import com.cloud.agent.api.DownloadSnapshotFromS3Command;
 -import com.cloud.agent.api.DownloadTemplateFromS3ToSecondaryStorageCommand;
++import com.cloud.agent.api.DownloadSnapshotFromSwiftCommand;
++import com.cloud.agent.api.DownloadTemplateFromSwiftToSecondaryStorageCommand;
+ import com.cloud.agent.api.GetStorageStatsAnswer;
+ import com.cloud.agent.api.GetStorageStatsCommand;
+ import com.cloud.agent.api.PingCommand;
+ import com.cloud.agent.api.PingStorageCommand;
+ import com.cloud.agent.api.ReadyAnswer;
+ import com.cloud.agent.api.ReadyCommand;
+ import com.cloud.agent.api.SecStorageFirewallCfgCommand;
+ import com.cloud.agent.api.SecStorageFirewallCfgCommand.PortConfig;
+ import com.cloud.agent.api.SecStorageSetupAnswer;
+ import com.cloud.agent.api.SecStorageSetupCommand;
+ import com.cloud.agent.api.SecStorageSetupCommand.Certificates;
+ import com.cloud.agent.api.SecStorageVMSetupCommand;
+ import com.cloud.agent.api.StartupCommand;
+ import com.cloud.agent.api.StartupSecondaryStorageCommand;
+ import com.cloud.agent.api.UploadTemplateToS3FromSecondaryStorageCommand;
 -import com.cloud.agent.api.DownloadSnapshotFromSwiftCommand;
 -import com.cloud.agent.api.DownloadTemplateFromSwiftToSecondaryStorageCommand;
+ import com.cloud.agent.api.UploadTemplateToSwiftFromSecondaryStorageCommand;
+ import com.cloud.agent.api.storage.CreateEntityDownloadURLCommand;
+ import com.cloud.agent.api.storage.DeleteEntityDownloadURLCommand;
+ import com.cloud.agent.api.storage.DeleteTemplateCommand;
+ import com.cloud.agent.api.storage.DeleteVolumeCommand;
 -import com.cloud.agent.api.storage.DownloadCommand;
 -import com.cloud.agent.api.storage.DownloadProgressCommand;
+ import com.cloud.agent.api.storage.ListTemplateAnswer;
+ import com.cloud.agent.api.storage.ListTemplateCommand;
+ import com.cloud.agent.api.storage.ListVolumeAnswer;
+ import com.cloud.agent.api.storage.ListVolumeCommand;
+ import com.cloud.agent.api.storage.UploadCommand;
+ import com.cloud.agent.api.storage.ssCommand;
++import com.cloud.agent.api.to.DataStoreTO;
++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.template.TemplateInfo;
++import com.cloud.storage.template.Processor;
++import com.cloud.storage.template.Processor.FormatInfo;
+ import com.cloud.storage.template.TemplateLocation;
++import com.cloud.storage.template.TemplateProp;
++import com.cloud.storage.template.VhdProcessor;
+ import com.cloud.utils.NumbersUtil;
+ import com.cloud.utils.S3Utils;
+ import com.cloud.utils.S3Utils.FileNamingStrategy;
 -import com.cloud.utils.S3Utils.ObjectNamingStrategy;
+ import com.cloud.utils.exception.CloudRuntimeException;
+ import com.cloud.utils.net.NetUtils;
+ import com.cloud.utils.script.OutputInterpreter;
+ import com.cloud.utils.script.Script;
+ import com.cloud.vm.SecondaryStorageVm;
+ 
 -public class NfsSecondaryStorageResource extends ServerResourceBase implements
 -SecondaryStorageResource {
++public class NfsSecondaryStorageResource extends ServerResourceBase implements SecondaryStorageResource {
+ 
 -    private static final Logger s_logger = Logger
 -            .getLogger(NfsSecondaryStorageResource.class);
++    private static final Logger s_logger = Logger.getLogger(NfsSecondaryStorageResource.class);
+ 
+     private static final String TEMPLATE_ROOT_DIR = "template/tmpl";
+     private static final String SNAPSHOT_ROOT_DIR = "snapshots";
++    private static final String VOLUME_ROOT_DIR = "volumes";
+ 
+     int _timeout;
+ 
 -    String _instance;  
++    String _instance;
+     String _dc;
+     String _pod;
+     String _guid;
+     String _role;
+     Map<String, Object> _params;
 -    StorageLayer _storage;
++    protected StorageLayer _storage;
+     protected boolean _inSystemVM = false;
+     boolean _sslCopy = false;
+ 
 -    DownloadManager _dlMgr;
 -    UploadManager _upldMgr;
++    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>();
+     private String _parent = "/mnt/SecStorage";
+     final private String _tmpltDir = "/var/cloudstack/template";
+     final private String _tmpltpp = "template.properties";
++    private String createTemplateFromSnapshotXenScript;
++
+     @Override
+     public void disconnected() {
+     }
+ 
+     @Override
+     public Answer executeRequest(Command cmd) {
+         if (cmd instanceof DownloadProgressCommand) {
 -            return _dlMgr.handleDownloadCommand(this, (DownloadProgressCommand)cmd);
++            return _dlMgr.handleDownloadCommand(this, (DownloadProgressCommand) cmd);
+         } else if (cmd instanceof DownloadCommand) {
 -            return _dlMgr.handleDownloadCommand(this, (DownloadCommand)cmd);
 -        } else if (cmd instanceof UploadCommand) {        	
 -            return _upldMgr.handleUploadCommand(this, (UploadCommand)cmd);
 -        } else if (cmd instanceof CreateEntityDownloadURLCommand){
 -            return _upldMgr.handleCreateEntityURLCommand((CreateEntityDownloadURLCommand)cmd);
 -        } else if(cmd instanceof DeleteEntityDownloadURLCommand){
 -            return _upldMgr.handleDeleteEntityDownloadURLCommand((DeleteEntityDownloadURLCommand)cmd);
++            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);
++            return execute((GetStorageStatsCommand) cmd);
+         } else if (cmd instanceof CheckHealthCommand) {
 -            return new CheckHealthAnswer((CheckHealthCommand)cmd, true);
++            return new CheckHealthAnswer((CheckHealthCommand) cmd, true);
+         } else if (cmd instanceof DeleteTemplateCommand) {
+             return execute((DeleteTemplateCommand) cmd);
+         } else if (cmd instanceof DeleteVolumeCommand) {
+             return execute((DeleteVolumeCommand) cmd);
 -        }else if (cmd instanceof ReadyCommand) {
 -            return new ReadyAnswer((ReadyCommand)cmd);
 -        } else if (cmd instanceof SecStorageFirewallCfgCommand){
 -            return execute((SecStorageFirewallCfgCommand)cmd);
 -        } else if (cmd instanceof SecStorageVMSetupCommand){
 -            return execute((SecStorageVMSetupCommand)cmd);
 -        } else if (cmd instanceof SecStorageSetupCommand){
 -            return execute((SecStorageSetupCommand)cmd);
 -        } else if (cmd instanceof ComputeChecksumCommand){
 -            return execute((ComputeChecksumCommand)cmd);
 -        } else if (cmd instanceof ListTemplateCommand){
 -            return execute((ListTemplateCommand)cmd);
 -        } else if (cmd instanceof ListVolumeCommand){
 -            return execute((ListVolumeCommand)cmd);
 -        }else if (cmd instanceof DownloadSnapshotFromSwiftCommand){
++        } else if (cmd instanceof ReadyCommand) {
++            return new ReadyAnswer((ReadyCommand) cmd);
++        } else if (cmd instanceof SecStorageFirewallCfgCommand) {
++            return execute((SecStorageFirewallCfgCommand) cmd);
++        } else if (cmd instanceof SecStorageVMSetupCommand) {
++            return execute((SecStorageVMSetupCommand) cmd);
++        } else if (cmd instanceof SecStorageSetupCommand) {
++            return execute((SecStorageSetupCommand) cmd);
++        } else if (cmd instanceof ComputeChecksumCommand) {
++            return execute((ComputeChecksumCommand) cmd);
++        } else if (cmd instanceof ListTemplateCommand) {
++            return execute((ListTemplateCommand) cmd);
++        } else if (cmd instanceof ListVolumeCommand) {
++            return execute((ListVolumeCommand) cmd);
++        } else if (cmd instanceof DownloadSnapshotFromSwiftCommand) {
+             return execute((DownloadSnapshotFromSwiftCommand)cmd);
+         } else if (cmd instanceof DownloadSnapshotFromS3Command) {
+             return execute((DownloadSnapshotFromS3Command) cmd);
 -        } else if (cmd instanceof DeleteSnapshotBackupCommand){
 -            return execute((DeleteSnapshotBackupCommand)cmd);
 -        } else if (cmd instanceof DeleteSnapshotsDirCommand){
 -            return execute((DeleteSnapshotsDirCommand)cmd);
++        } else if (cmd instanceof DeleteSnapshotBackupCommand) {
++            return execute((DeleteSnapshotBackupCommand) cmd);
++        } else if (cmd instanceof DeleteSnapshotsDirCommand) {
++            return execute((DeleteSnapshotsDirCommand) cmd);
+         } else if (cmd instanceof DownloadTemplateFromSwiftToSecondaryStorageCommand) {
+             return execute((DownloadTemplateFromSwiftToSecondaryStorageCommand) cmd);
 -        } else if (cmd instanceof DownloadTemplateFromS3ToSecondaryStorageCommand) {
 -            return execute((DownloadTemplateFromS3ToSecondaryStorageCommand) cmd);
+         } else if (cmd instanceof UploadTemplateToSwiftFromSecondaryStorageCommand) {
+             return execute((UploadTemplateToSwiftFromSecondaryStorageCommand) cmd);
+         } else if (cmd instanceof UploadTemplateToS3FromSecondaryStorageCommand) {
+             return execute((UploadTemplateToS3FromSecondaryStorageCommand) cmd);
 -        } else if (cmd instanceof DeleteObjectFromSwiftCommand) {
 -            return execute((DeleteObjectFromSwiftCommand) cmd);
 -        } else if (cmd instanceof DeleteTemplateFromS3Command) {
 -            return execute((DeleteTemplateFromS3Command) cmd);
 -        } else if (cmd instanceof CleanupSnapshotBackupCommand){
 -            return execute((CleanupSnapshotBackupCommand)cmd);
++        } else if (cmd instanceof CleanupSnapshotBackupCommand) {
++            return execute((CleanupSnapshotBackupCommand) cmd);
++        } else if (cmd instanceof CopyCommand) {
++            return execute((CopyCommand) cmd);
+         } else {
+             return Answer.createUnsupportedCommandAnswer(cmd);
+         }
+     }
+ 
 -    @SuppressWarnings("unchecked")
 -    private String determineS3TemplateDirectory(final Long accountId,
 -            final Long templateId) {
 -        return join(asList(TEMPLATE_ROOT_DIR, accountId, templateId),
 -                S3Utils.SEPARATOR);
 -    }
 -
 -    @SuppressWarnings("unchecked")
 -    private String determineStorageTemplatePath(final String storagePath,
 -            final Long accountId, final Long templateId) {
 -        return join(
 -                asList(getRootDir(storagePath), TEMPLATE_ROOT_DIR, accountId,
 -                        templateId), File.separator);
 -    }
 -
 -    private Answer execute(
 -            final DownloadTemplateFromS3ToSecondaryStorageCommand cmd) {
 -
 -        final S3TO s3 = cmd.getS3();
 -        final String storagePath = cmd.getStoragePath();
 -        final Long accountId = cmd.getAccountId();
 -        final Long templateId = cmd.getTemplateId();
++    protected Answer copyFromS3ToNfs(CopyCommand cmd, DataTO srcData, S3TO s3, DataTO destData, NfsTO destImageStore) {
++        final String storagePath = destImageStore.getUrl();
++        final String destPath = destData.getPath();
+ 
+         try {
+ 
 -            final File downloadDirectory = _storage
 -                    .getFile(determineStorageTemplatePath(storagePath,
 -                            accountId, templateId));
++            final File downloadDirectory = _storage.getFile(determineStorageTemplatePath(storagePath, destPath));
+             downloadDirectory.mkdirs();
+ 
+             if (!downloadDirectory.exists()) {
 -                final String errMsg = format(
 -                        "Unable to create directory "
 -                                + "download directory %1$s for download of template id "
 -                                + "%2$s from S3.", downloadDirectory.getName(),
 -                                templateId);
++                final String errMsg = format("Unable to create directory " + "download directory %1$s for download from S3.",
++                        downloadDirectory.getName());
+                 s_logger.error(errMsg);
 -                return new Answer(cmd, false, errMsg);
++                return new CopyCmdAnswer(errMsg);
+             }
+ 
 -            getDirectory(s3, s3.getBucketName(),
 -                    determineS3TemplateDirectory(accountId, templateId),
 -                    downloadDirectory, new FileNamingStrategy() {
++            List<File> files = getDirectory(s3, s3.getBucketName(), destPath, downloadDirectory, new FileNamingStrategy() {
+                 @Override
+                 public String determineFileName(final String key) {
+                     return substringAfterLast(key, S3Utils.SEPARATOR);
+                 }
+             });
+ 
 -            return new Answer(cmd, true, format("Successfully downloaded "
 -                    + "template id %1$s from S3 to directory %2$s", templateId,
 -                    downloadDirectory.getName()));
++            // find out template name
++            File destFile = null;
++            for (File f : files) {
++                if (!f.getName().endsWith(".properties")) {
++                    destFile = f;
++                    break;
++                }
++            }
+ 
++            if (destFile == null) {
++                return new CopyCmdAnswer("Can't find template");
++            }
++
++            DataTO newDestTO = null;
++
++            if (destData.getObjectType() == DataObjectType.TEMPLATE) {
++                TemplateObjectTO newTemplTO = new TemplateObjectTO();
++                newTemplTO.setPath(destPath + File.separator + destFile.getName());
++                newTemplTO.setName(destFile.getName());
++                newDestTO = newTemplTO;
++            } else {
++                return new CopyCmdAnswer("not implemented yet");
++            }
++
++            return new CopyCmdAnswer(newDestTO);
+         } catch (Exception e) {
+ 
 -            final String errMsg = format("Failed to upload template id %1$s "
 -                    + "due to $2%s", templateId, e.getMessage());
++            final String errMsg = format("Failed to download" + "due to $2%s", e.getMessage());
+             s_logger.error(errMsg, e);
 -            return new Answer(cmd, false, errMsg);
++            return new CopyCmdAnswer(errMsg);
++        }
++    }
++
++
++    protected Answer copySnapshotToTemplateFromNfsToNfsXenserver(CopyCommand cmd, SnapshotObjectTO srcData, NfsTO srcDataStore, TemplateObjectTO destData, NfsTO destDataStore) {
++        String srcMountPoint = this.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 = this.getRootDir(destDataStore.getUrl());
++        String destPath = destMountPoint + File.separator + destData.getPath();
++
++        String errMsg = null;
++        try {
++            this._storage.mkdir(destPath);
++
++            String templateUuid = UUID.randomUUID().toString();
++            String templateName = templateUuid + ".vhd";
++            Script command = new Script(this.createTemplateFromSnapshotXenScript, cmd.getWait(), s_logger);
++            command.add("-p", snapshotPath);
++            command.add("-s", snapshotName);
++            command.add("-n", templateName);
++            command.add("-t", destPath);
++            command.execute();
++
++            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, templateName);
++            loc.addFormat(info);
++            loc.save();
++
++            TemplateObjectTO newTemplate = new TemplateObjectTO();
++            newTemplate.setPath(destData.getPath() + File.separator + templateName);
++            newTemplate.setFormat(ImageFormat.VHD);
++            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);
+         }
+ 
++        return new CopyCmdAnswer("");
++    }
++
++    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) {
++            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);
++            }
++
++        }
++        return new CopyCmdAnswer("");
++    }
++
++    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 (srcDataStore instanceof S3TO && destDataStore instanceof NfsTO && destDataStore.getRole() == DataStoreRole.ImageCache){
++            S3TO s3 = (S3TO)srcDataStore;
++            NfsTO destImageStore = (NfsTO)destDataStore;
++            return this.copyFromS3ToNfs(cmd, srcData, s3, destData, destImageStore);
++        }
++
++
++        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);
++    }
++
++    @SuppressWarnings("unchecked")
++    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);
++    }
++
++    @SuppressWarnings("unchecked")
++    protected Long determineS3VolumeIdFromKey(String key) {
++        return Long.parseLong(StringUtils.substringAfterLast(StringUtils.substringBeforeLast(key, S3Utils.SEPARATOR), S3Utils.SEPARATOR));
++    }
++
++    @SuppressWarnings("unchecked")
++    private String determineStorageTemplatePath(final String storagePath, String dataPath) {
++        return join(asList(getRootDir(storagePath), dataPath), File.separator);
+     }
+ 
+     private Answer execute(DownloadTemplateFromSwiftToSecondaryStorageCommand cmd) {
+         SwiftTO swift = cmd.getSwift();
+         String secondaryStorageUrl = cmd.getSecondaryStorageUrl();
+         Long accountId = cmd.getAccountId();
+         Long templateId = cmd.getTemplateId();
+         String path = cmd.getPath();
+         String errMsg;
+         String lDir = null;
+         try {
+             String parent = getRootDir(secondaryStorageUrl);
+             lDir = parent + "/template/tmpl/" + accountId.toString() + "/" + templateId.toString();
+             String result = createLocalDir(lDir);
+             if (result != null) {
+                 errMsg = "downloadTemplateFromSwiftToSecondaryStorageCommand failed due to Create local directory failed";
+                 s_logger.warn(errMsg);
+                 throw new InternalErrorException(errMsg);
+             }
+             String lPath = lDir + "/" + path;
+             result = swiftDownload(swift, "T-" + templateId.toString(), path, lPath);
+             if (result != null) {
+                 errMsg = "failed to download template " + path + " from Swift to secondary storage " + lPath + " , err=" + result;
+                 s_logger.warn(errMsg);
+                 throw new CloudRuntimeException(errMsg);
+             }
+             path = "template.properties";
+             lPath = lDir + "/" + path;
+             result = swiftDownload(swift, "T-" + templateId.toString(), path, lPath);
+             if (result != null) {
+                 errMsg = "failed to download template " + path + " from Swift to secondary storage " + lPath + " , err=" + result;
+                 s_logger.warn(errMsg);
+                 throw new CloudRuntimeException(errMsg);
+             }
+             return new Answer(cmd, true, "success");
+         } catch (Exception e) {
+             if (lDir != null) {
+                 deleteLocalDir(lDir);
+             }
+             errMsg = cmd + " Command failed due to " + e.toString();
+             s_logger.warn(errMsg, e);
+             return new Answer(cmd, false, errMsg);
+         }
+     }
+ 
++    private Answer execute(DownloadCommand cmd) {
++        DataStoreTO dstore = cmd.getDataStore();
++        if (dstore instanceof NfsTO || dstore instanceof S3TO ) {
++            return _dlMgr.handleDownloadCommand(this, cmd);
++        }
++        /*
++        else if (dstore instanceof S3TO) {
++            // TODO: start download job to handle this
++            // TODO: how to handle download progress for S3
++            S3TO s3 = (S3TO) cmd.getDataStore();
++            String url = cmd.getUrl();
++            String user = null;
++            String password = null;
++            if (cmd.getAuth() != null) {
++                user = cmd.getAuth().getUserName();
++                password = new String(cmd.getAuth().getPassword());
++            }
++            // get input stream from the given url
++            InputStream in = UriUtils.getInputStreamFromUrl(url, user, password);
++            URI uri;
++            URL urlObj;
++            try {
++                uri = new URI(url);
++                urlObj = new URL(url);
++            } catch (URISyntaxException e) {
++                throw new CloudRuntimeException("URI is incorrect: " + url);
++            } catch (MalformedURLException e) {
++                throw new CloudRuntimeException("URL is incorrect: " + url);
++            }
++
++            final String bucket = s3.getBucketName();
++            String path = null;
++            if (cmd.getResourceType() == ResourceType.TEMPLATE) {
++                // convention is no / in the end for install path based on
++                // S3Utils implementation.
++                // template key is
++                // TEMPLATE_ROOT_DIR/account_id/template_id/template_name, by
++                // adding template_name in the key, I can avoid generating a
++                // template.properties file
++                // for listTemplateCommand.
++                path = determineS3TemplateDirectory(cmd.getAccountId(), cmd.getResourceId(), cmd.getName());
++            } else {
++                path = determineS3VolumeDirectory(cmd.getAccountId(), cmd.getResourceId());
++            }
++
++            String key = join(asList(path, urlObj.getFile()), S3Utils.SEPARATOR);
++            S3Utils.putObject(s3, in, bucket, key);
++            List<S3ObjectSummary> s3Obj = S3Utils.getDirectory(s3, bucket, path);
++            if (s3Obj == null || s3Obj.size() == 0) {
++                return new Answer(cmd, false, "Failed to download to S3 bucket: " + bucket + " with key: " + key);
++            } else {
++                return new DownloadAnswer(null, 100, null, Status.DOWNLOADED, path, path, s3Obj.get(0).getSize(), s3Obj.get(0).getSize(), s3Obj
++                        .get(0).getETag());
++            }
++        } */
++        else if (dstore instanceof SwiftTO) {
++            // TODO: need to move code from
++            // execute(uploadTemplateToSwiftFromSecondaryStorageCommand) here,
++            // but we need to handle
++            // source is url, most likely we need to modify our existing
++            // swiftUpload python script.
++            return new Answer(cmd, false, "Swift is not currently support DownloadCommand");
++        } else {
++            return new Answer(cmd, false, "Unsupported image data store: " + dstore);
++        }
++
++    }
++
+     private Answer execute(UploadTemplateToSwiftFromSecondaryStorageCommand cmd) {
+         SwiftTO swift = cmd.getSwift();
+         String secondaryStorageUrl = cmd.getSecondaryStorageUrl();
+         Long accountId = cmd.getAccountId();
+         Long templateId = cmd.getTemplateId();
+         try {
+             String parent = getRootDir(secondaryStorageUrl);
+             String lPath = parent + "/template/tmpl/" + accountId.toString() + "/" + templateId.toString();
+             if (!_storage.isFile(lPath + "/template.properties")) {
+                 String errMsg = cmd + " Command failed due to template doesn't exist ";
+                 s_logger.debug(errMsg);
+                 return new Answer(cmd, false, errMsg);
+             }
+             String result = swiftUpload(swift, "T-" + templateId.toString(), lPath, "*");
+             if (result != null) {
+                 String errMsg = "failed to upload template from secondary storage " + lPath + " to swift  , err=" + result;
+                 s_logger.debug(errMsg);
+                 return new Answer(cmd, false, errMsg);
+             }
+             return new Answer(cmd, true, "success");
+         } catch (Exception e) {
+             String errMsg = cmd + " Command failed due to " + e.toString();
+             s_logger.warn(errMsg, e);
+             return new Answer(cmd, false, errMsg);
+         }
+     }
+ 
+     private Answer execute(UploadTemplateToS3FromSecondaryStorageCommand cmd) {
++        /*
++                final S3TO s3 = cmd.getS3();
++                final Long accountId = cmd.getAccountId();
++                final Long templateId = cmd.getTemplateId();
+ 
++                try {
+         final S3TO s3 = cmd.getS3();
+         final Long accountId = cmd.getAccountId();
+         final Long templateId = cmd.getTemplateId();
+ 
+         try {
+ 
+             final String templatePath = determineStorageTemplatePath(
+                     cmd.getStoragePath(), accountId, templateId);
+ 
+             if (s_logger.isDebugEnabled()) {
+                 s_logger.debug("Found template id " + templateId
+                         + " account id " + accountId + " from directory "
+                         + templatePath + " to upload to S3.");
+             }
+ 
+             if (!_storage.isDirectory(templatePath)) {
+                 final String errMsg = format("S3 Sync Failure: Directory %1$s"
+                         + "for template id %2$s does not exist.", templatePath,
+                         templateId);
+                 s_logger.error(errMsg);
+                 return new Answer(cmd, false, errMsg);
+             }
+ 
+             if (!_storage.isFile(templatePath + "/template.properties")) {
+                 final String errMsg = format("S3 Sync Failure: Template id "
+                         + "%1$s does not exist on the file system.",
+                         templatePath);
+                 s_logger.error(errMsg);
+                 return new Answer(cmd, false, errMsg);
+             }
+ 
+             if (s_logger.isDebugEnabled()) {
+                 s_logger.debug(format(
+                         "Pushing template id %1$s from %2$s to S3...",
+                         templateId, templatePath));
+             }
+ 
+             final String bucket = s3.getBucketName();
+             putDirectory(s3, bucket, _storage.getFile(templatePath),
+                     new FilenameFilter() {
+                 @Override
+                 public boolean accept(final File directory,
+                         final String fileName) {
+                     File fileToUpload = new File(directory.getAbsolutePath() + "/" + fileName);
+                     return !fileName.startsWith(".") && !fileToUpload.isDirectory();
+                 }
+             }, new ObjectNamingStrategy() {
+                 @Override
+                 public String determineKey(final File file) {
+                     s_logger.debug(String
+                             .format("Determining key using account id %1$s and template id %2$s",
+                                     accountId, templateId));
+                     return join(
+                             asList(determineS3TemplateDirectory(
+                                     accountId, templateId), file
+                                     .getName()), S3Utils.SEPARATOR);
+                 }
+             });
+ 
+             return new Answer(
+                     cmd,
+                     true,
+                     format("Uploaded the contents of directory %1$s for template id %2$s to S3 bucket %3$s",
+                             templatePath, templateId, bucket));
+ 
+         } catch (Exception e) {
+ 
+             final String errMsg = format("Failed to upload template id %1$s",
+                     templateId);
+             s_logger.error(errMsg, e);
+             return new Answer(cmd, false, errMsg);
 -
 -        }
 -
 -    }
 -
 -    private Answer execute(DeleteObjectFromSwiftCommand cmd) {
 -        SwiftTO swift = cmd.getSwift();
 -        String container = cmd.getContainer();
 -        String object = cmd.getObject();
 -        if (object == null) {
 -            object = "";
 -        }
 -        try {
 -            String result = swiftDelete(swift, container, object);
 -            if (result != null) {
 -                String errMsg = "failed to delete object " + container + "/" + object + " , err=" + result;
 -                s_logger.warn(errMsg);
 -                return new Answer(cmd, false, errMsg);
 -            }
 -            return new Answer(cmd, true, "success");
 -        } catch (Exception e) {
 -            String errMsg = cmd + " Command failed due to " + e.toString();
 -            s_logger.warn(errMsg, e);
 -            return new Answer(cmd, false, errMsg);
 -        }
 -
 -    }
 -
 -    private Answer execute(final DeleteTemplateFromS3Command cmd) {
 -
 -        final S3TO s3 = cmd.getS3();
 -        final Long accountId = cmd.getAccountId();
 -        final Long templateId = cmd.getTemplateId();
 -
 -        if (accountId == null || (accountId != null && accountId <= 0)) {
 -            final String errorMessage = "No account id specified for S3 template deletion.";
 -            s_logger.error(errorMessage);
 -            return new Answer(cmd, false, errorMessage);
 -        }
 -
 -        if (templateId == null || (templateId != null && templateId <= 0)) {
 -            final String errorMessage = "No template id specified for S3 template deletion.";
 -            s_logger.error(errorMessage);
 -            return new Answer(cmd, false, errorMessage);
 -        }
 -
 -        if (s3 == null) {
 -            final String errorMessge = "No S3 client options provided";
 -            s_logger.error(errorMessge);
 -            return new Answer(cmd, false, errorMessge);
 -        }
 -
 -        final String bucket = s3.getBucketName();
 -        try {
 -            deleteDirectory(s3, bucket,
 -                    determineS3TemplateDirectory(templateId, accountId));
 -            return new Answer(cmd, true, String.format(
 -                    "Deleted template %1%s from bucket %2$s.", templateId,
 -                    bucket));
 -        } catch (Exception e) {
 -            final String errorMessage = String
 -                    .format("Failed to delete templaet id %1$s from bucket %2$s due to the following error: %3$s",
 -                            templateId, bucket, e.getMessage());
 -            s_logger.error(errorMessage, e);
 -            return new Answer(cmd, false, errorMessage);
 -        }
 -
++        */
++        return new Answer(cmd, false, "not supported ");
+     }
+ 
+     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);
++        command.add("/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + swift.getAccount()
++                + ":" + swift.getUserName() + " -K " + swift.getKey() + " download " + container + " " + rfilename + " -o " + lFullPath);
+         OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
+         String result = command.execute(parser);
+         if (result != null) {
+             String errMsg = "swiftDownload failed  err=" + result;
+             s_logger.warn(errMsg);
+             return errMsg;
+         }
+         if (parser.getLines() != null) {
+             String[] lines = parser.getLines().split("\\n");
+             for (String line : lines) {
+                 if (line.contains("Errno") || line.contains("failed")) {
+                     String errMsg = "swiftDownload failed , err=" + lines.toString();
+                     s_logger.warn(errMsg);
+                     return errMsg;
+                 }
+             }
+         }
+         return null;
+ 
+     }
+ 
+     String swiftDownloadContainer(SwiftTO swift, String container, String ldir) {
+         Script command = new Script("/bin/bash", s_logger);
+         command.add("-c");
 -        command.add("cd " + ldir + ";/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + swift.getAccount() + ":" + swift.getUserName() + " -K "
 -                + swift.getKey() + " download " + container);
++        command.add("cd " + ldir + ";/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U "
++                + swift.getAccount() + ":" + swift.getUserName() + " -K " + swift.getKey() + " download " + container);
+         OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
+         String result = command.execute(parser);
+         if (result != null) {
+             String errMsg = "swiftDownloadContainer failed  err=" + result;
+             s_logger.warn(errMsg);
+             return errMsg;
+         }
+         if (parser.getLines() != null) {
+             String[] lines = parser.getLines().split("\\n");
+             for (String line : lines) {
+                 if (line.contains("Errno") || line.contains("failed")) {
+                     String errMsg = "swiftDownloadContainer failed , err=" + lines.toString();
+                     s_logger.warn(errMsg);
+                     return errMsg;
+                 }
+             }
+         }
+         return null;
+ 
+     }
+ 
+     String swiftUpload(SwiftTO swift, String container, String lDir, String lFilename) {
+         long SWIFT_MAX_SIZE = 5L * 1024L * 1024L * 1024L;
+         List<String> files = new ArrayList<String>();
+         if (lFilename.equals("*")) {
+             File dir = new File(lDir);
+             for (String file : dir.list()) {
+                 if (file.startsWith(".")) {
+                     continue;
+                 }
+                 files.add(file);
+             }
+         } else {
+             files.add(lFilename);
+         }
+ 
+         for (String file : files) {
+             File f = new File(lDir + "/" + file);
+             long size = f.length();
+             Script command = new Script("/bin/bash", s_logger);
+             command.add("-c");
+             if (size <= SWIFT_MAX_SIZE) {
 -                command.add("cd " + lDir + ";/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + swift.getAccount() + ":" + swift.getUserName()
 -                        + " -K " + swift.getKey() + " upload " + container + " " + file);
++                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);
++                command.add("cd " + lDir + ";/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U "
++                        + swift.getAccount() + ":" + swift.getUserName() + " -K " + swift.getKey() + " upload -S " + SWIFT_MAX_SIZE + " " + container
++                        + " " + file);
+             }
+             OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
+             String result = command.execute(parser);
+             if (result != null) {
+                 String errMsg = "swiftUpload failed , err=" + result;
+                 s_logger.warn(errMsg);
+                 return errMsg;
+             }
+             if (parser.getLines() != null) {
+                 String[] lines = parser.getLines().split("\\n");
+                 for (String line : lines) {
+                     if (line.contains("Errno") || line.contains("failed")) {
+                         String errMsg = "swiftUpload failed , err=" + lines.toString();
+                         s_logger.warn(errMsg);
+                         return errMsg;
+                     }
+                 }
+             }
+         }
+ 
+         return null;
+     }
+ 
+     String[] swiftList(SwiftTO swift, String container, String rFilename) {
+         Script command = new Script("/bin/bash", s_logger);
+         command.add("-c");
 -        command.add("/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + swift.getAccount() + ":" + swift.getUserName() + " -K "
 -                + swift.getKey() + " list " + container + " " + rFilename);
++        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);
++        command.add("/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + swift.getAccount()
++                + ":" + swift.getUserName() + " -K " + swift.getKey() + " delete " + container + " " + object);
+         OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
+         String result = command.execute(parser);
+         if (result != null) {
+             String errMsg = "swiftDelete failed , err=" + result;
+             s_logger.warn(errMsg);
+             return errMsg;
+         }
+         if (parser.getLines() != null) {
+             String[] lines = parser.getLines().split("\\n");
+             for (String line : lines) {
+                 if (line.contains("Errno") || line.contains("failed")) {
+                     String errMsg = "swiftDelete failed , err=" + lines.toString();
+                     s_logger.warn(errMsg);
+                     return errMsg;
+                 }
+             }
+         }
+         return null;
+     }
+ 
 -
 -    public Answer execute(DeleteSnapshotsDirCommand cmd){
++    // TODO: this DeleteSnapshotsDirCommand should be removed after
++    // SnapshotManager refactor, this is used to delete those snapshot directory
++    // in the cachestorage. This should be able to be done through
++    // DeleteSnapshotBackupCommand with deleteAll flag set to true.
++    public Answer execute(DeleteSnapshotsDirCommand cmd) {
+         String secondaryStorageUrl = cmd.getSecondaryStorageUrl();
+         Long accountId = cmd.getAccountId();
+         Long volumeId = cmd.getVolumeId();
+         try {
+             String parent = getRootDir(secondaryStorageUrl);
+             String lPath = parent + "/snapshots/" + String.valueOf(accountId) + "/" + String.valueOf(volumeId) + "/*";
+             String result = deleteLocalFile(lPath);
+             if (result != null) {
+                 String errMsg = "failed to delete all snapshots " + lPath + " , err=" + result;
+                 s_logger.warn(errMsg);
+                 return new Answer(cmd, false, errMsg);
+             }
+             return new Answer(cmd, true, "success");
+         } catch (Exception e) {
+             String errMsg = cmd + " Command failed due to " + e.toString();
+             s_logger.warn(errMsg, e);
+             return new Answer(cmd, false, errMsg);
+         }
+     }
+ 
+     public Answer execute(final DownloadSnapshotFromS3Command cmd) {
+ 
+         final S3TO s3 = cmd.getS3();
+         final String secondaryStorageUrl = cmd.getSecondaryStorageUrl();
+         final Long accountId = cmd.getAccountId();
+         final Long volumeId = cmd.getVolumeId();
+ 
+         try {
+ 
 -            executeWithNoWaitLock(determineSnapshotLockId(accountId, volumeId),
 -                    new Callable<Void>() {
++            executeWithNoWaitLock(determineSnapshotLockId(accountId, volumeId), new Callable<Void>() {
+ 
+                 @Override
+                 public Void call() throws Exception {
+ 
 -                    final String directoryName = determineSnapshotLocalDirectory(
 -                            secondaryStorageUrl, accountId, volumeId);
++                    final String directoryName = determineSnapshotLocalDirectory(secondaryStorageUrl, accountId, volumeId);
+ 
+                     String result = createLocalDir(directoryName);
+                     if (result != null) {
 -                        throw new InternalErrorException(
 -                                format("Failed to create directory %1$s during S3 snapshot download.",
 -                                        directoryName));
++                        throw new InternalErrorException(format("Failed to create directory %1$s during S3 snapshot download.", directoryName));
+                     }
+ 
 -                    final String snapshotFileName = determineSnapshotBackupFilename(cmd
 -                            .getSnapshotUuid());
 -                    final String key = determineSnapshotS3Key(
 -                            accountId, volumeId, snapshotFileName);
 -                    final File targetFile = S3Utils.getFile(s3,
 -                            s3.getBucketName(), key,
 -                            _storage.getFile(directoryName),
 -                            new FileNamingStrategy() {
++                    final String snapshotFileName = determineSnapshotBackupFilename(cmd.getSnapshotUuid());
++                    final String key = determineSnapshotS3Key(accountId, volumeId, snapshotFileName);
++                    final File targetFile = S3Utils.getFile(s3, s3.getBucketName(), key, _storage.getFile(directoryName), new FileNamingStrategy() {
+ 
+                         @Override
 -                        public String determineFileName(
 -                                String key) {
++                        public String determineFileName(String key) {
+                             return snapshotFileName;
+                         }
+ 
+                     });
+ 
+                     if (cmd.getParent() != null) {
+ 
 -                        final String parentPath = join(
 -                                File.pathSeparator, directoryName,
 -                                determineSnapshotBackupFilename(cmd
 -                                        .getParent()));
 -                        result = setVhdParent(
 -                                targetFile.getAbsolutePath(),
 -                                parentPath);
++                        final String parentPath = join(File.pathSeparator, directoryName, determineSnapshotBackupFilename(cmd.getParent()));
++                        result = setVhdParent(targetFile.getAbsolutePath(), parentPath);
+                         if (result != null) {
 -                            throw new InternalErrorException(
 -                                    format("Failed to set the parent for backup %1$s to %2$s due to %3$s.",
 -                                            targetFile
 -                                            .getAbsolutePath(),
 -                                            parentPath, result));
++                            throw new InternalErrorException(format("Failed to set the parent for backup %1$s to %2$s due to %3$s.",
++                                    targetFile.getAbsolutePath(), parentPath, result));
+                         }
+ 
+                     }
+ 
+                     return null;
+ 
+                 }
+ 
+             });
+ 
 -            return new Answer(
 -                    cmd,
 -                    true,
 -                    format("Succesfully retrieved volume id %1$s for account id %2$s to %3$s from S3.",
 -                            volumeId, accountId, secondaryStorageUrl));
++            return new Answer(cmd, true, format("Succesfully retrieved volume id %1$s for account id %2$s to %3$s from S3.", volumeId, accountId,
++                    secondaryStorageUrl));
+ 
+         } catch (Exception e) {
 -            final String errMsg = format(
 -                    "Failed to retrieve volume id %1$s for account id %2$s to %3$s from S3 due to exception %4$s",
 -                    volumeId, accountId, secondaryStorageUrl, e.getMessage());
++            final String errMsg = format("Failed to retrieve volume id %1$s for account id %2$s to %3$s from S3 due to exception %4$s", volumeId,
++                    accountId, secondaryStorageUrl, e.getMessage());
+             s_logger.error(errMsg);
+             return new Answer(cmd, false, errMsg);
+         }
+ 
+     }
+ 
 -    private String determineSnapshotS3Directory(final Long accountId,
 -            final Long volumeId) {
++    private String determineSnapshotS3Directory(final Long accountId, final Long volumeId) {
+         return join(S3Utils.SEPARATOR, SNAPSHOT_ROOT_DIR, accountId, volumeId);
+     }
+ 
 -    private String determineSnapshotS3Key(final Long accountId,
 -            final Long volumeId, final String snapshotFileName) {
++    private String determineSnapshotS3Key(final Long accountId, final Long volumeId, final String snapshotFileName) {
+ 
 -        final String directoryName = determineSnapshotS3Directory(accountId,
 -                volumeId);
++        final String directoryName = determineSnapshotS3Directory(accountId, volumeId);
+         return join(S3Utils.SEPARATOR, directoryName, snapshotFileName);
+ 
+     }
+ 
 -    private String determineSnapshotLocalDirectory(
 -            final String secondaryStorageUrl, final Long accountId,
 -            final Long volumeId) {
 -        return join(File.pathSeparator, getRootDir(secondaryStorageUrl),
 -                SNAPSHOT_ROOT_DIR, accountId, volumeId);
++    private String determineSnapshotLocalDirectory(final String secondaryStorageUrl, final Long accountId, final Long volumeId) {
++        return join(File.pathSeparator, getRootDir(secondaryStorageUrl), SNAPSHOT_ROOT_DIR, accountId, volumeId);
+     }
+ 
++
+     public Answer execute(DownloadSnapshotFromSwiftCommand cmd){
+         SwiftTO swift = cmd.getSwift();
+         String secondaryStorageUrl = cmd.getSecondaryStorageUrl();
+         Long accountId = cmd.getAccountId();
+         Long volumeId = cmd.getVolumeId();
+         String rFilename = cmd.getSnapshotUuid();
+         String sParent = cmd.getParent();
+         String errMsg = "";
+         try {
+             String parent = getRootDir(secondaryStorageUrl);
+             String lPath = parent + "/snapshots/" + String.valueOf(accountId) + "/" + String.valueOf(volumeId);
+ 
+             String result = createLocalDir(lPath);
 -            if ( result != null ) {
++            if (result != null) {
+                 errMsg = "downloadSnapshotFromSwiftCommand failed due to Create local path failed";
+                 s_logger.warn(errMsg);
+                 throw new InternalErrorException(errMsg);
+             }
+             String lFilename = rFilename;
 -            if ( rFilename.startsWith("VHD-") ) {
++            if (rFilename.startsWith("VHD-")) {
+                 lFilename = rFilename.replace("VHD-", "") + ".vhd";
+             }
+             String lFullPath = lPath + "/" + lFilename;
+             result = swiftDownload(swift, "S-" + volumeId.toString(), rFilename, lFullPath);
+             if (result != null) {
+                 return new Answer(cmd, false, result);
+             }
+             if (sParent != null) {
+                 if (sParent.startsWith("VHD-") || sParent.endsWith(".vhd")) {
+                     String pFilename = sParent;
+                     if (sParent.startsWith("VHD-")) {
+                         pFilename = pFilename.replace("VHD-", "") + ".vhd";
+                     }
+                     String pFullPath = lPath + "/" + pFilename;
+                     result = setVhdParent(lFullPath, pFullPath);
+                     if (result != null) {
+                         return new Answer(cmd, false, result);
+                     }
+                 }
+             }
+ 
+             return new Answer(cmd, true, "success");
+         } catch (Exception e) {
+             String msg = cmd + " Command failed due to " + e.toString();
+             s_logger.warn(msg, e);
+             throw new CloudRuntimeException(msg);
+         }
+     }
+ 
+     private Answer execute(ComputeChecksumCommand cmd) {
+ 
+         String relativeTemplatePath = cmd.getTemplatePath();
+         String parent = getRootDir(cmd);
+ 
+         if (relativeTemplatePath.startsWith(File.separator)) {
+             relativeTemplatePath = relativeTemplatePath.substring(1);
+         }
+ 
+         if (!parent.endsWith(File.separator)) {
+             parent += File.separator;
+         }
+         String absoluteTemplatePath = parent + relativeTemplatePath;
+         MessageDigest digest;
+         String checksum = null;
 -        File f = new File(absoluteTemplatePath);   
++        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 );   
++        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 = 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 );   
++            if (s_logger.isDebugEnabled()) {
++                s_logger.debug("Successfully calculated checksum for file " + absoluteTemplatePath + " - " + checksum);
+             }
+ 
 -        }catch(IOException e) {
++        } 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 {
++        } catch (NoSuchAlgorithmException e) {
++            return new Answer(cmd, false, checksum);
++        } finally {
+             try {
 -                if(is != null)
++                if (is != null)
+                     is.close();
+             } catch (IOException e) {
 -                if(s_logger.isDebugEnabled()){
 -                    s_logger.debug("Could not close the file " +absoluteTemplatePath);   
++                if (s_logger.isDebugEnabled()) {
++                    s_logger.debug("Could not close the file " + absoluteTemplatePath);
+                 }
 -                return new Answer(cmd, false, checksum);   
 -            }                        
++                return new Answer(cmd, false, checksum);
++            }
+         }
+ 
+         return new Answer(cmd, true, checksum);
+     }
+ 
+     private void configCerts(Certificates certs) {
+         if (certs == null) {
+             configureSSL();
+         } else {
+             String prvKey = certs.getPrivKey();
+             String pubCert = certs.getPrivCert();
+             String certChain = certs.getCertChain();
+ 
+             try {
+                 File prvKeyFile = File.createTempFile("prvkey", null);
+                 String prvkeyPath = prvKeyFile.getAbsolutePath();
+                 BufferedWriter out = new BufferedWriter(new FileWriter(prvKeyFile));
+                 out.write(prvKey);
+                 out.close();
+ 
+                 File pubCertFile = File.createTempFile("pubcert", null);
+                 String pubCertFilePath = pubCertFile.getAbsolutePath();
+ 
+                 out = new BufferedWriter(new FileWriter(pubCertFile));
+                 out.write(pubCert);
+                 out.close();
+ 
+                 configureSSL(prvkeyPath, pubCertFilePath, null);
+ 
+                 prvKeyFile.delete();
+                 pubCertFile.delete();
+ 
+             } catch (IOException e) {
+                 s_logger.debug("Failed to config ssl: " + e.toString());
+             }
+         }
+     }
+ 
+     private Answer execute(SecStorageSetupCommand cmd) {
 -        if (!_inSystemVM){
++        if (!_inSystemVM) {
+             return new Answer(cmd, true, null);
+         }
 -        String secUrl = cmd.getSecUrl();
 -        try {
 -            URI uri = new URI(secUrl);
 -            String nfsHost = uri.getHost();
++        DataStoreTO dStore = cmd.getDataStore();
++        if (dStore instanceof NfsTO) {
++            String secUrl = cmd.getSecUrl();
++            try {
++                URI uri = new URI(secUrl);
++                String nfsHost = uri.getHost();
+ 
 -            InetAddress nfsHostAddr = InetAddress.getByName(nfsHost);
 -            String nfsHostIp = nfsHostAddr.getHostAddress();
++                InetAddress nfsHostAddr = InetAddress.getByName(nfsHost);
++                String nfsHostIp = nfsHostAddr.getHostAddress();
+ 
 -            addRouteToInternalIpOrCidr(_storageGateway, _storageIp, _storageNetmask, nfsHostIp);
 -            String nfsPath = nfsHostIp + ":" + uri.getPath();
 -            String dir = UUID.nameUUIDFromBytes(nfsPath.getBytes()).toString();
 -            String root = _parent + "/" + dir;
 -            mount(root, nfsPath);
++                addRouteToInternalIpOrCidr(_storageGateway, _storageIp, _storageNetmask, nfsHostIp);
++                String nfsPath = nfsHostIp + ":" + uri.getPath();
++                String dir = UUID.nameUUIDFromBytes(nfsPath.getBytes()).toString();
++                String root = _parent + "/" + dir;
++                mount(root, nfsPath);
+ 
 -            configCerts(cmd.getCerts());
++                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);
++                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);
+         }
+     }
+ 
 -    private String deleteSnapshotBackupFromLocalFileSystem(
 -            final String secondaryStorageUrl, final Long accountId,
 -            final Long volumeId, final String name, final Boolean deleteAllFlag) {
++    private String deleteSnapshotBackupFromLocalFileSystem(final String secondaryStorageUrl, final Long accountId, final Long volumeId,
++            final String name, final Boolean deleteAllFlag) {
+ 
 -        final String lPath = determineSnapshotLocalDirectory(
 -                secondaryStorageUrl, accountId, volumeId)
 -                + File.pathSeparator
++        final String lPath = determineSnapshotLocalDirectory(secondaryStorageUrl, accountId, volumeId) + File.pathSeparator
+                 + (deleteAllFlag ? "*" : "*" + name + "*");
+ 
+         final String result = deleteLocalFile(lPath);
+ 
+         if (result != null) {
+             return "failed to delete snapshot " + lPath + " , err=" + result;
+         }
+ 
+         return null;
+ 
+     }
+ 
 -    private String deleteSnapshotBackupfromS3(final S3TO s3,
 -            final String secondaryStorageUrl, final Long accountId,
 -            final Long volumeId, final String name, final Boolean deleteAllFlag) {
++    private String deleteSnapshotBackupfromS3(final S3TO s3, final Long accountId, final Long volumeId, final String name, final Boolean deleteAllFlag) {
+ 
+         try {
+ 
+             final String bucket = s3.getBucketName();
+ 
 -            final String result = executeWithNoWaitLock(
 -                    determineSnapshotLockId(accountId, volumeId),
 -                    new Callable<String>() {
++            final String result = executeWithNoWaitLock(determineSnapshotLockId(accountId, volumeId), new Callable<String>() {
+ 
 -                        @Override
 -                        public String call() throws Exception {
 -
 -                            final String innerResult = deleteSnapshotBackupFromLocalFileSystem(
 -                                    secondaryStorageUrl, accountId, volumeId,
 -                                    name, deleteAllFlag);
 -                            if (innerResult != null) {
 -                                return innerResult;
 -                            }
 -
 -                            if (deleteAllFlag) {
 -                                S3Utils.deleteDirectory(
 -                                        s3,
 -                                        bucket,
 -                                        determineSnapshotS3Directory(accountId,
 -                                                volumeId));
 -                            } else {
 -                                S3Utils.deleteObject(
 -                                        s3,
 -                                        bucket,
 -                                        determineSnapshotS3Key(
 -                                                accountId,
 -                                                volumeId,
 -                                                determineSnapshotBackupFilename(name)));
 -                            }
 -
 -                            return null;
++                @Override
++                public String call() throws Exception {
+ 
 -                        }
++                    if (deleteAllFlag) {
++                        S3Utils.deleteDirectory(s3, bucket, determineSnapshotS3Directory(accountId, volumeId));
++                    } else {
++                        S3Utils.deleteObject(s3, bucket, determineSnapshotS3Key(accountId, volumeId, determineSnapshotBackupFilename(name)));
++                    }
+ 
 -                    });
++                    return null;
++
++                }
++
++            });
+ 
+             return result;
+ 
+         } catch (Exception e) {
+ 
 -            s_logger.error(
 -                    String.format(
 -                            "Failed to delete snapshot backup for account id %1$s volume id %2$sfrom S3.",
 -                            accountId, volumeId), e);
++            s_logger.error(String.format("Failed to delete snapshot backup for account id %1$s volume id %2$sfrom S3.", accountId, volumeId), e);
+             return e.getMessage();
+ 
+         }
+ 
+     }
+ 
+     private String determineSnapshotBackupFilename(final String snapshotUuid) {
+         return snapshotUuid + ".vhd";
+     }
+ 
 -    private String determineSnapshotLockId(final Long accountId,
 -            final Long volumeId) {
++    private String determineSnapshotLockId(final Long accountId, final Long volumeId) {
+         return join("_", "SNAPSHOT", accountId, volumeId);
+     }
+ 
+     protected Answer execute(final DeleteSnapshotBackupCommand cmd) {
 -        String secondaryStorageUrl = cmd.getSecondaryStorageUrl();
+         Long accountId = cmd.getAccountId();
+         Long volumeId = cmd.getVolumeId();
+         String name = cmd.getSnapshotUuid();
 -        try {
 -            SwiftTO swift = cmd.getSwift();
 -            S3TO s3 = cmd.getS3();
 -            if (swift == null) {
 -                final String result = deleteSnapshotBackupFromLocalFileSystem(
 -                        secondaryStorageUrl, accountId, volumeId, name,
 -                        cmd.isAll());
 -                if (result != null) {
 -                    s_logger.warn(result);
 -                    return new Answer(cmd, false, result);
 -                }
 -            } else if (s3 != null) {
 -                final String result = deleteSnapshotBackupfromS3(s3,
 -                        secondaryStorageUrl, accountId, volumeId, name,
 -                        cmd.isAll());
 -                if (result != null) {
 -                    s_logger.warn(result);
 -                    return new Answer(cmd, false, result);
 -                }
++        DataStoreTO dstore = cmd.getDataStore();
++        if (dstore instanceof NfsTO) {
++            final String result = deleteSnapshotBackupFromLocalFileSystem(((NfsTO) dstore).getUrl(), accountId, volumeId, name, cmd.isAll());
++            if (result != null) {
++                s_logger.warn(result);
++                return new Answer(cmd, false, result);
++            }
++        } else if (dstore instanceof S3TO) {
++            final String result = deleteSnapshotBackupfromS3((S3TO) dstore, accountId, volumeId, name, cmd.isAll());
++            if (result != null) {
++                s_logger.warn(result);
++                return new Answer(cmd, false, result);
++            }
++        } else if (dstore instanceof SwiftTO) {
++            String filename;
++            if (cmd.isAll()) {
++                filename = "";
+             } else {
 -                String filename;
 -                if (cmd.isAll()) {
 -                    filename = "";
 -                } else {
 -                    filename = name;
 -                }
 -                String result = swiftDelete(swift, "V-" + volumeId.toString(), filename);
 -                if (result != null) {
 -                    String errMsg = "failed to delete snapshot " + filename + " , err=" + result;
 -                    s_logger.warn(errMsg);
 -                    return new Answer(cmd, false, errMsg);
 -                }
++                filename = name;
+             }
 -            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);
++            String result = swiftDelete((SwiftTO) dstore, "V-" + volumeId.toString(), filename);
++            if (result != null) {
++                String errMsg = "failed to delete snapshot " + filename + " , err=" + result;
++                s_logger.warn(errMsg);
++                return new Answer(cmd, false, errMsg);
++            }
++        } else {
++            return new Answer(cmd, false, "Unsupported image data store: " + dstore);
+         }
++        return new Answer(cmd, true, "success");
+     }
+ 
 -    Map<String, TemplateInfo> swiftListTemplate(SwiftTO swift) {
++    Map<String, TemplateProp> swiftListTemplate(SwiftTO swift) {
+         String[] containers = swiftList(swift, "", "");
+         if (containers == null) {
+             return null;
+         }
 -        Map<String, TemplateInfo> tmpltInfos = new HashMap<String, TemplateInfo>();
 -        for( String container : containers) {
 -            if ( container.startsWith("T-")) {
++        Map<String, TemplateProp> tmpltInfos = new HashMap<String, TemplateProp>();
++        for (String container : containers) {
++            if (container.startsWith("T-")) {
+                 String ldir = _tmpltDir + "/" + UUID.randomUUID().toString();
+                 createLocalDir(ldir);
+                 String lFullPath = ldir + "/" + _tmpltpp;
+                 swiftDownload(swift, container, _tmpltpp, lFullPath);
+                 TemplateLocation loc = new TemplateLocation(_storage, ldir);
+                 try {
+                     if (!loc.load()) {
+                         s_logger.warn("Can not parse template.properties file for template " + container);
+                         continue;
+                     }
+                 } catch (IOException e) {
+                     s_logger.warn("Unable to load template location " + ldir + " due to " + e.toString(), e);
+                     continue;
+                 }
 -                TemplateInfo tInfo = loc.getTemplateInfo();
++                TemplateProp tInfo = loc.getTemplateInfo();
+                 tInfo.setInstallPath(container);
+                 tmpltInfos.put(tInfo.getTemplateName(), tInfo);
+                 loc.purge();
+                 deleteLocalDir(ldir);
+             }
+         }
+         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, this.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 = this.determineS3TemplateNameFromKey(key);
++            // TODO: isPublic value, where to get?
++            TemplateProp tInfo = new TemplateProp(uniqueName, installPath, 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, this.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 = this.determineS3VolumeIdFromKey(key);
++            // TODO: how to get volume template name
++            TemplateProp tInfo = new TemplateProp(id.toString(), installPath, objectSummary.getSize(), objectSummary.getSize(), true, false);
++            tmpltInfos.put(id, tInfo);
++        }
++        return tmpltInfos;
++
++    }
++
+     private Answer execute(ListTemplateCommand cmd) {
++        if (!_inSystemVM) {
++            return new Answer(cmd, true, null);
++        }
+ 
 -        if (cmd.getSwift() != null) {
 -            Map<String, TemplateInfo> templateInfos = swiftListTemplate(cmd.getSwift());
 -            return new ListTemplateAnswer(cmd.getSwift().toString(), templateInfos);
++        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 {
 -            String root = getRootDir(cmd.getSecUrl());
 -            Map<String, TemplateInfo> templateInfos = _dlMgr.gatherTemplateInfo(root);
 -            return new ListTemplateAnswer(cmd.getSecUrl(), templateInfos);
++            return new Answer(cmd, false, "Unsupported image data store: " + store);
+         }
+     }
+ 
+     private Answer execute(ListVolumeCommand cmd) {
 -
 -        String root = getRootDir(cmd.getSecUrl());
 -        Map<Long, TemplateInfo> templateInfos = _dlMgr.gatherVolumeInfo(root);
 -        return new ListVolumeAnswer(cmd.getSecUrl(), templateInfos);
++        if (!_inSystemVM) {
++            return new Answer(cmd, true, null);
++        }
++        DataStoreTO store = cmd.getDataStore();
++        if (store instanceof NfsTO) {
++            NfsTO nfs = (NfsTO)store;
++            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){
++        if (!_inSystemVM) {
+             return new Answer(cmd, true, null);
+         }
+         boolean success = true;
+         StringBuilder result = new StringBuilder();
 -        for (String cidr: cmd.getAllowedInternalSites()) {
++        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. 
++                 * ip route to nfs through storage ip.
+                  */
+                 continue;
+             }
+             String tmpresult = allowOutgoingOnPrivate(cidr);
+             if (tmpresult != null) {
+                 result.append(", ").append(tmpresult);
+                 success = false;
+             }
+         }
+         if (success) {
+             if (cmd.getCopyPassword() != null && cmd.getCopyUserName() != null) {
+                 String tmpresult = configureAuth(cmd.getCopyUserName(), cmd.getCopyPassword());
+                 if (tmpresult != null) {
+                     result.append("Failed to configure auth for copy ").append(tmpresult);
+                     success = false;
+                 }
+             }
+         }
+         return new Answer(cmd, success, result.toString());
+ 
+     }
+ 
+     private String setVhdParent(String lFullPath, String pFullPath) {
+         Script command = new Script("/bin/bash", s_logger);
+         command.add("-c");
+         command.add("/bin/vhd-util modify -n " + lFullPath + " -p " + pFullPath);
+         String result = command.execute();
+         if (result != null) {
+             String errMsg = "failed to set vhd parent, child " + lFullPath + " parent " + pFullPath + ", err=" + result;
+             s_logger.warn(errMsg);
+             return errMsg;
+         }
+         return null;
+     }
+ 
+     private String createLocalDir(String folder) {
+         Script command = new Script("/bin/bash", s_logger);
+         command.add("-c");
+         command.add("mkdir -p " + folder);
+         String result = command.execute();
+         if (result != null) {
+             String errMsg = "Create local path " + folder + " failed , err=" + result;
+             s_logger.warn(errMsg);
+             return errMsg;
+         }
+         return null;
+     }
+ 
+     private String deleteLocalDir(String folder) {
+         Script command = new Script("/bin/bash", s_logger);
+         command.add("-c");
+         command.add("rmdir " + folder);
+         String result = command.execute();
+         if (result != null) {
+             String errMsg = "Delete local path " + folder + " failed , err=" + result;
+             s_logger.warn(errMsg);
+             return errMsg;
+         }
+         return null;
+     }
+ 
+     private String deleteLocalFile(String fullPath) {
+         Script command = new Script("/bin/bash", s_logger);
+         command.add("-c");
+         command.add("rm -f " + fullPath);
+         String result = command.execute();
+         if (result != null) {
+             String errMsg = "Failed to delete file " + fullPath + ", err=" + result;
+             s_logger.warn(errMsg);
+             return errMsg;
+         }
+         return null;
+     }
+ 
+     public String allowOutgoingOnPrivate(String destCidr) {
+         if (!_inSystemVM) {
+             return null;
+         }
+         Script command = new Script("/bin/bash", s_logger);
+         String intf = "eth1";
+         command.add("-c");
+         command.add("iptables -I OUTPUT -o " + intf + " -d " + destCidr + " -p tcp -m state --state NEW -m tcp  -j ACCEPT");
+ 
+         String result = command.execute();
+         if (result != null) {
 -            s_logger.warn("Error in allowing outgoing to " + destCidr + ", err=" + result );
++            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){
++        if (!_inSystemVM) {
+             return new Answer(cmd, true, null);
+         }
+ 
+         List<String> ipList = new ArrayList<String>();
+ 
 -        for (PortConfig pCfg:cmd.getPortConfigs()){
++        for (PortConfig pCfg : cmd.getPortConfigs()) {
+             if (pCfg.isAdd()) {
 -                ipList.add(pCfg.getSourceIp());		
++                ipList.add(pCfg.getSourceIp());
+             }
+         }
+         boolean success = true;
+         String result;
+         result = configureIpFirewall(ipList, cmd.getIsAppendAIp());
 -        if (result !=null)
++        if (result != null)
+             success = false;
+ 
+         return new Answer(cmd, success, result);
+     }
+ 
+     protected GetStorageStatsAnswer execute(final GetStorageStatsCommand cmd) {
+         String rootDir = getRootDir(cmd.getSecUrl());
+         final long usedSize = getUsedSize(rootDir);
+         final long totalSize = getTotalSize(rootDir);
+         if (usedSize == -1 || totalSize == -1) {
+             return new GetStorageStatsAnswer(cmd, "Unable to get storage stats");
+         } else {
 -            return new GetStorageStatsAnswer(cmd, totalSize, usedSize) ;
++            return new GetStorageStatsAnswer(cmd, totalSize, usedSize);
+         }
+     }
+ 
+     protected Answer execute(final DeleteTemplateCommand cmd) {
 -        String relativeTemplatePath = cmd.getTemplatePath();
 -        String parent = getRootDir(cmd);
++        DataStoreTO dstore = cmd.getDataStore();
++        if (dstore instanceof NfsTO) {
++            NfsTO nfs = (NfsTO) dstore;
++            String relativeTemplatePath = cmd.getTemplatePath();
++            String parent = getRootDir(nfs.getUrl());
++
++            if (relativeTemplatePath.startsWith(File.separator)) {
++                relativeTemplatePath = relativeTemplatePath.substring(1);
++            }
+ 
 -        if (relativeTemplatePath.startsWith(File.separator)) {
 -            relativeTemplatePath = relativeTemplatePath.substring(1);
 -        }
++            if (!parent.endsWith(File.separator)) {
++                parent += File.separator;
++            }
++            String absoluteTemplatePath = parent + relativeTemplatePath;
++            File tmpltParent = new File(absoluteTemplatePath).getParentFile();
++            String details = null;
++            if (!tmpltParent.exists()) {
++                details = "template parent directory " + tmpltParent.getName() + " doesn't exist";
++                s_logger.debug(details);
++                return new Answer(cmd, true, details);
++            }
++            File[] tmpltFiles = tmpltParent.listFiles();
++            if (tmpltFiles == null || tmpltFiles.length == 0) {
++                details = "No files under template parent directory " + tmpltParent.getName();
++                s_logger.debug(details);
++            } else {
++                boolean found = false;
++                for (File f : tmpltFiles) {
++                    if (!found && f.getName().equals("template.properties")) {
++                        found = true;
++                    }
+ 
 -        if (!parent.endsWith(File.separator)) {
 -            parent += File.separator;
 -        }
 -        String absoluteTemplatePath = parent + relativeTemplatePath;
 -        File tmpltParent = new File(absoluteTemplatePath).getParentFile();
 -        String details = null;
 -        if (!tmpltParent.exists()) {
 -            details = "template parent directory " + tmpltParent.getName() + " doesn't exist";
 -            s_logger.debug(details);
 -            return new Answer(cmd, true, details);
 -        }
 -        File[] tmpltFiles = tmpltParent.listFiles();
 -        if (tmpltFiles == null || tmpltFiles.length == 0) {
 -            details = "No files under template parent directory " + tmpltParent.getName();
 -            s_logger.debug(details);
 -        } else {
 -            boolean found = false;
 -            for (File f : tmpltFiles) {
 -                if (!found && f.getName().equals("template.properties")) {
 -                    found = true;
 -                }
++                    // 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();
++                        }
++                    }
+ 
 -                // 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(

<TRUNCATED>

Mime
View raw message