Skip to content

Commit 7b85ea1

Browse files
committed
Show chain size in snapshot response for incremental snapshots
1 parent d693736 commit 7b85ea1

File tree

9 files changed

+41
-3
lines changed

9 files changed

+41
-3
lines changed

api/src/main/java/org/apache/cloudstack/api/ApiConstants.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1113,6 +1113,7 @@ public class ApiConstants {
11131113
public static final String NETWORK_SPANNED_ZONES = "zonesnetworkspans";
11141114
public static final String METADATA = "metadata";
11151115
public static final String PHYSICAL_SIZE = "physicalsize";
1116+
public static final String CHAIN_SIZE = "chainsize";
11161117
public static final String OVM3_POOL = "ovm3pool";
11171118
public static final String OVM3_CLUSTER = "ovm3cluster";
11181119
public static final String OVM3_VIP = "ovm3vip";

api/src/main/java/org/apache/cloudstack/api/response/SnapshotResponse.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,10 @@ public class SnapshotResponse extends BaseResponseWithTagInformation implements
107107
@Param(description = "physical size of backedup snapshot on image store")
108108
private long physicalSize;
109109

110+
@SerializedName(ApiConstants.CHAIN_SIZE)
111+
@Param(description = "chain size of snapshot including all parent snapshots. Shown only for incremental snapshots if snapshot.show.chain.size setting is set to true", since = "4.21.0")
112+
private Long chainSize;
113+
110114
@SerializedName(ApiConstants.ZONE_ID)
111115
@Param(description = "id of the availability zone")
112116
private String zoneId;
@@ -244,6 +248,10 @@ public void setPhysicalSize(long physicalSize) {
244248
this.physicalSize = physicalSize;
245249
}
246250

251+
public void setChainSize(long chainSize) {
252+
this.chainSize = chainSize;
253+
}
254+
247255
@Override
248256
public void setProjectId(String projectId) {
249257
this.projectId = projectId;

server/src/main/java/com/cloud/api/query/dao/SnapshotJoinDaoImpl.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
import com.cloud.storage.VMTemplateStorageResourceAssoc;
4747
import com.cloud.storage.Volume.Type;
4848
import com.cloud.storage.VolumeVO;
49+
import com.cloud.storage.snapshot.SnapshotManager;
4950
import com.cloud.user.Account;
5051
import com.cloud.user.AccountService;
5152
import com.cloud.utils.db.Filter;
@@ -96,9 +97,27 @@ private void setSnapshotInfoDetailsInResponse(SnapshotJoinVO snapshot, SnapshotR
9697
} else {
9798
snapshotResponse.setRevertable(snapshotInfo.isRevertable());
9899
snapshotResponse.setPhysicalSize(snapshotInfo.getPhysicalSize());
100+
101+
boolean showChainSize = SnapshotManager.snapshotShowChainSize.valueIn(snapshot.getDataCenterId());
102+
if (showChainSize && snapshotInfo.getParent() != null) {
103+
long chainSize = calculateChainSize(snapshotInfo);
104+
snapshotResponse.setChainSize(chainSize);
105+
}
99106
}
100107
}
101108

109+
private long calculateChainSize(SnapshotInfo snapshotInfo) {
110+
long chainSize = snapshotInfo.getPhysicalSize();
111+
SnapshotInfo parent = snapshotInfo.getParent();
112+
113+
while (parent != null) {
114+
chainSize += parent.getPhysicalSize();
115+
parent = parent.getParent();
116+
}
117+
118+
return chainSize;
119+
}
120+
102121
private String getSnapshotStatus(SnapshotJoinVO snapshot) {
103122
String status = snapshot.getStatus().toString();
104123
if (snapshot.getDownloadState() == null) {

server/src/main/java/com/cloud/storage/snapshot/SnapshotManager.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,10 @@ public interface SnapshotManager extends Configurable {
6161
ConfigKey<Integer> snapshotDeltaMax = new ConfigKey<>(Integer.class, "snapshot.delta.max", "Snapshots", "16", "Max delta snapshots between two full snapshots. " +
6262
"Only valid for KVM and XenServer.", true, ConfigKey.Scope.Global, null);
6363

64+
ConfigKey<Boolean> snapshotShowChainSize = new ConfigKey<>(Boolean.class, "snapshot.show.chain.size", "Snapshots", "true",
65+
"Whether to show chain size (sum of physical size of snapshot and all its parents) for incremental snapshots in the snapshot response",
66+
true, ConfigKey.Scope.Global, null);
67+
6468
void deletePoliciesForVolume(Long volumeId);
6569

6670
/**

server/src/main/java/com/cloud/storage/snapshot/SnapshotManagerImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ public String getConfigComponentName() {
294294
@Override
295295
public ConfigKey<?>[] getConfigKeys() {
296296
return new ConfigKey<?>[] {BackupRetryAttempts, BackupRetryInterval, SnapshotHourlyMax, SnapshotDailyMax, SnapshotMonthlyMax, SnapshotWeeklyMax, usageSnapshotSelection,
297-
SnapshotInfo.BackupSnapshotAfterTakingSnapshot, VmStorageSnapshotKvm, kvmIncrementalSnapshot, snapshotDeltaMax};
297+
SnapshotInfo.BackupSnapshotAfterTakingSnapshot, VmStorageSnapshotKvm, kvmIncrementalSnapshot, snapshotDeltaMax, snapshotShowChainSize};
298298
}
299299

300300
@Override

tools/marvin/setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
raise RuntimeError("python setuptools is required to build Marvin")
2828

2929

30-
VERSION = "4.21.0.0-SNAPSHOT"
30+
VERSION = "4.21.0.0"
3131

3232
setup(name="Marvin",
3333
version=VERSION,

ui/public/locales/en.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,7 @@
505505
"label.certificate.upload.failed": "Certificate upload failed",
506506
"label.certificate.upload.failed.description": "Failed to update SSL Certificate. Failed to pass certificate validation check.",
507507
"label.certificateid": "Certificate ID",
508+
"label.chainsize": "Chain size",
508509
"label.change": "Change",
509510
"label.change.affinity": "Change affinity",
510511
"label.change.bgp.peers": "Change BGP peers",

ui/src/components/view/DetailsTab.vue

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,11 @@
8787
{{ parseFloat(dataResource.virtualsize / (1024.0 * 1024.0 * 1024.0)).toFixed(2) }} GiB
8888
</div>
8989
</div>
90+
<div v-else-if="$route.meta.name === 'snapshot' && item === 'chainsize'">
91+
<div>
92+
{{ parseFloat(dataResource.chainsize / (1024.0 * 1024.0 * 1024.0)).toFixed(2) }} GiB
93+
</div>
94+
</div>
9095
<div v-else-if="['name', 'type'].includes(item)">
9196
<span v-if="['USER.LOGIN', 'USER.LOGOUT', 'ROUTER.HEALTH.CHECKS', 'FIREWALL.CLOSE', 'ALERT.SERVICE.DOMAINROUTER'].includes(dataResource[item])">{{ $t(dataResource[item].toLowerCase()) }}</span>
9297
<span v-else>{{ dataResource[item] }}</span>

ui/src/config/section/storage.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,7 @@ export default {
324324
fields.push('zonename')
325325
return fields
326326
},
327-
details: ['name', 'id', 'volumename', 'volumetype', 'snapshottype', 'intervaltype', 'physicalsize', 'virtualsize', 'account', 'domain', 'created'],
327+
details: ['name', 'id', 'volumename', 'volumetype', 'snapshottype', 'intervaltype', 'physicalsize', 'virtualsize', 'chainsize', 'account', 'domain', 'created'],
328328
tabs: [
329329
{
330330
name: 'details',

0 commit comments

Comments
 (0)