mirror of https://github.com/apache/cloudstack.git
CLOUDSTACK-4211: fix s3 on kvm
This commit is contained in:
parent
ab254a5131
commit
9a89fd94fc
|
|
@ -80,7 +80,8 @@ import com.cloud.utils.db.DB;
|
|||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
|
||||
@Component
|
||||
public class AncientDataMotionStrategy implements DataMotionStrategy {
|
||||
public class
|
||||
AncientDataMotionStrategy implements DataMotionStrategy {
|
||||
private static final Logger s_logger = Logger.getLogger(AncientDataMotionStrategy.class);
|
||||
@Inject
|
||||
EndPointSelector selector;
|
||||
|
|
|
|||
|
|
@ -35,6 +35,11 @@ import java.util.UUID;
|
|||
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import com.cloud.agent.api.storage.CopyVolumeAnswer;
|
||||
import com.cloud.agent.api.to.DataObjectType;
|
||||
import com.cloud.agent.api.to.S3TO;
|
||||
import com.cloud.agent.api.to.StorageFilerTO;
|
||||
import com.cloud.utils.S3Utils;
|
||||
import org.apache.cloudstack.storage.command.AttachAnswer;
|
||||
import org.apache.cloudstack.storage.command.AttachCommand;
|
||||
import org.apache.cloudstack.storage.command.CopyCmdAnswer;
|
||||
|
|
@ -92,6 +97,8 @@ import com.ceph.rbd.Rbd;
|
|||
import com.ceph.rbd.RbdImage;
|
||||
import com.ceph.rbd.RbdException;
|
||||
|
||||
import static com.cloud.utils.S3Utils.putFile;
|
||||
|
||||
public class KVMStorageProcessor implements StorageProcessor {
|
||||
private static final Logger s_logger = Logger.getLogger(KVMStorageProcessor.class);
|
||||
private KVMStoragePoolManager storagePoolMgr;
|
||||
|
|
@ -293,13 +300,114 @@ public class KVMStorageProcessor implements StorageProcessor {
|
|||
|
||||
@Override
|
||||
public Answer copyVolumeFromImageCacheToPrimary(CopyCommand cmd) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
DataTO srcData = cmd.getSrcTO();
|
||||
DataTO destData = cmd.getDestTO();
|
||||
DataStoreTO srcStore = srcData.getDataStore();
|
||||
DataStoreTO destStore = destData.getDataStore();
|
||||
PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO) destStore;
|
||||
if (!(srcStore instanceof NfsTO)) {
|
||||
return new CopyCmdAnswer("can only handle nfs storage");
|
||||
}
|
||||
NfsTO nfsStore = (NfsTO)srcStore;
|
||||
String srcVolumePath = srcData.getPath();
|
||||
String secondaryStorageUrl = nfsStore.getUrl();
|
||||
KVMStoragePool secondaryStoragePool = null;
|
||||
KVMStoragePool primaryPool = null;
|
||||
try {
|
||||
try {
|
||||
primaryPool = storagePoolMgr.getStoragePool(
|
||||
primaryStore.getPoolType(),
|
||||
primaryStore.getUuid());
|
||||
} catch (CloudRuntimeException e) {
|
||||
if (e.getMessage().contains("not found")) {
|
||||
primaryPool = storagePoolMgr.createStoragePool(primaryStore.getUuid(),
|
||||
primaryStore.getHost(), primaryStore.getPort(),
|
||||
primaryStore.getPath(), null,
|
||||
primaryStore.getPoolType());
|
||||
} else {
|
||||
return new CopyCmdAnswer(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
String volumeName = UUID.randomUUID().toString();
|
||||
|
||||
int index = srcVolumePath.lastIndexOf(File.separator);
|
||||
String volumeDir = srcVolumePath.substring(0, index);
|
||||
String srcVolumeName = srcVolumePath.substring(index + 1);
|
||||
secondaryStoragePool = storagePoolMgr.getStoragePoolByURI(
|
||||
secondaryStorageUrl + File.separator + volumeDir
|
||||
);
|
||||
KVMPhysicalDisk volume = secondaryStoragePool
|
||||
.getPhysicalDisk(srcVolumeName + ".qcow2");
|
||||
storagePoolMgr.copyPhysicalDisk(volume, volumeName,
|
||||
primaryPool);
|
||||
VolumeObjectTO newVol = new VolumeObjectTO();
|
||||
newVol.setPath(volumeName);
|
||||
return new CopyCmdAnswer(newVol);
|
||||
} catch (CloudRuntimeException e) {
|
||||
return new CopyCmdAnswer(e.toString());
|
||||
} finally {
|
||||
if (secondaryStoragePool != null) {
|
||||
storagePoolMgr.deleteStoragePool(secondaryStoragePool.getType(),secondaryStoragePool.getUuid());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Answer copyVolumeFromPrimaryToSecondary(CopyCommand cmd) {
|
||||
return null;
|
||||
DataTO srcData = cmd.getSrcTO();
|
||||
DataTO destData = cmd.getDestTO();
|
||||
DataStoreTO srcStore = srcData.getDataStore();
|
||||
DataStoreTO destStore = destData.getDataStore();
|
||||
PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO) srcStore;
|
||||
if (!(destStore instanceof NfsTO)) {
|
||||
return new CopyCmdAnswer("can only handle nfs storage");
|
||||
}
|
||||
NfsTO nfsStore = (NfsTO)destStore;
|
||||
String srcVolumePath = srcData.getPath();
|
||||
String destVolumePath = destData.getPath();
|
||||
String secondaryStorageUrl = nfsStore.getUrl();
|
||||
KVMStoragePool secondaryStoragePool = null;
|
||||
KVMStoragePool primaryPool = null;
|
||||
try {
|
||||
try {
|
||||
primaryPool = storagePoolMgr.getStoragePool(
|
||||
primaryStore.getPoolType(),
|
||||
primaryStore.getUuid());
|
||||
} catch (CloudRuntimeException e) {
|
||||
if (e.getMessage().contains("not found")) {
|
||||
primaryPool = storagePoolMgr.createStoragePool(primaryStore.getUuid(),
|
||||
primaryStore.getHost(), primaryStore.getPort(),
|
||||
primaryStore.getPath(), null,
|
||||
primaryStore.getPoolType());
|
||||
} else {
|
||||
return new CopyCmdAnswer(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
String volumeName = UUID.randomUUID().toString();
|
||||
|
||||
|
||||
String destVolumeName = volumeName + ".qcow2";
|
||||
KVMPhysicalDisk volume = primaryPool.getPhysicalDisk(srcVolumePath);
|
||||
secondaryStoragePool = storagePoolMgr.getStoragePoolByURI(
|
||||
secondaryStorageUrl);
|
||||
secondaryStoragePool.createFolder(destVolumePath);
|
||||
storagePoolMgr.deleteStoragePool(secondaryStoragePool.getType(),secondaryStoragePool.getUuid());
|
||||
secondaryStoragePool = storagePoolMgr.getStoragePoolByURI(
|
||||
secondaryStorageUrl + File.separator + destVolumePath);
|
||||
storagePoolMgr.copyPhysicalDisk(volume,
|
||||
destVolumeName,secondaryStoragePool);
|
||||
VolumeObjectTO newVol = new VolumeObjectTO();
|
||||
newVol.setPath(destVolumePath + File.separator + volumeName);
|
||||
return new CopyCmdAnswer(newVol);
|
||||
} catch (CloudRuntimeException e) {
|
||||
return new CopyCmdAnswer(e.toString());
|
||||
} finally {
|
||||
if (secondaryStoragePool != null) {
|
||||
storagePoolMgr.deleteStoragePool(secondaryStoragePool.getType(),secondaryStoragePool.getUuid());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -419,7 +527,70 @@ public class KVMStorageProcessor implements StorageProcessor {
|
|||
public Answer createTemplateFromSnapshot(CopyCommand cmd) {
|
||||
return null; //To change body of implemented methods use File | Settings | File Templates.
|
||||
}
|
||||
protected String copyToS3(File srcFile, S3TO destStore, String destPath) {
|
||||
final String bucket = destStore.getBucketName();
|
||||
|
||||
String key = destPath + S3Utils.SEPARATOR + srcFile.getName();
|
||||
putFile(destStore, srcFile, bucket, key);
|
||||
return key;
|
||||
}
|
||||
protected Answer copyToObjectStore(CopyCommand cmd) {
|
||||
DataTO srcData = cmd.getSrcTO();
|
||||
DataTO destData = cmd.getDestTO();
|
||||
SnapshotObjectTO snapshot = (SnapshotObjectTO) srcData;
|
||||
DataStoreTO imageStore = destData.getDataStore();
|
||||
NfsTO srcStore = (NfsTO)srcData.getDataStore();
|
||||
String srcPath = srcData.getPath();
|
||||
int index = srcPath.lastIndexOf(File.separator);
|
||||
String srcSnapshotDir = srcPath.substring(0, index);
|
||||
String srcFileName = srcPath.substring(index + 1);
|
||||
KVMStoragePool srcStorePool = null;
|
||||
try {
|
||||
srcStorePool = storagePoolMgr.getStoragePoolByURI(srcStore.getUrl() + File.separator + srcSnapshotDir);
|
||||
if (srcStorePool == null) {
|
||||
return new CopyCmdAnswer("Can't get store:" + srcStore.getUrl());
|
||||
}
|
||||
File srcFile = new File(srcStorePool.getLocalPath() + File.separator + srcFileName);
|
||||
if (!srcFile.exists()) {
|
||||
return new CopyCmdAnswer("Can't find src file: " + srcPath);
|
||||
}
|
||||
String destPath = null;
|
||||
if (imageStore instanceof S3TO) {
|
||||
destPath = copyToS3(srcFile, (S3TO)imageStore, destData.getPath());
|
||||
} else {
|
||||
return new CopyCmdAnswer("Unsupported protocol");
|
||||
}
|
||||
SnapshotObjectTO newSnapshot = new SnapshotObjectTO();
|
||||
newSnapshot.setPath(destPath);
|
||||
return new CopyCmdAnswer(newSnapshot);
|
||||
} finally {
|
||||
if (srcStorePool != null) {
|
||||
srcStorePool.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected Answer backupSnapshotForObjectStore(CopyCommand cmd) {
|
||||
DataTO srcData = cmd.getSrcTO();
|
||||
DataTO destData = cmd.getDestTO();
|
||||
SnapshotObjectTO snapshot = (SnapshotObjectTO) srcData;
|
||||
DataStoreTO imageStore = destData.getDataStore();
|
||||
DataTO cacheData = cmd.getCacheTO();
|
||||
if (cacheData == null) {
|
||||
return new CopyCmdAnswer("Failed to copy to object store without cache store");
|
||||
}
|
||||
DataStoreTO cacheStore = cacheData.getDataStore();
|
||||
((SnapshotObjectTO) destData).setDataStore(cacheStore);
|
||||
CopyCmdAnswer answer = (CopyCmdAnswer)backupSnapshot(cmd);
|
||||
if (!answer.getResult()) {
|
||||
return answer;
|
||||
}
|
||||
SnapshotObjectTO snapshotOnCacheStore = (SnapshotObjectTO)answer.getNewData();
|
||||
snapshotOnCacheStore.setDataStore(cacheStore);
|
||||
((SnapshotObjectTO) destData).setDataStore(imageStore);
|
||||
CopyCommand newCpyCmd = new CopyCommand(snapshotOnCacheStore, destData, cmd.getWait(), cmd.executeInSequence());
|
||||
return copyToObjectStore(newCpyCmd);
|
||||
}
|
||||
@Override
|
||||
public Answer backupSnapshot(CopyCommand cmd) {
|
||||
DataTO srcData = cmd.getSrcTO();
|
||||
|
|
@ -430,7 +601,7 @@ public class KVMStorageProcessor implements StorageProcessor {
|
|||
DataStoreTO imageStore = destData.getDataStore();
|
||||
|
||||
if (!(imageStore instanceof NfsTO)) {
|
||||
return new CopyCmdAnswer("unsupported protocol");
|
||||
return backupSnapshotForObjectStore(cmd);
|
||||
}
|
||||
NfsTO nfsImageStore = (NfsTO) imageStore;
|
||||
|
||||
|
|
|
|||
|
|
@ -506,9 +506,21 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
|||
SnapshotObjectTO snapshot = (SnapshotObjectTO)srcData;
|
||||
template.setFormat(snapshot.getVolume().getFormat());
|
||||
return new CopyCmdAnswer(template);
|
||||
} else if (destDataStore instanceof S3TO) {
|
||||
//create template on the same data store
|
||||
CopyCmdAnswer answer = (CopyCmdAnswer)copySnapshotToTemplateFromNfsToNfs(cmd, (SnapshotObjectTO) srcData, (NfsTO) srcDataStore,
|
||||
(TemplateObjectTO) destData, (NfsTO) srcDataStore);
|
||||
if (!answer.getResult()) {
|
||||
return answer;
|
||||
}
|
||||
TemplateObjectTO newTemplate = (TemplateObjectTO)answer.getNewData();
|
||||
newTemplate.setDataStore(srcDataStore);
|
||||
CopyCommand newCpyCmd = new CopyCommand(newTemplate, destData, cmd.getWait(), cmd.executeInSequence());
|
||||
return copyFromNfsToS3(newCpyCmd);
|
||||
}
|
||||
}
|
||||
return new CopyCmdAnswer("");
|
||||
s_logger.debug("Failed to create templat from snapshot");
|
||||
return new CopyCmdAnswer("Unsupported prototcol");
|
||||
}
|
||||
|
||||
protected Answer copyFromNfsToImage(CopyCommand cmd) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue