From 10f65b67d7dabab78404d1cc5e03978d4bcd25d5 Mon Sep 17 00:00:00 2001 From: Abhisar Sinha <63767682+abh1sar@users.noreply.github.com> Date: Sun, 25 Jan 2026 11:39:40 +0530 Subject: [PATCH] image upload working --- .../cloudstack/backup/ImageTransfer.java | 2 +- .../cloudstack/backup/ImageTransferVO.java | 2 +- .../backup/dao/ImageTransferDao.java | 2 ++ .../backup/dao/ImageTransferDaoImpl.java | 12 +++++++ .../backup/IncrementalBackupServiceImpl.java | 27 +++++++-------- .../resource/NfsSecondaryStorageResource.java | 33 ++++++++++++++++++- 6 files changed, 62 insertions(+), 16 deletions(-) diff --git a/api/src/main/java/org/apache/cloudstack/backup/ImageTransfer.java b/api/src/main/java/org/apache/cloudstack/backup/ImageTransfer.java index f43be2bdafe..ca6b546e04f 100644 --- a/api/src/main/java/org/apache/cloudstack/backup/ImageTransfer.java +++ b/api/src/main/java/org/apache/cloudstack/backup/ImageTransfer.java @@ -33,7 +33,7 @@ public interface ImageTransfer extends ControlledEntity, InternalIdentity { String getUuid(); - long getBackupId(); + Long getBackupId(); long getDiskId(); diff --git a/engine/schema/src/main/java/org/apache/cloudstack/backup/ImageTransferVO.java b/engine/schema/src/main/java/org/apache/cloudstack/backup/ImageTransferVO.java index 4990a168a05..25e5b213ca8 100644 --- a/engine/schema/src/main/java/org/apache/cloudstack/backup/ImageTransferVO.java +++ b/engine/schema/src/main/java/org/apache/cloudstack/backup/ImageTransferVO.java @@ -117,7 +117,7 @@ public class ImageTransferVO implements ImageTransfer { } @Override - public long getBackupId() { + public Long getBackupId() { return backupId; } diff --git a/engine/schema/src/main/java/org/apache/cloudstack/backup/dao/ImageTransferDao.java b/engine/schema/src/main/java/org/apache/cloudstack/backup/dao/ImageTransferDao.java index e5e57c4acda..805e23d3358 100644 --- a/engine/schema/src/main/java/org/apache/cloudstack/backup/dao/ImageTransferDao.java +++ b/engine/schema/src/main/java/org/apache/cloudstack/backup/dao/ImageTransferDao.java @@ -27,4 +27,6 @@ public interface ImageTransferDao extends GenericDao { List listByBackupId(Long backupId); ImageTransferVO findByUuid(String uuid); ImageTransferVO findByNbdPort(int port); + + ImageTransferVO findByVolume(Long volumeId); } diff --git a/engine/schema/src/main/java/org/apache/cloudstack/backup/dao/ImageTransferDaoImpl.java b/engine/schema/src/main/java/org/apache/cloudstack/backup/dao/ImageTransferDaoImpl.java index 57587858661..2a34650f210 100644 --- a/engine/schema/src/main/java/org/apache/cloudstack/backup/dao/ImageTransferDaoImpl.java +++ b/engine/schema/src/main/java/org/apache/cloudstack/backup/dao/ImageTransferDaoImpl.java @@ -34,6 +34,7 @@ public class ImageTransferDaoImpl extends GenericDaoBase private SearchBuilder backupIdSearch; private SearchBuilder uuidSearch; private SearchBuilder nbdPortSearch; + private SearchBuilder volumeSearch; public ImageTransferDaoImpl() { } @@ -51,6 +52,10 @@ public class ImageTransferDaoImpl extends GenericDaoBase nbdPortSearch = createSearchBuilder(); nbdPortSearch.and("nbdPort", nbdPortSearch.entity().getNbdPort(), SearchCriteria.Op.EQ); nbdPortSearch.done(); + + volumeSearch = createSearchBuilder(); + volumeSearch.and("volumeId", volumeSearch.entity().getDiskId(), SearchCriteria.Op.EQ); + volumeSearch.done(); } @Override @@ -73,4 +78,11 @@ public class ImageTransferDaoImpl extends GenericDaoBase sc.setParameters("nbdPort", port); return findOneBy(sc); } + + @Override + public ImageTransferVO findByVolume(Long volumeId) { + SearchCriteria sc = volumeSearch.create(); + sc.setParameters("volumeId", volumeId); + return findOneBy(sc); + } } diff --git a/server/src/main/java/org/apache/cloudstack/backup/IncrementalBackupServiceImpl.java b/server/src/main/java/org/apache/cloudstack/backup/IncrementalBackupServiceImpl.java index 9c5943b9e80..5eb83516a0e 100644 --- a/server/src/main/java/org/apache/cloudstack/backup/IncrementalBackupServiceImpl.java +++ b/server/src/main/java/org/apache/cloudstack/backup/IncrementalBackupServiceImpl.java @@ -273,20 +273,14 @@ public class IncrementalBackupServiceImpl extends ManagerBase implements Increme } } - private ImageTransferVO createDownloadImageTransfer(CreateImageTransferCmd cmd) { + private ImageTransferVO createDownloadImageTransfer(CreateImageTransferCmd cmd, VolumeVO volume) { Long backupId = cmd.getBackupId(); - Long volumeId = cmd.getVolumeId(); BackupVO backup = backupDao.findById(backupId); if (backup == null) { throw new CloudRuntimeException("Backup not found: " + backupId); } boolean dummyOffering = isDummyOffering(backup.getBackupOfferingId()); - Volume volume = volumeDao.findById(volumeId); - if (volume == null) { - throw new CloudRuntimeException("Volume not found: " + volumeId); - } - String transferId = UUID.randomUUID().toString(); Host host = hostDao.findById(backup.getHostId()); CreateImageTransferCommand transferCmd = new CreateImageTransferCommand( @@ -315,7 +309,7 @@ public class IncrementalBackupServiceImpl extends ManagerBase implements Increme ImageTransferVO imageTransfer = new ImageTransferVO( transferId, backupId, - volumeId, + volume.getId(), backup.getHostId(), backup.getNbdPort(), ImageTransferVO.Phase.transferring, @@ -345,17 +339,16 @@ public class IncrementalBackupServiceImpl extends ManagerBase implements Increme return hosts.get(0); } - private ImageTransferVO createUploadImageTransfer(CreateImageTransferCmd cmd) { + private ImageTransferVO createUploadImageTransfer(CreateImageTransferCmd cmd, VolumeVO volume) { String transferId = UUID.randomUUID().toString(); int nbdPort = allocateNbdPort(); - VolumeVO volume = volumeDao.findById(cmd.getVolumeId()); Long poolId = volume.getPoolId(); StoragePoolVO storagePoolVO = primaryDataStoreDao.findById(poolId); Host host = getFirstHostFromStoragePool(storagePoolVO); + // todo: This only works with file based storage (not ceph, linbit) String volumePath = String.format("/mnt/%s/%s", storagePoolVO.getUuid(), volume.getPath()); - StartNBDServerAnswer nbdServerAnswer; StartNBDServerCommand nbdServerCmd = new StartNBDServerCommand( transferId, @@ -415,10 +408,18 @@ public class IncrementalBackupServiceImpl extends ManagerBase implements Increme @Override public ImageTransferResponse createImageTransfer(CreateImageTransferCmd cmd) { ImageTransfer imageTransfer; + Long volumeId = cmd.getVolumeId(); + VolumeVO volume = volumeDao.findById(cmd.getVolumeId()); + + ImageTransferVO existingTransfer = imageTransferDao.findByVolume(volume.getId()); + if (existingTransfer != null) { + throw new CloudRuntimeException("Image transfer already in progress for volume: " + volume.getUuid()); + } + if (cmd.getDirection().equals(ImageTransfer.Direction.upload)) { - imageTransfer = createUploadImageTransfer(cmd); + imageTransfer = createUploadImageTransfer(cmd, volume); } else if (cmd.getDirection().equals(ImageTransfer.Direction.download)) { - imageTransfer = createDownloadImageTransfer(cmd); + imageTransfer = createDownloadImageTransfer(cmd, volume); } else { throw new CloudRuntimeException("Invalid direction: " + cmd.getDirection()); } diff --git a/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java b/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java index 70feb3d5a3c..88b93d7643b 100644 --- a/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java +++ b/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java @@ -3725,14 +3725,19 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S private boolean stopImageServer() { String unitName = "cloudstack-image-server"; + final int imageServerPort = 54323; Script checkScript = new Script("/bin/bash", logger); checkScript.add("-c"); checkScript.add(String.format("systemctl is-active --quiet %s", unitName)); String checkResult = checkScript.execute(); if (checkResult != null) { - logger.info(String.format("Image server not running, resetting failed state", unitName)); + logger.info(String.format("Image server not running, resetting failed state")); resetService(unitName); + // Still try to remove firewall rule in case it exists + if (_inSystemVM) { + removeFirewallRule(imageServerPort); + } return true; } @@ -3743,9 +3748,27 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S resetService(unitName); logger.info(String.format("Image server %s stopped", unitName)); + // Close firewall port for image server + if (_inSystemVM) { + removeFirewallRule(imageServerPort); + } + return true; } + private void removeFirewallRule(int port) { + String rule = String.format("-p tcp -m state --state NEW -m tcp --dport %d -j ACCEPT", port); + Script removeScript = new Script("/bin/bash", logger); + removeScript.add("-c"); + removeScript.add(String.format("iptables -D INPUT %s || true", rule)); + String result = removeScript.execute(); + if (result != null && !result.isEmpty() && !result.contains("iptables: Bad rule")) { + logger.debug(String.format("Firewall rule removal result for port %d: %s", port, result)); + } else { + logger.info(String.format("Firewall rule removed for port %d (or did not exist)", port)); + } + } + private boolean startImageServerIfNotRunning(int imageServerPort) { final String imageServerScript = "/opt/cloud/bin/image_server.py"; String unitName = "cloudstack-image-server"; @@ -3800,6 +3823,14 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S logger.error(String.format("Image server failed to start within %d seconds", maxWaitSeconds)); return false; } + + // Open firewall port for image server + if (_inSystemVM) { + String rule = String.format("-p tcp -m state --state NEW -m tcp --dport %d -j ACCEPT", imageServerPort); + IpTablesHelper.addConditionally(IpTablesHelper.INPUT_CHAIN, true, rule, + String.format("Error in opening up image server port %d", imageServerPort)); + } + return true; }