Skip to content

Commit c72a10e

Browse files
committed
Nas provider support for backup storage stats
1 parent beb05ae commit c72a10e

File tree

15 files changed

+290
-9
lines changed

15 files changed

+290
-9
lines changed

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,4 +129,11 @@ public interface BackupProvider {
129129
* @return a pair of Used size and Total size for the backup storage
130130
*/
131131
Pair<Long, Long> getBackupStorageStats(Long zoneId);
132+
133+
/**
134+
* Gets the backup storage usage (Used, Total) from the plugin and stores it in db
135+
* @param zoneId the zone for which to return metrics
136+
*/
137+
void syncBackupStorageStats(Long zoneId);
138+
132139
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@ public interface BackupRepository extends InternalIdentity, Identity {
2828
String getType();
2929
String getAddress();
3030
String getMountOptions();
31+
void setUsedBytes(Long usedBytes);
3132
Long getCapacityBytes();
3233
Long getUsedBytes();
34+
void setCapacityBytes(Long capacityBytes);
3335
Date getCreated();
3436
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
//
2+
// Licensed to the Apache Software Foundation (ASF) under one
3+
// or more contributor license agreements. See the NOTICE file
4+
// distributed with this work for additional information
5+
// regarding copyright ownership. The ASF licenses this file
6+
// to you under the Apache License, Version 2.0 (the
7+
// "License"); you may not use this file except in compliance
8+
// with the License. You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing,
13+
// software distributed under the License is distributed on an
14+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
// KIND, either express or implied. See the License for the
16+
// specific language governing permissions and limitations
17+
// under the License.
18+
//
19+
20+
package org.apache.cloudstack.backup;
21+
22+
import com.cloud.agent.api.Answer;
23+
import com.cloud.agent.api.Command;
24+
25+
public class BackupStorageStatsAnswer extends Answer {
26+
private Long totalSize;
27+
private Long usedSize;
28+
29+
public BackupStorageStatsAnswer(final Command command, final boolean success, final String details) {
30+
super(command, success, details);
31+
this.totalSize = 0L;
32+
this.usedSize = 0L;
33+
}
34+
35+
public Long getTotalSize() {
36+
return totalSize;
37+
}
38+
39+
public void setTotalSize(Long totalSize) {
40+
this.totalSize = totalSize;
41+
}
42+
43+
public Long getUsedSize() {
44+
return usedSize;
45+
}
46+
47+
public void setUsedSize(Long usedSize) {
48+
this.usedSize = usedSize;
49+
}
50+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
//
2+
// Licensed to the Apache Software Foundation (ASF) under one
3+
// or more contributor license agreements. See the NOTICE file
4+
// distributed with this work for additional information
5+
// regarding copyright ownership. The ASF licenses this file
6+
// to you under the Apache License, Version 2.0 (the
7+
// "License"); you may not use this file except in compliance
8+
// with the License. You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing,
13+
// software distributed under the License is distributed on an
14+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
// KIND, either express or implied. See the License for the
16+
// specific language governing permissions and limitations
17+
// under the License.
18+
//
19+
20+
package org.apache.cloudstack.backup;
21+
22+
import com.cloud.agent.api.Command;
23+
import com.cloud.agent.api.LogLevel;
24+
25+
public class GetBackupStorageStatsCommand extends Command {
26+
private String backupRepoType;
27+
private String backupRepoAddress;
28+
@LogLevel(LogLevel.Log4jLevel.Off)
29+
private String mountOptions;
30+
31+
public GetBackupStorageStatsCommand(String backupRepoType, String backupRepoAddress, String mountOptions) {
32+
super();
33+
this.backupRepoType = backupRepoType;
34+
this.backupRepoAddress = backupRepoAddress;
35+
this.mountOptions = mountOptions;
36+
}
37+
38+
public String getBackupRepoType() {
39+
return backupRepoType;
40+
}
41+
42+
public void setBackupRepoType(String backupRepoType) {
43+
this.backupRepoType = backupRepoType;
44+
}
45+
46+
public String getBackupRepoAddress() {
47+
return backupRepoAddress;
48+
}
49+
50+
public void setBackupRepoAddress(String backupRepoAddress) {
51+
this.backupRepoAddress = backupRepoAddress;
52+
}
53+
54+
public String getMountOptions() {
55+
return mountOptions == null ? "" : mountOptions;
56+
}
57+
58+
public void setMountOptions(String mountOptions) {
59+
this.mountOptions = mountOptions;
60+
}
61+
62+
@Override
63+
public boolean executeInSequence() {
64+
return true;
65+
}
66+
}

engine/schema/src/main/java/org/apache/cloudstack/backup/BackupRepositoryVO.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,11 +144,21 @@ public Long getUsedBytes() {
144144
return usedBytes;
145145
}
146146

147+
@Override
148+
public void setUsedBytes(Long usedBytes) {
149+
this.usedBytes = usedBytes;
150+
}
151+
147152
@Override
148153
public Long getCapacityBytes() {
149154
return capacityBytes;
150155
}
151156

157+
@Override
158+
public void setCapacityBytes(Long capacityBytes) {
159+
this.capacityBytes = capacityBytes;
160+
}
161+
152162
public Date getCreated() {
153163
return created;
154164
}

engine/schema/src/main/java/org/apache/cloudstack/backup/dao/BackupRepositoryDao.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,6 @@ public interface BackupRepositoryDao extends GenericDao<BackupRepositoryVO, Long
2828
List<BackupRepository> listByZoneAndProvider(Long zoneId, String provider);
2929

3030
BackupRepository findByBackupOfferingId(Long backupOfferingId);
31+
32+
boolean updateCapacity(BackupRepository backupRepository, Long capacityBytes, Long usedBytes);
3133
}

engine/schema/src/main/java/org/apache/cloudstack/backup/dao/BackupRepositoryDaoImpl.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,4 +64,12 @@ public BackupRepository findByBackupOfferingId(Long backupOfferingId) {
6464
}
6565
return findByUuid(offering.getExternalId());
6666
}
67+
68+
@Override
69+
public boolean updateCapacity(BackupRepository backupRepository, Long capacityBytes, Long usedBytes) {
70+
BackupRepositoryVO repository = findById(backupRepository.getId());
71+
repository.setCapacityBytes(capacityBytes);
72+
repository.setUsedBytes(usedBytes);
73+
return update(repository.getId(), repository);
74+
}
6775
}

