mirror of https://github.com/apache/cloudstack.git
server changes
Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>
This commit is contained in:
parent
3460a5de99
commit
b926c7474d
|
|
@ -22,7 +22,7 @@ import java.util.Map;
|
|||
import com.cloud.agent.api.Answer;
|
||||
|
||||
public class GetImageTransferProgressAnswer extends Answer {
|
||||
private Map<String, Integer> progressMap; // transferId -> progress percentage (0-100)
|
||||
private Map<String, Long> progressMap; // transferId -> progress percentage (0-100)
|
||||
|
||||
public GetImageTransferProgressAnswer() {
|
||||
}
|
||||
|
|
@ -32,16 +32,16 @@ public class GetImageTransferProgressAnswer extends Answer {
|
|||
}
|
||||
|
||||
public GetImageTransferProgressAnswer(GetImageTransferProgressCommand cmd, boolean success, String details,
|
||||
Map<String, Integer> progressMap) {
|
||||
Map<String, Long> progressMap) {
|
||||
super(cmd, success, details);
|
||||
this.progressMap = progressMap;
|
||||
}
|
||||
|
||||
public Map<String, Integer> getProgressMap() {
|
||||
public Map<String, Long> getProgressMap() {
|
||||
return progressMap;
|
||||
}
|
||||
|
||||
public void setProgressMap(Map<String, Integer> progressMap) {
|
||||
public void setProgressMap(Map<String, Long> progressMap) {
|
||||
this.progressMap = progressMap;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ public class LibvirtGetImageTransferProgressCommandWrapper extends CommandWrappe
|
|||
List<String> transferIds = cmd.getTransferIds();
|
||||
Map<String, String> volumePaths = cmd.getVolumePaths();
|
||||
Map<String, Long> volumeSizes = cmd.getVolumeSizes();
|
||||
Map<String, Integer> progressMap = new HashMap<>();
|
||||
Map<String, Long> progressMap = new HashMap<>();
|
||||
|
||||
if (transferIds == null || transferIds.isEmpty()) {
|
||||
return new GetImageTransferProgressAnswer(cmd, true, "No transfers to check", progressMap);
|
||||
|
|
@ -54,16 +54,16 @@ public class LibvirtGetImageTransferProgressCommandWrapper extends CommandWrappe
|
|||
Long volumeSize = volumeSizes.get(transferId);
|
||||
|
||||
if (volumePath == null || volumeSize == null || volumeSize == 0) {
|
||||
logger.warn("Missing volume path or size for transferId: " + transferId);
|
||||
progressMap.put(transferId, 0);
|
||||
logger.warn("Missing volume path or size for transferId: {}", transferId);
|
||||
progressMap.put(transferId, null);
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
File file = new File(volumePath);
|
||||
if (!file.exists()) {
|
||||
logger.warn("Volume file does not exist: " + volumePath);
|
||||
progressMap.put(transferId, 0);
|
||||
logger.warn("Volume file does not exist: {}", volumePath);
|
||||
progressMap.put(transferId, null);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -71,24 +71,17 @@ public class LibvirtGetImageTransferProgressCommandWrapper extends CommandWrappe
|
|||
|
||||
if (volumePath.endsWith(".qcow2") || volumePath.endsWith(".qcow")) {
|
||||
try {
|
||||
long virtualSize = KVMPhysicalDisk.getVirtualSizeFromFile(volumePath);
|
||||
currentSize = virtualSize;
|
||||
currentSize = KVMPhysicalDisk.getVirtualSizeFromFile(volumePath);
|
||||
} catch (Exception e) {
|
||||
logger.warn("Failed to get virtual size for qcow2 file: " + volumePath + ", using physical size", e);
|
||||
logger.warn("Failed to get virtual size for qcow2 file: {}, using physical size", volumePath, e);
|
||||
}
|
||||
}
|
||||
|
||||
int progress = 0;
|
||||
if (volumeSize > 0) {
|
||||
progress = (int) Math.min(100, Math.max(0, (currentSize * 100) / volumeSize));
|
||||
}
|
||||
|
||||
progressMap.put(transferId, progress);
|
||||
logger.debug("Transfer {} progress: {}% (current: {}, total: {})", transferId, progress, currentSize, volumeSize);
|
||||
progressMap.put(transferId, currentSize);
|
||||
logger.debug("Transfer {} progress, current: {})", transferId, currentSize, volumeSize);
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Error getting progress for transferId: " + transferId + ", path: " + volumePath, e);
|
||||
progressMap.put(transferId, 0);
|
||||
logger.error("Error getting progress for transferId: {}, path: {}", transferId, volumePath, e);
|
||||
progressMap.put(transferId, null);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ import java.util.stream.Collectors;
|
|||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.command.admin.backup.CreateImageTransferCmd;
|
||||
import org.apache.cloudstack.api.command.admin.backup.DeleteVmCheckpointCmd;
|
||||
import org.apache.cloudstack.api.command.admin.backup.FinalizeBackupCmd;
|
||||
|
|
@ -50,20 +51,27 @@ import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
|
|||
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
|
||||
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.collections.MapUtils;
|
||||
import org.joda.time.DateTime;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.cloud.agent.AgentManager;
|
||||
import com.cloud.agent.api.Answer;
|
||||
import com.cloud.api.ApiDBUtils;
|
||||
import com.cloud.exception.AgentUnavailableException;
|
||||
import com.cloud.exception.OperationTimedoutException;
|
||||
import com.cloud.host.Host;
|
||||
import com.cloud.host.HostVO;
|
||||
import com.cloud.host.dao.HostDao;
|
||||
import com.cloud.storage.ScopeType;
|
||||
import com.cloud.storage.Storage;
|
||||
import com.cloud.storage.Volume;
|
||||
import com.cloud.storage.VolumeDetailVO;
|
||||
import com.cloud.storage.VolumeStats;
|
||||
import com.cloud.storage.VolumeVO;
|
||||
import com.cloud.storage.dao.VolumeDao;
|
||||
import com.cloud.storage.dao.VolumeDetailsDao;
|
||||
import com.cloud.utils.NumbersUtil;
|
||||
import com.cloud.utils.component.ManagerBase;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.vm.VMInstanceVO;
|
||||
|
|
@ -85,6 +93,9 @@ public class IncrementalBackupServiceImpl extends ManagerBase implements Increme
|
|||
@Inject
|
||||
private VolumeDao volumeDao;
|
||||
|
||||
@Inject
|
||||
private VolumeDetailsDao volumeDetailsDao;
|
||||
|
||||
@Inject
|
||||
private AgentManager agentManager;
|
||||
|
||||
|
|
@ -653,6 +664,7 @@ public class IncrementalBackupServiceImpl extends ManagerBase implements Increme
|
|||
|
||||
Map<Long, List<ImageTransferVO>> transfersByHost = transferringTransfers.stream()
|
||||
.collect(Collectors.groupingBy(ImageTransferVO::getHostId));
|
||||
Map<Long, VolumeVO> transferVolumeMap = new HashMap<>();
|
||||
|
||||
for (Map.Entry<Long, List<ImageTransferVO>> entry : transfersByHost.entrySet()) {
|
||||
Long hostId = entry.getKey();
|
||||
|
|
@ -669,6 +681,7 @@ public class IncrementalBackupServiceImpl extends ManagerBase implements Increme
|
|||
logger.warn("Volume not found for image transfer: " + transfer.getUuid());
|
||||
continue;
|
||||
}
|
||||
transferVolumeMap.put(transfer.getId(), volume);
|
||||
|
||||
String transferId = transfer.getUuid();
|
||||
transferIds.add(transferId);
|
||||
|
|
@ -693,23 +706,27 @@ public class IncrementalBackupServiceImpl extends ManagerBase implements Increme
|
|||
GetImageTransferProgressCommand cmd = new GetImageTransferProgressCommand(transferIds, volumePaths, volumeSizes);
|
||||
GetImageTransferProgressAnswer answer = (GetImageTransferProgressAnswer) agentManager.send(hostId, cmd);
|
||||
|
||||
if (answer != null && answer.getResult() && answer.getProgressMap() != null) {
|
||||
for (ImageTransferVO transfer : hostTransfers) {
|
||||
String transferId = transfer.getUuid();
|
||||
Integer progress = answer.getProgressMap().get(transferId);
|
||||
if (progress != null) {
|
||||
transfer.setProgress(progress);
|
||||
if (progress == 100) {
|
||||
transfer.setPhase(ImageTransfer.Phase.finished);
|
||||
logger.debug("Updated phase for image transfer {} to finished", transferId);
|
||||
}
|
||||
imageTransferDao.update(transfer.getId(), transfer);
|
||||
logger.debug("Updated progress for image transfer {}: {}%", transferId, progress);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (answer == null || !answer.getResult() || MapUtils.isEmpty(answer.getProgressMap())) {
|
||||
logger.warn("Failed to get progress for transfers on host {}: {}", hostId,
|
||||
answer != null ? answer.getDetails() : "null answer");
|
||||
return;
|
||||
}
|
||||
for (ImageTransferVO transfer : hostTransfers) {
|
||||
String transferId = transfer.getUuid();
|
||||
Long currentSize = answer.getProgressMap().get(transferId);
|
||||
if (currentSize == null) {
|
||||
continue;
|
||||
}
|
||||
VolumeVO volume = transferVolumeMap.get(transfer.getId());
|
||||
long totalSize = getVolumeTotalSize(volume);
|
||||
int progress = Math.max((int)((currentSize * 100) / totalSize), 100);
|
||||
transfer.setProgress(progress);
|
||||
if (currentSize >= 100) {
|
||||
transfer.setPhase(ImageTransfer.Phase.finished);
|
||||
logger.debug("Updated phase for image transfer {} to finished", transferId);
|
||||
}
|
||||
imageTransferDao.update(transfer.getId(), transfer);
|
||||
logger.debug("Updated progress for image transfer {}: {}%", transferId, progress);
|
||||
}
|
||||
|
||||
} catch (AgentUnavailableException | OperationTimedoutException e) {
|
||||
|
|
@ -724,6 +741,31 @@ public class IncrementalBackupServiceImpl extends ManagerBase implements Increme
|
|||
}
|
||||
}
|
||||
|
||||
private long getVolumeTotalSize(VolumeVO volume) {
|
||||
VolumeDetailVO detail = volumeDetailsDao.findDetail(volume.getId(), ApiConstants.VIRTUAL_SIZE);
|
||||
if (detail != null) {
|
||||
long size = NumbersUtil.parseLong(detail.getValue(), 0L);
|
||||
if (size > 0) {
|
||||
return size;
|
||||
}
|
||||
}
|
||||
ApiDBUtils.getVolumeStatistics(volume.getPath());
|
||||
VolumeStats vs = null;
|
||||
if (List.of(Storage.ImageFormat.VHD, Storage.ImageFormat.QCOW2, Storage.ImageFormat.RAW).contains(volume.getFormat())) {
|
||||
if (volume.getPath() != null) {
|
||||
vs = ApiDBUtils.getVolumeStatistics(volume.getPath());
|
||||
}
|
||||
} else if (volume.getFormat() == Storage.ImageFormat.OVA) {
|
||||
if (volume.getChainInfo() != null) {
|
||||
vs = ApiDBUtils.getVolumeStatistics(volume.getChainInfo());
|
||||
}
|
||||
}
|
||||
if (vs != null && vs.getPhysicalSize() > 0) {
|
||||
return vs.getPhysicalSize();
|
||||
}
|
||||
return volume.getSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getConfigComponentName() {
|
||||
return IncrementalBackupService.class.getSimpleName();
|
||||
|
|
|
|||
|
|
@ -586,14 +586,6 @@ class Handler(BaseHTTPRequestHandler):
|
|||
try:
|
||||
logging.info("PUT start image_id=%s content_length=%d", image_id, content_length)
|
||||
with _NbdConn(cfg["host"], int(cfg["port"]), cfg.get("export")) as conn:
|
||||
size = conn.size()
|
||||
if content_length != size:
|
||||
self._send_error_json(
|
||||
HTTPStatus.BAD_REQUEST,
|
||||
f"Content-Length must equal image size ({size})",
|
||||
)
|
||||
return
|
||||
|
||||
offset = 0
|
||||
remaining = content_length
|
||||
while remaining > 0:
|
||||
|
|
|
|||
Loading…
Reference in New Issue