mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
delete snapshot at the backend
This commit is contained in:
parent
c6a5a7ee00
commit
879a954b98
@ -53,8 +53,8 @@ public class SnapshotCommand extends Command {
|
|||||||
public SnapshotCommand(StoragePool pool,
|
public SnapshotCommand(StoragePool pool,
|
||||||
String secondaryStorageUrl, String snapshotUuid,
|
String secondaryStorageUrl, String snapshotUuid,
|
||||||
String snapshotName, Long dcId, Long accountId, Long volumeId) {
|
String snapshotName, Long dcId, Long accountId, Long volumeId) {
|
||||||
this.primaryStoragePoolNameLabel = pool.getUuid();
|
// this.primaryStoragePoolNameLabel = pool.getUuid();
|
||||||
this.primaryPool = new StorageFilerTO(pool);
|
//this.primaryPool = new StorageFilerTO(pool);
|
||||||
this.snapshotUuid = snapshotUuid;
|
this.snapshotUuid = snapshotUuid;
|
||||||
this.secondaryStorageUrl = secondaryStorageUrl;
|
this.secondaryStorageUrl = secondaryStorageUrl;
|
||||||
this.dcId = dcId;
|
this.dcId = dcId;
|
||||||
|
|||||||
@ -25,8 +25,6 @@ import org.apache.cloudstack.storage.command.DeleteCommand;
|
|||||||
import org.apache.cloudstack.storage.command.DettachCommand;
|
import org.apache.cloudstack.storage.command.DettachCommand;
|
||||||
|
|
||||||
import com.cloud.agent.api.Answer;
|
import com.cloud.agent.api.Answer;
|
||||||
import com.cloud.agent.api.to.DataTO;
|
|
||||||
import com.cloud.agent.api.to.DiskTO;
|
|
||||||
|
|
||||||
public interface StorageProcessor {
|
public interface StorageProcessor {
|
||||||
public Answer copyTemplateToPrimaryStorage(CopyCommand cmd);
|
public Answer copyTemplateToPrimaryStorage(CopyCommand cmd);
|
||||||
@ -43,4 +41,5 @@ public interface StorageProcessor {
|
|||||||
public Answer createSnapshot(CreateObjectCommand cmd);
|
public Answer createSnapshot(CreateObjectCommand cmd);
|
||||||
public Answer deleteVolume(DeleteCommand cmd);
|
public Answer deleteVolume(DeleteCommand cmd);
|
||||||
public Answer createVolumeFromSnapshot(CopyCommand cmd);
|
public Answer createVolumeFromSnapshot(CopyCommand cmd);
|
||||||
|
public Answer deleteSnapshot(DeleteCommand cmd);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -110,6 +110,8 @@ public class StorageSubsystemCommandHandlerBase implements StorageSubsystemComma
|
|||||||
Answer answer = null;
|
Answer answer = null;
|
||||||
if (data.getObjectType() == DataObjectType.VOLUME) {
|
if (data.getObjectType() == DataObjectType.VOLUME) {
|
||||||
answer = processor.deleteVolume(cmd);
|
answer = processor.deleteVolume(cmd);
|
||||||
|
} else if (data.getObjectType() == DataObjectType.SNAPSHOT) {
|
||||||
|
answer = processor.deleteSnapshot(cmd);
|
||||||
} else {
|
} else {
|
||||||
answer = new Answer(cmd, false, "unsupported type");
|
answer = new Answer(cmd, false, "unsupported type");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -51,6 +51,7 @@ 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;
|
||||||
|
import com.cloud.utils.script.Script;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
public class MockLocalNfsSecondaryStorageResource extends
|
public class MockLocalNfsSecondaryStorageResource extends
|
||||||
@ -67,6 +68,8 @@ public class MockLocalNfsSecondaryStorageResource extends
|
|||||||
// TODO Auto-generated catch block
|
// TODO Auto-generated catch block
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
createTemplateFromSnapshotXenScript = Script.findScript(getDefaultScriptsDir(), "create_privatetemplate_from_snapshot_xen.sh");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
_storage = new JavaStorageLayer();
|
_storage = new JavaStorageLayer();
|
||||||
|
|||||||
@ -0,0 +1,20 @@
|
|||||||
|
package org.apache.cloudstack.storage.test;
|
||||||
|
|
||||||
|
import org.apache.cloudstack.storage.LocalHostEndpoint;
|
||||||
|
import org.apache.cloudstack.storage.command.CopyCommand;
|
||||||
|
import org.apache.cloudstack.storage.command.DownloadCommand;
|
||||||
|
|
||||||
|
import com.cloud.agent.api.Answer;
|
||||||
|
import com.cloud.agent.api.Command;
|
||||||
|
import com.cloud.agent.api.DeleteSnapshotBackupCommand;
|
||||||
|
|
||||||
|
public class MockLocalHostEndPoint extends LocalHostEndpoint {
|
||||||
|
@Override
|
||||||
|
public Answer sendMessage(Command cmd) {
|
||||||
|
if ((cmd instanceof CopyCommand) || (cmd instanceof DownloadCommand) || (cmd instanceof DeleteSnapshotBackupCommand)) {
|
||||||
|
return resource.executeRequest(cmd);
|
||||||
|
}
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return new Answer(cmd, false, "unsupported command:" + cmd.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -156,6 +156,7 @@ public class SnapshotTest extends CloudStackTestNGBase {
|
|||||||
long primaryStoreId;
|
long primaryStoreId;
|
||||||
VMTemplateVO image;
|
VMTemplateVO image;
|
||||||
String imageStoreName = "testImageStore";
|
String imageStoreName = "testImageStore";
|
||||||
|
RemoteHostEndPoint remoteEp;
|
||||||
@Test(priority = -1)
|
@Test(priority = -1)
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
ComponentContext.initComponentsLifeCycle();
|
ComponentContext.initComponentsLifeCycle();
|
||||||
@ -250,6 +251,7 @@ public class SnapshotTest extends CloudStackTestNGBase {
|
|||||||
TemplateObjectTO to = new TemplateObjectTO();
|
TemplateObjectTO to = new TemplateObjectTO();
|
||||||
to.setPath(this.getImageInstallPath());
|
to.setPath(this.getImageInstallPath());
|
||||||
to.setFormat(ImageFormat.VHD);
|
to.setFormat(ImageFormat.VHD);
|
||||||
|
to.setSize(1000L);
|
||||||
CopyCmdAnswer answer = new CopyCmdAnswer(to);
|
CopyCmdAnswer answer = new CopyCmdAnswer(to);
|
||||||
templateOnStore.processEvent(Event.CreateOnlyRequested);
|
templateOnStore.processEvent(Event.CreateOnlyRequested);
|
||||||
templateOnStore.processEvent(Event.OperationSuccessed, answer);
|
templateOnStore.processEvent(Event.OperationSuccessed, answer);
|
||||||
@ -263,10 +265,10 @@ public class SnapshotTest extends CloudStackTestNGBase {
|
|||||||
hosts.add(this.host);
|
hosts.add(this.host);
|
||||||
Mockito.when(resourceMgr.listAllUpAndEnabledHosts((Type) Mockito.any(), Mockito.anyLong(), Mockito.anyLong(), Mockito.anyLong())).thenReturn(hosts);
|
Mockito.when(resourceMgr.listAllUpAndEnabledHosts((Type) Mockito.any(), Mockito.anyLong(), Mockito.anyLong(), Mockito.anyLong())).thenReturn(hosts);
|
||||||
|
|
||||||
RemoteHostEndPoint ep = RemoteHostEndPoint.getHypervisorHostEndPoint(this.host.getId(), this.host.getPrivateIpAddress());
|
remoteEp = RemoteHostEndPoint.getHypervisorHostEndPoint(this.host.getId(), this.host.getPrivateIpAddress());
|
||||||
Mockito.when(epSelector.select(Mockito.any(DataObject.class), Mockito.any(DataObject.class))).thenReturn(ep);
|
Mockito.when(epSelector.select(Mockito.any(DataObject.class), Mockito.any(DataObject.class))).thenReturn(remoteEp);
|
||||||
Mockito.when(epSelector.select(Mockito.any(DataObject.class))).thenReturn(ep);
|
Mockito.when(epSelector.select(Mockito.any(DataObject.class))).thenReturn(remoteEp);
|
||||||
Mockito.when(epSelector.select(Mockito.any(DataStore.class))).thenReturn(ep);
|
Mockito.when(epSelector.select(Mockito.any(DataStore.class))).thenReturn(remoteEp);
|
||||||
Mockito.when(hyGuruMgr.getGuruProcessedCommandTargetHost(Mockito.anyLong(), Mockito.any(Command.class))).thenReturn(this.host.getId());
|
Mockito.when(hyGuruMgr.getGuruProcessedCommandTargetHost(Mockito.anyLong(), Mockito.any(Command.class))).thenReturn(this.host.getId());
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -360,20 +362,35 @@ public class SnapshotTest extends CloudStackTestNGBase {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
//@Test
|
@Test
|
||||||
public void createSnapshot() {
|
public void createSnapshot() {
|
||||||
VolumeInfo vol = createCopyBaseImage();
|
VolumeInfo vol = createCopyBaseImage();
|
||||||
SnapshotVO snapshotVO = createSnapshotInDb(vol);
|
SnapshotVO snapshotVO = createSnapshotInDb(vol);
|
||||||
SnapshotInfo snapshot = this.snapshotFactory.getSnapshot(snapshotVO.getId(), vol.getDataStore());
|
SnapshotInfo snapshot = this.snapshotFactory.getSnapshot(snapshotVO.getId(), vol.getDataStore());
|
||||||
|
SnapshotInfo newSnapshot = null;
|
||||||
for (SnapshotStrategy strategy : this.snapshotStrategies) {
|
for (SnapshotStrategy strategy : this.snapshotStrategies) {
|
||||||
if (strategy.canHandle(snapshot)) {
|
if (strategy.canHandle(snapshot)) {
|
||||||
strategy.takeSnapshot(snapshot);
|
newSnapshot = strategy.takeSnapshot(snapshot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
AssertJUnit.assertNotNull(newSnapshot);
|
||||||
|
|
||||||
|
LocalHostEndpoint ep = new MockLocalHostEndPoint();
|
||||||
|
ep.setResource(new MockLocalNfsSecondaryStorageResource());
|
||||||
|
Mockito.when(epSelector.select(Mockito.any(DataStore.class))).thenReturn(ep);
|
||||||
|
|
||||||
|
//delete snapshot
|
||||||
|
for (SnapshotStrategy strategy : this.snapshotStrategies) {
|
||||||
|
if (strategy.canHandle(snapshot)) {
|
||||||
|
strategy.deleteSnapshot(newSnapshot.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Mockito.when(epSelector.select(Mockito.any(DataStore.class))).thenReturn(remoteEp);
|
||||||
}
|
}
|
||||||
|
|
||||||
private VMTemplateVO createTemplateInDb() {
|
private VMTemplateVO createTemplateInDb() {
|
||||||
image = new VMTemplateVO();
|
VMTemplateVO image = new VMTemplateVO();
|
||||||
image.setTemplateType(TemplateType.USER);
|
image.setTemplateType(TemplateType.USER);
|
||||||
|
|
||||||
image.setUniqueName(UUID.randomUUID().toString());
|
image.setUniqueName(UUID.randomUUID().toString());
|
||||||
@ -393,8 +410,50 @@ public class SnapshotTest extends CloudStackTestNGBase {
|
|||||||
image = imageDataDao.persist(image);
|
image = imageDataDao.persist(image);
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void createVolumeFromSnapshot() {
|
||||||
|
VolumeInfo vol = createCopyBaseImage();
|
||||||
|
SnapshotVO snapshotVO = createSnapshotInDb(vol);
|
||||||
|
SnapshotInfo snapshot = this.snapshotFactory.getSnapshot(snapshotVO.getId(), vol.getDataStore());
|
||||||
|
boolean result = false;
|
||||||
|
for (SnapshotStrategy strategy : this.snapshotStrategies) {
|
||||||
|
if (strategy.canHandle(snapshot)) {
|
||||||
|
snapshot = strategy.takeSnapshot(snapshot);
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//@Test
|
AssertJUnit.assertTrue(result);
|
||||||
|
|
||||||
|
VolumeVO volVO = createVolume(vol.getTemplateId(), vol.getPoolId());
|
||||||
|
VolumeInfo newVol = this.volFactory.getVolume(volVO.getId());
|
||||||
|
this.volumeService.createVolumeFromSnapshot(newVol, newVol.getDataStore(), snapshot);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void deleteSnapshot() {
|
||||||
|
VolumeInfo vol = createCopyBaseImage();
|
||||||
|
SnapshotVO snapshotVO = createSnapshotInDb(vol);
|
||||||
|
SnapshotInfo snapshot = this.snapshotFactory.getSnapshot(snapshotVO.getId(), vol.getDataStore());
|
||||||
|
SnapshotInfo newSnapshot = null;
|
||||||
|
for (SnapshotStrategy strategy : this.snapshotStrategies) {
|
||||||
|
if (strategy.canHandle(snapshot)) {
|
||||||
|
newSnapshot = strategy.takeSnapshot(snapshot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AssertJUnit.assertNotNull(newSnapshot);
|
||||||
|
|
||||||
|
//create another snapshot
|
||||||
|
for (SnapshotStrategy strategy : this.snapshotStrategies) {
|
||||||
|
if (strategy.canHandle(snapshot)) {
|
||||||
|
strategy.deleteSnapshot(newSnapshot.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void createTemplateFromSnapshot() {
|
public void createTemplateFromSnapshot() {
|
||||||
VolumeInfo vol = createCopyBaseImage();
|
VolumeInfo vol = createCopyBaseImage();
|
||||||
SnapshotVO snapshotVO = createSnapshotInDb(vol);
|
SnapshotVO snapshotVO = createSnapshotInDb(vol);
|
||||||
@ -417,23 +476,5 @@ public class SnapshotTest extends CloudStackTestNGBase {
|
|||||||
this.imageService.createTemplateFromSnapshotAsync(snapshot, tmpl, imageStore);
|
this.imageService.createTemplateFromSnapshotAsync(snapshot, tmpl, imageStore);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void createVolumeFromSnapshot() {
|
|
||||||
VolumeInfo vol = createCopyBaseImage();
|
|
||||||
SnapshotVO snapshotVO = createSnapshotInDb(vol);
|
|
||||||
SnapshotInfo snapshot = this.snapshotFactory.getSnapshot(snapshotVO.getId(), vol.getDataStore());
|
|
||||||
boolean result = false;
|
|
||||||
for (SnapshotStrategy strategy : this.snapshotStrategies) {
|
|
||||||
if (strategy.canHandle(snapshot)) {
|
|
||||||
snapshot = strategy.takeSnapshot(snapshot);
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AssertJUnit.assertTrue(result);
|
|
||||||
|
|
||||||
VolumeVO volVO = createVolume(vol.getTemplateId(), vol.getPoolId());
|
|
||||||
VolumeInfo newVol = this.volFactory.getVolume(volVO.getId());
|
|
||||||
this.volumeService.createVolumeFromSnapshot(newVol, newVol.getDataStore(), snapshot);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -299,6 +299,9 @@ public class SnapshotServiceImpl implements SnapshotService {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
SnapshotResult res = future.get();
|
SnapshotResult res = future.get();
|
||||||
|
if (res.isFailed()) {
|
||||||
|
throw new CloudRuntimeException(res.getResult());
|
||||||
|
}
|
||||||
SnapshotInfo destSnapshot = res.getSnashot();
|
SnapshotInfo destSnapshot = res.getSnashot();
|
||||||
return destSnapshot;
|
return destSnapshot;
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
@ -319,6 +322,12 @@ public class SnapshotServiceImpl implements SnapshotService {
|
|||||||
AsyncCallFuture<SnapshotResult> future = context.future;
|
AsyncCallFuture<SnapshotResult> future = context.future;
|
||||||
SnapshotResult snapResult = new SnapshotResult(destSnapshot, result.getAnswer());
|
SnapshotResult snapResult = new SnapshotResult(destSnapshot, result.getAnswer());
|
||||||
if (result.isFailed()) {
|
if (result.isFailed()) {
|
||||||
|
try {
|
||||||
|
destSnapshot.processEvent(Event.OperationFailed);
|
||||||
|
srcSnapshot.processEvent(Snapshot.Event.OperationFailed);
|
||||||
|
} catch (NoTransitionException e) {
|
||||||
|
s_logger.debug("Failed to update state: " + e.toString());
|
||||||
|
}
|
||||||
snapResult.setResult(result.getResult());
|
snapResult.setResult(result.getResult());
|
||||||
future.complete(snapResult);
|
future.complete(snapResult);
|
||||||
return null;
|
return null;
|
||||||
@ -397,7 +406,33 @@ public class SnapshotServiceImpl implements SnapshotService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean deleteSnapshot(SnapshotInfo snapInfo) {
|
public boolean deleteSnapshot(SnapshotInfo snapInfo) {
|
||||||
return true;
|
snapInfo.processEvent(ObjectInDataStoreStateMachine.Event.DestroyRequested);
|
||||||
|
|
||||||
|
AsyncCallFuture<SnapshotResult> future = new AsyncCallFuture<SnapshotResult>();
|
||||||
|
DeleteSnapshotContext<CommandResult> context = new DeleteSnapshotContext<CommandResult>(null,
|
||||||
|
snapInfo, future);
|
||||||
|
AsyncCallbackDispatcher<SnapshotServiceImpl, CommandResult> caller = AsyncCallbackDispatcher
|
||||||
|
.create(this);
|
||||||
|
caller.setCallback(
|
||||||
|
caller.getTarget().deleteSnapshotCallback(null, null))
|
||||||
|
.setContext(context);
|
||||||
|
DataStore store = snapInfo.getDataStore();
|
||||||
|
store.getDriver().deleteAsync(snapInfo, caller);
|
||||||
|
|
||||||
|
SnapshotResult result = null;
|
||||||
|
try {
|
||||||
|
result = future.get();
|
||||||
|
if (result.isFailed()) {
|
||||||
|
throw new CloudRuntimeException(result.getResult());
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
s_logger.debug("delete snapshot is failed: " + e.toString());
|
||||||
|
} catch (ExecutionException e) {
|
||||||
|
s_logger.debug("delete snapshot is failed: " + e.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -139,7 +139,7 @@ public class XenserverSnapshotStrategy extends SnapshotStrategyBase {
|
|||||||
SnapshotInfo child = snapshot.getChild();
|
SnapshotInfo child = snapshot.getChild();
|
||||||
SnapshotInfo parent = snapshot.getParent();
|
SnapshotInfo parent = snapshot.getParent();
|
||||||
if (child == null) {
|
if (child == null) {
|
||||||
if (!parent.getPath().equalsIgnoreCase(snapshot.getPath())) {
|
if (parent == null || !parent.getPath().equalsIgnoreCase(snapshot.getPath())) {
|
||||||
this.snapshotSvr.deleteSnapshot(snapshot);
|
this.snapshotSvr.deleteSnapshot(snapshot);
|
||||||
snapshot = parent;
|
snapshot = parent;
|
||||||
continue;
|
continue;
|
||||||
@ -178,9 +178,10 @@ public class XenserverSnapshotStrategy extends SnapshotStrategyBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
/*
|
||||||
if (snapshotOnPrimary != null) {
|
if (snapshotOnPrimary != null) {
|
||||||
deleteSnapshotChain(snapshotOnPrimary);
|
deleteSnapshotChain(snapshotOnPrimary);
|
||||||
}
|
}*/
|
||||||
|
|
||||||
SnapshotInfo snapshotOnImage = this.snapshotDataFactory.getSnapshot(snapshotId, DataStoreRole.Image);
|
SnapshotInfo snapshotOnImage = this.snapshotDataFactory.getSnapshot(snapshotId, DataStoreRole.Image);
|
||||||
if (snapshotOnImage != null) {
|
if (snapshotOnImage != null) {
|
||||||
|
|||||||
@ -36,7 +36,7 @@ import com.cloud.storage.download.DownloadListener;
|
|||||||
|
|
||||||
public class LocalHostEndpoint implements EndPoint {
|
public class LocalHostEndpoint implements EndPoint {
|
||||||
private ScheduledExecutorService executor;
|
private ScheduledExecutorService executor;
|
||||||
ServerResource resource;
|
protected ServerResource resource;
|
||||||
public LocalHostEndpoint() {
|
public LocalHostEndpoint() {
|
||||||
resource = new LocalNfsSecondaryStorageResource();
|
resource = new LocalNfsSecondaryStorageResource();
|
||||||
executor = Executors.newScheduledThreadPool(10);
|
executor = Executors.newScheduledThreadPool(10);
|
||||||
|
|||||||
@ -409,6 +409,8 @@ public class KVMStorageProcessor implements StorageProcessor {
|
|||||||
|
|
||||||
TemplateObjectTO newTemplate = new TemplateObjectTO();
|
TemplateObjectTO newTemplate = new TemplateObjectTO();
|
||||||
newTemplate.setPath(templateFolder + File.separator + templateName + ".qcow2");
|
newTemplate.setPath(templateFolder + File.separator + templateName + ".qcow2");
|
||||||
|
newTemplate.setSize(info.virtualSize);
|
||||||
|
newTemplate.setFormat(ImageFormat.QCOW2);
|
||||||
return new CopyCmdAnswer(newTemplate);
|
return new CopyCmdAnswer(newTemplate);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
s_logger.debug("Failed to create template from volume: " + e.toString());
|
s_logger.debug("Failed to create template from volume: " + e.toString());
|
||||||
@ -902,4 +904,8 @@ public class KVMStorageProcessor implements StorageProcessor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Answer deleteSnapshot(DeleteCommand cmd) {
|
||||||
|
return new Answer(cmd);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -69,6 +69,7 @@ import com.cloud.hypervisor.vmware.resource.VmwareResource;
|
|||||||
import com.cloud.hypervisor.vmware.util.VmwareContext;
|
import com.cloud.hypervisor.vmware.util.VmwareContext;
|
||||||
import com.cloud.hypervisor.vmware.util.VmwareHelper;
|
import com.cloud.hypervisor.vmware.util.VmwareHelper;
|
||||||
import com.cloud.serializer.GsonHelper;
|
import com.cloud.serializer.GsonHelper;
|
||||||
|
import com.cloud.storage.DataStoreRole;
|
||||||
import com.cloud.storage.JavaStorageLayer;
|
import com.cloud.storage.JavaStorageLayer;
|
||||||
import com.cloud.storage.StorageLayer;
|
import com.cloud.storage.StorageLayer;
|
||||||
import com.cloud.storage.Volume;
|
import com.cloud.storage.Volume;
|
||||||
@ -579,6 +580,7 @@ public class VmwareStorageProcessor implements StorageProcessor {
|
|||||||
TemplateObjectTO newTemplate = new TemplateObjectTO();
|
TemplateObjectTO newTemplate = new TemplateObjectTO();
|
||||||
newTemplate.setPath(template.getName());
|
newTemplate.setPath(template.getName());
|
||||||
newTemplate.setFormat(ImageFormat.OVA);
|
newTemplate.setFormat(ImageFormat.OVA);
|
||||||
|
newTemplate.setSize(result.third());
|
||||||
return new CopyCmdAnswer(newTemplate);
|
return new CopyCmdAnswer(newTemplate);
|
||||||
|
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
@ -1272,4 +1274,15 @@ public class VmwareStorageProcessor implements StorageProcessor {
|
|||||||
}
|
}
|
||||||
return new CopyCmdAnswer(details);
|
return new CopyCmdAnswer(details);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Answer deleteSnapshot(DeleteCommand cmd) {
|
||||||
|
SnapshotObjectTO snapshot = (SnapshotObjectTO)cmd.getData();
|
||||||
|
DataStoreTO store = snapshot.getDataStore();
|
||||||
|
if (store.getRole() == DataStoreRole.Primary) {
|
||||||
|
return new Answer(cmd);
|
||||||
|
} else {
|
||||||
|
return new Answer(cmd, false, "unsupported command");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -66,6 +66,7 @@ import com.cloud.agent.api.to.StorageFilerTO;
|
|||||||
import com.cloud.agent.api.to.SwiftTO;
|
import com.cloud.agent.api.to.SwiftTO;
|
||||||
import com.cloud.exception.InternalErrorException;
|
import com.cloud.exception.InternalErrorException;
|
||||||
import com.cloud.hypervisor.xen.resource.CitrixResourceBase.SRType;
|
import com.cloud.hypervisor.xen.resource.CitrixResourceBase.SRType;
|
||||||
|
import com.cloud.storage.DataStoreRole;
|
||||||
import com.cloud.storage.Storage.ImageFormat;
|
import com.cloud.storage.Storage.ImageFormat;
|
||||||
import com.cloud.storage.Storage.StoragePoolType;
|
import com.cloud.storage.Storage.StoragePoolType;
|
||||||
import com.cloud.storage.resource.StorageProcessor;
|
import com.cloud.storage.resource.StorageProcessor;
|
||||||
@ -1389,6 +1390,7 @@ public class XenServerStorageProcessor implements StorageProcessor {
|
|||||||
TemplateObjectTO newTemplate = new TemplateObjectTO();
|
TemplateObjectTO newTemplate = new TemplateObjectTO();
|
||||||
newTemplate.setPath(installPath);
|
newTemplate.setPath(installPath);
|
||||||
newTemplate.setFormat(ImageFormat.VHD);
|
newTemplate.setFormat(ImageFormat.VHD);
|
||||||
|
newTemplate.setSize(virtualSize);
|
||||||
CopyCmdAnswer answer = new CopyCmdAnswer(newTemplate);
|
CopyCmdAnswer answer = new CopyCmdAnswer(newTemplate);
|
||||||
return answer;
|
return answer;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@ -1470,4 +1472,32 @@ public class XenServerStorageProcessor implements StorageProcessor {
|
|||||||
// In all cases return something.
|
// In all cases return something.
|
||||||
return new CopyCmdAnswer(details);
|
return new CopyCmdAnswer(details);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Answer deleteSnapshot(DeleteCommand cmd) {
|
||||||
|
SnapshotObjectTO snapshot = (SnapshotObjectTO)cmd.getData();
|
||||||
|
DataStoreTO store = snapshot.getDataStore();
|
||||||
|
if (store.getRole() == DataStoreRole.Primary) {
|
||||||
|
Connection conn = this.hypervisorResource.getConnection();
|
||||||
|
VDI snapshotVdi = getVDIbyUuid(conn, snapshot.getPath());
|
||||||
|
if (snapshotVdi == null) {
|
||||||
|
return new Answer(null);
|
||||||
|
}
|
||||||
|
String errMsg = null;
|
||||||
|
try {
|
||||||
|
this.deleteVDI(conn, snapshotVdi);
|
||||||
|
} catch (BadServerResponse e) {
|
||||||
|
s_logger.debug("delete snapshot failed:" + e.toString());
|
||||||
|
errMsg = e.toString();
|
||||||
|
} catch (XenAPIException e) {
|
||||||
|
s_logger.debug("delete snapshot failed:" + e.toString());
|
||||||
|
errMsg = e.toString();
|
||||||
|
} catch (XmlRpcException e) {
|
||||||
|
s_logger.debug("delete snapshot failed:" + e.toString());
|
||||||
|
errMsg = e.toString();
|
||||||
|
}
|
||||||
|
return new Answer(cmd, false, errMsg);
|
||||||
|
}
|
||||||
|
return new Answer(cmd, false, "unsupported storage type");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -48,6 +48,7 @@ import org.apache.cloudstack.storage.snapshot.SnapshotObject;
|
|||||||
|
|
||||||
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.DeleteSnapshotBackupCommand;
|
||||||
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.DownloadAnswer;
|
||||||
@ -101,8 +102,6 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver {
|
|||||||
@Inject
|
@Inject
|
||||||
private S3Manager _s3Mgr;
|
private S3Manager _s3Mgr;
|
||||||
@Inject AccountDao _accountDao;
|
@Inject AccountDao _accountDao;
|
||||||
@Inject UserVmDao _userVmDao;
|
|
||||||
@Inject UserVmJoinDao _userVmJoinDao;
|
|
||||||
@Inject
|
@Inject
|
||||||
SecondaryStorageVmManager _ssvmMgr;
|
SecondaryStorageVmManager _ssvmMgr;
|
||||||
@Inject
|
@Inject
|
||||||
@ -280,46 +279,37 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver {
|
|||||||
|
|
||||||
UsageEventUtils.publishUsageEvent(eventType, account.getId(), sZoneId, templateId, null, null, null);
|
UsageEventUtils.publishUsageEvent(eventType, account.getId(), sZoneId, templateId, null, null, null);
|
||||||
|
|
||||||
List<UserVmJoinVO> userVmUsingIso = _userVmJoinDao.listActiveByIsoId(templateId);
|
// get installpath of this template on image store
|
||||||
// check if there is any VM using this ISO.
|
TemplateDataStoreVO tmplStore = _templateStoreDao.findByStoreTemplate(storeId, templateId);
|
||||||
if (userVmUsingIso == null || userVmUsingIso.isEmpty()) {
|
String installPath = tmplStore.getInstallPath();
|
||||||
// get installpath of this template on image store
|
if (installPath != null) {
|
||||||
TemplateDataStoreVO tmplStore = _templateStoreDao.findByStoreTemplate(storeId, templateId);
|
DeleteTemplateCommand cmd = new DeleteTemplateCommand(store.getTO(), installPath, template.getId(), template.getAccountId());
|
||||||
String installPath = tmplStore.getInstallPath();
|
EndPoint ep = _epSelector.select(templateObj);
|
||||||
if (installPath != null) {
|
Answer answer = ep.sendMessage(cmd);
|
||||||
DeleteTemplateCommand cmd = new DeleteTemplateCommand(store.getTO(), installPath, template.getId(), template.getAccountId());
|
|
||||||
EndPoint ep = _epSelector.select(templateObj);
|
|
||||||
Answer answer = ep.sendMessage(cmd);
|
|
||||||
|
|
||||||
if (answer == null || !answer.getResult()) {
|
if (answer == null || !answer.getResult()) {
|
||||||
s_logger.debug("Failed to deleted template at store: " + store.getName());
|
s_logger.debug("Failed to deleted template at store: " + store.getName());
|
||||||
CommandResult result = new CommandResult();
|
CommandResult result = new CommandResult();
|
||||||
result.setSuccess(false);
|
result.setSuccess(false);
|
||||||
result.setResult("Delete template failed");
|
result.setResult("Delete template failed");
|
||||||
callback.complete(result);
|
callback.complete(result);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
s_logger.debug("Deleted template at: " + installPath);
|
s_logger.debug("Deleted template at: " + installPath);
|
||||||
CommandResult result = new CommandResult();
|
CommandResult result = new CommandResult();
|
||||||
result.setSuccess(true);
|
result.setSuccess(true);
|
||||||
callback.complete(result);
|
callback.complete(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<VMTemplateZoneVO> templateZones = templateZoneDao.listByZoneTemplate(sZoneId, templateId);
|
List<VMTemplateZoneVO> templateZones = templateZoneDao.listByZoneTemplate(sZoneId, templateId);
|
||||||
if (templateZones != null) {
|
if (templateZones != null) {
|
||||||
for (VMTemplateZoneVO templateZone : templateZones) {
|
for (VMTemplateZoneVO templateZone : templateZones) {
|
||||||
templateZoneDao.remove(templateZone.getId());
|
templateZoneDao.remove(templateZone.getId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} else{
|
|
||||||
// cannot delete iso due to some VMs are using this
|
|
||||||
s_logger.debug("Cannot delete iso since some user vms are referencing it");
|
|
||||||
CommandResult result = new CommandResult();
|
|
||||||
result.setResult("Cannot delete iso since some user vms are referencing it");
|
|
||||||
callback.complete(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void deleteSnapshot(DataObject data, AsyncCompletionCallback<CommandResult> callback) {
|
private void deleteSnapshot(DataObject data, AsyncCompletionCallback<CommandResult> callback) {
|
||||||
@ -336,29 +326,17 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
/*String secondaryStoragePoolUrl = secStore.getUri();
|
String secondaryStoragePoolUrl = secStore.getUri();
|
||||||
Long dcId = snapshot.getDataCenterId();
|
|
||||||
Long accountId = snapshot.getAccountId();
|
|
||||||
Long volumeId = snapshot.getVolumeId();
|
|
||||||
|
|
||||||
String backupOfSnapshot = snapshotObj;
|
|
||||||
if (backupOfSnapshot == null) {
|
|
||||||
callback.complete(result);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
DeleteSnapshotBackupCommand cmd = new DeleteSnapshotBackupCommand(
|
DeleteSnapshotBackupCommand cmd = new DeleteSnapshotBackupCommand(
|
||||||
secStore.getTO(), secondaryStoragePoolUrl, dcId, accountId, volumeId,
|
secStore.getTO(), secondaryStoragePoolUrl, null, null, null,
|
||||||
backupOfSnapshot, false);
|
snapshotObj.getPath(), false);
|
||||||
EndPoint ep = _epSelector.select(secStore);
|
EndPoint ep = _epSelector.select(secStore);
|
||||||
Answer answer = ep.sendMessage(cmd);
|
Answer answer = ep.sendMessage(cmd);
|
||||||
|
|
||||||
if ((answer != null) && answer.getResult()) {
|
if (answer != null && !answer.getResult()) {
|
||||||
snapshot.setBackupSnapshotId(null);
|
|
||||||
snapshotDao.update(snapshotObj.getId(), snapshot);
|
|
||||||
} else if (answer != null) {
|
|
||||||
result.setResult(answer.getDetails());
|
result.setResult(answer.getDetails());
|
||||||
}*/
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
s_logger.debug("failed to delete snapshot: " + snapshotObj.getId() + ": " + e.toString());
|
s_logger.debug("failed to delete snapshot: " + snapshotObj.getId() + ": " + e.toString());
|
||||||
result.setResult(e.toString());
|
result.setResult(e.toString());
|
||||||
|
|||||||
@ -88,6 +88,8 @@ import com.cloud.agent.api.storage.DestroyCommand;
|
|||||||
import com.cloud.agent.api.to.DataTO;
|
import com.cloud.agent.api.to.DataTO;
|
||||||
import com.cloud.agent.api.to.DiskTO;
|
import com.cloud.agent.api.to.DiskTO;
|
||||||
import com.cloud.api.ApiDBUtils;
|
import com.cloud.api.ApiDBUtils;
|
||||||
|
import com.cloud.api.query.dao.UserVmJoinDao;
|
||||||
|
import com.cloud.api.query.vo.UserVmJoinVO;
|
||||||
import com.cloud.async.AsyncJobManager;
|
import com.cloud.async.AsyncJobManager;
|
||||||
import com.cloud.async.AsyncJobVO;
|
import com.cloud.async.AsyncJobVO;
|
||||||
import com.cloud.configuration.Config;
|
import com.cloud.configuration.Config;
|
||||||
@ -253,6 +255,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
@Inject VolumeManager _volumeMgr;
|
@Inject VolumeManager _volumeMgr;
|
||||||
@Inject ImageStoreDao _imageStoreDao;
|
@Inject ImageStoreDao _imageStoreDao;
|
||||||
@Inject EndPointSelector _epSelector;
|
@Inject EndPointSelector _epSelector;
|
||||||
|
@Inject UserVmJoinDao _userVmJoinDao;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
ConfigurationServer _configServer;
|
ConfigurationServer _configServer;
|
||||||
@ -1122,6 +1125,12 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
if (template.getFormat() != ImageFormat.ISO) {
|
if (template.getFormat() != ImageFormat.ISO) {
|
||||||
throw new InvalidParameterValueException("Please specify a valid iso.");
|
throw new InvalidParameterValueException("Please specify a valid iso.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<UserVmJoinVO> userVmUsingIso = _userVmJoinDao.listActiveByIsoId(templateId);
|
||||||
|
// check if there is any VM using this ISO.
|
||||||
|
if (!userVmUsingIso.isEmpty()) {
|
||||||
|
throw new InvalidParameterValueException("Unable to delete iso, as it's used by other vms");
|
||||||
|
}
|
||||||
|
|
||||||
if (zoneId != null && (this._dataStoreMgr.getImageStore(zoneId) == null)) {
|
if (zoneId != null && (this._dataStoreMgr.getImageStore(zoneId) == null)) {
|
||||||
throw new InvalidParameterValueException("Failed to find a secondary storage store in the specified zone.");
|
throw new InvalidParameterValueException("Failed to find a secondary storage store in the specified zone.");
|
||||||
|
|||||||
@ -45,6 +45,7 @@ import javax.naming.ConfigurationException;
|
|||||||
|
|
||||||
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.command.DeleteCommand;
|
||||||
import org.apache.cloudstack.storage.command.DownloadCommand;
|
import org.apache.cloudstack.storage.command.DownloadCommand;
|
||||||
import org.apache.cloudstack.storage.command.DownloadProgressCommand;
|
import org.apache.cloudstack.storage.command.DownloadProgressCommand;
|
||||||
import org.apache.cloudstack.storage.template.DownloadManager;
|
import org.apache.cloudstack.storage.template.DownloadManager;
|
||||||
@ -161,7 +162,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
|||||||
protected String _parent = "/mnt/SecStorage";
|
protected 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";
|
||||||
private String createTemplateFromSnapshotXenScript;
|
protected String createTemplateFromSnapshotXenScript;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void disconnected() {
|
public void disconnected() {
|
||||||
@ -223,7 +224,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
|||||||
return Answer.createUnsupportedCommandAnswer(cmd);
|
return Answer.createUnsupportedCommandAnswer(cmd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Answer copyFromS3ToNfs(CopyCommand cmd, DataTO srcData, S3TO s3, DataTO destData, NfsTO destImageStore) {
|
protected Answer copyFromS3ToNfs(CopyCommand cmd, DataTO srcData, S3TO s3, DataTO destData, NfsTO destImageStore) {
|
||||||
final String storagePath = destImageStore.getUrl();
|
final String storagePath = destImageStore.getUrl();
|
||||||
final String destPath = destData.getPath();
|
final String destPath = destData.getPath();
|
||||||
@ -353,7 +354,11 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
|||||||
command.add("-s", snapshotName);
|
command.add("-s", snapshotName);
|
||||||
command.add("-n", templateName);
|
command.add("-n", templateName);
|
||||||
command.add("-t", destPath);
|
command.add("-t", destPath);
|
||||||
command.execute();
|
String result = command.execute();
|
||||||
|
|
||||||
|
if (result != null && !result.equalsIgnoreCase("")) {
|
||||||
|
return new CopyCmdAnswer(result);
|
||||||
|
}
|
||||||
|
|
||||||
Map<String, Object> params = new HashMap<String, Object>();
|
Map<String, Object> params = new HashMap<String, Object>();
|
||||||
params.put(StorageLayer.InstanceConfigKey, _storage);
|
params.put(StorageLayer.InstanceConfigKey, _storage);
|
||||||
@ -1109,9 +1114,14 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
|||||||
|
|
||||||
private String deleteSnapshotBackupFromLocalFileSystem(final String secondaryStorageUrl, final Long accountId, final Long volumeId,
|
private String deleteSnapshotBackupFromLocalFileSystem(final String secondaryStorageUrl, final Long accountId, final Long volumeId,
|
||||||
final String name, final Boolean deleteAllFlag) {
|
final String name, final Boolean deleteAllFlag) {
|
||||||
|
String lPath = null;
|
||||||
final String lPath = determineSnapshotLocalDirectory(secondaryStorageUrl, accountId, volumeId) + File.pathSeparator
|
int index = name.lastIndexOf(File.separator);
|
||||||
+ (deleteAllFlag ? "*" : "*" + name + "*");
|
String snapshotPath = name.substring(0, index);
|
||||||
|
if (deleteAllFlag) {
|
||||||
|
lPath = this.getRootDir(secondaryStorageUrl) + File.separator + snapshotPath + File.separator + "*";
|
||||||
|
} else {
|
||||||
|
lPath = this.getRootDir(secondaryStorageUrl) + File.separator + name + "*";
|
||||||
|
}
|
||||||
|
|
||||||
final String result = deleteLocalFile(lPath);
|
final String result = deleteLocalFile(lPath);
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user