Skip to content

Commit 8952215

Browse files
committed
Upgrade of backroll
1 parent dd07f56 commit 8952215

18 files changed

Lines changed: 212 additions & 243 deletions

File tree

api/src/main/java/org/apache/cloudstack/backup/BackupProvider.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,15 +101,15 @@ public interface BackupProvider {
101101

102102
/**
103103
* Syncs backup metrics (backup size, protected size) from the plugin and stores it within the provider
104-
* @param zoneId the zone for which to return metrics
104+
* @param zoneId the zone for which to synchronize metrics
105105
*/
106106
void syncBackupMetrics(Long zoneId);
107107

108108
/**
109109
* Returns a list of Backup.RestorePoint
110110
* @param vm the machine to get the restore points for
111111
*/
112-
List<Backup.RestorePoint> listRestorePoints(VirtualMachine vm);
112+
List<Backup.RestorePoint> listRestorePoints(VirtualMachine vm);
113113

114114
/**
115115
* Creates and returns an entry in the backups table by getting the information from restorePoint and vm.

plugins/backup/backroll/pom.xml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
<parent>
2626
<artifactId>cloudstack-plugins</artifactId>
2727
<groupId>org.apache.cloudstack</groupId>
28-
<version>4.21.0.0-SNAPSHOT</version>
28+
<version>4.23.0.0-SNAPSHOT</version>
2929
<relativePath>../../pom.xml</relativePath>
3030
</parent>
3131
<dependencies>
@@ -49,5 +49,10 @@
4949
<version>${cs.wiremock.version}</version>
5050
<scope>test</scope>
5151
</dependency>
52+
<dependency>
53+
<groupId>org.apache.cloudstack</groupId>
54+
<artifactId>cloud-engine-storage-volume</artifactId>
55+
<version>${project.version}</version>
56+
</dependency>
5257
</dependencies>
5358
</project>

plugins/backup/backroll/src/main/java/org/apache/cloudstack/backup/BackrollBackupProvider.java

Lines changed: 87 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,12 @@
1616
// under the License.
1717
package org.apache.cloudstack.backup;
1818

19-
import java.io.IOException;
20-
import java.net.URISyntaxException;
21-
import java.security.KeyManagementException;
22-
import java.security.NoSuchAlgorithmException;
23-
import java.util.ArrayList;
24-
import java.util.HashMap;
25-
import java.util.List;
26-
import java.util.Map;
27-
import java.util.Objects;
28-
import java.util.stream.Collectors;
29-
30-
import javax.inject.Inject;
31-
32-
19+
import com.cloud.utils.Pair;
20+
import com.cloud.utils.component.AdapterBase;
21+
import com.cloud.utils.exception.CloudRuntimeException;
22+
import com.cloud.vm.VMInstanceVO;
23+
import com.cloud.vm.VirtualMachine;
24+
import com.cloud.vm.dao.VMInstanceDao;
3325
import org.apache.cloudstack.backup.Backup.Metric;
3426
import org.apache.cloudstack.backup.Backup.RestorePoint;
3527
import org.apache.cloudstack.backup.backroll.BackrollClient;
@@ -40,19 +32,22 @@
4032
import org.apache.cloudstack.backup.dao.BackupDao;
4133
import org.apache.cloudstack.framework.config.ConfigKey;
4234
import org.apache.cloudstack.framework.config.Configurable;
43-
4435
import org.apache.commons.collections.CollectionUtils;
4536
import org.apache.commons.lang3.StringUtils;
4637
import org.apache.http.ParseException;
4738
import org.apache.logging.log4j.Logger;
4839
import org.joda.time.DateTime;
4940

50-
import com.cloud.utils.Pair;
51-
import com.cloud.utils.component.AdapterBase;
52-
import com.cloud.utils.exception.CloudRuntimeException;
53-
import com.cloud.vm.VMInstanceVO;
54-
import com.cloud.vm.VirtualMachine;
55-
import com.cloud.vm.dao.VMInstanceDao;
41+
import javax.inject.Inject;
42+
import java.io.IOException;
43+
import java.net.URISyntaxException;
44+
import java.security.KeyManagementException;
45+
import java.security.NoSuchAlgorithmException;
46+
import java.util.HashMap;
47+
import java.util.List;
48+
import java.util.Map;
49+
import java.util.Objects;
50+
import java.util.stream.Collectors;
5651

5752
public class BackrollBackupProvider extends AdapterBase implements BackupProvider, Configurable {
5853

@@ -88,6 +83,8 @@ public BackrollBackupProvider(BackupDao backupDao, VMInstanceDao vmInstanceDao,
8883
}
8984

9085
public BackrollBackupProvider(){}
86+
87+
private Map<VirtualMachine, Backup.Metric> backupFilesMetricsMap = new HashMap<>();
9188

9289
@Override
9390
public String getName() {
@@ -104,24 +101,14 @@ public List<BackupOffering> listBackupOfferings(Long zoneId) {
104101
logger.debug("Listing backup policies on backroll B&R Plugin");
105102
BackrollClient client = getClient(zoneId);
106103
try{
107-
String urlToRequest = client.getBackupOfferingUrl();
108-
logger.info("BackrollProvider: urlToRequest: " + urlToRequest);
109-
if (!StringUtils.isEmpty(urlToRequest)){
110-
List<BackupOffering> results = new ArrayList<BackupOffering>();
111-
// return client.getBackupOfferings(urlToRequest);
112-
results = client.getBackupOfferings(urlToRequest);
113-
if(results.size()>0) {
114-
logger.info("BackrollProvider: results > 0");
115-
} else {
116-
logger.info("BackrollProvider: results <= 0");
117-
}
118-
return results;
119-
}
104+
var results = client.getBackupOfferings();
105+
106+
logger.info("BackrollProvider: results " + (results.size() > 0 ? "> 0" : "<= 0"));
107+
return results;
120108
} catch (ParseException | BackrollApiException | IOException e) {
121109
logger.info("BackrollProvider: catch erreur: {}", e);
122110
throw new CloudRuntimeException("Failed to load backup offerings");
123111
}
124-
return new ArrayList<BackupOffering>();
125112
}
126113

127114
@Override
@@ -134,7 +121,8 @@ public boolean isValidProviderOffering(Long zoneId, String uuid) {
134121
public boolean assignVMToBackupOffering(VirtualMachine vm, BackupOffering backupOffering) {
135122
logger.info("Creating VM backup for VM {} from backup offering {}", vm.getInstanceName(), backupOffering.getName());
136123
if(vm instanceof VMInstanceVO) {
137-
((VMInstanceVO) vm).setBackupExternalId(backupOffering.getUuid());
124+
((VMInstanceVO) vm).setBackupExternalId(backupOffering.getUuid());
125+
138126
return true;
139127
}
140128
return false;
@@ -143,17 +131,15 @@ public boolean assignVMToBackupOffering(VirtualMachine vm, BackupOffering backup
143131
@Override
144132
public boolean restoreVMFromBackup(VirtualMachine vm, Backup backup) {
145133
logger.debug("Restoring vm {} from backup {} on the backroll Backup Provider", vm.getUuid(), backup.getUuid());
146-
boolean isSuccess;
134+
147135
try {
148-
isSuccess = getClient(vm.getDataCenterId()).restoreVMFromBackup(vm.getUuid(), getBackupName(backup));
136+
return getClient(vm.getDataCenterId()).restoreVMFromBackup(vm.getUuid(), getBackupName(backup));
149137
} catch (ParseException | BackrollApiException | IOException e) {
150138
throw new CloudRuntimeException("Failed to restore VM from Backup");
151139
}
152-
return isSuccess;
153140
}
154141

155-
@Override
156-
public Map<VirtualMachine, Backup.Metric> getBackupMetrics(Long zoneId, List<VirtualMachine> vms) {
142+
private Map<VirtualMachine, Backup.Metric> getBackupMetrics(Long zoneId, List<VirtualMachine> vms) {
157143
final Map<VirtualMachine, Backup.Metric> metrics = new HashMap<>();
158144
if (CollectionUtils.isEmpty(vms)) {
159145
logger.warn("Unable to get VM Backup Metrics because the list of VMs is empty.");
@@ -288,35 +274,38 @@ public boolean willDeleteBackupsOnOfferingRemoval() {
288274
}
289275

290276
@Override
291-
public Pair<Boolean, Backup> takeBackup(VirtualMachine vm) {
277+
public Pair<Boolean, Backup> takeBackup(VirtualMachine vm, Boolean quiesceVM) {
292278
logger.info("Starting backup for VM ID {} on backroll provider", vm.getUuid());
293279
final BackrollClient client = getClient(vm.getDataCenterId());
294280

295281
try {
296-
String urlToRequest = client.startBackupJob(vm.getUuid());
297-
logger.info("BackrollProvider: urlToRequest: " + urlToRequest);
298-
String backupJob = urlToRequest.replace("/status/", "");
299-
if (!StringUtils.isEmpty(backupJob)) {
300-
BackupVO backup = new BackupVO();
301-
backup.setVmId(vm.getId());
302-
backup.setExternalId(backupJob);
303-
backup.setType("INCREMENTAL");
304-
backup.setDate(new DateTime().toDate());
305-
backup.setSize(0L);
306-
backup.setProtectedSize(0L);
307-
backup.setStatus(Backup.Status.BackingUp);
308-
backup.setBackupOfferingId(vm.getBackupOfferingId());
309-
backup.setAccountId(vm.getAccountId());
310-
backup.setDomainId(vm.getDomainId());
311-
backup.setZoneId(vm.getDataCenterId());
312-
Boolean result = backupDao.persist(backup) != null;
313-
return new Pair<Boolean,Backup>(result, backup);
282+
String backupExternalId = client.startBackupJob(vm.getUuid());
283+
284+
if (StringUtils.isEmpty(backupExternalId)) {
285+
return new Pair<>(false, null);
314286
}
287+
288+
var backup = new BackupVO();
289+
backup.setVmId(vm.getId());
290+
backup.setExternalId(backupExternalId);
291+
backup.setType("INCREMENTAL");
292+
backup.setDate(new DateTime().toDate());
293+
backup.setSize(0L);
294+
backup.setProtectedSize(0L);
295+
backup.setStatus(Backup.Status.BackingUp);
296+
backup.setBackupOfferingId(vm.getBackupOfferingId());
297+
backup.setAccountId(vm.getAccountId());
298+
backup.setDomainId(vm.getDomainId());
299+
backup.setZoneId(vm.getDataCenterId());
300+
301+
Boolean result = backupDao.persist(backup) != null;
302+
303+
return new Pair<Boolean,Backup>(result, backup);
304+
315305
} catch (ParseException | BackrollApiException | IOException e) {
316306
logger.debug(e.getMessage());
317307
throw new CloudRuntimeException("Failed to take backup");
318308
}
319-
return new Pair<Boolean,Backup>(false, null);
320309
}
321310

322311
@Override
@@ -364,13 +353,12 @@ private boolean deleteBackupInDb(Backup backup) {
364353
backupToUpdate.setStatus(Backup.Status.Removed);
365354
if (backupDao.persist(backupToUpdate) != null) {
366355
logger.debug("BACKROLL: Backroll backup {} deleted in database.", backup.getUuid());
367-
VMInstanceVO vm = vmInstanceDao.findByIdIncludingRemoved(backup.getVmId());
368356
return true;
369357
}
370358
return false;
371359
}
372360

373-
protected BackrollClient getClient(final Long zoneId) {
361+
private BackrollClient getClient(final Long zoneId) {
374362
logger.debug("Backroll Provider GetClient with zone id {}", zoneId);
375363
try {
376364
if (backrollClient == null) {
@@ -397,8 +385,8 @@ private String getBackupName(String externalId) {
397385
}
398386

399387
@Override
400-
public Pair<Boolean, String> restoreBackedUpVolume(Backup backup, String volumeUuid, String hostIp, String dataStoreUuid, Pair<String, VirtualMachine.State> vmNameAndState) {
401-
logger.debug("Restoring volume {} from backup {} on the Backroll Backup Provider", volumeUuid, backup.getUuid());
388+
public Pair<Boolean, String> restoreBackedUpVolume(Backup backup, Backup.VolumeInfo backupVolumeInfo, String hostIp, String dataStoreUuid, Pair<String, VirtualMachine.State> vmNameAndState) {
389+
logger.debug("Restoring volume {} from backup {} on the Backroll Backup Provider", backupVolumeInfo.getUuid(), backup.getUuid());
402390
throw new CloudRuntimeException("Backroll plugin does not support this feature");
403391
}
404392

@@ -414,7 +402,7 @@ public List<RestorePoint> listRestorePoints(VirtualMachine vm) {
414402
}
415403

416404
@Override
417-
public Backup createNewBackupEntryForRestorePoint(RestorePoint restorePoint, VirtualMachine vm, Metric metric) {
405+
public Backup createNewBackupEntryForRestorePoint(RestorePoint restorePoint, VirtualMachine vm) {
418406
final BackrollClient client = getClient(vm.getDataCenterId());
419407
BackupVO backupToInsert = new BackupVO();
420408
backupToInsert.setVmId(vm.getId());
@@ -440,4 +428,37 @@ public Backup createNewBackupEntryForRestorePoint(RestorePoint restorePoint, Vir
440428
backupDao.persist(backupToInsert);
441429
return backupToInsert;
442430
}
431+
432+
@Override
433+
public Boolean crossZoneInstanceCreationEnabled(BackupOffering backupOffering) {
434+
return false;
435+
}
436+
437+
@Override
438+
public Pair<Boolean, String> restoreBackupToVM(VirtualMachine vm, Backup backup, String hostIp, String dataStoreUuid) {
439+
throw new UnsupportedOperationException("Not supported yet."); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/GeneratedMethodBody
440+
}
441+
442+
@Override
443+
public void syncBackupMetrics(Long zoneId) {
444+
final List<VMInstanceVO> vms = vmInstanceDao.listByZoneId(zoneId);
445+
446+
final var castedVMList = vms.stream().map((v) -> (VirtualMachine)v).collect(Collectors.toList());
447+
448+
backupFilesMetricsMap = getBackupMetrics(zoneId, castedVMList);
449+
}
450+
451+
@Override
452+
public boolean supportsInstanceFromBackup() {
453+
return true;
454+
}
455+
456+
@Override
457+
public Pair<Long, Long> getBackupStorageStats(Long zoneId) {
458+
return new Pair<>(0L, 0L);
459+
}
460+
461+
@Override
462+
public void syncBackupStorageStats(Long zoneId) {
463+
}
443464
}

plugins/backup/backroll/src/main/java/org/apache/cloudstack/backup/backroll/BackrollClient.java

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,10 @@
1616
// under the License.
1717
package org.apache.cloudstack.backup.backroll;
1818

19-
import java.io.IOException;
20-
import java.net.URISyntaxException;
21-
import java.security.KeyManagementException;
22-
import java.security.NoSuchAlgorithmException;
23-
import java.util.ArrayList;
24-
import java.util.List;
25-
19+
import com.fasterxml.jackson.databind.ObjectMapper;
2620
import org.apache.cloudstack.backup.Backup;
27-
import org.apache.cloudstack.backup.BackupOffering;
2821
import org.apache.cloudstack.backup.Backup.Metric;
22+
import org.apache.cloudstack.backup.BackupOffering;
2923
import org.apache.cloudstack.backup.backroll.model.BackrollBackupMetrics;
3024
import org.apache.cloudstack.backup.backroll.model.BackrollOffering;
3125
import org.apache.cloudstack.backup.backroll.model.BackrollTaskStatus;
@@ -45,15 +39,18 @@
4539
import org.apache.cloudstack.backup.backroll.utils.BackrollApiException;
4640
import org.apache.cloudstack.backup.backroll.utils.BackrollHttpClientProvider;
4741
import org.apache.commons.lang3.StringUtils;
48-
4942
import org.apache.logging.log4j.LogManager;
5043
import org.apache.logging.log4j.Logger;
51-
5244
import org.joda.time.DateTime;
53-
5445
import org.json.JSONException;
5546
import org.json.JSONObject;
56-
import com.fasterxml.jackson.databind.ObjectMapper;
47+
48+
import java.io.IOException;
49+
import java.net.URISyntaxException;
50+
import java.security.KeyManagementException;
51+
import java.security.NoSuchAlgorithmException;
52+
import java.util.ArrayList;
53+
import java.util.List;
5754

5855
public class BackrollClient {
5956

@@ -69,28 +66,33 @@ public BackrollClient(BackrollHttpClientProvider httpProvider)
6966

7067
public String startBackupJob(final String jobId) throws IOException, BackrollApiException {
7168
logger.info("startBackupJob : Trying to start backup for Backroll job: {}", jobId);
72-
String backupJob = "";
69+
7370
BackrollTaskRequestResponse requestResponse = httpProvider.post(String.format("/tasks/singlebackup/%s", jobId),
7471
null, BackrollTaskRequestResponse.class);
72+
7573
logger.info("startBackupJob : BackupJob status link: {}", requestResponse.location);
76-
backupJob = requestResponse.location.replace("/api/v1", "");
77-
return StringUtils.isEmpty(backupJob) ? null : backupJob;
74+
75+
var backupExternalId = requestResponse.location.replace("/api/v1/status/", "");
76+
77+
return StringUtils.isEmpty(backupExternalId) ? null : backupExternalId;
7878
}
7979

80-
public String getBackupOfferingUrl() throws IOException, BackrollApiException {
80+
public List<BackupOffering> getBackupOfferings() throws BackrollApiException, IOException {
81+
8182
logger.info("Trying to get backroll backup policies url");
82-
String url = "";
83+
String urlTask = "";
8384
BackrollTaskRequestResponse requestResponse = httpProvider.get("/backup_policies",
8485
BackrollTaskRequestResponse.class);
8586
logger.info("BackrollClient:getBackupOfferingUrl:Apres Parse: " + requestResponse.location);
86-
url = requestResponse.location.replace("/api/v1", "");
87-
return StringUtils.isEmpty(url) ? null : url;
88-
}
89-
90-
public List<BackupOffering> getBackupOfferings(String idTask) throws BackrollApiException, IOException {
87+
urlTask = requestResponse.location.replace("/api/v1", "");
88+
89+
if (!StringUtils.isEmpty(urlTask)){
90+
return new ArrayList<BackupOffering>();
91+
}
92+
9193
logger.info("Trying to list backroll backup policies");
9294
final List<BackupOffering> policies = new ArrayList<>();
93-
BackupPoliciesResponse backupPoliciesResponse = httpProvider.waitGet(idTask, BackupPoliciesResponse.class);
95+
BackupPoliciesResponse backupPoliciesResponse = httpProvider.waitGet(urlTask, BackupPoliciesResponse.class);
9496
logger.info(
9597
"BackrollClient:getBackupOfferings:Apres Parse: " + backupPoliciesResponse.backupPolicies.get(0).name);
9698
for (final BackrollBackupPolicyResponse policy : backupPoliciesResponse.backupPolicies) {

plugins/backup/backroll/src/main/java/org/apache/cloudstack/backup/backroll/model/BackrollOffering.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@
1616
// under the License.
1717
package org.apache.cloudstack.backup.backroll.model;
1818

19-
import java.util.Date;
20-
2119
import org.apache.cloudstack.backup.BackupOffering;
2220

21+
import java.util.Date;
22+
2323
public class BackrollOffering implements BackupOffering {
2424

2525
private String name;

0 commit comments

Comments
 (0)