Make veeam-kvm exclusive with other providers

finalize all pending image transfers when finalize backup is called
This commit is contained in:
Abhisar Sinha 2026-03-31 07:52:56 +05:30 committed by Abhishek Kumar
parent ebdcf70c70
commit e32a6ab7d9
3 changed files with 20 additions and 16 deletions

View File

@ -58,7 +58,7 @@ public interface BackupManager extends BackupService, Configurable, PluggableSer
ConfigKey<String> BackupProviderPlugin = new ValidatedConfigKey<>("Advanced", String.class,
"backup.framework.provider.plugin",
"dummy",
"The backup and recovery provider plugin. Valid plugin values: dummy, veeam, networker, nas and veeam-kvm",
"The backup and recovery provider plugin. Valid plugin values: dummy, veeam, networker, nas",
true, ConfigKey.Scope.Zone, BackupFrameworkEnabled.key(), value -> validateBackupProviderConfig((String)value));
ConfigKey<Long> BackupSyncPollingInterval = new ConfigKey<>("Advanced", Long.class,
@ -263,7 +263,7 @@ public interface BackupManager extends BackupService, Configurable, PluggableSer
if (value != null && (value.contains(",") || value.trim().contains(" "))) {
throw new IllegalArgumentException("Multiple backup provider plugins are not supported. Please provide a single plugin value.");
}
List<String> validPlugins = List.of("dummy", "veeam", "networker", "nas", "veeam-kvm");
List<String> validPlugins = List.of("dummy", "veeam", "networker", "nas");
if (value != null && !validPlugins.contains(value)) {
throw new IllegalArgumentException("Invalid backup provider plugin: " + value + ". Valid plugin values are: " + String.join(", ", validPlugins));
}

View File

@ -34,7 +34,7 @@ import org.apache.cloudstack.framework.config.Configurable;
import com.cloud.utils.component.PluggableService;
/**
* Service for managing oVirt-style incremental backups using libvirt checkpoints
* Service for Creating Backups and ImageTransfer sessions which will be consumed by an external orchestrator.
*/
public interface KVMBackupExportService extends Configurable, PluggableService {
@ -43,7 +43,7 @@ public interface KVMBackupExportService extends Configurable, PluggableService {
"10",
"The image transfer progress polling interval in seconds.", true, ConfigKey.Scope.Global);
ConfigKey<Boolean> ExposeKVMBackupExportServiceApis = new ConfigKey<>("Hidden", Boolean.class,
ConfigKey<Boolean> ExposeKVMBackupExportServiceApis = new ConfigKey<>("Advanced", Boolean.class,
"expose.kvm.backup.export.service.apis",
"false",
"Enable to expose APIs for testing the KVM Backup Export Service.", false, ConfigKey.Scope.Global);

View File

@ -74,6 +74,7 @@ import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.VirtualMachine.State;
import com.cloud.vm.dao.VMInstanceDao;
import static org.apache.cloudstack.backup.BackupManager.BackupFrameworkEnabled;
import static org.apache.cloudstack.backup.BackupManager.BackupProviderPlugin;
@Component
@ -105,6 +106,10 @@ public class KVMBackupExportServiceImpl extends ManagerBase implements KVMBackup
private Timer imageTransferTimer;
private boolean isKVMBackupExportServiceSupported(Long zoneId) {
return !BackupFrameworkEnabled.value() || StringUtils.equals("dummy", BackupProviderPlugin.valueIn(zoneId));
}
@Override
public Backup createBackup(StartBackupCmd cmd) {
Long vmId = cmd.getVmId();
@ -114,9 +119,9 @@ public class KVMBackupExportServiceImpl extends ManagerBase implements KVMBackup
throw new CloudRuntimeException("VM not found: " + vmId);
}
if (!StringUtils.equals("veeam-kvm", BackupProviderPlugin.valueIn(vm.getDataCenterId()))) {
throw new CloudRuntimeException("Feature not enabled. Set Zone level config backup.framework.provider.plugin" +
" to \"veeam-kvm\" to enable the feature.");
if (!isKVMBackupExportServiceSupported(vm.getDataCenterId())) {
throw new CloudRuntimeException("Veeam-KVM integration can not be used along with the " + BackupProviderPlugin.valueIn(vm.getDataCenterId()) +
" backup provider. Either set backup.framework.enabled to false or set the Zone level config backup.framework.provider.plugin to \"dummy\".");
}
if (vm.getState() != State.Running && vm.getState() != State.Stopped) {
@ -248,10 +253,9 @@ public class KVMBackupExportServiceImpl extends ManagerBase implements KVMBackup
List<ImageTransferVO> transfers = imageTransferDao.listByBackupId(backupId);
for (ImageTransferVO transfer : transfers) {
if (transfer.getPhase() != ImageTransferVO.Phase.finished) {
updateBackupState(backup, Backup.Status.Failed);
throw new CloudRuntimeException(String.format("Image transfer %s not finalized for backup: %s", transfer.getUuid(), backup.getUuid()));
logger.warn("Finalize called for backup {} while Image transfer {} is not finalized, attempting to finalize it", backup.getUuid(), transfer.getUuid());
finalizeImageTransfer(transfer.getId());
}
imageTransferDao.remove(transfer.getId());
}
if (vm.getState() == State.Running) {
@ -496,9 +500,9 @@ public class KVMBackupExportServiceImpl extends ManagerBase implements KVMBackup
throw new CloudRuntimeException("Volume not found with the specified Id");
}
if (!StringUtils.equals("veeam-kvm", BackupProviderPlugin.valueIn(volume.getDataCenterId()))) {
throw new CloudRuntimeException("Feature not enabled. Set Zone level config backup.framework.provider.plugin" +
" to \"veeam-kvm\" to enable the feature.");
if (!isKVMBackupExportServiceSupported(volume.getDataCenterId())) {
throw new CloudRuntimeException("Veeam-KVM integration can not be used along with the " + BackupProviderPlugin.valueIn(volume.getDataCenterId()) +
" backup provider. Either set backup.framework.enabled to false or set the Zone level config backup.framework.provider.plugin to \"dummy\".");
}
ImageTransferVO existingTransfer = imageTransferDao.findUnfinishedByVolume(volume.getId());
@ -665,9 +669,9 @@ public class KVMBackupExportServiceImpl extends ManagerBase implements KVMBackup
if (vm == null) {
throw new CloudRuntimeException("VM not found: " + cmd.getVmId());
}
if (!StringUtils.equals("veeam-kvm", BackupProviderPlugin.valueIn(vm.getDataCenterId()))) {
throw new CloudRuntimeException("Feature not enabled. Set Zone level config backup.framework.provider.plugin" +
" to \"veeam-kvm\" to enable the feature.");
if (!isKVMBackupExportServiceSupported(vm.getDataCenterId())) {
throw new CloudRuntimeException("Veeam-KVM integration can not be used along with the " + BackupProviderPlugin.valueIn(vm.getDataCenterId()) +
" backup provider. Either set backup.framework.enabled to false or set the Zone level config backup.framework.provider.plugin to \"dummy\".");
}
vm.setActiveCheckpointId(null);