Skip to content

Commit c9e7ccf

Browse files
committed
Merge pull request #1615 from nvazquez/nfsConfigKey
CLOUDSTACK-9438: Fix for CLOUDSTACK-9252 - Make NFS version changeable in UIJIRA TICKET: https://issues.apache.org/jira/browse/CLOUDSTACK-9438 ### Introduction From #1361 it was possible to configure NFS version for secondary storage mount. However, changing NFS version requires inserting an new detail on `image_store_details` table, with `name = 'nfs.version'` and `value = X` where X is desired NFS version, and then restarting management server for changes to take effect. Our improvement aims to make NFS version changeable from UI, instead of previously described workflow. ### Proposed solution Basically, NFS version is defined as an image store ConfigKey, this implied: * Adding a new Config scope: **ImageStore** * Make `ImageStoreDetailsDao` class to extend `ResourceDetailsDaoBase` and `ImageStoreDetailVO` implement `ResourceDetail` * Insert `'display'` column on `image_store_details` table * Extending `ListCfgsCmd` and `UpdateCfgCmd` to support **ImageStore** scope, which implied: ** Injecting `ImageStoreDetailsDao` and `ImageStoreDao` on `ConfigurationManagerImpl` class, on `cloud-server` module. ### Important It is important to mention that `ImageStoreDaoImpl` and `ImageStoreDetailsDaoImpl` classes were moved from `cloud-engine-storage` to `cloud-engine-schema` module in order to Spring find those beans to inject on `ConfigurationManagerImpl` in `cloud-server` module. We had this maven dependencies between modules: * `cloud-server --> cloud-engine-schema` * `cloud-engine-storage --> cloud-secondary-storage --> cloud-server` As `ImageStoreDaoImpl` and `ImageStoreDetailsDao` were defined in `cloud-engine-storage`, and they needed in `cloud-server` module, to be injected on `ConfigurationManagerImpl`, if we added dependency from `cloud-server` to `cloud-engine-storage` we would introduce a dependency cycle. To avoid this cycle, we moved those classes to `cloud-engine-schema` module * pr/1615: CLOUDSTACK-9438: Fix for CLOUDSTACK-9252 - Make NFS version changeable in UI Signed-off-by: Rajani Karuturi <rajani.karuturi@accelerite.com>
2 parents 3351825 + 2e77496 commit c9e7ccf

24 files changed

Lines changed: 422 additions & 98 deletions

File tree

api/src/org/apache/cloudstack/api/command/admin/config/ListCfgsByCmd.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import org.apache.cloudstack.api.response.AccountResponse;
2929
import org.apache.cloudstack.api.response.ClusterResponse;
3030
import org.apache.cloudstack.api.response.ConfigurationResponse;
31+
import org.apache.cloudstack.api.response.ImageStoreResponse;
3132
import org.apache.cloudstack.api.response.ListResponse;
3233
import org.apache.cloudstack.api.response.StoragePoolResponse;
3334
import org.apache.cloudstack.api.response.ZoneResponse;
@@ -76,6 +77,12 @@ public class ListCfgsByCmd extends BaseListCmd {
7677
description = "the ID of the Account to update the parameter value for corresponding account")
7778
private Long accountId;
7879

80+
@Parameter(name = ApiConstants.IMAGE_STORE_UUID,
81+
type = CommandType.UUID,
82+
entityType = ImageStoreResponse.class,
83+
description = "the ID of the Image Store to update the parameter value for corresponding image store")
84+
private Long imageStoreId;
85+
7986
// ///////////////////////////////////////////////////
8087
// ///////////////// Accessors ///////////////////////
8188
// ///////////////////////////////////////////////////
@@ -104,6 +111,10 @@ public Long getAccountId() {
104111
return accountId;
105112
}
106113

