Show chain size in snapshot response for incremental snapshots (#11313)

This commit is contained in:
Abhisar Sinha 2025-07-31 18:22:48 +05:30 committed by GitHub
parent 9f5828a027
commit e805e45342
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 49 additions and 5 deletions

View File

@ -1143,6 +1143,7 @@ public class ApiConstants {
public static final String NETWORK_SPANNED_ZONES = "zonesnetworkspans";
public static final String METADATA = "metadata";
public static final String PHYSICAL_SIZE = "physicalsize";
public static final String CHAIN_SIZE = "chainsize";
public static final String OVM3_POOL = "ovm3pool";
public static final String OVM3_CLUSTER = "ovm3cluster";
public static final String OVM3_VIP = "ovm3vip";

View File

@ -107,6 +107,10 @@ public class SnapshotResponse extends BaseResponseWithTagInformation implements
@Param(description = "physical size of backedup snapshot on image store")
private long physicalSize;
@SerializedName(ApiConstants.CHAIN_SIZE)
@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")
private Long chainSize;
@SerializedName(ApiConstants.ZONE_ID)
@Param(description = "id of the availability zone")
private String zoneId;
@ -244,6 +248,10 @@ public class SnapshotResponse extends BaseResponseWithTagInformation implements
this.physicalSize = physicalSize;
}
public void setChainSize(long chainSize) {
this.chainSize = chainSize;
}
@Override
public void setProjectId(String projectId) {
this.projectId = projectId;

View File

@ -46,6 +46,7 @@ import com.cloud.storage.Snapshot;
import com.cloud.storage.VMTemplateStorageResourceAssoc;
import com.cloud.storage.Volume.Type;
import com.cloud.storage.VolumeVO;
import com.cloud.storage.snapshot.SnapshotManager;
import com.cloud.user.Account;
import com.cloud.user.AccountService;
import com.cloud.utils.db.Filter;
@ -96,9 +97,27 @@ public class SnapshotJoinDaoImpl extends GenericDaoBaseWithTagInformation<Snapsh
} else {
snapshotResponse.setRevertable(snapshotInfo.isRevertable());
snapshotResponse.setPhysicalSize(snapshotInfo.getPhysicalSize());
boolean showChainSize = SnapshotManager.snapshotShowChainSize.valueIn(snapshot.getDataCenterId());
if (showChainSize && snapshotInfo.getParent() != null) {
long chainSize = calculateChainSize(snapshotInfo);
snapshotResponse.setChainSize(chainSize);
}
}
}
private long calculateChainSize(SnapshotInfo snapshotInfo) {
long chainSize = snapshotInfo.getPhysicalSize();
SnapshotInfo parent = snapshotInfo.getParent();
while (parent != null) {
chainSize += parent.getPhysicalSize();
parent = parent.getParent();
}
return chainSize;
}
private String getSnapshotStatus(SnapshotJoinVO snapshot) {
String status = snapshot.getStatus().toString();
if (snapshot.getDownloadState() == null) {

View File

@ -61,6 +61,10 @@ public interface SnapshotManager extends Configurable {
ConfigKey<Integer> snapshotDeltaMax = new ConfigKey<>(Integer.class, "snapshot.delta.max", "Snapshots", "16", "Max delta snapshots between two full snapshots. " +
"Only valid for KVM and XenServer.", true, ConfigKey.Scope.Global, null);
ConfigKey<Boolean> snapshotShowChainSize = new ConfigKey<>(Boolean.class, "snapshot.show.chain.size", "Snapshots", "false",
"Whether to show chain size (sum of physical size of snapshot and all its parents) for incremental snapshots in the snapshot response",
true, ConfigKey.Scope.Global, null);
void deletePoliciesForVolume(Long volumeId);
/**

View File

@ -294,7 +294,7 @@ public class SnapshotManagerImpl extends MutualExclusiveIdsManagerBase implement
@Override
public ConfigKey<?>[] getConfigKeys() {
return new ConfigKey<?>[] {BackupRetryAttempts, BackupRetryInterval, SnapshotHourlyMax, SnapshotDailyMax, SnapshotMonthlyMax, SnapshotWeeklyMax, usageSnapshotSelection,
SnapshotInfo.BackupSnapshotAfterTakingSnapshot, VmStorageSnapshotKvm, kvmIncrementalSnapshot, snapshotDeltaMax};
SnapshotInfo.BackupSnapshotAfterTakingSnapshot, VmStorageSnapshotKvm, kvmIncrementalSnapshot, snapshotDeltaMax, snapshotShowChainSize};
}
@Override

View File

@ -509,6 +509,7 @@
"label.certificate.upload.failed": "Certificate upload failed",
"label.certificate.upload.failed.description": "Failed to update SSL Certificate. Failed to pass certificate validation check.",
"label.certificateid": "Certificate ID",
"label.chainsize": "Chain size",
"label.change": "Change",
"label.change.affinity": "Change affinity",
"label.change.bgp.peers": "Change BGP peers",

View File

@ -75,17 +75,22 @@
</div>
<div v-else-if="['template', 'iso'].includes($route.meta.name) && item === 'size'">
<div>
{{ parseFloat(dataResource.size / (1024.0 * 1024.0 * 1024.0)).toFixed(2) }} GiB
{{ sizeInGiB(dataResource.size) }} GiB
</div>
</div>
<div v-else-if="['volume', 'snapshot', 'template', 'iso'].includes($route.meta.name) && item === 'physicalsize'">
<div>
{{ parseFloat(dataResource.physicalsize / (1024.0 * 1024.0 * 1024.0)).toFixed(2) }} GiB
{{ sizeInGiB(dataResource.physicalsize) }} GiB
</div>
</div>
<div v-else-if="['volume', 'snapshot', 'template', 'iso'].includes($route.meta.name) && item === 'virtualsize'">
<div>
{{ parseFloat(dataResource.virtualsize / (1024.0 * 1024.0 * 1024.0)).toFixed(2) }} GiB
{{ sizeInGiB(dataResource.virtualsize) }} GiB
</div>
</div>
<div v-else-if="$route.meta.name === 'snapshot' && item === 'chainsize'">
<div>
{{ sizeInGiB(dataResource.chainsize) }} GiB
</div>
</div>
<div v-else-if="['name', 'type'].includes(item)">
@ -473,6 +478,12 @@ export default {
}
return `label.${source}`
},
sizeInGiB (sizeInBytes) {
if (!sizeInBytes || sizeInBytes === 0) {
return '0.00'
}
return parseFloat(sizeInBytes / (1024.0 * 1024.0 * 1024.0)).toFixed(2)
}
}
}

View File

@ -324,7 +324,7 @@ export default {
fields.push('zonename')
return fields
},
details: ['name', 'id', 'volumename', 'volumetype', 'snapshottype', 'intervaltype', 'physicalsize', 'virtualsize', 'account', 'domain', 'created'],
details: ['name', 'id', 'volumename', 'volumetype', 'snapshottype', 'intervaltype', 'physicalsize', 'virtualsize', 'chainsize', 'account', 'domain', 'created'],
tabs: [
{
name: 'details',