JoaoJandre commented on code in PR #6589:
URL: https://github.com/apache/cloudstack/pull/6589#discussion_r1332005642
##########
engine/schema/src/main/java/org/apache/cloudstack/backup/dao/BackupDaoImpl.java:
##########
@@ -141,32 +143,37 @@ public List<Backup> syncBackups(Long zoneId, Long vmId,
List<Backup> externalBac
@Override
public BackupResponse newBackupResponse(Backup backup) {
- VMInstanceVO vm =
vmInstanceDao.findByIdIncludingRemoved(backup.getVmId());
- AccountVO account =
accountDao.findByIdIncludingRemoved(vm.getAccountId());
- DomainVO domain = domainDao.findByIdIncludingRemoved(vm.getDomainId());
- DataCenterVO zone =
dataCenterDao.findByIdIncludingRemoved(vm.getDataCenterId());
- BackupOffering offering =
backupOfferingDao.findByIdIncludingRemoved(vm.getBackupOfferingId());
-
- BackupResponse response = new BackupResponse();
- response.setId(backup.getUuid());
- response.setVmId(vm.getUuid());
- response.setVmName(vm.getHostName());
- response.setExternalId(backup.getExternalId());
- response.setType(backup.getType());
- response.setDate(backup.getDate());
- response.setSize(backup.getSize());
- response.setProtectedSize(backup.getProtectedSize());
- response.setStatus(backup.getStatus());
- response.setVolumes(new
Gson().toJson(vm.getBackupVolumeList().toArray(), Backup.VolumeInfo[].class));
- response.setBackupOfferingId(offering.getUuid());
- response.setBackupOffering(offering.getName());
- response.setAccountId(account.getUuid());
- response.setAccount(account.getAccountName());
- response.setDomainId(domain.getUuid());
- response.setDomain(domain.getName());
- response.setZoneId(zone.getUuid());
- response.setZone(zone.getName());
- response.setObjectName("backup");
- return response;
+ try {
+ VMInstanceVO vm =
vmInstanceDao.findByIdIncludingRemoved(backup.getVmId());
+ AccountVO account =
accountDao.findByIdIncludingRemoved(vm.getAccountId());
+ DomainVO domain =
domainDao.findByIdIncludingRemoved(vm.getDomainId());
+ DataCenterVO zone =
dataCenterDao.findByIdIncludingRemoved(vm.getDataCenterId());
+ BackupOffering offering =
backupOfferingDao.findByIdIncludingRemoved(backup.getBackupOfferingId());
+
+ BackupResponse response = new BackupResponse();
+ response.setId(backup.getUuid());
+ response.setVmId(vm.getUuid());
+ response.setVmName(vm.getHostName());
+ response.setExternalId(backup.getExternalId());
+ response.setType(backup.getType());
+ response.setDate(backup.getDate());
+ response.setSize(backup.getSize());
+ response.setProtectedSize(backup.getProtectedSize());
+ response.setStatus(backup.getStatus());
+
response.setVolumes(GSON.toJson(vm.getBackupVolumeList().toArray(),
Backup.VolumeInfo[].class));
+ response.setBackupOfferingId(offering.getUuid());
+ response.setBackupOffering(offering.getName());
+ response.setAccountId(account.getUuid());
+ response.setAccount(account.getAccountName());
+ response.setDomainId(domain.getUuid());
+ response.setDomain(domain.getName());
+ response.setZoneId(zone.getUuid());
+ response.setZone(zone.getName());
+ response.setObjectName("backup");
+ return response;
+ } catch (Exception e) {
+ LOGGER.error(String.format("Failed to create backup response from
Backup [id: %s, vmId: %s] due to: [%s].", backup.getId(), backup.getVmId(),
e.getMessage()), e);
+ return null;
+ }
Review Comment:
Does this whole block need to be guarded with a Pokemon catch?
Which methods are we expecting to throw exceptions?
We can probably change the catch to a couple of exceptions.
##########
engine/schema/src/main/resources/META-INF/db/schema-41720to41800.sql:
##########
@@ -1562,6 +1562,21 @@ DELETE FROM `cloud`.`snapshot_store_ref`
WHERE store_role = "Primary" AND store_id IN (SELECT id FROM storage_pool
WHERE removed IS NOT NULL);
+ALTER TABLE `cloud`.`backups` ADD backup_volumes TEXT NULL COMMENT 'details of
backedup volumes';
+
+-- Populate column backup_volumes in table backups with a GSON
+-- formed by concatenating the UUID, type, size, path and deviceId
+-- of the volumes of VMs that have some backup offering.
+-- Required for the restore process of a backup using Veeam
+-- The Gson result can be in one of this formats:
+-- When VM has only ROOT disk:
[{"uuid":"<uuid>","type":"<type>","size":<size>,"path":"<path>","deviceId":<deviceId>}]
+-- When VM has more tha one disk:
[{"uuid":"<uuid>","type":"<type>","size":<size>,"path":"<path>","deviceId":<deviceId>},
{"uuid":"<uuid>","type":"<type>","size":<size>,"path":"<path>","deviceId":<deviceId>},
<>]
+UPDATE `cloud`.`backups` b INNER JOIN `cloud`.`vm_instance` vm ON b.vm_id =
vm.id SET b.backup_volumes = (SELECT CONCAT("[", GROUP_CONCAT(
CONCAT("{\"uuid\":\"", v.uuid, "\",\"type\":\"", v.volume_type, "\",\"size\":",
v.`size`, ",\"path\":\"", v.path, "\",\"deviceId\":", v.device_id, "}")
SEPARATOR ","), "]") FROM `cloud`.`volumes` v WHERE v.instance_id = vm.id);
+
+ALTER TABLE `cloud`.`vm_instance` ADD backup_name varchar(255) NULL COMMENT
'backup job name when using Veeam provider';
+
+UPDATE `cloud`.`vm_instance` vm INNER JOIN `cloud`.`backup_offering` bo ON
vm.backup_offering_id = bo.id SET vm.backup_name = CONCAT(vm.instance_name,
"-CSBKP-", vm.uuid);
+
Review Comment:
Change this to schema-41810to41900.sql
##########
plugins/backup/veeam/src/main/java/org/apache/cloudstack/backup/veeam/VeeamClient.java:
##########
@@ -505,41 +532,26 @@ public boolean addVMToVeeamJob(final String jobId, final
String vmwareInstanceNa
throw new CloudRuntimeException("Failed to add VM to backup offering
likely due to timeout, please check Veeam tasks");
}
- public boolean removeVMFromVeeamJob(final String jobId, final String
vmwareInstanceName, final String vmwareDcName) {
- LOG.debug("Trying to remove VM from backup offering that is a Veeam
job: " + jobId);
- try {
- final String hierarchyId = findDCHierarchy(vmwareDcName);
- final String veeamVmRefId = lookupVM(hierarchyId,
vmwareInstanceName);
- final HttpResponse response =
get(String.format("/jobs/%s/includes", jobId));
- checkResponseOK(response);
- final ObjectMapper objectMapper = new XmlMapper();
-
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,
false);
- final ObjectsInJob jobObjects =
objectMapper.readValue(response.getEntity().getContent(), ObjectsInJob.class);
- if (jobObjects == null || jobObjects.getObjects() == null) {
- LOG.warn("No objects found in the Veeam job " + jobId);
- return false;
- }
- for (final ObjectInJob jobObject : jobObjects.getObjects()) {
- if (jobObject.getName().equals(vmwareInstanceName) &&
jobObject.getHierarchyObjRef().equals(veeamVmRefId)) {
- final HttpResponse deleteResponse =
delete(String.format("/jobs/%s/includes/%s", jobId,
jobObject.getObjectInJobId()));
- return checkTaskStatus(deleteResponse);
- }
- }
- LOG.warn(vmwareInstanceName + " VM was not found to be attached to
Veaam job (backup offering): " + jobId);
- return false;
- } catch (final IOException e) {
- LOG.error("Failed to list Veeam jobs due to:", e);
- checkResponseTimeOut(e);
- }
- return false;
+ private boolean checkIfVmAlreadyExistsInJob(String jobId, String
vmwareInstanceName) {
+ jobId = jobId.replace("urn:veeam:Job:", "");
+ LOG.debug(String.format("Checking if VM [name: %s] is already assigned
to the Backup Job [name: %s].", vmwareInstanceName, jobId));
+ List<String> cmds = Arrays.asList(
+ String.format("$job = (Get-VBRJob ^| Where-Object { $_.Id -eq
'%s' })", jobId),
+ "if ($job) { ",
+ String.format("$vm = Get-VBRJobObject -Job $job -Name '%s'",
vmwareInstanceName),
+ "if ($vm) { Write-Output \"VM has already in Job\" } else {
Write-Output \"False\" }",
+ "} else { Write-Output \"False\" }"
+ );
+ Pair<Boolean, String> result = executePowerShellCommands(cmds);
+ return result.first() && !result.second().contains("False");
}
public boolean restoreFullVM(final String vmwareInstanceName, final String
restorePointId) {
LOG.debug("Trying to restore full VM: " + vmwareInstanceName + " from
backup");
try {
final HttpResponse response =
post(String.format("/vmRestorePoints/%s?action=restore", restorePointId), null);
return checkTaskStatus(response);
- } catch (final IOException e) {
+ } catch (final Exception e) {
Review Comment:
Why catch Exception here?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]