114+
public Long getImageStoreId() {
115+
return imageStoreId;
116+
}
117+
107118
@Override
108119
public Long getPageSizeVal() {
109120
Long defaultPageSize = 500L;
@@ -147,6 +158,9 @@ public void execute() {
147158
if (getAccountId() != null) {
148159
cfgResponse.setScope("account");
149160
}
161+
if (getImageStoreId() != null){
162+
cfgResponse.setScope("imagestore");
163+
}
150164
configResponses.add(cfgResponse);
151165
}
152166

api/src/org/apache/cloudstack/api/command/admin/config/UpdateCfgCmd.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@
1919
import com.google.common.base.Strings;
2020
import org.apache.cloudstack.acl.RoleService;
2121
import org.apache.log4j.Logger;
22-
2322
import org.apache.cloudstack.api.APICommand;
23+
import org.apache.cloudstack.api.ApiArgValidator;
2424
import org.apache.cloudstack.api.ApiConstants;
2525
import org.apache.cloudstack.api.ApiErrorCode;
2626
import org.apache.cloudstack.api.BaseCmd;
@@ -29,6 +29,7 @@
2929
import org.apache.cloudstack.api.response.AccountResponse;
3030
import org.apache.cloudstack.api.response.ClusterResponse;
3131
import org.apache.cloudstack.api.response.ConfigurationResponse;
32+
import org.apache.cloudstack.api.response.ImageStoreResponse;
3233
import org.apache.cloudstack.api.response.StoragePoolResponse;
3334
import org.apache.cloudstack.api.response.ZoneResponse;
3435
import org.apache.cloudstack.config.Configuration;
@@ -75,6 +76,13 @@ public class UpdateCfgCmd extends BaseCmd {
7576
description = "the ID of the Account to update the parameter value for corresponding account")
7677
private Long accountId;
7778

79+
@Parameter(name = ApiConstants.IMAGE_STORE_UUID,
80+
type = CommandType.UUID,
81+
entityType = ImageStoreResponse.class,
82+
description = "the ID of the Image Store to update the parameter value for corresponding image store",
83+
validations = ApiArgValidator.PositiveNumber)
84+
private Long imageStoreId;
85+
7886
/////////////////////////////////////////////////////
7987
/////////////////// Accessors ///////////////////////
8088
/////////////////////////////////////////////////////
@@ -107,6 +115,10 @@ public Long getAccountId() {
107115
return accountId;
108116
}
109117

118+
public Long getImageStoreId() {
119+
return imageStoreId;
120+
}
121+
110122
/////////////////////////////////////////////////////
111123
/////////////// API Implementation///////////////////
112124
/////////////////////////////////////////////////////

engine/components-api/src/com/cloud/capacity/CapacityManager.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,16 @@ public interface CapacityManager {
7373
"If set to true, creates VMs as full clones on ESX hypervisor",
7474
true,
7575
ConfigKey.Scope.StoragePool);
76+
static final ConfigKey<Integer> ImageStoreNFSVersion =
77+
new ConfigKey<Integer>(
78+
Integer.class,
79+
"secstorage.nfs.version",
80+
"Advanced",
81+
null,
82+
"Enforces specific NFS version when mounting Secondary Storage. If NULL default selection is performed",
83+
true,
84+
ConfigKey.Scope.ImageStore,
85+
null);
7686

7787
public boolean releaseVmCapacity(VirtualMachine vm, boolean moveFromReserved, boolean moveToReservered, Long hostId);
7888

engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,8 +176,8 @@
176176
<bean id="hostTagsDaoImpl" class="com.cloud.host.dao.HostTagsDaoImpl" />
177177
<bean id="hostTransferMapDaoImpl" class="com.cloud.cluster.agentlb.dao.HostTransferMapDaoImpl" />
178178
<bean id="iPAddressDaoImpl" class="com.cloud.network.dao.IPAddressDaoImpl" />
179-
<bean id="imageStoreDaoImpl" class="org.apache.cloudstack.storage.image.db.ImageStoreDaoImpl" />
180-
<bean id="imageStoreDetailsDaoImpl" class="org.apache.cloudstack.storage.image.db.ImageStoreDetailsDaoImpl" />
179+
<bean id="imageStoreDaoImpl" class="org.apache.cloudstack.storage.datastore.db.ImageStoreDaoImpl" />
180+
<bean id="imageStoreDetailsDaoImpl" class="org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDaoImpl" />
181181
<bean id="imageStoreJoinDaoImpl" class="com.cloud.api.query.dao.ImageStoreJoinDaoImpl" />
182182
<bean id="snapshotDataStoreDaoImpl" class="org.apache.cloudstack.storage.image.db.SnapshotDataStoreDaoImpl" />
183183
<bean id="templateDataStoreDaoImpl" class="org.apache.cloudstack.storage.image.db.TemplateDataStoreDaoImpl" />

engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java renamed to engine/schema/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDaoImpl.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
* specific language governing permissions and limitations
1717
* under the License.
1818
*/
19-
package org.apache.cloudstack.storage.image.db;
19+
package org.apache.cloudstack.storage.datastore.db;
2020

2121
import java.util.List;
2222
import java.util.Map;
@@ -26,8 +26,6 @@
2626
import org.springframework.stereotype.Component;
2727

2828
import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
29-
import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
30-
import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
3129

3230
import com.cloud.storage.DataStoreRole;
3331
import com.cloud.storage.ScopeType;

engine/schema/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDetailVO.java

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,61 +23,61 @@
2323
import javax.persistence.Id;
2424
import javax.persistence.Table;
2525

26-
import org.apache.cloudstack.api.InternalIdentity;
26+
import org.apache.cloudstack.api.ResourceDetail;
2727

2828
@Entity
2929
@Table(name = "image_store_details")
30-
public class ImageStoreDetailVO implements InternalIdentity {
30+
public class ImageStoreDetailVO implements ResourceDetail {
3131
@Id
3232
@GeneratedValue(strategy = GenerationType.IDENTITY)
3333
@Column(name = "id")
3434
long id;
3535

3636
@Column(name = "store_id")
37-
long storeId;
37+
long resourceId;
3838

3939
@Column(name = "name")
4040
String name;
4141

4242
@Column(name = "value")
4343
String value;
4444

45+
@Column(name = "display")
46+
private boolean display = true;
47+
4548
public ImageStoreDetailVO() {
4649
}
4750

48-
public ImageStoreDetailVO(long storeId, String name, String value) {
49-
this.storeId = storeId;
51+
public ImageStoreDetailVO(long storeId, String name, String value, boolean display) {
52+
this.resourceId = storeId;
5053
this.name = name;
5154
this.value = value;
55+
this.display = display;
5256
}
5357

5458
@Override
5559
public long getId() {
5660
return id;
5761
}
5862

59-
public long getStoreId() {
60-
return storeId;
61-
}
62-
63-
public void setStoreId(long storeId) {
64-
this.storeId = storeId;
63+
@Override
64+
public long getResourceId() {
65+
return resourceId;
6566
}
6667

68+
@Override
6769
public String getName() {
6870
return name;
6971
}
7072

71-
public void setName(String name) {
72-
this.name = name;
73-
}
74-
73+
@Override
7574
public String getValue() {
7675
return value;
7776
}
7877

79-
public void setValue(String value) {
80-
this.value = value;
78+
@Override
79+
public boolean isDisplay() {
80+
return display;
8181
}
8282

8383
}

engine/schema/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDetailsDao.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,11 @@
1818

1919
import java.util.Map;
2020

21+
import org.apache.cloudstack.resourcedetail.ResourceDetailsDao;
22+
2123
import com.cloud.utils.db.GenericDao;
2224

23-
public interface ImageStoreDetailsDao extends GenericDao<ImageStoreDetailVO, Long> {
25+
public interface ImageStoreDetailsDao extends GenericDao<ImageStoreDetailVO, Long>, ResourceDetailsDao<ImageStoreDetailVO> {
2426

2527
void update(long storeId, Map<String, String> details);
2628

engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDetailsDaoImpl.java renamed to engine/schema/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDetailsDaoImpl.java

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,34 +14,36 @@
1414
// KIND, either express or implied. See the License for the
1515
// specific language governing permissions and limitations
1616
// under the License.
17-
package org.apache.cloudstack.storage.image.db;
17+
package org.apache.cloudstack.storage.datastore.db;
1818

1919
import java.util.HashMap;
2020
import java.util.List;
2121
import java.util.Map;
2222

23-
2423
import org.springframework.stereotype.Component;
2524

26-
import org.apache.cloudstack.api.ApiConstants;
27-
import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailVO;
28-
import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao;
29-
3025
import com.cloud.utils.crypt.DBEncryptionUtil;
31-
import com.cloud.utils.db.GenericDaoBase;
26+
import com.cloud.utils.db.QueryBuilder;
3227
import com.cloud.utils.db.SearchBuilder;
3328
import com.cloud.utils.db.SearchCriteria;
29+
import com.cloud.utils.db.SearchCriteria.Op;
3430
import com.cloud.utils.db.TransactionLegacy;
3531

32+
import org.apache.cloudstack.api.ApiConstants;
33+
import org.apache.cloudstack.framework.config.ConfigKey;
34+
import org.apache.cloudstack.framework.config.ConfigKey.Scope;
35+
import org.apache.cloudstack.framework.config.ScopedConfigStorage;
36+
import org.apache.cloudstack.resourcedetail.ResourceDetailsDaoBase;
37+
3638
@Component
37-
public class ImageStoreDetailsDaoImpl extends GenericDaoBase<ImageStoreDetailVO, Long> implements ImageStoreDetailsDao {
39+
public class ImageStoreDetailsDaoImpl extends ResourceDetailsDaoBase<ImageStoreDetailVO> implements ImageStoreDetailsDao, ScopedConfigStorage {
3840

3941
protected final SearchBuilder<ImageStoreDetailVO> storeSearch;
4042

41-
protected ImageStoreDetailsDaoImpl() {
43+
public ImageStoreDetailsDaoImpl() {
4244
super();
4345
storeSearch = createSearchBuilder();
44-
storeSearch.and("store", storeSearch.entity().getStoreId(), SearchCriteria.Op.EQ);
46+
storeSearch.and("store", storeSearch.entity().getResourceId(), SearchCriteria.Op.EQ);
4547
storeSearch.done();
4648
}
4749

@@ -54,7 +56,7 @@ public void update(long storeId, Map<String, String> details) {
5456
txn.start();
5557
expunge(sc);
5658
for (Map.Entry<String, String> entry : details.entrySet()) {
57-
ImageStoreDetailVO detail = new ImageStoreDetailVO(storeId, entry.getKey(), entry.getValue());
59+
ImageStoreDetailVO detail = new ImageStoreDetailVO(storeId, entry.getKey(), entry.getValue(), true);
5860
persist(detail);
5961
}
6062
txn.commit();
@@ -88,7 +90,30 @@ public void deleteDetails(long storeId) {
8890
for (ImageStoreDetailVO result : results) {
8991
remove(result.getId());
9092
}
93+
}
94+
95+
@Override
96+
public Scope getScope() {
97+
return ConfigKey.Scope.ImageStore;
98+
}
99+
100+
@Override
101+
public ImageStoreDetailVO findDetail(long storeId, String name) {
102+
QueryBuilder<ImageStoreDetailVO> sc = QueryBuilder.create(ImageStoreDetailVO.class);
103+
sc.and(sc.entity().getResourceId(), Op.EQ, storeId);
104+
sc.and(sc.entity().getName(), Op.EQ, name);
105+
return sc.find();
106+
}
91107

108+
@Override
109+
public String getConfigValue(long id, ConfigKey<?> key) {
110+
ImageStoreDetailVO vo = findDetail(id, key.key());
111+
return vo == null ? null : vo.getValue();
112+
}
113+
114+
@Override
115+
public void addDetail(long resourceId, String key, String value, boolean display) {
116+
super.addDetail(new ImageStoreDetailVO(resourceId, key, value, display));
92117
}
93118

94119
}

engine/storage/integration-test/test/resource/fakeDriverTestContext.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@
3535
</property>
3636
</bean>
3737

38-
<bean id="imageStoreDaoImpl" class="org.apache.cloudstack.storage.image.db.ImageStoreDaoImpl" />
39-
<bean id="imageStoreDetailsDaoImpl" class="org.apache.cloudstack.storage.image.db.ImageStoreDetailsDaoImpl" />
38+
<bean id="imageStoreDaoImpl" class="org.apache.cloudstack.storage.datastore.db.ImageStoreDaoImpl" />
39+
<bean id="imageStoreDetailsDaoImpl" class="org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDaoImpl" />
4040
<bean id="snapshotDataStoreDaoImpl" class="org.apache.cloudstack.storage.image.db.SnapshotDataStoreDaoImpl" />
4141
<bean id="templateDataStoreDaoImpl" class="org.apache.cloudstack.storage.image.db.TemplateDataStoreDaoImpl" />
4242
<bean id="volumeDataStoreDaoImpl" class="org.apache.cloudstack.storage.image.db.VolumeDataStoreDaoImpl" />

engine/storage/integration-test/test/resources/storageContext.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@
3535
</property>
3636
</bean>
3737

38-
<bean id="imageStoreDaoImpl" class="org.apache.cloudstack.storage.image.db.ImageStoreDaoImpl" />
39-
<bean id="imageStoreDetailsDaoImpl" class="org.apache.cloudstack.storage.image.db.ImageStoreDetailsDaoImpl" />
38+
<bean id="imageStoreDaoImpl" class="org.apache.cloudstack.storage.datastore.db.ImageStoreDaoImpl" />
39+
<bean id="imageStoreDetailsDaoImpl" class="org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDaoImpl" />
4040
<bean id="snapshotDataStoreDaoImpl" class="org.apache.cloudstack.storage.image.db.SnapshotDataStoreDaoImpl" />
4141
<bean id="templateDataStoreDaoImpl" class="org.apache.cloudstack.storage.image.db.TemplateDataStoreDaoImpl" />
4242
<bean id="volumeDataStoreDaoImpl" class="org.apache.cloudstack.storage.image.db.VolumeDataStoreDaoImpl" />

0 commit comments

Comments
 (0)