Handle ListTemplateCommand in NfsSecondaryStorageResource for various

data store provider.
This commit is contained in:
Min Chen 2013-04-26 12:25:06 -07:00
parent de27f0ff53
commit 91bfbdf1c4
16 changed files with 490 additions and 703 deletions

View File

@ -1,106 +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.agent.api;
import com.cloud.agent.api.to.S3TO;
public class DeleteTemplateFromS3Command extends Command {
private S3TO s3;
private Long templateId;
private Long accountId;
protected DeleteTemplateFromS3Command() {
super();
}
public DeleteTemplateFromS3Command(final S3TO s3, final Long accountId,
final Long templateId) {
super();
this.s3 = s3;
this.accountId = accountId;
this.templateId = templateId;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((accountId == null) ? 0 : accountId.hashCode());
result = prime * result + ((s3 == null) ? 0 : s3.hashCode());
result = prime * result
+ ((templateId == null) ? 0 : templateId.hashCode());
return result;
}
@Override
public boolean equals(Object thatObject) {
if (this == thatObject) {
return true;
}
if (thatObject == null) {
return false;
}
if (getClass() != thatObject.getClass()) {
return false;
}
final DeleteTemplateFromS3Command thatCommand = (DeleteTemplateFromS3Command) thatObject;
if (!(accountId == thatCommand.accountId)
|| (this.accountId != null && this.accountId
.equals(thatCommand.accountId))) {
return false;
}
if (!(templateId == thatCommand.templateId)
|| (this.templateId != null && this.templateId
.equals(thatCommand.templateId))) {
return false;
}
return true;
}
public S3TO getS3() {
return s3;
}
public Long getTemplateId() {
return templateId;
}
public Long getAccountId() {
return accountId;
}
@Override
public boolean executeInSequence() {
return true;
}
}

View File

