Skip to content

Commit 7c5b7ca

Browse files
authored
Extra parameter for UpdateImageStore (apache#8941)
* Extra parameter for UpdateImageStore * add name parameter * ui * cleanup * update DB from storage stats results
1 parent 56b69b1 commit 7c5b7ca

File tree

9 files changed

+71
-31
lines changed

9 files changed

+71
-31
lines changed

api/src/main/java/com/cloud/storage/StorageService.java

+3
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import org.apache.cloudstack.api.command.admin.storage.DeletePoolCmd;
2828
import org.apache.cloudstack.api.command.admin.storage.DeleteSecondaryStagingStoreCmd;
2929
import org.apache.cloudstack.api.command.admin.storage.SyncStoragePoolCmd;
30+
import org.apache.cloudstack.api.command.admin.storage.UpdateImageStoreCmd;
3031
import org.apache.cloudstack.api.command.admin.storage.UpdateStoragePoolCmd;
3132

3233
import com.cloud.exception.DiscoveryException;
@@ -103,6 +104,8 @@ public interface StorageService {
103104
*/
104105
ImageStore migrateToObjectStore(String name, String url, String providerName, Map<String, String> details) throws DiscoveryException;
105106

107+
ImageStore updateImageStore(UpdateImageStoreCmd cmd);
108+
106109
ImageStore updateImageStoreStatus(Long id, Boolean readonly);
107110

108111
void updateStorageCapabilities(Long poolId, boolean failOnChecks);

api/src/main/java/org/apache/cloudstack/api/command/admin/storage/UpdateImageStoreCmd.java

+18-3
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,17 @@ public class UpdateImageStoreCmd extends BaseCmd {
4141
@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = ImageStoreResponse.class, required = true, description = "Image Store UUID")
4242
private Long id;
4343

44-
@Parameter(name = ApiConstants.READ_ONLY, type = CommandType.BOOLEAN, required = true, description = "If set to true, it designates the corresponding image store to read-only, " +
45-
"hence not considering them during storage migration")
44+
@Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = false, description = "The new name for the Image Store.")
45+
private String name;
46+
47+
@Parameter(name = ApiConstants.READ_ONLY, type = CommandType.BOOLEAN, required = false,
48+
description = "If set to true, it designates the corresponding image store to read-only, hence not considering them during storage migration")
4649
private Boolean readonly;
4750

51+
@Parameter(name = ApiConstants.CAPACITY_BYTES, type = CommandType.LONG, required = false,
52+
description = "The number of bytes CloudStack can use on this image storage.\n\tNOTE: this will be overwritten by the StatsCollector as soon as there is a SSVM to query the storage.")
53+
private Long capacityBytes;
54+
4855
/////////////////////////////////////////////////////
4956
/////////////////// Accessors ///////////////////////
5057
/////////////////////////////////////////////////////
@@ -53,17 +60,25 @@ public Long getId() {
5360
return id;
5461
}
5562

63+
public String getName() {
64+
return name;
65+
}
66+
5667
public Boolean getReadonly() {
5768
return readonly;
5869
}
5970

71+
public Long getCapacityBytes() {
72+
return capacityBytes;
73+
}
74+
6075
/////////////////////////////////////////////////////
6176
/////////////// API Implementation///////////////////
6277
/////////////////////////////////////////////////////
6378

6479
@Override
6580
public void execute() {
66-
ImageStore result = _storageService.updateImageStoreStatus(getId(), getReadonly());
81+
ImageStore result = _storageService.updateImageStore(this);
6782
ImageStoreResponse storeResponse = null;
6883
if (result != null) {
6984
storeResponse = _responseGenerator.createImageStoreResponse(result);

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

+7-7
Original file line numberDiff line numberDiff line change
@@ -27,39 +27,39 @@
2727

2828
@EntityReference(value = ImageStore.class)
2929
public class ImageStoreResponse extends BaseResponseWithAnnotations {
30-
@SerializedName("id")
30+
@SerializedName(ApiConstants.ID)
3131
@Param(description = "the ID of the image store")
3232
private String id;
3333

34-
@SerializedName("zoneid")
34+
@SerializedName(ApiConstants.ZONE_ID)
3535
@Param(description = "the Zone ID of the image store")
3636
private String zoneId;
3737

3838
@SerializedName(ApiConstants.ZONE_NAME)
3939
@Param(description = "the Zone name of the image store")
4040
private String zoneName;
4141

42-
@SerializedName("name")
42+
@SerializedName(ApiConstants.NAME)
4343
@Param(description = "the name of the image store")
4444
private String name;
4545

46-
@SerializedName("url")
46+
@SerializedName(ApiConstants.URL)
4747
@Param(description = "the url of the image store")
4848
private String url;
4949

50-
@SerializedName("protocol")
50+
@SerializedName(ApiConstants.PROTOCOL)
5151
@Param(description = "the protocol of the image store")
5252
private String protocol;
5353

5454
@SerializedName("providername")
5555
@Param(description = "the provider name of the image store")
5656
private String providerName;
5757

58-
@SerializedName("scope")
58+
@SerializedName(ApiConstants.SCOPE)
5959
@Param(description = "the scope of the image store")
6060
private ScopeType scope;
6161

62-
@SerializedName("readonly")
62+
@SerializedName(ApiConstants.READ_ONLY)
6363
@Param(description = "defines if store is read-only")
6464
private Boolean readonly;
6565

engine/components-api/src/main/java/com/cloud/storage/StorageManager.java

+2
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,8 @@ static Boolean getFullCloneConfiguration(Long storeId) {
350350

351351
Long getDiskIopsWriteRate(ServiceOffering offering, DiskOffering diskOffering);
352352

353+
ImageStore updateImageStoreStatus(Long id, String name, Boolean readonly, Long capacityBytes);
354+
353355
void cleanupDownloadUrls();
354356

355357
void setDiskProfileThrottling(DiskProfile dskCh, ServiceOffering offering, DiskOffering diskOffering);

server/src/main/java/com/cloud/api/query/QueryManagerImpl.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -2739,7 +2739,7 @@ private Pair<List<HostTagVO>, Integer> searchForHostTagsInternal(ListHostTagsCmd
27392739
@Override
27402740
public ListResponse<ImageStoreResponse> searchForImageStores(ListImageStoresCmd cmd) {
27412741
Pair<List<ImageStoreJoinVO>, Integer> result = searchForImageStoresInternal(cmd);
2742-
ListResponse<ImageStoreResponse> response = new ListResponse<ImageStoreResponse>();
2742+
ListResponse<ImageStoreResponse> response = new ListResponse<>();
27432743

27442744
List<ImageStoreResponse> poolResponses = ViewResponseHelper.createImageStoreResponse(result.first().toArray(new ImageStoreJoinVO[result.first().size()]));
27452745
response.setResponses(poolResponses, result.second());

server/src/main/java/com/cloud/server/StatsCollector.java

+15-2
Original file line numberDiff line numberDiff line change
@@ -1671,7 +1671,7 @@ protected void runInContext() {
16711671
}
16721672

16731673
List<DataStore> stores = _dataStoreMgr.listImageStores();
1674-
ConcurrentHashMap<Long, StorageStats> storageStats = new ConcurrentHashMap<Long, StorageStats>();
1674+
ConcurrentHashMap<Long, StorageStats> storageStats = new ConcurrentHashMap<>();
16751675
for (DataStore store : stores) {
16761676
if (store.getUri() == null) {
16771677
continue;
@@ -1691,7 +1691,7 @@ protected void runInContext() {
16911691
LOGGER.trace("HostId: " + storeId + " Used: " + toHumanReadableSize(((StorageStats)answer).getByteUsed()) + " Total Available: " + toHumanReadableSize(((StorageStats)answer).getCapacityBytes()));
16921692
}
16931693
}
1694-
_storageStats = storageStats;
1694+
updateStorageStats(storageStats);
16951695
ConcurrentHashMap<Long, StorageStats> storagePoolStats = new ConcurrentHashMap<Long, StorageStats>();
16961696

16971697
List<StoragePoolVO> storagePools = _storagePoolDao.listAll();
@@ -1737,6 +1737,19 @@ protected void runInContext() {
17371737
LOGGER.error("Error trying to retrieve storage stats", t);
17381738
}
17391739
}
1740+
1741+
private void updateStorageStats(ConcurrentHashMap<Long, StorageStats> storageStats) {
1742+
for (Long storeId : storageStats.keySet()) {
1743+
if (_storageStats.containsKey(storeId)
1744+
&& (_storageStats.get(storeId).getCapacityBytes() == 0l
1745+
|| _storageStats.get(storeId).getCapacityBytes() != storageStats.get(storeId).getCapacityBytes())) {
1746+
// get add to DB rigorously
1747+
_storageManager.updateImageStoreStatus(storeId, null, null, storageStats.get(storeId).getCapacityBytes());
1748+
}
1749+
}
1750+
// if in _storageStats and not in storageStats it gets discarded
1751+
_storageStats = storageStats;
1752+
}
17401753
}
17411754

17421755
class AutoScaleMonitor extends ManagedContextRunnable {

server/src/main/java/com/cloud/storage/StorageManagerImpl.java

+22-3
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
import org.apache.cloudstack.api.command.admin.storage.DeletePoolCmd;
5858
import org.apache.cloudstack.api.command.admin.storage.DeleteSecondaryStagingStoreCmd;
5959
import org.apache.cloudstack.api.command.admin.storage.SyncStoragePoolCmd;
60+
import org.apache.cloudstack.api.command.admin.storage.UpdateImageStoreCmd;
6061
import org.apache.cloudstack.api.command.admin.storage.UpdateStoragePoolCmd;
6162
import org.apache.cloudstack.context.CallContext;
6263
import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope;
@@ -116,7 +117,6 @@
116117
import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity;
117118
import org.apache.cloudstack.storage.to.VolumeObjectTO;
118119
import org.apache.commons.collections.CollectionUtils;
119-
import org.apache.commons.lang3.StringUtils;
120120
import org.apache.log4j.Logger;
121121
import org.springframework.stereotype.Component;
122122

@@ -212,6 +212,7 @@
212212
import com.cloud.utils.NumbersUtil;
213213
import com.cloud.utils.Pair;
214214
import com.cloud.utils.UriUtils;
215+
import com.cloud.utils.StringUtils;
215216
import com.cloud.utils.component.ComponentContext;
216217
import com.cloud.utils.component.ManagerBase;
217218
import com.cloud.utils.concurrency.NamedThreadFactory;
@@ -2998,17 +2999,35 @@ public ImageStore migrateToObjectStore(String name, String url, String providerN
29982999
}
29993000

30003001
@Override
3001-
public ImageStore updateImageStoreStatus(Long id, Boolean readonly) {
3002+
public ImageStore updateImageStore(UpdateImageStoreCmd cmd) {
3003+
return updateImageStoreStatus(cmd.getId(), cmd.getName(), cmd.getReadonly(), cmd.getCapacityBytes());
3004+
}
3005+
3006+
@Override
3007+
public ImageStore updateImageStoreStatus(Long id, String name, Boolean readonly, Long capacityBytes) {
30023008
// Input validation
30033009
ImageStoreVO imageStoreVO = _imageStoreDao.findById(id);
30043010
if (imageStoreVO == null) {
30053011
throw new IllegalArgumentException("Unable to find image store with ID: " + id);
30063012
}
3007-
imageStoreVO.setReadonly(readonly);
3013+
if (com.cloud.utils.StringUtils.isNotBlank(name)) {
3014+
imageStoreVO.setName(name);
3015+
}
3016+
if (capacityBytes != null) {
3017+
imageStoreVO.setTotalSize(capacityBytes);
3018+
}
3019+
if (readonly != null) {
3020+
imageStoreVO.setReadonly(readonly);
3021+
}
30083022
_imageStoreDao.update(id, imageStoreVO);
30093023
return imageStoreVO;
30103024
}
30113025

3026+
@Override
3027+
public ImageStore updateImageStoreStatus(Long id, Boolean readonly) {
3028+
return updateImageStoreStatus(id, null, readonly, null);
3029+
}
3030+
30123031
/**
30133032
* @param poolId - Storage pool id for pool to update.
30143033
* @param failOnChecks - If true, throw an error if pool type and state checks fail.

ui/src/config/section/infra/secondaryStorages.js

+3-14
Original file line numberDiff line numberDiff line change
@@ -77,21 +77,10 @@ export default {
7777
},
7878
{
7979
api: 'updateImageStore',
80-
icon: 'stop-outlined',
81-
label: 'label.action.image.store.read.only',
82-
message: 'message.action.secondary.storage.read.only',
80+
icon: 'edit-outlined',
81+
label: 'label.edit',
8382
dataView: true,
84-
defaultArgs: { readonly: true },
85-
show: (record) => { return record.readonly === false }
86-
},
87-
{
88-
api: 'updateImageStore',
89-
icon: 'check-circle-outlined',
90-
label: 'label.action.image.store.read.write',
91-
message: 'message.action.secondary.storage.read.write',
92-
dataView: true,
93-
defaultArgs: { readonly: false },
94-
show: (record) => { return record.readonly === true }
83+
args: ['name', 'readonly', 'capacitybytes']
9584
},
9685
{
9786
api: 'deleteImageStore',

ui/src/views/AutogenView.vue

-1
Original file line numberDiff line numberDiff line change
@@ -679,7 +679,6 @@ export default {
679679
},
680680
getOkProps () {
681681
if (this.selectedRowKeys.length > 0 && this.currentAction?.groupAction) {
682-
return { props: { type: 'default' } }
683682
} else {
684683
return { props: { type: 'primary' } }
685684
}

0 commit comments

Comments
 (0)