mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
Handle ListTemplateCommand in NfsSecondaryStorageResource for various
data store provider.
This commit is contained in:
parent
de27f0ff53
commit
91bfbdf1c4
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@ -30,8 +30,7 @@ public class DeleteTemplateCommand extends ssCommand {
|
||||
}
|
||||
|
||||
|
||||
public DeleteTemplateCommand(DataStoreTO store, String secUrl, String templatePath, Long templateId, Long accountId) {
|
||||
this.setSecUrl(secUrl);
|
||||
public DeleteTemplateCommand(DataStoreTO store, String templatePath, Long templateId, Long accountId) {
|
||||
this.templatePath = templatePath;
|
||||
this.templateId = templateId;
|
||||
this.accountId = accountId;
|
||||
|
||||
@ -51,6 +51,7 @@ public class DownloadSystemTemplateCommand extends Command {
|
||||
private Long accountId;
|
||||
private String url;
|
||||
private Long maxDownloadSizeInBytes;
|
||||
private String name;
|
||||
|
||||
protected DownloadSystemTemplateCommand() {
|
||||
}
|
||||
@ -63,6 +64,7 @@ public class DownloadSystemTemplateCommand extends Command {
|
||||
this.url = secUrl;
|
||||
this.maxDownloadSizeInBytes = maxDownloadSizeInBytes;
|
||||
this.resourceId = template.getId();
|
||||
this.name = template.getUniqueName();
|
||||
}
|
||||
|
||||
|
||||
@ -73,6 +75,7 @@ public class DownloadSystemTemplateCommand extends Command {
|
||||
this.maxDownloadSizeInBytes = maxDownloadSizeInBytes;
|
||||
this.resourceId = template.getId();
|
||||
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
|
||||
public boolean executeInSequence() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
@ -18,24 +18,17 @@ package com.cloud.agent.api.storage;
|
||||
|
||||
import com.cloud.agent.api.LogLevel;
|
||||
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 {
|
||||
private String secUrl;
|
||||
@LogLevel(Log4jLevel.Off)
|
||||
private SwiftTO swift;
|
||||
private DataStoreTO store;
|
||||
|
||||
public ListTemplateCommand() {
|
||||
}
|
||||
|
||||
public ListTemplateCommand(String secUrl) {
|
||||
this.secUrl = secUrl;
|
||||
this.swift = null;
|
||||
}
|
||||
|
||||
public ListTemplateCommand(SwiftTO swift) {
|
||||
this.secUrl = null;
|
||||
this.swift = swift;
|
||||
public ListTemplateCommand(DataStoreTO store) {
|
||||
this.store = store;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -43,12 +36,9 @@ public class ListTemplateCommand extends StorageCommand {
|
||||
return true;
|
||||
}
|
||||
|
||||
public String getSecUrl() {
|
||||
return secUrl;
|
||||
}
|
||||
|
||||
public SwiftTO getSwift() {
|
||||
return swift;
|
||||
public DataStoreTO getDataStore() {
|
||||
return store;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -9,16 +9,20 @@ import java.net.MalformedURLException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.amazonaws.services.s3.model.S3ObjectSummary;
|
||||
import com.cloud.agent.api.Answer;
|
||||
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.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.storage.VMTemplateStorageResourceAssoc.Status;
|
||||
import com.cloud.utils.S3Utils;
|
||||
import com.cloud.utils.UriUtils;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
@ -62,10 +66,19 @@ public class LocalNfsSecondaryStorageResource extends
|
||||
}
|
||||
|
||||
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);
|
||||
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,
|
||||
cmd.getResourceId(), bucket));
|
||||
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 NfsTO ){
|
||||
return new Answer(cmd, false, "Nfs needs to be pre-installed with system vm templates");
|
||||
|
||||
@ -50,6 +50,7 @@ import com.cloud.storage.template.DownloadManager;
|
||||
import com.cloud.storage.template.DownloadManagerImpl;
|
||||
import com.cloud.storage.template.TemplateProp;
|
||||
import com.cloud.utils.component.ComponentContext;
|
||||
import com.cloud.agent.api.to.NfsTO;
|
||||
|
||||
public class LocalSecondaryStorageResource extends ServerResourceBase implements SecondaryStorageResource {
|
||||
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) {
|
||||
String root = getRootDir();
|
||||
Map<String, TemplateProp> templateInfos = _dlMgr.gatherTemplateInfo(root);
|
||||
return new ListTemplateAnswer(cmd.getSecUrl(), templateInfos);
|
||||
return new ListTemplateAnswer(((NfsTO)cmd.getDataStore()).getUrl(), templateInfos);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -16,7 +16,6 @@
|
||||
// under the License.
|
||||
package com.cloud.storage.resource;
|
||||
|
||||
import static com.cloud.utils.S3Utils.deleteDirectory;
|
||||
import static com.cloud.utils.S3Utils.getDirectory;
|
||||
import static com.cloud.utils.StringUtils.join;
|
||||
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.CopyCommand;
|
||||
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;
|
||||
@ -63,7 +64,6 @@ 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.GetStorageStatsAnswer;
|
||||
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.DeleteTemplateCommand;
|
||||
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.DownloadProgressCommand;
|
||||
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.storage.DataStoreRole;
|
||||
import com.cloud.storage.StorageLayer;
|
||||
import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
|
||||
import com.cloud.storage.template.DownloadManager;
|
||||
import com.cloud.storage.template.DownloadManagerImpl;
|
||||
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.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";
|
||||
@ -160,6 +160,7 @@ SecondaryStorageResource {
|
||||
final private String _parent = "/mnt/SecStorage";
|
||||
final private String _tmpltDir = "/var/cloudstack/template";
|
||||
final private String _tmpltpp = "template.properties";
|
||||
|
||||
@Override
|
||||
public void disconnected() {
|
||||
}
|
||||
@ -214,8 +215,6 @@ SecondaryStorageResource {
|
||||
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 CopyCommand) {
|
||||
@ -225,7 +224,6 @@ SecondaryStorageResource {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected Answer copyFromS3ToNfs(CopyCommand cmd, DataTO srcData, S3TO s3,
|
||||
|
||||
DataTO destData, NfsTO destImageStore) {
|
||||
@ -234,23 +232,17 @@ SecondaryStorageResource {
|
||||
|
||||
try {
|
||||
|
||||
final File downloadDirectory = _storage
|
||||
.getFile(determineStorageTemplatePath(storagePath,
|
||||
destPath));
|
||||
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 from S3.", downloadDirectory.getName()
|
||||
);
|
||||
final String errMsg = format("Unable to create directory " + "download directory %1$s for download from S3.",
|
||||
downloadDirectory.getName());
|
||||
s_logger.error(errMsg);
|
||||
return new CopyCmdAnswer(errMsg);
|
||||
}
|
||||
|
||||
List<File> files = getDirectory(s3, s3.getBucketName(),
|
||||
destPath,
|
||||
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);
|
||||
@ -284,8 +276,7 @@ SecondaryStorageResource {
|
||||
return new CopyCmdAnswer(newDestTO);
|
||||
} catch (Exception e) {
|
||||
|
||||
final String errMsg = format("Failed to download"
|
||||
+ "due to $2%s", e.getMessage());
|
||||
final String errMsg = format("Failed to download" + "due to $2%s", e.getMessage());
|
||||
s_logger.error(errMsg, e);
|
||||
return new CopyCmdAnswer(errMsg);
|
||||
}
|
||||
@ -303,9 +294,7 @@ SecondaryStorageResource {
|
||||
DataStoreTO srcDataStore = srcData.getDataStore();
|
||||
DataStoreTO destDataStore = destData.getDataStore();
|
||||
|
||||
if (srcDataStore.getRole() == DataStoreRole.Image
|
||||
&& destDataStore.getRole() == DataStoreRole.ImageCache
|
||||
) {
|
||||
if (srcDataStore.getRole() == DataStoreRole.Image && destDataStore.getRole() == DataStoreRole.ImageCache) {
|
||||
|
||||
if (!(destDataStore instanceof NfsTO)) {
|
||||
s_logger.debug("only support nfs as cache storage");
|
||||
@ -313,11 +302,9 @@ SecondaryStorageResource {
|
||||
}
|
||||
|
||||
if (srcDataStore instanceof S3TO) {
|
||||
return copyFromS3ToNfs(cmd, srcData, (S3TO)srcDataStore,
|
||||
destData, (NfsTO)destDataStore);
|
||||
return copyFromS3ToNfs(cmd, srcData, (S3TO) srcDataStore, destData, (NfsTO) destDataStore);
|
||||
} else if (srcDataStore instanceof SwiftTO) {
|
||||
return copyFromSwiftToNfs(cmd, srcData, (SwiftTO)srcDataStore,
|
||||
destData, (NfsTO)destDataStore);
|
||||
return copyFromSwiftToNfs(cmd, srcData, (SwiftTO) srcDataStore, destData, (NfsTO) destDataStore);
|
||||
} else {
|
||||
return Answer.createUnsupportedCommandAnswer(cmd);
|
||||
}
|
||||
@ -327,17 +314,19 @@ SecondaryStorageResource {
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected String determineS3TemplateDirectory(final Long accountId,
|
||||
final Long templateId) {
|
||||
return join(asList(TEMPLATE_ROOT_DIR, accountId, templateId),
|
||||
S3Utils.SEPARATOR);
|
||||
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 determineStorageTemplatePath(final String storagePath,
|
||||
String dataPath) {
|
||||
return join(
|
||||
asList(getRootDir(storagePath), dataPath), File.separator);
|
||||
private String determineS3TemplateNameFromKey(String key){
|
||||
return 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) {
|
||||
@ -387,8 +376,8 @@ SecondaryStorageResource {
|
||||
DataStoreTO dstore = cmd.getDataStore();
|
||||
if (dstore instanceof NfsTO) {
|
||||
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
|
||||
S3TO s3 = (S3TO) cmd.getDataStore();
|
||||
String url = cmd.getUrl();
|
||||
@ -412,17 +401,27 @@ SecondaryStorageResource {
|
||||
}
|
||||
|
||||
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);
|
||||
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,
|
||||
cmd.getResourceId(), bucket));
|
||||
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.
|
||||
} 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{
|
||||
} else {
|
||||
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) {
|
||||
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) {
|
||||
@ -630,8 +587,8 @@ SecondaryStorageResource {
|
||||
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) {
|
||||
@ -674,11 +631,12 @@ SecondaryStorageResource {
|
||||
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);
|
||||
@ -705,8 +663,8 @@ SecondaryStorageResource {
|
||||
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) {
|
||||
@ -727,9 +685,8 @@ SecondaryStorageResource {
|
||||
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) {
|
||||
@ -750,7 +707,6 @@ SecondaryStorageResource {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public Answer execute(DeleteSnapshotsDirCommand cmd) {
|
||||
String secondaryStorageUrl = cmd.getSecondaryStorageUrl();
|
||||
Long accountId = cmd.getAccountId();
|
||||
@ -781,34 +737,24 @@ SecondaryStorageResource {
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@ -816,19 +762,11 @@ SecondaryStorageResource {
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
}
|
||||
@ -839,41 +777,34 @@ SecondaryStorageResource {
|
||||
|
||||
});
|
||||
|
||||
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) {
|
||||
@ -948,7 +879,6 @@ SecondaryStorageResource {
|
||||
s_logger.debug("parent path " + parent + " relative template path " + relativeTemplatePath);
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
digest = MessageDigest.getInstance("MD5");
|
||||
is = new FileInputStream(f);
|
||||
@ -968,8 +898,7 @@ SecondaryStorageResource {
|
||||
return new Answer(cmd, false, checksum);
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
return new Answer(cmd, false, checksum);
|
||||
}
|
||||
finally {
|
||||
} finally {
|
||||
try {
|
||||
if (is != null)
|
||||
is.close();
|
||||
@ -1047,20 +976,17 @@ SecondaryStorageResource {
|
||||
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
|
||||
} 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);
|
||||
@ -1073,42 +999,27 @@ SecondaryStorageResource {
|
||||
|
||||
}
|
||||
|
||||
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 String secondaryStorageUrl, final Long accountId, final Long volumeId,
|
||||
final String name, final Boolean deleteAllFlag) {
|
||||
|
||||
try {
|
||||
|
||||
final String bucket = s3.getBucketName();
|
||||
|
||||
final String result = executeWithNoWaitLock(
|
||||
determineSnapshotLockId(accountId, volumeId),
|
||||
new Callable<String>() {
|
||||
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);
|
||||
final String innerResult = deleteSnapshotBackupFromLocalFileSystem(secondaryStorageUrl, accountId, volumeId, name, deleteAllFlag);
|
||||
if (innerResult != null) {
|
||||
return innerResult;
|
||||
}
|
||||
|
||||
if (deleteAllFlag) {
|
||||
S3Utils.deleteDirectory(
|
||||
s3,
|
||||
bucket,
|
||||
determineSnapshotS3Directory(accountId,
|
||||
volumeId));
|
||||
S3Utils.deleteDirectory(s3, bucket, determineSnapshotS3Directory(accountId, volumeId));
|
||||
} else {
|
||||
S3Utils.deleteObject(
|
||||
s3,
|
||||
bucket,
|
||||
determineSnapshotS3Key(
|
||||
accountId,
|
||||
volumeId,
|
||||
determineSnapshotBackupFilename(name)));
|
||||
S3Utils.deleteObject(s3, bucket, determineSnapshotS3Key(accountId, volumeId, determineSnapshotBackupFilename(name)));
|
||||
}
|
||||
|
||||
return null;
|
||||
@ -1121,10 +1032,7 @@ SecondaryStorageResource {
|
||||
|
||||
} 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();
|
||||
|
||||
}
|
||||
@ -1135,8 +1043,7 @@ SecondaryStorageResource {
|
||||
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);
|
||||
}
|
||||
|
||||
@ -1147,17 +1054,13 @@ SecondaryStorageResource {
|
||||
String name = cmd.getSnapshotUuid();
|
||||
DataStoreTO dstore = cmd.getDataStore();
|
||||
if (dstore instanceof NfsTO) {
|
||||
final String result = deleteSnapshotBackupFromLocalFileSystem(
|
||||
secondaryStorageUrl, accountId, volumeId, name,
|
||||
cmd.isAll());
|
||||
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 (dstore instanceof S3TO) {
|
||||
final String result = deleteSnapshotBackupfromS3((S3TO)dstore,
|
||||
secondaryStorageUrl, accountId, volumeId, name,
|
||||
cmd.isAll());
|
||||
final String result = deleteSnapshotBackupfromS3((S3TO) dstore, secondaryStorageUrl, accountId, volumeId, name, cmd.isAll());
|
||||
if (result != null) {
|
||||
s_logger.warn(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) {
|
||||
if (!_inSystemVM) {
|
||||
return new Answer(cmd, true, null);
|
||||
}
|
||||
if (cmd.getSwift() != null) {
|
||||
Map<String, TemplateProp> templateInfos = swiftListTemplate(cmd.getSwift());
|
||||
return new ListTemplateAnswer(cmd.getSwift().toString(), templateInfos);
|
||||
} else {
|
||||
String root = getRootDir(cmd.getSecUrl());
|
||||
|
||||
DataStoreTO store = cmd.getDataStore();
|
||||
if (store instanceof NfsTO) {
|
||||
NfsTO nfs = (NfsTO)store;
|
||||
String root = getRootDir(nfs.getUrl());
|
||||
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) {
|
||||
DataStoreTO dstore = cmd.getDataStore();
|
||||
if (dstore instanceof NfsTO) {
|
||||
NfsTO nfs = (NfsTO)dstore;
|
||||
String relativeTemplatePath = cmd.getTemplatePath();
|
||||
String parent = getRootDir(cmd);
|
||||
String parent = getRootDir(nfs.getUrl());
|
||||
|
||||
if (relativeTemplatePath.startsWith(File.separator)) {
|
||||
relativeTemplatePath = relativeTemplatePath.substring(1);
|
||||
@ -1422,33 +1355,14 @@ SecondaryStorageResource {
|
||||
return new Answer(cmd, true, null);
|
||||
} else if (dstore instanceof S3TO) {
|
||||
final S3TO s3 = (S3TO) dstore;
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
final String path = cmd.getTemplatePath();
|
||||
final String bucket = s3.getBucketName();
|
||||
try {
|
||||
S3Utils.deleteDirectory(s3, bucket,
|
||||
determineS3TemplateDirectory(templateId, accountId));
|
||||
return new Answer(cmd, true, String.format(
|
||||
"Deleted template %1%s from bucket %2$s.", templateId,
|
||||
bucket));
|
||||
S3Utils.deleteDirectory(s3, bucket, path);
|
||||
return new Answer(cmd, true, String.format("Deleted template %1%s from bucket %2$s.", path, bucket));
|
||||
} catch (Exception e) {
|
||||
final String errorMessage = String
|
||||
.format("Failed to delete templaet id %1$s from bucket %2$s due to the following error: %3$s",
|
||||
templateId, bucket, e.getMessage());
|
||||
final String errorMessage = String.format("Failed to delete templaet %1$s from bucket %2$s due to the following error: %3$s",
|
||||
path, bucket, e.getMessage());
|
||||
s_logger.error(errorMessage, e);
|
||||
return new Answer(cmd, false, errorMessage);
|
||||
}
|
||||
@ -1505,8 +1419,7 @@ SecondaryStorageResource {
|
||||
found = true;
|
||||
}
|
||||
if (!f.delete()) {
|
||||
return new Answer(cmd, false, "Unable to delete file " + f.getName() + " under Volume path "
|
||||
+ relativeVolumePath);
|
||||
return new Answer(cmd, false, "Unable to delete file " + f.getName() + " under Volume path " + relativeVolumePath);
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
@ -1515,8 +1428,7 @@ SecondaryStorageResource {
|
||||
}
|
||||
}
|
||||
if (!tmpltParent.delete()) {
|
||||
details = "Unable to delete directory " + tmpltParent.getName() + " under Volume path "
|
||||
+ relativeVolumePath;
|
||||
details = "Unable to delete directory " + tmpltParent.getName() + " under Volume path " + relativeVolumePath;
|
||||
s_logger.debug(details);
|
||||
return new Answer(cmd, false, details);
|
||||
}
|
||||
@ -1528,7 +1440,8 @@ SecondaryStorageResource {
|
||||
if (!parent.endsWith(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);
|
||||
if (ssParent.exists() && ssParent.isDirectory()) {
|
||||
File[] files = ssParent.listFiles();
|
||||
@ -1551,7 +1464,6 @@ SecondaryStorageResource {
|
||||
return new Answer(cmd, true, null);
|
||||
}
|
||||
|
||||
|
||||
synchronized public String getRootDir(String secUrl) {
|
||||
try {
|
||||
URI uri = new URI(secUrl);
|
||||
@ -1571,7 +1483,6 @@ SecondaryStorageResource {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getRootDir(ssCommand cmd) {
|
||||
return getRootDir(cmd.getSecUrl());
|
||||
@ -1605,7 +1516,6 @@ SecondaryStorageResource {
|
||||
return (long) (Double.parseDouble(size.substring(0, size.length() - 1)) * multiplier);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Type getType() {
|
||||
if (SecondaryStorageVm.Role.templateProcessor.toString().equals(_role))
|
||||
@ -1700,7 +1610,6 @@ SecondaryStorageResource {
|
||||
|
||||
_instance = (String) params.get("instance");
|
||||
|
||||
|
||||
String inSystemVM = (String) params.get("secondary.storage.vm");
|
||||
if (inSystemVM == null || "true".equalsIgnoreCase(inSystemVM)) {
|
||||
_inSystemVM = true;
|
||||
@ -1773,7 +1682,8 @@ SecondaryStorageResource {
|
||||
if (eth1ip != null && eth1mask != null) {
|
||||
inSameSubnet = NetUtils.sameSubnet(eth1ip, destIpOrCidr, eth1mask);
|
||||
} else {
|
||||
s_logger.warn("addRouteToInternalIp: unable to determine same subnet: _eth1ip=" + eth1ip + ", dest ip=" + destIpOrCidr + ", _eth1mask=" + eth1mask);
|
||||
s_logger.warn("addRouteToInternalIp: unable to determine same subnet: _eth1ip=" + eth1ip + ", dest ip=" + destIpOrCidr
|
||||
+ ", _eth1mask=" + eth1mask);
|
||||
}
|
||||
} else {
|
||||
inSameSubnet = NetUtils.isNetworkAWithinNetworkB(destIpOrCidr, NetUtils.ipAndNetMaskToCidr(eth1ip, eth1mask));
|
||||
@ -1888,7 +1798,8 @@ SecondaryStorageResource {
|
||||
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)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -414,7 +414,7 @@ public class TemplateServiceImpl implements TemplateService {
|
||||
|
||||
|
||||
private Map<String, TemplateProp> listTemplate(DataStore ssStore) {
|
||||
ListTemplateCommand cmd = new ListTemplateCommand(ssStore.getUri());
|
||||
ListTemplateCommand cmd = new ListTemplateCommand(ssStore.getTO());
|
||||
EndPoint ep = _epSelector.select(ssStore);
|
||||
Answer answer = ep.sendMessage(cmd);
|
||||
if (answer != null && answer.getResult()) {
|
||||
|
||||
@ -292,7 +292,7 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver {
|
||||
TemplateDataStoreVO tmplStore = _templateStoreDao.findByStoreTemplate(storeId, templateId);
|
||||
String installPath = tmplStore.getInstallPath();
|
||||
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);
|
||||
Answer answer = ep.sendMessage(cmd);
|
||||
|
||||
|
||||
@ -249,7 +249,7 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver {
|
||||
TemplateDataStoreVO tmplStore = _templateStoreDao.findByStoreTemplate(storeId, templateId);
|
||||
String installPath = tmplStore.getInstallPath();
|
||||
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);
|
||||
Answer answer = ep.sendMessage(cmd);
|
||||
|
||||
|
||||
@ -243,7 +243,7 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver {
|
||||
TemplateDataStoreVO tmplStore = _templateStoreDao.findByStoreTemplate(storeId, templateId);
|
||||
String installPath = tmplStore.getInstallPath();
|
||||
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);
|
||||
Answer answer = ep.sendMessage(cmd);
|
||||
|
||||
|
||||
@ -93,7 +93,7 @@ public class SamplePrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver
|
||||
CreateCmdResult result = null;
|
||||
CreateObjectAnswer volAnswer = (CreateObjectAnswer) callback.getResult();
|
||||
if (volAnswer.getResult()) {
|
||||
result = new CreateCmdResult(volAnswer.getPath(), volAnswer.getSize());
|
||||
result = new CreateCmdResult(volAnswer.getPath(), volAnswer);
|
||||
} else {
|
||||
result = new CreateCmdResult("", null);
|
||||
result.setResult(volAnswer.getDetails());
|
||||
|
||||
@ -1245,7 +1245,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
||||
|
||||
if (installPath != null) {
|
||||
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());
|
||||
Answer answer = ep.sendMessage(cmd);
|
||||
|
||||
|
||||
@ -49,7 +49,7 @@ public interface S3Manager extends Manager {
|
||||
|
||||
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,
|
||||
final long templateId, final int primaryStorageDownloadWait);
|
||||
|
||||
@ -41,7 +41,6 @@ import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.ejb.Local;
|
||||
import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
@ -54,7 +53,6 @@ import org.springframework.stereotype.Component;
|
||||
|
||||
import com.cloud.agent.AgentManager;
|
||||
import com.cloud.agent.api.Answer;
|
||||
import com.cloud.agent.api.DeleteTemplateFromS3Command;
|
||||
import com.cloud.agent.api.DownloadTemplateFromS3ToSecondaryStorageCommand;
|
||||
import com.cloud.agent.api.UploadTemplateToS3FromSecondaryStorageCommand;
|
||||
import com.cloud.agent.api.to.S3TO;
|
||||
@ -282,70 +280,7 @@ public class S3ManagerImpl extends ManagerBase implements S3Manager {
|
||||
+ "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")
|
||||
@Override
|
||||
|
||||
@ -54,6 +54,7 @@ import com.amazonaws.services.s3.AmazonS3Client;
|
||||
import com.amazonaws.services.s3.model.Bucket;
|
||||
import com.amazonaws.services.s3.model.GetObjectRequest;
|
||||
import com.amazonaws.services.s3.model.ObjectMetadata;
|
||||
import com.amazonaws.services.s3.model.S3Object;
|
||||
import com.amazonaws.services.s3.model.S3ObjectSummary;
|
||||
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")
|
||||
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,
|
||||
final String directory, final AmazonS3 client) {
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user