@ -30,8 +30,7 @@ public class DeleteTemplateCommand extends ssCommand {
} }
public DeleteTemplateCommand(DataStoreTO store, String secUrl, String templatePath, Long templateId, Long accountId) { public DeleteTemplateCommand(DataStoreTO store, String templatePath, Long templateId, Long accountId) {
this.setSecUrl(secUrl);
this.templatePath = templatePath; this.templatePath = templatePath;
this.templateId = templateId; this.templateId = templateId;
this.accountId = accountId; this.accountId = accountId;

View File

@ -51,6 +51,7 @@ public class DownloadSystemTemplateCommand extends Command {
private Long accountId; private Long accountId;
private String url; private String url;
private Long maxDownloadSizeInBytes; private Long maxDownloadSizeInBytes;
private String name;
protected DownloadSystemTemplateCommand() { protected DownloadSystemTemplateCommand() {
} }
@ -63,6 +64,7 @@ public class DownloadSystemTemplateCommand extends Command {
this.url = secUrl; this.url = secUrl;
this.maxDownloadSizeInBytes = maxDownloadSizeInBytes; this.maxDownloadSizeInBytes = maxDownloadSizeInBytes;
this.resourceId = template.getId(); this.resourceId = template.getId();
this.name = template.getUniqueName();
} }
@ -73,6 +75,7 @@ public class DownloadSystemTemplateCommand extends Command {
this.maxDownloadSizeInBytes = maxDownloadSizeInBytes; this.maxDownloadSizeInBytes = maxDownloadSizeInBytes;
this.resourceId = template.getId(); this.resourceId = template.getId();
auth = new PasswordAuth(user, passwd); auth = new PasswordAuth(user, passwd);
this.name = template.getUniqueName();
} }
@ -144,6 +147,18 @@ public class DownloadSystemTemplateCommand extends Command {
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override @Override
public boolean executeInSequence() { public boolean executeInSequence() {
// TODO Auto-generated method stub // TODO Auto-generated method stub

View File

@ -18,24 +18,17 @@ package com.cloud.agent.api.storage;
import com.cloud.agent.api.LogLevel; import com.cloud.agent.api.LogLevel;
import com.cloud.agent.api.LogLevel.Log4jLevel; import com.cloud.agent.api.LogLevel.Log4jLevel;
import com.cloud.agent.api.to.SwiftTO; import com.cloud.agent.api.to.DataStoreTO;
public class ListTemplateCommand extends StorageCommand { public class ListTemplateCommand extends StorageCommand {
private String secUrl;
@LogLevel(Log4jLevel.Off) @LogLevel(Log4jLevel.Off)
private SwiftTO swift; private DataStoreTO store;
public ListTemplateCommand() { public ListTemplateCommand() {
} }
public ListTemplateCommand(String secUrl) { public ListTemplateCommand(DataStoreTO store) {
this.secUrl = secUrl; this.store = store;
this.swift = null;
}
public ListTemplateCommand(SwiftTO swift) {
this.secUrl = null;
this.swift = swift;
} }
@Override @Override
@ -43,12 +36,9 @@ public class ListTemplateCommand extends StorageCommand {
return true; return true;
} }
public String getSecUrl() {
return secUrl;
}
public SwiftTO getSwift() { public DataStoreTO getDataStore() {
return swift; return store;
} }
} }

View File

@ -9,16 +9,20 @@ import java.net.MalformedURLException;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.net.URL; import java.net.URL;
import java.util.List;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import com.amazonaws.services.s3.model.S3ObjectSummary;
import com.cloud.agent.api.Answer; import com.cloud.agent.api.Answer;
import com.cloud.agent.api.Command; import com.cloud.agent.api.Command;
import com.cloud.agent.api.storage.DownloadAnswer;
import com.cloud.agent.api.storage.DownloadSystemTemplateCommand; import com.cloud.agent.api.storage.DownloadSystemTemplateCommand;
import com.cloud.agent.api.to.DataStoreTO; import com.cloud.agent.api.to.DataStoreTO;
import com.cloud.agent.api.to.NfsTO; import com.cloud.agent.api.to.NfsTO;
import com.cloud.agent.api.to.S3TO; import com.cloud.agent.api.to.S3TO;
import com.cloud.agent.api.to.SwiftTO; import com.cloud.agent.api.to.SwiftTO;
import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
import com.cloud.utils.S3Utils; import com.cloud.utils.S3Utils;
import com.cloud.utils.UriUtils; import com.cloud.utils.UriUtils;
import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.exception.CloudRuntimeException;
@ -62,10 +66,19 @@ public class LocalNfsSecondaryStorageResource extends
} }
final String bucket = s3.getBucketName(); final String bucket = s3.getBucketName();
String key = join(asList(determineS3TemplateDirectory(cmd.getAccountId(), cmd.getResourceId()), urlObj.getFile()), S3Utils.SEPARATOR); // convention is no / in the end for install path based on S3Utils implementation.
String path = determineS3TemplateDirectory(cmd.getAccountId(), cmd.getResourceId(), cmd.getName());
// template key is
// TEMPLATE_ROOT_DIR/account_id/template_id/template_name
String key = join(asList(path, urlObj.getFile()), S3Utils.SEPARATOR);
S3Utils.putObject(s3, in, bucket, key); S3Utils.putObject(s3, in, bucket, key);
return new Answer(cmd, true, format("Uploaded the contents of input stream from %1$s for template id %2$s to S3 bucket %3$s", url, List<S3ObjectSummary> s3Obj = S3Utils.getDirectory(s3, bucket, path);
cmd.getResourceId(), bucket)); 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 NfsTO ){ else if ( dstore instanceof NfsTO ){
return new Answer(cmd, false, "Nfs needs to be pre-installed with system vm templates"); return new Answer(cmd, false, "Nfs needs to be pre-installed with system vm templates");

View File

@ -50,6 +50,7 @@ import com.cloud.storage.template.DownloadManager;
import com.cloud.storage.template.DownloadManagerImpl; import com.cloud.storage.template.DownloadManagerImpl;
import com.cloud.storage.template.TemplateProp; import com.cloud.storage.template.TemplateProp;
import com.cloud.utils.component.ComponentContext; import com.cloud.utils.component.ComponentContext;
import com.cloud.agent.api.to.NfsTO;
public class LocalSecondaryStorageResource extends ServerResourceBase implements SecondaryStorageResource { public class LocalSecondaryStorageResource extends ServerResourceBase implements SecondaryStorageResource {
private static final Logger s_logger = Logger.getLogger(LocalSecondaryStorageResource.class); private static final Logger s_logger = Logger.getLogger(LocalSecondaryStorageResource.class);
@ -110,7 +111,7 @@ public class LocalSecondaryStorageResource extends ServerResourceBase implements
private Answer execute(ListTemplateCommand cmd) { private Answer execute(ListTemplateCommand cmd) {
String root = getRootDir(); String root = getRootDir();
Map<String, TemplateProp> templateInfos = _dlMgr.gatherTemplateInfo(root); Map<String, TemplateProp> templateInfos = _dlMgr.gatherTemplateInfo(root);
return new ListTemplateAnswer(cmd.getSecUrl(), templateInfos); return new ListTemplateAnswer(((NfsTO)cmd.getDataStore()).getUrl(), templateInfos);
} }
@Override @Override

View File

@ -16,7 +16,6 @@
// under the License. // under the License.
package com.cloud.storage.resource; package com.cloud.storage.resource;
import static com.cloud.utils.S3Utils.deleteDirectory;
import static com.cloud.utils.S3Utils.getDirectory; import static com.cloud.utils.S3Utils.getDirectory;
import static com.cloud.utils.StringUtils.join; import static com.cloud.utils.StringUtils.join;
import static com.cloud.utils.db.GlobalLock.executeWithNoWaitLock; import static com.cloud.utils.db.GlobalLock.executeWithNoWaitLock;
@ -52,8 +51,10 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataTO;
import org.apache.cloudstack.storage.command.CopyCmdAnswer; import org.apache.cloudstack.storage.command.CopyCmdAnswer;
import org.apache.cloudstack.storage.command.CopyCommand; import org.apache.cloudstack.storage.command.CopyCommand;
import org.apache.cloudstack.storage.to.TemplateObjectTO; import org.apache.cloudstack.storage.to.TemplateObjectTO;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import com.amazonaws.services.s3.model.S3ObjectSummary;
import com.cloud.agent.api.Answer; import com.cloud.agent.api.Answer;
import com.cloud.agent.api.CheckHealthAnswer; import com.cloud.agent.api.CheckHealthAnswer;
import com.cloud.agent.api.CheckHealthCommand; import com.cloud.agent.api.CheckHealthCommand;
@ -63,7 +64,6 @@ import com.cloud.agent.api.ComputeChecksumCommand;
import com.cloud.agent.api.DeleteObjectFromSwiftCommand; import com.cloud.agent.api.DeleteObjectFromSwiftCommand;
import com.cloud.agent.api.DeleteSnapshotBackupCommand; import com.cloud.agent.api.DeleteSnapshotBackupCommand;
import com.cloud.agent.api.DeleteSnapshotsDirCommand; import com.cloud.agent.api.DeleteSnapshotsDirCommand;
import com.cloud.agent.api.DeleteTemplateFromS3Command;
import com.cloud.agent.api.DownloadSnapshotFromS3Command; import com.cloud.agent.api.DownloadSnapshotFromS3Command;
import com.cloud.agent.api.GetStorageStatsAnswer; import com.cloud.agent.api.GetStorageStatsAnswer;
import com.cloud.agent.api.GetStorageStatsCommand; import com.cloud.agent.api.GetStorageStatsCommand;
@ -87,6 +87,7 @@ import com.cloud.agent.api.storage.CreateEntityDownloadURLCommand;
import com.cloud.agent.api.storage.DeleteEntityDownloadURLCommand; import com.cloud.agent.api.storage.DeleteEntityDownloadURLCommand;
import com.cloud.agent.api.storage.DeleteTemplateCommand; import com.cloud.agent.api.storage.DeleteTemplateCommand;
import com.cloud.agent.api.storage.DeleteVolumeCommand; import com.cloud.agent.api.storage.DeleteVolumeCommand;
import com.cloud.agent.api.storage.DownloadAnswer;
import com.cloud.agent.api.storage.DownloadCommand; import com.cloud.agent.api.storage.DownloadCommand;
import com.cloud.agent.api.storage.DownloadProgressCommand; import com.cloud.agent.api.storage.DownloadProgressCommand;
import com.cloud.agent.api.storage.ListTemplateAnswer; import com.cloud.agent.api.storage.ListTemplateAnswer;
@ -105,6 +106,7 @@ import com.cloud.host.Host.Type;
import com.cloud.resource.ServerResourceBase; import com.cloud.resource.ServerResourceBase;
import com.cloud.storage.DataStoreRole; import com.cloud.storage.DataStoreRole;
import com.cloud.storage.StorageLayer; import com.cloud.storage.StorageLayer;
import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
import com.cloud.storage.template.DownloadManager; import com.cloud.storage.template.DownloadManager;
import com.cloud.storage.template.DownloadManagerImpl; import com.cloud.storage.template.DownloadManagerImpl;
import com.cloud.storage.template.DownloadManagerImpl.ZfsPathParser; import com.cloud.storage.template.DownloadManagerImpl.ZfsPathParser;
@ -122,11 +124,9 @@ import com.cloud.utils.script.OutputInterpreter;
import com.cloud.utils.script.Script; import com.cloud.utils.script.Script;
import com.cloud.vm.SecondaryStorageVm; import com.cloud.vm.SecondaryStorageVm;
public class NfsSecondaryStorageResource extends ServerResourceBase implements public class NfsSecondaryStorageResource extends ServerResourceBase implements SecondaryStorageResource {
SecondaryStorageResource {
private static final Logger s_logger = Logger private static final Logger s_logger = Logger.getLogger(NfsSecondaryStorageResource.class);
.getLogger(NfsSecondaryStorageResource.class);
private static final String TEMPLATE_ROOT_DIR = "template/tmpl"; private static final String TEMPLATE_ROOT_DIR = "template/tmpl";
private static final String SNAPSHOT_ROOT_DIR = "snapshots"; private static final String SNAPSHOT_ROOT_DIR = "snapshots";
@ -160,6 +160,7 @@ SecondaryStorageResource {
final private String _parent = "/mnt/SecStorage"; final private String _parent = "/mnt/SecStorage";
final private String _tmpltDir = "/var/cloudstack/template"; final private String _tmpltDir = "/var/cloudstack/template";
final private String _tmpltpp = "template.properties"; final private String _tmpltpp = "template.properties";
@Override @Override
public void disconnected() { public void disconnected() {
} }
@ -214,8 +215,6 @@ SecondaryStorageResource {
return execute((UploadTemplateToS3FromSecondaryStorageCommand) cmd); return execute((UploadTemplateToS3FromSecondaryStorageCommand) cmd);
} else if (cmd instanceof DeleteObjectFromSwiftCommand) { } else if (cmd instanceof DeleteObjectFromSwiftCommand) {
return execute((DeleteObjectFromSwiftCommand) cmd); return execute((DeleteObjectFromSwiftCommand) cmd);
} else if (cmd instanceof DeleteTemplateFromS3Command) {
return execute((DeleteTemplateFromS3Command) cmd);
} else if (cmd instanceof CleanupSnapshotBackupCommand) { } else if (cmd instanceof CleanupSnapshotBackupCommand) {
return execute((CleanupSnapshotBackupCommand) cmd); return execute((CleanupSnapshotBackupCommand) cmd);
} else if (cmd instanceof CopyCommand) { } else if (cmd instanceof CopyCommand) {
@ -225,7 +224,6 @@ SecondaryStorageResource {
} }
} }
protected Answer copyFromS3ToNfs(CopyCommand cmd, DataTO srcData, S3TO s3, protected Answer copyFromS3ToNfs(CopyCommand cmd, DataTO srcData, S3TO s3,
DataTO destData, NfsTO destImageStore) { DataTO destData, NfsTO destImageStore) {
@ -234,23 +232,17 @@ SecondaryStorageResource {
try { try {
final File downloadDirectory = _storage final File downloadDirectory = _storage.getFile(determineStorageTemplatePath(storagePath, destPath));
.getFile(determineStorageTemplatePath(storagePath,
destPath));
downloadDirectory.mkdirs(); downloadDirectory.mkdirs();
if (!downloadDirectory.exists()) { if (!downloadDirectory.exists()) {
final String errMsg = format( final String errMsg = format("Unable to create directory " + "download directory %1$s for download from S3.",
"Unable to create directory " downloadDirectory.getName());
+ "download directory %1$s for download from S3.", downloadDirectory.getName()
);
s_logger.error(errMsg); s_logger.error(errMsg);
return new CopyCmdAnswer(errMsg); return new CopyCmdAnswer(errMsg);
} }
List<File> files = getDirectory(s3, s3.getBucketName(), List<File> files = getDirectory(s3, s3.getBucketName(), destPath, downloadDirectory, new FileNamingStrategy() {
destPath,
downloadDirectory, new FileNamingStrategy() {
@Override @Override
public String determineFileName(final String key) { public String determineFileName(final String key) {
return substringAfterLast(key, S3Utils.SEPARATOR); return substringAfterLast(key, S3Utils.SEPARATOR);
@ -284,8 +276,7 @@ SecondaryStorageResource {
return new CopyCmdAnswer(newDestTO); return new CopyCmdAnswer(newDestTO);
} catch (Exception e) { } catch (Exception e) {
final String errMsg = format("Failed to download" final String errMsg = format("Failed to download" + "due to $2%s", e.getMessage());
+ "due to $2%s", e.getMessage());
s_logger.error(errMsg, e); s_logger.error(errMsg, e);
return new CopyCmdAnswer(errMsg); return new CopyCmdAnswer(errMsg);
} }
@ -303,9 +294,7 @@ SecondaryStorageResource {
DataStoreTO srcDataStore = srcData.getDataStore(); DataStoreTO srcDataStore = srcData.getDataStore();
DataStoreTO destDataStore = destData.getDataStore(); DataStoreTO destDataStore = destData.getDataStore();
if (srcDataStore.getRole() == DataStoreRole.Image if (srcDataStore.getRole() == DataStoreRole.Image && destDataStore.getRole() == DataStoreRole.ImageCache) {
&& destDataStore.getRole() == DataStoreRole.ImageCache
) {
if (!(destDataStore instanceof NfsTO)) { if (!(destDataStore instanceof NfsTO)) {
s_logger.debug("only support nfs as cache storage"); s_logger.debug("only support nfs as cache storage");
@ -313,11 +302,9 @@ SecondaryStorageResource {
} }
if (srcDataStore instanceof S3TO) { if (srcDataStore instanceof S3TO) {
return copyFromS3ToNfs(cmd, srcData, (S3TO)srcDataStore, return copyFromS3ToNfs(cmd, srcData, (S3TO) srcDataStore, destData, (NfsTO) destDataStore);
destData, (NfsTO)destDataStore);
} else if (srcDataStore instanceof SwiftTO) { } else if (srcDataStore instanceof SwiftTO) {
return copyFromSwiftToNfs(cmd, srcData, (SwiftTO)srcDataStore, return copyFromSwiftToNfs(cmd, srcData, (SwiftTO) srcDataStore, destData, (NfsTO) destDataStore);
destData, (NfsTO)destDataStore);
} else { } else {
return Answer.createUnsupportedCommandAnswer(cmd); return Answer.createUnsupportedCommandAnswer(cmd);
} }
@ -327,17 +314,19 @@ SecondaryStorageResource {
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
protected String determineS3TemplateDirectory(final Long accountId, protected String determineS3TemplateDirectory(final Long accountId, final Long templateId, final String templateUniqueName) {
final Long templateId) { return join(asList(TEMPLATE_ROOT_DIR, accountId, templateId, templateUniqueName), S3Utils.SEPARATOR);
return join(asList(TEMPLATE_ROOT_DIR, accountId, templateId),
S3Utils.SEPARATOR);
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private String determineStorageTemplatePath(final String storagePath, private String determineS3TemplateNameFromKey(String key){
String dataPath) { return StringUtils.substringAfterLast(StringUtils.substringBeforeLast(key, S3Utils.SEPARATOR), S3Utils.SEPARATOR);
return join( }
asList(getRootDir(storagePath), dataPath), File.separator);
@SuppressWarnings("unchecked")
private String determineStorageTemplatePath(final String storagePath, String dataPath) {
return join(asList(getRootDir(storagePath), dataPath), File.separator);
} }
private Answer execute(downloadTemplateFromSwiftToSecondaryStorageCommand cmd) { private Answer execute(downloadTemplateFromSwiftToSecondaryStorageCommand cmd) {
@ -387,8 +376,8 @@ SecondaryStorageResource {
DataStoreTO dstore = cmd.getDataStore(); DataStoreTO dstore = cmd.getDataStore();
if (dstore instanceof NfsTO) { if (dstore instanceof NfsTO) {
return _dlMgr.handleDownloadCommand(this, cmd); return _dlMgr.handleDownloadCommand(this, cmd);
} } else if (dstore instanceof S3TO) {
else if ( dstore instanceof S3TO ){ // TODO: start download job to handle this
// TODO: how to handle download progress for S3 // TODO: how to handle download progress for S3
S3TO s3 = (S3TO) cmd.getDataStore(); S3TO s3 = (S3TO) cmd.getDataStore();
String url = cmd.getUrl(); String url = cmd.getUrl();
@ -412,17 +401,27 @@ SecondaryStorageResource {
} }
final String bucket = s3.getBucketName(); final String bucket = s3.getBucketName();
String key = join(asList(determineS3TemplateDirectory(cmd.getAccountId(), cmd.getResourceId()), urlObj.getFile()), S3Utils.SEPARATOR); // convention is no / in the end for install path based on S3Utils implementation.
String path = determineS3TemplateDirectory(cmd.getAccountId(), cmd.getResourceId(), cmd.getName());
// template key is
// TEMPLATE_ROOT_DIR/account_id/template_id/template_name
String key = join(asList(path, urlObj.getFile()), S3Utils.SEPARATOR);
S3Utils.putObject(s3, in, bucket, key); S3Utils.putObject(s3, in, bucket, key);
return new Answer(cmd, true, format("Uploaded the contents of input stream from %1$s for template id %2$s to S3 bucket %3$s", url, List<S3ObjectSummary> s3Obj = S3Utils.getDirectory(s3, bucket, path);
cmd.getResourceId(), bucket)); 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 ){ } else if (dstore instanceof SwiftTO) {
//TODO: need to move code from execute(uploadTemplateToSwiftFromSecondaryStorageCommand) here, but we need to handle // TODO: need to move code from
// source is url, most likely we need to modify our existing swiftUpload python script. // 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"); return new Answer(cmd, false, "Swift is not currently support DownloadCommand");
} } else {
else{
return new Answer(cmd, false, "Unsupported image data store: " + dstore); return new Answer(cmd, false, "Unsupported image data store: " + dstore);
} }
@ -559,53 +558,11 @@ SecondaryStorageResource {
private Answer execute(final DeleteTemplateFromS3Command cmd) {
final S3TO s3 = cmd.getS3();
final Long accountId = cmd.getAccountId();
final Long templateId = cmd.getTemplateId();
if (accountId == null || (accountId != null && accountId <= 0)) {
final String errorMessage = "No account id specified for S3 template deletion.";
s_logger.error(errorMessage);
return new Answer(cmd, false, errorMessage);
}
if (templateId == null || (templateId != null && templateId <= 0)) {
final String errorMessage = "No template id specified for S3 template deletion.";
s_logger.error(errorMessage);
return new Answer(cmd, false, errorMessage);
}
if (s3 == null) {
final String errorMessge = "No S3 client options provided";
s_logger.error(errorMessge);
return new Answer(cmd, false, errorMessge);
}
final String bucket = s3.getBucketName();
try {
deleteDirectory(s3, bucket,
determineS3TemplateDirectory(templateId, accountId));
return new Answer(cmd, true, String.format(
"Deleted template %1%s from bucket %2$s.", templateId,
bucket));
} catch (Exception e) {
final String errorMessage = String
.format("Failed to delete templaet id %1$s from bucket %2$s due to the following error: %3$s",
templateId, bucket, e.getMessage());
s_logger.error(errorMessage, e);
return new Answer(cmd, false, errorMessage);
}
}
String swiftDownload(SwiftTO swift, String container, String rfilename, String lFullPath) { String swiftDownload(SwiftTO swift, String container, String rfilename, String lFullPath) {
Script command = new Script("/bin/bash", s_logger); Script command = new Script("/bin/bash", s_logger);
command.add("-c"); command.add("-c");
command.add("/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " command.add("/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + swift.getAccount()
+ swift.getUrl() + " -U " + swift.getAccount() + ":" + swift.getUserName() + " -K " + swift.getKey() + ":" + swift.getUserName() + " -K " + swift.getKey() + " download " + container + " " + rfilename + " -o " + lFullPath);
+ " download " + container + " " + rfilename + " -o " + lFullPath);
OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser(); OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
String result = command.execute(parser); String result = command.execute(parser);
if (result != null) { if (result != null) {
@ -630,8 +587,8 @@ SecondaryStorageResource {
String swiftDownloadContainer(SwiftTO swift, String container, String ldir) { String swiftDownloadContainer(SwiftTO swift, String container, String ldir) {
Script command = new Script("/bin/bash", s_logger); Script command = new Script("/bin/bash", s_logger);
command.add("-c"); 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 " command.add("cd " + ldir + ";/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U "
+ swift.getKey() + " download " + container); + swift.getAccount() + ":" + swift.getUserName() + " -K " + swift.getKey() + " download " + container);
OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser(); OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
String result = command.execute(parser); String result = command.execute(parser);
if (result != null) { if (result != null) {
@ -674,11 +631,12 @@ SecondaryStorageResource {
Script command = new Script("/bin/bash", s_logger); Script command = new Script("/bin/bash", s_logger);
command.add("-c"); command.add("-c");
if (size <= SWIFT_MAX_SIZE) { 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() command.add("cd " + lDir + ";/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U "
+ " -K " + swift.getKey() + " upload " + container + " " + file); + swift.getAccount() + ":" + swift.getUserName() + " -K " + swift.getKey() + " upload " + container + " " + file);
} else { } else {
command.add("cd " + lDir + ";/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + swift.getAccount() + ":" + swift.getUserName() command.add("cd " + lDir + ";/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U "
+ " -K " + swift.getKey() + " upload -S " + SWIFT_MAX_SIZE + " " + container + " " + file); + swift.getAccount() + ":" + swift.getUserName() + " -K " + swift.getKey() + " upload -S " + SWIFT_MAX_SIZE + " " + container
+ " " + file);
} }
OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser(); OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
String result = command.execute(parser); String result = command.execute(parser);
@ -705,8 +663,8 @@ SecondaryStorageResource {
String[] swiftList(SwiftTO swift, String container, String rFilename) { String[] swiftList(SwiftTO swift, String container, String rFilename) {
Script command = new Script("/bin/bash", s_logger); Script command = new Script("/bin/bash", s_logger);
command.add("-c"); 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 " command.add("/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + swift.getAccount()
+ swift.getKey() + " list " + container + " " + rFilename); + ":" + swift.getUserName() + " -K " + swift.getKey() + " list " + container + " " + rFilename);
OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser(); OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
String result = command.execute(parser); String result = command.execute(parser);
if (result == null && parser.getLines() != null) { if (result == null && parser.getLines() != null) {
@ -727,9 +685,8 @@ SecondaryStorageResource {
String swiftDelete(SwiftTO swift, String container, String object) { String swiftDelete(SwiftTO swift, String container, String object) {
Script command = new Script("/bin/bash", s_logger); Script command = new Script("/bin/bash", s_logger);
command.add("-c"); command.add("-c");
command.add("/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " command.add("/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + swift.getAccount()
+ swift.getUrl() + " -U " + swift.getAccount() + ":" + swift.getUserName() + " -K " + swift.getKey() + ":" + swift.getUserName() + " -K " + swift.getKey() + " delete " + container + " " + object);
+ " delete " + container + " " + object);
OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser(); OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
String result = command.execute(parser); String result = command.execute(parser);
if (result != null) { if (result != null) {
@ -750,7 +707,6 @@ SecondaryStorageResource {
return null; return null;
} }
public Answer execute(DeleteSnapshotsDirCommand cmd) { public Answer execute(DeleteSnapshotsDirCommand cmd) {
String secondaryStorageUrl = cmd.getSecondaryStorageUrl(); String secondaryStorageUrl = cmd.getSecondaryStorageUrl();
Long accountId = cmd.getAccountId(); Long accountId = cmd.getAccountId();
@ -781,34 +737,24 @@ SecondaryStorageResource {
try { try {
executeWithNoWaitLock(determineSnapshotLockId(accountId, volumeId), executeWithNoWaitLock(determineSnapshotLockId(accountId, volumeId), new Callable<Void>() {
new Callable<Void>() {
@Override @Override
public Void call() throws Exception { public Void call() throws Exception {
final String directoryName = determineSnapshotLocalDirectory( final String directoryName = determineSnapshotLocalDirectory(secondaryStorageUrl, accountId, volumeId);
secondaryStorageUrl, accountId, volumeId);
String result = createLocalDir(directoryName); String result = createLocalDir(directoryName);
if (result != null) { if (result != null) {
throw new InternalErrorException( throw new InternalErrorException(format("Failed to create directory %1$s during S3 snapshot download.", directoryName));
format("Failed to create directory %1$s during S3 snapshot download.",
directoryName));
} }
final String snapshotFileName = determineSnapshotBackupFilename(cmd final String snapshotFileName = determineSnapshotBackupFilename(cmd.getSnapshotUuid());
.getSnapshotUuid()); final String key = determineSnapshotS3Key(accountId, volumeId, snapshotFileName);
final String key = determineSnapshotS3Key( final File targetFile = S3Utils.getFile(s3, s3.getBucketName(), key, _storage.getFile(directoryName), new FileNamingStrategy() {
accountId, volumeId, snapshotFileName);
final File targetFile = S3Utils.getFile(s3,
s3.getBucketName(), key,
_storage.getFile(directoryName),
new FileNamingStrategy() {
@Override @Override
public String determineFileName( public String determineFileName(String key) {
String key) {
return snapshotFileName; return snapshotFileName;
} }
@ -816,19 +762,11 @@ SecondaryStorageResource {
if (cmd.getParent() != null) { if (cmd.getParent() != null) {
final String parentPath = join( final String parentPath = join(File.pathSeparator, directoryName, determineSnapshotBackupFilename(cmd.getParent()));
File.pathSeparator, directoryName, result = setVhdParent(targetFile.getAbsolutePath(), parentPath);
determineSnapshotBackupFilename(cmd
.getParent()));
result = setVhdParent(
targetFile.getAbsolutePath(),
parentPath);
if (result != null) { if (result != null) {
throw new InternalErrorException( throw new InternalErrorException(format("Failed to set the parent for backup %1$s to %2$s due to %3$s.",
format("Failed to set the parent for backup %1$s to %2$s due to %3$s.", targetFile.getAbsolutePath(), parentPath, result));
targetFile
.getAbsolutePath(),
parentPath, result));
} }
} }
@ -839,41 +777,34 @@ SecondaryStorageResource {
}); });
return new Answer( return new Answer(cmd, true, format("Succesfully retrieved volume id %1$s for account id %2$s to %3$s from S3.", volumeId, accountId,
cmd, secondaryStorageUrl));
true,
format("Succesfully retrieved volume id %1$s for account id %2$s to %3$s from S3.",
volumeId, accountId, secondaryStorageUrl));
} catch (Exception e) { } catch (Exception e) {
final String errMsg = format( 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,
"Failed to retrieve volume id %1$s for account id %2$s to %3$s from S3 due to exception %4$s", accountId, secondaryStorageUrl, e.getMessage());
volumeId, accountId, secondaryStorageUrl, e.getMessage());
s_logger.error(errMsg); s_logger.error(errMsg);
return new Answer(cmd, false, 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); return join(S3Utils.SEPARATOR, SNAPSHOT_ROOT_DIR, accountId, volumeId);
} }
private String determineSnapshotS3Key(final Long accountId, private String determineSnapshotS3Key(final Long accountId, final Long volumeId, final String snapshotFileName) {
final Long volumeId, final String snapshotFileName) {
final String directoryName = determineSnapshotS3Directory(accountId, final String directoryName = determineSnapshotS3Directory(accountId, volumeId);
volumeId);
return join(S3Utils.SEPARATOR, directoryName, snapshotFileName); return join(S3Utils.SEPARATOR, directoryName, snapshotFileName);
} }
private String determineSnapshotLocalDirectory( private String determineSnapshotLocalDirectory(final String secondaryStorageUrl, final Long accountId, final Long volumeId) {
final String secondaryStorageUrl, final Long accountId, return join(File.pathSeparator, getRootDir(secondaryStorageUrl), SNAPSHOT_ROOT_DIR, accountId, volumeId);
final Long volumeId) {
return join(File.pathSeparator, getRootDir(secondaryStorageUrl),
SNAPSHOT_ROOT_DIR, accountId, volumeId);
} }
public Answer execute(downloadSnapshotFromSwiftCommand cmd) { public Answer execute(downloadSnapshotFromSwiftCommand cmd) {
@ -948,7 +879,6 @@ SecondaryStorageResource {
s_logger.debug("parent path " + parent + " relative template path " + relativeTemplatePath); s_logger.debug("parent path " + parent + " relative template path " + relativeTemplatePath);
} }
try { try {
digest = MessageDigest.getInstance("MD5"); digest = MessageDigest.getInstance("MD5");
is = new FileInputStream(f); is = new FileInputStream(f);
@ -968,8 +898,7 @@ SecondaryStorageResource {
return new Answer(cmd, false, checksum); return new Answer(cmd, false, checksum);
} catch (NoSuchAlgorithmException e) { } catch (NoSuchAlgorithmException e) {
return new Answer(cmd, false, checksum); return new Answer(cmd, false, checksum);
} } finally {
finally {
try { try {
if (is != null) if (is != null)
is.close(); is.close();
@ -1047,20 +976,17 @@ SecondaryStorageResource {
return new Answer(cmd, false, msg); return new Answer(cmd, false, msg);
} }
} } else {
else{ // TODO: what do we need to setup for S3/Swift, maybe need to mount
// TODO: what do we need to setup for S3/Swift, maybe need to mount to some cache storage // to some cache storage
return new Answer(cmd, true, null); return new Answer(cmd, true, null);
} }
} }
private String deleteSnapshotBackupFromLocalFileSystem( private String deleteSnapshotBackupFromLocalFileSystem(final String secondaryStorageUrl, final Long accountId, final Long volumeId,
final String secondaryStorageUrl, final Long accountId, final String name, final Boolean deleteAllFlag) {
final Long volumeId, final String name, final Boolean deleteAllFlag) {
final String lPath = determineSnapshotLocalDirectory( final String lPath = determineSnapshotLocalDirectory(secondaryStorageUrl, accountId, volumeId) + File.pathSeparator
secondaryStorageUrl, accountId, volumeId)
+ File.pathSeparator
+ (deleteAllFlag ? "*" : "*" + name + "*"); + (deleteAllFlag ? "*" : "*" + name + "*");
final String result = deleteLocalFile(lPath); final String result = deleteLocalFile(lPath);
@ -1073,42 +999,27 @@ SecondaryStorageResource {
} }
private String deleteSnapshotBackupfromS3(final S3TO s3, private String deleteSnapshotBackupfromS3(final S3TO s3, final String secondaryStorageUrl, final Long accountId, final Long volumeId,
final String secondaryStorageUrl, final Long accountId, final String name, final Boolean deleteAllFlag) {
final Long volumeId, final String name, final Boolean deleteAllFlag) {
try { try {
final String bucket = s3.getBucketName(); final String bucket = s3.getBucketName();
final String result = executeWithNoWaitLock( final String result = executeWithNoWaitLock(determineSnapshotLockId(accountId, volumeId), new Callable<String>() {
determineSnapshotLockId(accountId, volumeId),
new Callable<String>() {
@Override @Override
public String call() throws Exception { public String call() throws Exception {
final String innerResult = deleteSnapshotBackupFromLocalFileSystem( final String innerResult = deleteSnapshotBackupFromLocalFileSystem(secondaryStorageUrl, accountId, volumeId, name, deleteAllFlag);
secondaryStorageUrl, accountId, volumeId,
name, deleteAllFlag);
if (innerResult != null) { if (innerResult != null) {
return innerResult; return innerResult;
} }
if (deleteAllFlag) { if (deleteAllFlag) {
S3Utils.deleteDirectory( S3Utils.deleteDirectory(s3, bucket, determineSnapshotS3Directory(accountId, volumeId));
s3,
bucket,
determineSnapshotS3Directory(accountId,
volumeId));
} else { } else {
S3Utils.deleteObject( S3Utils.deleteObject(s3, bucket, determineSnapshotS3Key(accountId, volumeId, determineSnapshotBackupFilename(name)));
s3,
bucket,
determineSnapshotS3Key(
accountId,
volumeId,
determineSnapshotBackupFilename(name)));
} }
return null; return null;
@ -1121,10 +1032,7 @@ SecondaryStorageResource {
} catch (Exception e) { } catch (Exception e) {
s_logger.error( s_logger.error(String.format("Failed to delete snapshot backup for account id %1$s volume id %2$sfrom S3.", accountId, volumeId), e);
String.format(
"Failed to delete snapshot backup for account id %1$s volume id %2$sfrom S3.",
accountId, volumeId), e);
return e.getMessage(); return e.getMessage();
} }
@ -1135,8 +1043,7 @@ SecondaryStorageResource {
return snapshotUuid + ".vhd"; return snapshotUuid + ".vhd";
} }
private String determineSnapshotLockId(final Long accountId, private String determineSnapshotLockId(final Long accountId, final Long volumeId) {
final Long volumeId) {
return join("_", "SNAPSHOT", accountId, volumeId); return join("_", "SNAPSHOT", accountId, volumeId);
} }
@ -1147,17 +1054,13 @@ SecondaryStorageResource {
String name = cmd.getSnapshotUuid(); String name = cmd.getSnapshotUuid();
DataStoreTO dstore = cmd.getDataStore(); DataStoreTO dstore = cmd.getDataStore();
if (dstore instanceof NfsTO) { if (dstore instanceof NfsTO) {
final String result = deleteSnapshotBackupFromLocalFileSystem( final String result = deleteSnapshotBackupFromLocalFileSystem(secondaryStorageUrl, accountId, volumeId, name, cmd.isAll());
secondaryStorageUrl, accountId, volumeId, name,
cmd.isAll());
if (result != null) { if (result != null) {
s_logger.warn(result); s_logger.warn(result);
return new Answer(cmd, false, result); return new Answer(cmd, false, result);
} }
} else if (dstore instanceof S3TO) { } else if (dstore instanceof S3TO) {
final String result = deleteSnapshotBackupfromS3((S3TO)dstore, final String result = deleteSnapshotBackupfromS3((S3TO) dstore, secondaryStorageUrl, accountId, volumeId, name, cmd.isAll());
secondaryStorageUrl, accountId, volumeId, name,
cmd.isAll());
if (result != null) { if (result != null) {
s_logger.warn(result); s_logger.warn(result);
return new Answer(cmd, false, result); return new Answer(cmd, false, result);
@ -1214,17 +1117,46 @@ SecondaryStorageResource {
} }
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;
}
private Answer execute(ListTemplateCommand cmd) { private Answer execute(ListTemplateCommand cmd) {
if (!_inSystemVM) { if (!_inSystemVM) {
return new Answer(cmd, true, null); return new Answer(cmd, true, null);
} }
if (cmd.getSwift() != null) {
Map<String, TemplateProp> templateInfos = swiftListTemplate(cmd.getSwift()); DataStoreTO store = cmd.getDataStore();
return new ListTemplateAnswer(cmd.getSwift().toString(), templateInfos); if (store instanceof NfsTO) {
} else { NfsTO nfs = (NfsTO)store;
String root = getRootDir(cmd.getSecUrl()); String root = getRootDir(nfs.getUrl());
Map<String, TemplateProp> templateInfos = _dlMgr.gatherTemplateInfo(root); Map<String, TemplateProp> templateInfos = _dlMgr.gatherTemplateInfo(root);
return new ListTemplateAnswer(cmd.getSecUrl(), templateInfos); return new ListTemplateAnswer(nfs.getUrl(), 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);
} }
} }
@ -1377,8 +1309,9 @@ SecondaryStorageResource {
protected Answer execute(final DeleteTemplateCommand cmd) { protected Answer execute(final DeleteTemplateCommand cmd) {
DataStoreTO dstore = cmd.getDataStore(); DataStoreTO dstore = cmd.getDataStore();
if (dstore instanceof NfsTO) { if (dstore instanceof NfsTO) {
NfsTO nfs = (NfsTO)dstore;
String relativeTemplatePath = cmd.getTemplatePath(); String relativeTemplatePath = cmd.getTemplatePath();
String parent = getRootDir(cmd); String parent = getRootDir(nfs.getUrl());
if (relativeTemplatePath.startsWith(File.separator)) { if (relativeTemplatePath.startsWith(File.separator)) {
relativeTemplatePath = relativeTemplatePath.substring(1); relativeTemplatePath = relativeTemplatePath.substring(1);
@ -1422,33 +1355,14 @@ SecondaryStorageResource {
return new Answer(cmd, true, null); return new Answer(cmd, true, null);
} else if (dstore instanceof S3TO) { } else if (dstore instanceof S3TO) {
final S3TO s3 = (S3TO) dstore; final S3TO s3 = (S3TO) dstore;
final Long accountId = cmd.getAccountId(); final String path = cmd.getTemplatePath();
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);
}
final String bucket = s3.getBucketName(); final String bucket = s3.getBucketName();
try { try {
S3Utils.deleteDirectory(s3, bucket, S3Utils.deleteDirectory(s3, bucket, path);
determineS3TemplateDirectory(templateId, accountId)); return new Answer(cmd, true, String.format("Deleted template %1%s from bucket %2$s.", path, bucket));
return new Answer(cmd, true, String.format(
"Deleted template %1%s from bucket %2$s.", templateId,
bucket));
} catch (Exception e) { } catch (Exception e) {
final String errorMessage = String final String errorMessage = String.format("Failed to delete templaet %1$s from bucket %2$s due to the following error: %3$s",
.format("Failed to delete templaet id %1$s from bucket %2$s due to the following error: %3$s", path, bucket, e.getMessage());
templateId, bucket, e.getMessage());
s_logger.error(errorMessage, e); s_logger.error(errorMessage, e);
return new Answer(cmd, false, errorMessage); return new Answer(cmd, false, errorMessage);
} }
@ -1505,8 +1419,7 @@ SecondaryStorageResource {
found = true; found = true;
} }
if (!f.delete()) { if (!f.delete()) {
return new Answer(cmd, false, "Unable to delete file " + f.getName() + " under Volume path " return new Answer(cmd, false, "Unable to delete file " + f.getName() + " under Volume path " + relativeVolumePath);
+ relativeVolumePath);
} }
} }
if (!found) { if (!found) {
@ -1515,8 +1428,7 @@ SecondaryStorageResource {
} }
} }
if (!tmpltParent.delete()) { if (!tmpltParent.delete()) {
details = "Unable to delete directory " + tmpltParent.getName() + " under Volume path " details = "Unable to delete directory " + tmpltParent.getName() + " under Volume path " + relativeVolumePath;
+ relativeVolumePath;
s_logger.debug(details); s_logger.debug(details);
return new Answer(cmd, false, details); return new Answer(cmd, false, details);
} }
@ -1528,7 +1440,8 @@ SecondaryStorageResource {
if (!parent.endsWith(File.separator)) { if (!parent.endsWith(File.separator)) {
parent += File.separator; parent += File.separator;
} }
String absoluteSnapsthotDir = parent + File.separator + "snapshots" + File.separator + cmd.getAccountId() + File.separator + cmd.getVolumeId(); String absoluteSnapsthotDir = parent + File.separator + "snapshots" + File.separator + cmd.getAccountId() + File.separator
+ cmd.getVolumeId();
File ssParent = new File(absoluteSnapsthotDir); File ssParent = new File(absoluteSnapsthotDir);
if (ssParent.exists() && ssParent.isDirectory()) { if (ssParent.exists() && ssParent.isDirectory()) {
File[] files = ssParent.listFiles(); File[] files = ssParent.listFiles();
@ -1551,7 +1464,6 @@ SecondaryStorageResource {
return new Answer(cmd, true, null); return new Answer(cmd, true, null);
} }
synchronized public String getRootDir(String secUrl) { synchronized public String getRootDir(String secUrl) {
try { try {
URI uri = new URI(secUrl); URI uri = new URI(secUrl);
@ -1571,7 +1483,6 @@ SecondaryStorageResource {
} }
} }
@Override @Override
public String getRootDir(ssCommand cmd) { public String getRootDir(ssCommand cmd) {
return getRootDir(cmd.getSecUrl()); return getRootDir(cmd.getSecUrl());
@ -1605,7 +1516,6 @@ SecondaryStorageResource {
return (long) (Double.parseDouble(size.substring(0, size.length() - 1)) * multiplier); return (long) (Double.parseDouble(size.substring(0, size.length() - 1)) * multiplier);
} }
@Override @Override
public Type getType() { public Type getType() {
if (SecondaryStorageVm.Role.templateProcessor.toString().equals(_role)) if (SecondaryStorageVm.Role.templateProcessor.toString().equals(_role))
@ -1700,7 +1610,6 @@ SecondaryStorageResource {
_instance = (String) params.get("instance"); _instance = (String) params.get("instance");
String inSystemVM = (String) params.get("secondary.storage.vm"); String inSystemVM = (String) params.get("secondary.storage.vm");
if (inSystemVM == null || "true".equalsIgnoreCase(inSystemVM)) { if (inSystemVM == null || "true".equalsIgnoreCase(inSystemVM)) {
_inSystemVM = true; _inSystemVM = true;
@ -1773,7 +1682,8 @@ SecondaryStorageResource {
if (eth1ip != null && eth1mask != null) { if (eth1ip != null && eth1mask != null) {
inSameSubnet = NetUtils.sameSubnet(eth1ip, destIpOrCidr, eth1mask); inSameSubnet = NetUtils.sameSubnet(eth1ip, destIpOrCidr, eth1mask);
} else { } else {
s_logger.warn("addRouteToInternalIp: unable to determine same subnet: _eth1ip=" + eth1ip + ", dest ip=" + destIpOrCidr + ", _eth1mask=" + eth1mask); s_logger.warn("addRouteToInternalIp: unable to determine same subnet: _eth1ip=" + eth1ip + ", dest ip=" + destIpOrCidr
+ ", _eth1mask=" + eth1mask);
} }
} else { } else {
inSameSubnet = NetUtils.isNetworkAWithinNetworkB(destIpOrCidr, NetUtils.ipAndNetMaskToCidr(eth1ip, eth1mask)); inSameSubnet = NetUtils.isNetworkAWithinNetworkB(destIpOrCidr, NetUtils.ipAndNetMaskToCidr(eth1ip, eth1mask));
@ -1888,7 +1798,8 @@ SecondaryStorageResource {
return null; return null;
} }
// XXX: Adding the check for creation of snapshots dir here. Might have to move it somewhere more logical later. // XXX: Adding the check for creation of snapshots dir here. Might have
// to move it somewhere more logical later.
if (!checkForSnapshotsDir(root)) { if (!checkForSnapshotsDir(root)) {
return null; return null;
} }

View File

@ -414,7 +414,7 @@ public class TemplateServiceImpl implements TemplateService {
private Map<String, TemplateProp> listTemplate(DataStore ssStore) { private Map<String, TemplateProp> listTemplate(DataStore ssStore) {
ListTemplateCommand cmd = new ListTemplateCommand(ssStore.getUri()); ListTemplateCommand cmd = new ListTemplateCommand(ssStore.getTO());
EndPoint ep = _epSelector.select(ssStore); EndPoint ep = _epSelector.select(ssStore);
Answer answer = ep.sendMessage(cmd); Answer answer = ep.sendMessage(cmd);
if (answer != null && answer.getResult()) { if (answer != null && answer.getResult()) {

View File

@ -292,7 +292,7 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver {
TemplateDataStoreVO tmplStore = _templateStoreDao.findByStoreTemplate(storeId, templateId); TemplateDataStoreVO tmplStore = _templateStoreDao.findByStoreTemplate(storeId, templateId);
String installPath = tmplStore.getInstallPath(); String installPath = tmplStore.getInstallPath();
if (installPath != null) { if (installPath != null) {
DeleteTemplateCommand cmd = new DeleteTemplateCommand(store.getTO(), store.getUri(), installPath, template.getId(), template.getAccountId()); DeleteTemplateCommand cmd = new DeleteTemplateCommand(store.getTO(), installPath, template.getId(), template.getAccountId());
EndPoint ep = _epSelector.select(templateObj); EndPoint ep = _epSelector.select(templateObj);
Answer answer = ep.sendMessage(cmd); Answer answer = ep.sendMessage(cmd);

View File

@ -249,7 +249,7 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver {
TemplateDataStoreVO tmplStore = _templateStoreDao.findByStoreTemplate(storeId, templateId); TemplateDataStoreVO tmplStore = _templateStoreDao.findByStoreTemplate(storeId, templateId);
String installPath = tmplStore.getInstallPath(); String installPath = tmplStore.getInstallPath();
if (installPath != null) { if (installPath != null) {
DeleteTemplateCommand cmd = new DeleteTemplateCommand(store.getTO(), store.getUri(), installPath, template.getId(), template.getAccountId()); DeleteTemplateCommand cmd = new DeleteTemplateCommand(store.getTO(), installPath, template.getId(), template.getAccountId());
EndPoint ep = _epSelector.select(templateObj); EndPoint ep = _epSelector.select(templateObj);
Answer answer = ep.sendMessage(cmd); Answer answer = ep.sendMessage(cmd);

View File

@ -243,7 +243,7 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver {
TemplateDataStoreVO tmplStore = _templateStoreDao.findByStoreTemplate(storeId, templateId); TemplateDataStoreVO tmplStore = _templateStoreDao.findByStoreTemplate(storeId, templateId);
String installPath = tmplStore.getInstallPath(); String installPath = tmplStore.getInstallPath();
if (installPath != null) { if (installPath != null) {
DeleteTemplateCommand cmd = new DeleteTemplateCommand(store.getTO(), store.getUri(), installPath, template.getId(), template.getAccountId()); DeleteTemplateCommand cmd = new DeleteTemplateCommand(store.getTO(), installPath, template.getId(), template.getAccountId());
EndPoint ep = _epSelector.select(templateObj); EndPoint ep = _epSelector.select(templateObj);
Answer answer = ep.sendMessage(cmd); Answer answer = ep.sendMessage(cmd);

View File

@ -93,7 +93,7 @@ public class SamplePrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver
CreateCmdResult result = null; CreateCmdResult result = null;
CreateObjectAnswer volAnswer = (CreateObjectAnswer) callback.getResult(); CreateObjectAnswer volAnswer = (CreateObjectAnswer) callback.getResult();
if (volAnswer.getResult()) { if (volAnswer.getResult()) {
result = new CreateCmdResult(volAnswer.getPath(), volAnswer.getSize()); result = new CreateCmdResult(volAnswer.getPath(), volAnswer);
} else { } else {
result = new CreateCmdResult("", null); result = new CreateCmdResult("", null);
result.setResult(volAnswer.getDetails()); result.setResult(volAnswer.getDetails());

View File

@ -1245,7 +1245,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
if (installPath != null) { if (installPath != null) {
EndPoint ep = _epSelector.select(store); EndPoint ep = _epSelector.select(store);
Command cmd = new DeleteTemplateCommand(store.getTO(), store.getUri(), destroyedTemplateStoreVO.getInstallPath(), Command cmd = new DeleteTemplateCommand(store.getTO(), destroyedTemplateStoreVO.getInstallPath(),
destroyedTemplate.getId(), destroyedTemplate.getAccountId()); destroyedTemplate.getId(), destroyedTemplate.getAccountId());
Answer answer = ep.sendMessage(cmd); Answer answer = ep.sendMessage(cmd);

View File

@ -49,7 +49,7 @@ public interface S3Manager extends Manager {
boolean isTemplateInstalled(Long templateId); boolean isTemplateInstalled(Long templateId);
void deleteTemplate(final Long accountId, final Long templateId); //void deleteTemplate(final Long accountId, final Long templateId);
String downloadTemplateFromS3ToSecondaryStorage(final long dcId, String downloadTemplateFromS3ToSecondaryStorage(final long dcId,
final long templateId, final int primaryStorageDownloadWait); final long templateId, final int primaryStorageDownloadWait);

View File

@ -41,7 +41,6 @@ import java.util.Map;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import javax.annotation.PostConstruct;
import javax.ejb.Local; import javax.ejb.Local;
import javax.inject.Inject; import javax.inject.Inject;
import javax.naming.ConfigurationException; import javax.naming.ConfigurationException;
@ -54,7 +53,6 @@ import org.springframework.stereotype.Component;
import com.cloud.agent.AgentManager; import com.cloud.agent.AgentManager;
import com.cloud.agent.api.Answer; import com.cloud.agent.api.Answer;
import com.cloud.agent.api.DeleteTemplateFromS3Command;
import com.cloud.agent.api.DownloadTemplateFromS3ToSecondaryStorageCommand; import com.cloud.agent.api.DownloadTemplateFromS3ToSecondaryStorageCommand;
import com.cloud.agent.api.UploadTemplateToS3FromSecondaryStorageCommand; import com.cloud.agent.api.UploadTemplateToS3FromSecondaryStorageCommand;
import com.cloud.agent.api.to.S3TO; import com.cloud.agent.api.to.S3TO;
@ -282,70 +280,7 @@ public class S3ManagerImpl extends ManagerBase implements S3Manager {
+ "been implemented"); + "been implemented");
} }
@Override
public void deleteTemplate(final Long templateId, final Long accountId) {
final S3TO s3 = getS3TO();
if (s3 == null) {
final String errorMessage = "Delete Template Failed: No S3 configuration defined.";
LOGGER.error(errorMessage);
throw new CloudRuntimeException(errorMessage);
}
final VMTemplateS3VO vmTemplateS3VO = vmTemplateS3Dao
.findOneByS3Template(s3.getId(), templateId);
if (vmTemplateS3VO == null) {
final String errorMessage = format(
"Delete Template Failed: Unable to find Template %1$s in S3.",
templateId);
LOGGER.error(errorMessage);
throw new CloudRuntimeException(errorMessage);
}
try {
executeWithNoWaitLock(determineLockId(accountId, templateId),
new Callable<Void>() {
@Override
public Void call() throws Exception {
final Answer answer = agentManager.sendToSSVM(null,
new DeleteTemplateFromS3Command(s3,
accountId, templateId));
if (answer == null || !answer.getResult()) {
final String errorMessage = format(
"Delete Template Failed: Unable to delete template id %1$s from S3 due to following error: %2$s",
templateId,
((answer == null) ? "answer is null"
: answer.getDetails()));
LOGGER.error(errorMessage);
throw new CloudRuntimeException(errorMessage);
}
vmTemplateS3Dao.remove(vmTemplateS3VO.getId());
LOGGER.debug(format(
"Deleted template %1$s from S3.",
templateId));
return null;
}
});
} catch (Exception e) {
final String errorMessage = format(
"Delete Template Failed: Unable to delete template id %1$s from S3 due to the following error: %2$s.",
templateId, e.getMessage());
LOGGER.error(errorMessage);
throw new CloudRuntimeException(errorMessage, e);
}
}
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override

View File

@ -54,6 +54,7 @@ import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.Bucket; import com.amazonaws.services.s3.model.Bucket;
import com.amazonaws.services.s3.model.GetObjectRequest; import com.amazonaws.services.s3.model.GetObjectRequest;
import com.amazonaws.services.s3.model.ObjectMetadata; import com.amazonaws.services.s3.model.ObjectMetadata;
import com.amazonaws.services.s3.model.S3Object;
import com.amazonaws.services.s3.model.S3ObjectSummary; import com.amazonaws.services.s3.model.S3ObjectSummary;
import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.exception.CloudRuntimeException;
@ -155,6 +156,22 @@ public final class S3Utils {
} }
// Note that whenever S3Object is returned, client code needs to close the internal stream to avoid resource leak.
public static S3Object getObject(final ClientOptions clientOptions,
final String bucketName, final String key) {
assert clientOptions != null;
assert !isBlank(bucketName);
assert !isBlank(key);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug(format("Get S3 object %1$s in "
+ "bucket %2$s", key, bucketName));
}
return acquireClient(clientOptions).getObject(bucketName, key);
}
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public static File getFile(final ClientOptions clientOptions, public static File getFile(final ClientOptions clientOptions,
@ -243,6 +260,18 @@ public final class S3Utils {
} }
public static List<S3ObjectSummary> getDirectory(final ClientOptions clientOptions,
final String bucketName, final String sourcePath){
assert clientOptions != null;
assert isNotBlank(bucketName);
assert isNotBlank(sourcePath);
final AmazonS3 connection = acquireClient(clientOptions);
// List the objects in the source directory on S3
return listDirectory(bucketName, sourcePath, connection);
}
private static List<S3ObjectSummary> listDirectory(final String bucketName, private static List<S3ObjectSummary> listDirectory(final String bucketName,
final String directory, final AmazonS3 client) { final String directory, final AmazonS3 client) {