fix for disk restore

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>
This commit is contained in:
Abhishek Kumar 2026-05-07 18:54:45 +05:30
parent e2a7bd2e25
commit 6af5094443
3 changed files with 57 additions and 1 deletions

View File

@ -77,6 +77,10 @@ public class DetachVolumeCmd extends BaseAsyncCmd implements UserCmd {
return virtualMachineId;
}
public void setId(Long id) {
this.id = id;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////

View File

@ -73,6 +73,7 @@ import org.apache.cloudstack.api.command.user.volume.AssignVolumeCmd;
import org.apache.cloudstack.api.command.user.volume.AttachVolumeCmd;
import org.apache.cloudstack.api.command.user.volume.CreateVolumeCmd;
import org.apache.cloudstack.api.command.user.volume.DestroyVolumeCmd;
import org.apache.cloudstack.api.command.user.volume.DetachVolumeCmd;
import org.apache.cloudstack.api.command.user.volume.ListVolumesCmd;
import org.apache.cloudstack.api.command.user.volume.UpdateVolumeCmd;
import org.apache.cloudstack.api.command.user.zone.ListZonesCmd;
@ -198,6 +199,7 @@ import com.cloud.vm.NicVO;
import com.cloud.vm.UserVmManager;
import com.cloud.vm.UserVmVO;
import com.cloud.vm.VMInstanceDetailVO;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VmDetailConstants;
import com.cloud.vm.dao.NicDao;
import com.cloud.vm.dao.UserVmDao;
@ -1265,6 +1267,30 @@ public class ServerAdapter extends ManagerBase {
return VolumeJoinVOToDiskConverter.toDiskAttachment(attachedVolumeVO, this::getVolumePhysicalSize);
}
@ApiAccess(command = DetachVolumeCmd.class)
public void detachInstanceDisk(final String vmUuid, final String volumeUuid) {
UserVmVO vmVo = userVmDao.findByUuid(vmUuid);
if (vmVo == null) {
throw new InvalidParameterValueException("VM with ID " + vmUuid + " not found");
}
if (!VirtualMachine.State.Stopped.equals(vmVo.getState())) {
throw new InvalidParameterValueException("VM with ID " + vmUuid + " must be in stopped state to detach disk");
}
accountService.checkAccess(CallContext.current().getCallingAccount(), SecurityChecker.AccessType.OperateEntry,
false, vmVo);
VolumeVO volumeVo = volumeDao.findByUuid(volumeUuid);
if (volumeVo == null) {
throw new InvalidParameterValueException("Volume with ID " + volumeUuid + " not found");
}
if (volumeVo.getInstanceId() != vmVo.getId()) {
throw new InvalidParameterValueException("Volume with ID " + volumeUuid + " is not attached to VM with ID " + vmUuid);
}
DetachVolumeCmd cmd = new DetachVolumeCmd();
ComponentContext.inject(cmd);
cmd.setId(volumeVo.getId());
volumeApiService.detachVolumeFromVM(cmd);
}
@ApiAccess(command = CreateVolumeCmd.class)
public Disk createDisk(Disk request) {
if (request == null) {

View File

@ -19,6 +19,7 @@ package org.apache.cloudstack.veeam.api;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
@ -174,7 +175,14 @@ public class VmsRouteHandler extends ManagerBase implements RouteHandler {
} else if (idAndSubPath.size() == 3) {
String subPath = idAndSubPath.get(1);
String subId = idAndSubPath.get(2);
if ("snapshots".equals(subPath)) {
if ("diskattachments".equals(subPath)) {
if (!"DELETE".equalsIgnoreCase(method)) {
io.methodNotAllowed(resp, "DELETE", outFormat);
} else {
handleDeleteDiskAttachmentForVmId(id, subId, req, resp, outFormat, io);
}
return;
} else if ("snapshots".equals(subPath)) {
if (!"GET".equalsIgnoreCase(method) && !"DELETE".equalsIgnoreCase(method)) {
io.methodNotAllowed(resp, "GET, DELETE", outFormat);
} else if ("GET".equalsIgnoreCase(method)) {
@ -410,6 +418,24 @@ public class VmsRouteHandler extends ManagerBase implements RouteHandler {
}
}
protected void handleDeleteDiskAttachmentForVmId(final String vmId, final String diskId,
final HttpServletRequest req, final HttpServletResponse resp,
final Negotiation.OutFormat outFormat, final VeeamControlServlet io) throws IOException {
boolean delete = Boolean.FALSE.toString().equals(req.getParameter("detach_only"));
try {
serverAdapter.detachInstanceDisk(vmId, diskId);
if (delete) {
serverAdapter.deleteDisk(diskId);
}
Map<String, String> response = Map.of("status", "complete");
io.getWriter().write(resp, HttpServletResponse.SC_OK, response, outFormat);
} catch (InvalidParameterValueException e) {
io.notFound(resp, e.getMessage(), outFormat);
} catch (CloudRuntimeException e) {
io.badRequest(resp, e.getMessage(), outFormat);
}
}
protected void handleGetSnapshotById(final String id, final HttpServletResponse resp,
final Negotiation.OutFormat outFormat, final VeeamControlServlet io) throws IOException {
try {