plugins/backup/dummy/src/main/java/org/apache/cloudstack/backup/DummyBackupProvider.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,10 @@ public Pair<Long, Long> getBackupStorageStats(Long zoneId) {
183183
return new Pair<>(8L * 1024 * 1024 * 1024, 10L * 1024 * 1024 * 1024);
184184
}
185185

186+
@Override
187+
public void syncBackupStorageStats(Long zoneId) {
188+
}
189+
186190
@Override
187191
public boolean restoreBackupToVM(VirtualMachine vm, Backup backup, String hostIp, String dataStoreUuid) {
188192
return true;

plugins/backup/nas/src/main/java/org/apache/cloudstack/backup/NASBackupProvider.java

Lines changed: 48 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
import java.util.HashMap;
5858
import java.util.Objects;
5959
import java.util.Optional;
60+
import java.util.Random;
6061
import java.util.UUID;
6162
import java.util.stream.Collectors;
6263

@@ -69,6 +70,9 @@ public class NASBackupProvider extends AdapterBase implements BackupProvider, Co
6970
@Inject
7071
private BackupRepositoryDao backupRepositoryDao;
7172

73+
@Inject
74+
private BackupRepositoryService backupRepositoryService;
75+
7276
@Inject
7377
private HostDao hostDao;
7478

@@ -90,6 +94,19 @@ public class NASBackupProvider extends AdapterBase implements BackupProvider, Co
9094
@Inject
9195
BackupManager backupManager;
9296

97+
private Host getUpHostInZone(Long zoneId) {
98+
List<HostVO> hosts = hostDao.listByDataCenterIdAndHypervisorType(zoneId, Hypervisor.HypervisorType.KVM);
99+
if (hosts.size() == 0) {
100+
return null;
101+
}
102+
103+
Random random = new Random();
104+
int randomIndex = random.nextInt(hosts.size());
105+
HostVO hostInZone = hosts.get(randomIndex);
106+
LOG.debug("Found Host {} in zone {}", zoneId);
107+
return hostInZone;
108+
}
109+
93110
protected Host getLastVMHypervisorHost(VirtualMachine vm) {
94111
Long hostId = vm.getLastHostId();
95112
if (hostId == null) {
@@ -110,13 +127,7 @@ protected Host getLastVMHypervisorHost(VirtualMachine vm) {
110127
}
111128
}
112129
// Try to find any Host in the zone
113-
for (final HostVO hostInZone : hostDao.listByDataCenterIdAndHypervisorType(host.getDataCenterId(), Hypervisor.HypervisorType.KVM)) {
114-
if (hostInZone.getStatus() == Status.Up) {
115-
LOG.debug("Found Host {} in zone {}", hostInZone, host.getDataCenterId());
116-
return hostInZone;
117-
}
118-
}
119-
return null;
130+
return getUpHostInZone(host.getDataCenterId());
120131
}
121132

122133
protected Host getVMHypervisorHost(VirtualMachine vm) {
@@ -434,7 +445,36 @@ public boolean supportsInstanceFromBackup() {
434445

435446
@Override
436447
public Pair<Long, Long> getBackupStorageStats(Long zoneId) {
437-
return new Pair<>(0L, 0L);
448+
final List<BackupRepository> repositories = backupRepositoryDao.listByZoneAndProvider(zoneId, getName());
449+
Long totalSize = 0L;
450+
Long usedSize = 0L;
451+
for (final BackupRepository repository : repositories) {
452+
if (repository.getCapacityBytes() != null) {
453+
totalSize += repository.getCapacityBytes();
454+
}
455+
if (repository.getUsedBytes() != null) {
456+
usedSize += repository.getUsedBytes();
457+
}
458+
}
459+
return new Pair<>(usedSize, totalSize);
460+
}
461+
462+
@Override
463+
public void syncBackupStorageStats(Long zoneId) {
464+
final List<BackupRepository> repositories = backupRepositoryDao.listByZoneAndProvider(zoneId, getName());
465+
final Host host = getUpHostInZone(zoneId);
466+
for (final BackupRepository repository : repositories) {
467+
GetBackupStorageStatsCommand command = new GetBackupStorageStatsCommand(repository.getType(), repository.getAddress(), repository.getMountOptions());
468+
BackupStorageStatsAnswer answer;
469+
try {
470+
answer = (BackupStorageStatsAnswer) agentManager.send(host.getId(), command);
471+
backupRepositoryDao.updateCapacity(repository, answer.getTotalSize(), answer.getUsedSize());
472+
} catch (AgentUnavailableException e) {
473+
logger.warn("Unable to contact backend control plane to get backup stats for repository: {}", repository.getName());
474+
} catch (OperationTimedoutException e) {
475+
logger.warn("Operation to get backup stats timed out for the repository: " + repository.getName());
476+
}
477+
}
438478
}
439479

440480
@Override

plugins/backup/networker/src/main/java/org/apache/cloudstack/backup/NetworkerBackupProvider.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -645,6 +645,10 @@ public Pair<Long, Long> getBackupStorageStats(Long zoneId) {
645645
return new Pair<>(0L, 0L);
646646
}
647647

648+
@Override
649+
public void syncBackupStorageStats(Long zoneId) {
650+
}
651+
648652
@Override
649653
public boolean willDeleteBackupsOnOfferingRemoval() { return false; }
650654

0 commit comments

Comments
 (0)