mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
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>
This commit is contained in:
commit
c9e7ccf46e
@ -28,6 +28,7 @@ import org.apache.cloudstack.api.Parameter;
|
|||||||
import org.apache.cloudstack.api.response.AccountResponse;
|
import org.apache.cloudstack.api.response.AccountResponse;
|
||||||
import org.apache.cloudstack.api.response.ClusterResponse;
|
import org.apache.cloudstack.api.response.ClusterResponse;
|
||||||
import org.apache.cloudstack.api.response.ConfigurationResponse;
|
import org.apache.cloudstack.api.response.ConfigurationResponse;
|
||||||
|
import org.apache.cloudstack.api.response.ImageStoreResponse;
|
||||||
import org.apache.cloudstack.api.response.ListResponse;
|
import org.apache.cloudstack.api.response.ListResponse;
|
||||||
import org.apache.cloudstack.api.response.StoragePoolResponse;
|
import org.apache.cloudstack.api.response.StoragePoolResponse;
|
||||||
import org.apache.cloudstack.api.response.ZoneResponse;
|
import org.apache.cloudstack.api.response.ZoneResponse;
|
||||||
@ -76,6 +77,12 @@ public class ListCfgsByCmd extends BaseListCmd {
|
|||||||
description = "the ID of the Account to update the parameter value for corresponding account")
|
description = "the ID of the Account to update the parameter value for corresponding account")
|
||||||
private Long accountId;
|
private Long accountId;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.IMAGE_STORE_UUID,
|
||||||
|
type = CommandType.UUID,
|
||||||
|
entityType = ImageStoreResponse.class,
|
||||||
|
description = "the ID of the Image Store to update the parameter value for corresponding image store")
|
||||||
|
private Long imageStoreId;
|
||||||
|
|
||||||
// ///////////////////////////////////////////////////
|
// ///////////////////////////////////////////////////
|
||||||
// ///////////////// Accessors ///////////////////////
|
// ///////////////// Accessors ///////////////////////
|
||||||
// ///////////////////////////////////////////////////
|
// ///////////////////////////////////////////////////
|
||||||
@ -104,6 +111,10 @@ public class ListCfgsByCmd extends BaseListCmd {
|
|||||||
return accountId;
|
return accountId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Long getImageStoreId() {
|
||||||
|
return imageStoreId;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Long getPageSizeVal() {
|
public Long getPageSizeVal() {
|
||||||
Long defaultPageSize = 500L;
|
Long defaultPageSize = 500L;
|
||||||
@ -147,6 +158,9 @@ public class ListCfgsByCmd extends BaseListCmd {
|
|||||||
if (getAccountId() != null) {
|
if (getAccountId() != null) {
|
||||||
cfgResponse.setScope("account");
|
cfgResponse.setScope("account");
|
||||||
}
|
}
|
||||||
|
if (getImageStoreId() != null){
|
||||||
|
cfgResponse.setScope("imagestore");
|
||||||
|
}
|
||||||
configResponses.add(cfgResponse);
|
configResponses.add(cfgResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -19,8 +19,8 @@ package org.apache.cloudstack.api.command.admin.config;
|
|||||||
import com.google.common.base.Strings;
|
import com.google.common.base.Strings;
|
||||||
import org.apache.cloudstack.acl.RoleService;
|
import org.apache.cloudstack.acl.RoleService;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
import org.apache.cloudstack.api.APICommand;
|
import org.apache.cloudstack.api.APICommand;
|
||||||
|
import org.apache.cloudstack.api.ApiArgValidator;
|
||||||
import org.apache.cloudstack.api.ApiConstants;
|
import org.apache.cloudstack.api.ApiConstants;
|
||||||
import org.apache.cloudstack.api.ApiErrorCode;
|
import org.apache.cloudstack.api.ApiErrorCode;
|
||||||
import org.apache.cloudstack.api.BaseCmd;
|
import org.apache.cloudstack.api.BaseCmd;
|
||||||
@ -29,6 +29,7 @@ import org.apache.cloudstack.api.ServerApiException;
|
|||||||
import org.apache.cloudstack.api.response.AccountResponse;
|
import org.apache.cloudstack.api.response.AccountResponse;
|
||||||
import org.apache.cloudstack.api.response.ClusterResponse;
|
import org.apache.cloudstack.api.response.ClusterResponse;
|
||||||
import org.apache.cloudstack.api.response.ConfigurationResponse;
|
import org.apache.cloudstack.api.response.ConfigurationResponse;
|
||||||
|
import org.apache.cloudstack.api.response.ImageStoreResponse;
|
||||||
import org.apache.cloudstack.api.response.StoragePoolResponse;
|
import org.apache.cloudstack.api.response.StoragePoolResponse;
|
||||||
import org.apache.cloudstack.api.response.ZoneResponse;
|
import org.apache.cloudstack.api.response.ZoneResponse;
|
||||||
import org.apache.cloudstack.config.Configuration;
|
import org.apache.cloudstack.config.Configuration;
|
||||||
@ -75,6 +76,13 @@ public class UpdateCfgCmd extends BaseCmd {
|
|||||||
description = "the ID of the Account to update the parameter value for corresponding account")
|
description = "the ID of the Account to update the parameter value for corresponding account")
|
||||||
private Long accountId;
|
private Long accountId;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.IMAGE_STORE_UUID,
|
||||||
|
type = CommandType.UUID,
|
||||||
|
entityType = ImageStoreResponse.class,
|
||||||
|
description = "the ID of the Image Store to update the parameter value for corresponding image store",
|
||||||
|
validations = ApiArgValidator.PositiveNumber)
|
||||||
|
private Long imageStoreId;
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
/////////////////// Accessors ///////////////////////
|
/////////////////// Accessors ///////////////////////
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
@ -107,6 +115,10 @@ public class UpdateCfgCmd extends BaseCmd {
|
|||||||
return accountId;
|
return accountId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Long getImageStoreId() {
|
||||||
|
return imageStoreId;
|
||||||
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
/////////////// API Implementation///////////////////
|
/////////////// API Implementation///////////////////
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
|
|||||||
@ -73,6 +73,16 @@ public interface CapacityManager {
|
|||||||
"If set to true, creates VMs as full clones on ESX hypervisor",
|
"If set to true, creates VMs as full clones on ESX hypervisor",
|
||||||
true,
|
true,
|
||||||
ConfigKey.Scope.StoragePool);
|
ConfigKey.Scope.StoragePool);
|
||||||
|
static final ConfigKey<Integer> ImageStoreNFSVersion =
|
||||||
|
new ConfigKey<Integer>(
|
||||||
|
Integer.class,
|
||||||
|
"secstorage.nfs.version",
|
||||||
|
"Advanced",
|
||||||
|
null,
|
||||||
|
"Enforces specific NFS version when mounting Secondary Storage. If NULL default selection is performed",
|
||||||
|
true,
|
||||||
|
ConfigKey.Scope.ImageStore,
|
||||||
|
null);
|
||||||
|
|
||||||
public boolean releaseVmCapacity(VirtualMachine vm, boolean moveFromReserved, boolean moveToReservered, Long hostId);
|
public boolean releaseVmCapacity(VirtualMachine vm, boolean moveFromReserved, boolean moveToReservered, Long hostId);
|
||||||
|
|
||||||
|
|||||||
@ -176,8 +176,8 @@
|
|||||||
<bean id="hostTagsDaoImpl" class="com.cloud.host.dao.HostTagsDaoImpl" />
|
<bean id="hostTagsDaoImpl" class="com.cloud.host.dao.HostTagsDaoImpl" />
|
||||||
<bean id="hostTransferMapDaoImpl" class="com.cloud.cluster.agentlb.dao.HostTransferMapDaoImpl" />
|
<bean id="hostTransferMapDaoImpl" class="com.cloud.cluster.agentlb.dao.HostTransferMapDaoImpl" />
|
||||||
<bean id="iPAddressDaoImpl" class="com.cloud.network.dao.IPAddressDaoImpl" />
|
<bean id="iPAddressDaoImpl" class="com.cloud.network.dao.IPAddressDaoImpl" />
|
||||||
<bean id="imageStoreDaoImpl" class="org.apache.cloudstack.storage.image.db.ImageStoreDaoImpl" />
|
<bean id="imageStoreDaoImpl" class="org.apache.cloudstack.storage.datastore.db.ImageStoreDaoImpl" />
|
||||||
<bean id="imageStoreDetailsDaoImpl" class="org.apache.cloudstack.storage.image.db.ImageStoreDetailsDaoImpl" />
|
<bean id="imageStoreDetailsDaoImpl" class="org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDaoImpl" />
|
||||||
<bean id="imageStoreJoinDaoImpl" class="com.cloud.api.query.dao.ImageStoreJoinDaoImpl" />
|
<bean id="imageStoreJoinDaoImpl" class="com.cloud.api.query.dao.ImageStoreJoinDaoImpl" />
|
||||||
<bean id="snapshotDataStoreDaoImpl" class="org.apache.cloudstack.storage.image.db.SnapshotDataStoreDaoImpl" />
|
<bean id="snapshotDataStoreDaoImpl" class="org.apache.cloudstack.storage.image.db.SnapshotDataStoreDaoImpl" />
|
||||||
<bean id="templateDataStoreDaoImpl" class="org.apache.cloudstack.storage.image.db.TemplateDataStoreDaoImpl" />
|
<bean id="templateDataStoreDaoImpl" class="org.apache.cloudstack.storage.image.db.TemplateDataStoreDaoImpl" />
|
||||||
|
|||||||
@ -16,7 +16,7 @@
|
|||||||
* specific language governing permissions and limitations
|
* specific language governing permissions and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
package org.apache.cloudstack.storage.image.db;
|
package org.apache.cloudstack.storage.datastore.db;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -26,8 +26,6 @@ import javax.naming.ConfigurationException;
|
|||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
|
import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
|
||||||
import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
|
|
||||||
import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
|
|
||||||
|
|
||||||
import com.cloud.storage.DataStoreRole;
|
import com.cloud.storage.DataStoreRole;
|
||||||
import com.cloud.storage.ScopeType;
|
import com.cloud.storage.ScopeType;
|
||||||
@ -23,18 +23,18 @@ import javax.persistence.GenerationType;
|
|||||||
import javax.persistence.Id;
|
import javax.persistence.Id;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
|
|
||||||
import org.apache.cloudstack.api.InternalIdentity;
|
import org.apache.cloudstack.api.ResourceDetail;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "image_store_details")
|
@Table(name = "image_store_details")
|
||||||
public class ImageStoreDetailVO implements InternalIdentity {
|
public class ImageStoreDetailVO implements ResourceDetail {
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
@Column(name = "id")
|
@Column(name = "id")
|
||||||
long id;
|
long id;
|
||||||
|
|
||||||
@Column(name = "store_id")
|
@Column(name = "store_id")
|
||||||
long storeId;
|
long resourceId;
|
||||||
|
|
||||||
@Column(name = "name")
|
@Column(name = "name")
|
||||||
String name;
|
String name;
|
||||||
@ -42,13 +42,17 @@ public class ImageStoreDetailVO implements InternalIdentity {
|
|||||||
@Column(name = "value")
|
@Column(name = "value")
|
||||||
String value;
|
String value;
|
||||||
|
|
||||||
|
@Column(name = "display")
|
||||||
|
private boolean display = true;
|
||||||
|
|
||||||
public ImageStoreDetailVO() {
|
public ImageStoreDetailVO() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public ImageStoreDetailVO(long storeId, String name, String value) {
|
public ImageStoreDetailVO(long storeId, String name, String value, boolean display) {
|
||||||
this.storeId = storeId;
|
this.resourceId = storeId;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.value = value;
|
this.value = value;
|
||||||
|
this.display = display;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -56,28 +60,24 @@ public class ImageStoreDetailVO implements InternalIdentity {
|
|||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getStoreId() {
|
@Override
|
||||||
return storeId;
|
public long getResourceId() {
|
||||||
}
|
return resourceId;
|
||||||
|
|
||||||
public void setStoreId(long storeId) {
|
|
||||||
this.storeId = storeId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setName(String name) {
|
@Override
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getValue() {
|
public String getValue() {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setValue(String value) {
|
@Override
|
||||||
this.value = value;
|
public boolean isDisplay() {
|
||||||
|
return display;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,9 +18,11 @@ package org.apache.cloudstack.storage.datastore.db;
|
|||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.apache.cloudstack.resourcedetail.ResourceDetailsDao;
|
||||||
|
|
||||||
import com.cloud.utils.db.GenericDao;
|
import com.cloud.utils.db.GenericDao;
|
||||||
|
|
||||||
public interface ImageStoreDetailsDao extends GenericDao<ImageStoreDetailVO, Long> {
|
public interface ImageStoreDetailsDao extends GenericDao<ImageStoreDetailVO, Long>, ResourceDetailsDao<ImageStoreDetailVO> {
|
||||||
|
|
||||||
void update(long storeId, Map<String, String> details);
|
void update(long storeId, Map<String, String> details);
|
||||||
|
|
||||||
|
|||||||
@ -14,34 +14,36 @@
|
|||||||
// KIND, either express or implied. See the License for the
|
// KIND, either express or implied. See the License for the
|
||||||
// specific language governing permissions and limitations
|
// specific language governing permissions and limitations
|
||||||
// under the License.
|
// under the License.
|
||||||
package org.apache.cloudstack.storage.image.db;
|
package org.apache.cloudstack.storage.datastore.db;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import org.apache.cloudstack.api.ApiConstants;
|
|
||||||
import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailVO;
|
|
||||||
import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao;
|
|
||||||
|
|
||||||
import com.cloud.utils.crypt.DBEncryptionUtil;
|
import com.cloud.utils.crypt.DBEncryptionUtil;
|
||||||
import com.cloud.utils.db.GenericDaoBase;
|
import com.cloud.utils.db.QueryBuilder;
|
||||||
import com.cloud.utils.db.SearchBuilder;
|
import com.cloud.utils.db.SearchBuilder;
|
||||||
import com.cloud.utils.db.SearchCriteria;
|
import com.cloud.utils.db.SearchCriteria;
|
||||||
|
import com.cloud.utils.db.SearchCriteria.Op;
|
||||||
import com.cloud.utils.db.TransactionLegacy;
|
import com.cloud.utils.db.TransactionLegacy;
|
||||||
|
|
||||||
|
import org.apache.cloudstack.api.ApiConstants;
|
||||||
|
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||||
|
import org.apache.cloudstack.framework.config.ConfigKey.Scope;
|
||||||
|
import org.apache.cloudstack.framework.config.ScopedConfigStorage;
|
||||||
|
import org.apache.cloudstack.resourcedetail.ResourceDetailsDaoBase;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
public class ImageStoreDetailsDaoImpl extends GenericDaoBase<ImageStoreDetailVO, Long> implements ImageStoreDetailsDao {
|
public class ImageStoreDetailsDaoImpl extends ResourceDetailsDaoBase<ImageStoreDetailVO> implements ImageStoreDetailsDao, ScopedConfigStorage {
|
||||||
|
|
||||||
protected final SearchBuilder<ImageStoreDetailVO> storeSearch;
|
protected final SearchBuilder<ImageStoreDetailVO> storeSearch;
|
||||||
|
|
||||||
protected ImageStoreDetailsDaoImpl() {
|
public ImageStoreDetailsDaoImpl() {
|
||||||
super();
|
super();
|
||||||
storeSearch = createSearchBuilder();
|
storeSearch = createSearchBuilder();
|
||||||
storeSearch.and("store", storeSearch.entity().getStoreId(), SearchCriteria.Op.EQ);
|
storeSearch.and("store", storeSearch.entity().getResourceId(), SearchCriteria.Op.EQ);
|
||||||
storeSearch.done();
|
storeSearch.done();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,7 +56,7 @@ public class ImageStoreDetailsDaoImpl extends GenericDaoBase<ImageStoreDetailVO,
|
|||||||
txn.start();
|
txn.start();
|
||||||
expunge(sc);
|
expunge(sc);
|
||||||
for (Map.Entry<String, String> entry : details.entrySet()) {
|
for (Map.Entry<String, String> entry : details.entrySet()) {
|
||||||
ImageStoreDetailVO detail = new ImageStoreDetailVO(storeId, entry.getKey(), entry.getValue());
|
ImageStoreDetailVO detail = new ImageStoreDetailVO(storeId, entry.getKey(), entry.getValue(), true);
|
||||||
persist(detail);
|
persist(detail);
|
||||||
}
|
}
|
||||||
txn.commit();
|
txn.commit();
|
||||||
@ -88,7 +90,30 @@ public class ImageStoreDetailsDaoImpl extends GenericDaoBase<ImageStoreDetailVO,
|
|||||||
for (ImageStoreDetailVO result : results) {
|
for (ImageStoreDetailVO result : results) {
|
||||||
remove(result.getId());
|
remove(result.getId());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Scope getScope() {
|
||||||
|
return ConfigKey.Scope.ImageStore;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ImageStoreDetailVO findDetail(long storeId, String name) {
|
||||||
|
QueryBuilder<ImageStoreDetailVO> sc = QueryBuilder.create(ImageStoreDetailVO.class);
|
||||||
|
sc.and(sc.entity().getResourceId(), Op.EQ, storeId);
|
||||||
|
sc.and(sc.entity().getName(), Op.EQ, name);
|
||||||
|
return sc.find();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getConfigValue(long id, ConfigKey<?> key) {
|
||||||
|
ImageStoreDetailVO vo = findDetail(id, key.key());
|
||||||
|
return vo == null ? null : vo.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addDetail(long resourceId, String key, String value, boolean display) {
|
||||||
|
super.addDetail(new ImageStoreDetailVO(resourceId, key, value, display));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -35,8 +35,8 @@
|
|||||||
</property>
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="imageStoreDaoImpl" class="org.apache.cloudstack.storage.image.db.ImageStoreDaoImpl" />
|
<bean id="imageStoreDaoImpl" class="org.apache.cloudstack.storage.datastore.db.ImageStoreDaoImpl" />
|
||||||
<bean id="imageStoreDetailsDaoImpl" class="org.apache.cloudstack.storage.image.db.ImageStoreDetailsDaoImpl" />
|
<bean id="imageStoreDetailsDaoImpl" class="org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDaoImpl" />
|
||||||
<bean id="snapshotDataStoreDaoImpl" class="org.apache.cloudstack.storage.image.db.SnapshotDataStoreDaoImpl" />
|
<bean id="snapshotDataStoreDaoImpl" class="org.apache.cloudstack.storage.image.db.SnapshotDataStoreDaoImpl" />
|
||||||
<bean id="templateDataStoreDaoImpl" class="org.apache.cloudstack.storage.image.db.TemplateDataStoreDaoImpl" />
|
<bean id="templateDataStoreDaoImpl" class="org.apache.cloudstack.storage.image.db.TemplateDataStoreDaoImpl" />
|
||||||
<bean id="volumeDataStoreDaoImpl" class="org.apache.cloudstack.storage.image.db.VolumeDataStoreDaoImpl" />
|
<bean id="volumeDataStoreDaoImpl" class="org.apache.cloudstack.storage.image.db.VolumeDataStoreDaoImpl" />
|
||||||
|
|||||||
@ -35,8 +35,8 @@
|
|||||||
</property>
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="imageStoreDaoImpl" class="org.apache.cloudstack.storage.image.db.ImageStoreDaoImpl" />
|
<bean id="imageStoreDaoImpl" class="org.apache.cloudstack.storage.datastore.db.ImageStoreDaoImpl" />
|
||||||
<bean id="imageStoreDetailsDaoImpl" class="org.apache.cloudstack.storage.image.db.ImageStoreDetailsDaoImpl" />
|
<bean id="imageStoreDetailsDaoImpl" class="org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDaoImpl" />
|
||||||
<bean id="snapshotDataStoreDaoImpl" class="org.apache.cloudstack.storage.image.db.SnapshotDataStoreDaoImpl" />
|
<bean id="snapshotDataStoreDaoImpl" class="org.apache.cloudstack.storage.image.db.SnapshotDataStoreDaoImpl" />
|
||||||
<bean id="templateDataStoreDaoImpl" class="org.apache.cloudstack.storage.image.db.TemplateDataStoreDaoImpl" />
|
<bean id="templateDataStoreDaoImpl" class="org.apache.cloudstack.storage.image.db.TemplateDataStoreDaoImpl" />
|
||||||
<bean id="volumeDataStoreDaoImpl" class="org.apache.cloudstack.storage.image.db.VolumeDataStoreDaoImpl" />
|
<bean id="volumeDataStoreDaoImpl" class="org.apache.cloudstack.storage.image.db.VolumeDataStoreDaoImpl" />
|
||||||
|
|||||||
@ -24,22 +24,23 @@ import javax.inject.Inject;
|
|||||||
|
|
||||||
import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao;
|
import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao;
|
||||||
|
|
||||||
|
import com.cloud.capacity.CapacityManager;
|
||||||
|
|
||||||
public abstract class NfsImageStoreDriverImpl extends BaseImageStoreDriverImpl {
|
public abstract class NfsImageStoreDriverImpl extends BaseImageStoreDriverImpl {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
ImageStoreDetailsDao _imageStoreDetailsDao;
|
ImageStoreDetailsDao _imageStoreDetailsDao;
|
||||||
|
|
||||||
private static final String NFS_VERSION_DETAILS_KEY = "nfs.version";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve NFS version to be used for imgStoreId store, if provided in image_store_details table
|
* Retrieve NFS version to be used for imgStoreId store, if provided in image_store_details table
|
||||||
* @param imgStoreId store id
|
* @param imgStoreId store id
|
||||||
* @return "nfs.version" associated value for imgStoreId in image_store_details table if exists, null if not
|
* @return "secstorage.nfs.version" associated value for imgStoreId in image_store_details table if exists, null if not
|
||||||
*/
|
*/
|
||||||
protected Integer getNfsVersion(long imgStoreId){
|
protected Integer getNfsVersion(long imgStoreId){
|
||||||
Map<String, String> imgStoreDetails = _imageStoreDetailsDao.getDetails(imgStoreId);
|
Map<String, String> imgStoreDetails = _imageStoreDetailsDao.getDetails(imgStoreId);
|
||||||
if (imgStoreDetails != null && imgStoreDetails.containsKey(NFS_VERSION_DETAILS_KEY)){
|
String nfsVersionKey = CapacityManager.ImageStoreNFSVersion.key();
|
||||||
String nfsVersionParam = imgStoreDetails.get(NFS_VERSION_DETAILS_KEY);
|
if (imgStoreDetails != null && imgStoreDetails.containsKey(nfsVersionKey)){
|
||||||
|
String nfsVersionParam = imgStoreDetails.get(nfsVersionKey);
|
||||||
return (nfsVersionParam != null ? Integer.valueOf(nfsVersionParam) : null);
|
return (nfsVersionParam != null ? Integer.valueOf(nfsVersionParam) : null);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@ -129,15 +129,12 @@ public class ImageStoreHelper {
|
|||||||
Iterator<String> keyIter = details.keySet().iterator();
|
Iterator<String> keyIter = details.keySet().iterator();
|
||||||
while (keyIter.hasNext()) {
|
while (keyIter.hasNext()) {
|
||||||
String key = keyIter.next().toString();
|
String key = keyIter.next().toString();
|
||||||
ImageStoreDetailVO detail = new ImageStoreDetailVO();
|
|
||||||
detail.setStoreId(store.getId());
|
|
||||||
detail.setName(key);
|
|
||||||
String value = details.get(key);
|
String value = details.get(key);
|
||||||
// encrypt swift key or s3 secret key
|
// encrypt swift key or s3 secret key
|
||||||
if (key.equals(ApiConstants.KEY) || key.equals(ApiConstants.S3_SECRET_KEY)) {
|
if (key.equals(ApiConstants.KEY) || key.equals(ApiConstants.S3_SECRET_KEY)) {
|
||||||
value = DBEncryptionUtil.encrypt(value);
|
value = DBEncryptionUtil.encrypt(value);
|
||||||
}
|
}
|
||||||
detail.setValue(value);
|
ImageStoreDetailVO detail = new ImageStoreDetailVO(store.getId(), key, value, true);
|
||||||
imageStoreDetailsDao.persist(detail);
|
imageStoreDetailsDao.persist(detail);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -31,7 +31,7 @@ import com.cloud.utils.exception.CloudRuntimeException;
|
|||||||
public class ConfigKey<T> {
|
public class ConfigKey<T> {
|
||||||
|
|
||||||
public static enum Scope {
|
public static enum Scope {
|
||||||
Global, Zone, Cluster, StoragePool, Account, ManagementServer
|
Global, Zone, Cluster, StoragePool, Account, ManagementServer, ImageStore
|
||||||
}
|
}
|
||||||
|
|
||||||
private final String _category;
|
private final String _category;
|
||||||
|
|||||||
@ -84,6 +84,7 @@ public class ConfigDepotImpl implements ConfigDepot, ConfigDepotAdmin {
|
|||||||
_scopeLevelConfigsMap.put(ConfigKey.Scope.Cluster, new HashSet<ConfigKey<?>>());
|
_scopeLevelConfigsMap.put(ConfigKey.Scope.Cluster, new HashSet<ConfigKey<?>>());
|
||||||
_scopeLevelConfigsMap.put(ConfigKey.Scope.StoragePool, new HashSet<ConfigKey<?>>());
|
_scopeLevelConfigsMap.put(ConfigKey.Scope.StoragePool, new HashSet<ConfigKey<?>>());
|
||||||
_scopeLevelConfigsMap.put(ConfigKey.Scope.Account, new HashSet<ConfigKey<?>>());
|
_scopeLevelConfigsMap.put(ConfigKey.Scope.Account, new HashSet<ConfigKey<?>>());
|
||||||
|
_scopeLevelConfigsMap.put(ConfigKey.Scope.ImageStore, new HashSet<ConfigKey<?>>());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -80,8 +80,8 @@ import org.apache.cloudstack.region.dao.RegionDaoImpl;
|
|||||||
import org.apache.cloudstack.spring.lifecycle.registry.ExtensionRegistry;
|
import org.apache.cloudstack.spring.lifecycle.registry.ExtensionRegistry;
|
||||||
import org.apache.cloudstack.storage.datastore.PrimaryDataStoreProviderManager;
|
import org.apache.cloudstack.storage.datastore.PrimaryDataStoreProviderManager;
|
||||||
import org.apache.cloudstack.storage.image.datastore.ImageStoreProviderManager;
|
import org.apache.cloudstack.storage.image.datastore.ImageStoreProviderManager;
|
||||||
|
import org.apache.cloudstack.storage.datastore.db.ImageStoreDaoImpl;
|
||||||
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDaoImpl;
|
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDaoImpl;
|
||||||
import org.apache.cloudstack.storage.image.db.ImageStoreDaoImpl;
|
|
||||||
import org.apache.cloudstack.storage.image.db.TemplateDataStoreDaoImpl;
|
import org.apache.cloudstack.storage.image.db.TemplateDataStoreDaoImpl;
|
||||||
import org.apache.cloudstack.usage.UsageService;
|
import org.apache.cloudstack.usage.UsageService;
|
||||||
|
|
||||||
|
|||||||
@ -1101,6 +1101,6 @@ public class CapacityManagerImpl extends ManagerBase implements CapacityManager,
|
|||||||
@Override
|
@Override
|
||||||
public ConfigKey<?>[] getConfigKeys() {
|
public ConfigKey<?>[] getConfigKeys() {
|
||||||
return new ConfigKey<?>[] {CpuOverprovisioningFactor, MemOverprovisioningFactor, StorageCapacityDisableThreshold, StorageOverprovisioningFactor,
|
return new ConfigKey<?>[] {CpuOverprovisioningFactor, MemOverprovisioningFactor, StorageCapacityDisableThreshold, StorageOverprovisioningFactor,
|
||||||
StorageAllocatedCapacityDisableThreshold, StorageOperationsExcludeCluster, VmwareCreateCloneFull};
|
StorageAllocatedCapacityDisableThreshold, StorageOperationsExcludeCluster, VmwareCreateCloneFull, ImageStoreNFSVersion};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -81,6 +81,9 @@ import org.apache.cloudstack.region.PortableIpVO;
|
|||||||
import org.apache.cloudstack.region.Region;
|
import org.apache.cloudstack.region.Region;
|
||||||
import org.apache.cloudstack.region.RegionVO;
|
import org.apache.cloudstack.region.RegionVO;
|
||||||
import org.apache.cloudstack.region.dao.RegionDao;
|
import org.apache.cloudstack.region.dao.RegionDao;
|
||||||
|
import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
|
||||||
|
import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao;
|
||||||
|
import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
|
||||||
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
|
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
|
||||||
import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao;
|
import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao;
|
||||||
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
||||||
@ -216,6 +219,7 @@ import com.cloud.vm.dao.NicIpAliasDao;
|
|||||||
import com.cloud.vm.dao.NicIpAliasVO;
|
import com.cloud.vm.dao.NicIpAliasVO;
|
||||||
import com.cloud.vm.dao.NicSecondaryIpDao;
|
import com.cloud.vm.dao.NicSecondaryIpDao;
|
||||||
import com.cloud.vm.dao.VMInstanceDao;
|
import com.cloud.vm.dao.VMInstanceDao;
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
|
|
||||||
public class ConfigurationManagerImpl extends ManagerBase implements ConfigurationManager, ConfigurationService, Configurable {
|
public class ConfigurationManagerImpl extends ManagerBase implements ConfigurationManager, ConfigurationService, Configurable {
|
||||||
public static final Logger s_logger = Logger.getLogger(ConfigurationManagerImpl.class);
|
public static final Logger s_logger = Logger.getLogger(ConfigurationManagerImpl.class);
|
||||||
@ -335,6 +339,10 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
|||||||
AffinityGroupService _affinityGroupService;
|
AffinityGroupService _affinityGroupService;
|
||||||
@Inject
|
@Inject
|
||||||
StorageManager _storageManager;
|
StorageManager _storageManager;
|
||||||
|
@Inject
|
||||||
|
ImageStoreDao _imageStoreDao;
|
||||||
|
@Inject
|
||||||
|
ImageStoreDetailsDao _imageStoreDetailsDao;
|
||||||
|
|
||||||
// FIXME - why don't we have interface for DataCenterLinkLocalIpAddressDao?
|
// FIXME - why don't we have interface for DataCenterLinkLocalIpAddressDao?
|
||||||
@Inject
|
@Inject
|
||||||
@ -520,6 +528,13 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
|||||||
_accountDetailsDao.update(accountDetailVO.getId(), accountDetailVO);
|
_accountDetailsDao.update(accountDetailVO.getId(), accountDetailVO);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ImageStore:
|
||||||
|
final ImageStoreVO imgStore = _imageStoreDao.findById(resourceId);
|
||||||
|
Preconditions.checkState(imgStore != null);
|
||||||
|
_imageStoreDetailsDao.addDetail(resourceId, name, value, true);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new InvalidParameterValueException("Scope provided is invalid");
|
throw new InvalidParameterValueException("Scope provided is invalid");
|
||||||
}
|
}
|
||||||
@ -626,6 +641,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
|||||||
final Long clusterId = cmd.getClusterId();
|
final Long clusterId = cmd.getClusterId();
|
||||||
final Long storagepoolId = cmd.getStoragepoolId();
|
final Long storagepoolId = cmd.getStoragepoolId();
|
||||||
final Long accountId = cmd.getAccountId();
|
final Long accountId = cmd.getAccountId();
|
||||||
|
final Long imageStoreId = cmd.getImageStoreId();
|
||||||
CallContext.current().setEventDetails(" Name: " + name + " New Value: " + (name.toLowerCase().contains("password") ? "*****" : value == null ? "" : value));
|
CallContext.current().setEventDetails(" Name: " + name + " New Value: " + (name.toLowerCase().contains("password") ? "*****" : value == null ? "" : value));
|
||||||
// check if config value exists
|
// check if config value exists
|
||||||
final ConfigurationVO config = _configDao.findByName(name);
|
final ConfigurationVO config = _configDao.findByName(name);
|
||||||
@ -676,6 +692,11 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
|||||||
id = storagepoolId;
|
id = storagepoolId;
|
||||||
paramCountCheck++;
|
paramCountCheck++;
|
||||||
}
|
}
|
||||||
|
if (imageStoreId != null) {
|
||||||
|
scope = ConfigKey.Scope.ImageStore.toString();
|
||||||
|
id = imageStoreId;
|
||||||
|
paramCountCheck++;
|
||||||
|
}
|
||||||
|
|
||||||
if (paramCountCheck > 1) {
|
if (paramCountCheck > 1) {
|
||||||
throw new InvalidParameterValueException("cannot handle multiple IDs, provide only one ID corresponding to the scope");
|
throw new InvalidParameterValueException("cannot handle multiple IDs, provide only one ID corresponding to the scope");
|
||||||
|
|||||||
@ -1672,6 +1672,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
|||||||
final Long clusterId = cmd.getClusterId();
|
final Long clusterId = cmd.getClusterId();
|
||||||
final Long storagepoolId = cmd.getStoragepoolId();
|
final Long storagepoolId = cmd.getStoragepoolId();
|
||||||
final Long accountId = cmd.getAccountId();
|
final Long accountId = cmd.getAccountId();
|
||||||
|
final Long imageStoreId = cmd.getImageStoreId();
|
||||||
String scope = null;
|
String scope = null;
|
||||||
Long id = null;
|
Long id = null;
|
||||||
int paramCountCheck = 0;
|
int paramCountCheck = 0;
|
||||||
@ -1696,6 +1697,11 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
|||||||
id = storagepoolId;
|
id = storagepoolId;
|
||||||
paramCountCheck++;
|
paramCountCheck++;
|
||||||
}
|
}
|
||||||
|
if (imageStoreId != null) {
|
||||||
|
scope = ConfigKey.Scope.ImageStore.toString();
|
||||||
|
id = imageStoreId;
|
||||||
|
paramCountCheck++;
|
||||||
|
}
|
||||||
|
|
||||||
if (paramCountCheck > 1) {
|
if (paramCountCheck > 1) {
|
||||||
throw new InvalidParameterValueException("cannot handle multiple IDs, provide only one ID corresponding to the scope");
|
throw new InvalidParameterValueException("cannot handle multiple IDs, provide only one ID corresponding to the scope");
|
||||||
|
|||||||
@ -20,48 +20,64 @@ import java.util.Map;
|
|||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
||||||
|
import org.apache.cloudstack.framework.config.impl.ConfigurationVO;
|
||||||
import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
|
import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
|
||||||
import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao;
|
import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao;
|
||||||
import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
|
import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
|
||||||
|
|
||||||
|
import com.cloud.capacity.CapacityManager;
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
|
|
||||||
public class ImageStoreDetailsUtil {
|
public class ImageStoreDetailsUtil {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
protected ImageStoreDao imageStoreDao;
|
protected ImageStoreDao imageStoreDao;
|
||||||
@Inject
|
@Inject
|
||||||
protected ImageStoreDetailsDao imageStoreDetailsDao;
|
protected ImageStoreDetailsDao imageStoreDetailsDao;
|
||||||
|
@Inject
|
||||||
|
protected ConfigurationDao configurationDao;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Obtain NFS protocol version (if provided) for a store id.<br/>
|
* Retrieve global secondary storage NFS version default value
|
||||||
* It can be set by adding an entry in {@code image_store_details} table, providing {@code name=nfs.version} and {@code value=X} (e.g. 3)
|
* @return global default value
|
||||||
|
*/
|
||||||
|
protected Integer getGlobalDefaultNfsVersion(){
|
||||||
|
ConfigurationVO globalNfsVersion = configurationDao.findByName(CapacityManager.ImageStoreNFSVersion.key());
|
||||||
|
Preconditions.checkState(globalNfsVersion != null, "Unable to find global NFS version for version key " + CapacityManager.ImageStoreNFSVersion.key());
|
||||||
|
String value = globalNfsVersion.getValue();
|
||||||
|
return (value != null ? Integer.valueOf(value) : null);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Obtain NFS protocol version (if provided) for a store id, if not use default config value<br/>
|
||||||
* @param storeId image store id
|
* @param storeId image store id
|
||||||
* @return {@code null} if {@code nfs.version} is not found for storeId <br/>
|
* @return {@code null} if {@code secstorage.nfs.version} is not found for storeId <br/>
|
||||||
* {@code X} if {@code nfs.version} is found found for storeId
|
* {@code X} if {@code secstorage.nfs.version} is found found for storeId
|
||||||
*/
|
*/
|
||||||
public Integer getNfsVersion(long storeId) throws NumberFormatException {
|
public Integer getNfsVersion(long storeId) throws NumberFormatException {
|
||||||
String nfsVersion = null;
|
|
||||||
if (imageStoreDetailsDao.getDetails(storeId) != null){
|
final Map<String, String> storeDetails = imageStoreDetailsDao.getDetails(storeId);
|
||||||
Map<String, String> storeDetails = imageStoreDetailsDao.getDetails(storeId);
|
if (storeDetails != null && storeDetails.containsKey(CapacityManager.ImageStoreNFSVersion.key())) {
|
||||||
if (storeDetails != null && storeDetails.containsKey("nfs.version")){
|
final String version = storeDetails.get(CapacityManager.ImageStoreNFSVersion.key());
|
||||||
nfsVersion = storeDetails.get("nfs.version");
|
return (version != null ? Integer.valueOf(version) : null);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return (nfsVersion != null ? Integer.valueOf(nfsVersion) : null);
|
|
||||||
|
return getGlobalDefaultNfsVersion();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Obtain NFS protocol version (if provided) for a store uuid.<br/>
|
* Obtain NFS protocol version (if provided) for a store uuid.<br/>
|
||||||
* It can be set by adding an entry in {@code image_store_details} table, providing {@code name=nfs.version} and {@code value=X} (e.g. 3)
|
* @param resourceId image store id
|
||||||
* @param storeId image store id
|
* @return {@code null} if {@code secstorage.nfs.version} is not found for storeUuid <br/>
|
||||||
* @return {@code null} if {@code nfs.version} is not found for storeUuid <br/>
|
* {@code X} if {@code secstorage.nfs.version} is found found for storeUuid
|
||||||
* {@code X} if {@code nfs.version} is found found for storeUuid
|
|
||||||
*/
|
*/
|
||||||
public Integer getNfsVersionByUuid(String storeUuid){
|
public Integer getNfsVersionByUuid(String storeUuid){
|
||||||
ImageStoreVO imageStore = imageStoreDao.findByUuid(storeUuid);
|
ImageStoreVO imageStore = imageStoreDao.findByUuid(storeUuid);
|
||||||
if (imageStore != null){
|
if (imageStore != null){
|
||||||
return getNfsVersion(imageStore.getId());
|
return getNfsVersion(imageStore.getId());
|
||||||
}
|
}
|
||||||
return null;
|
return getGlobalDefaultNfsVersion();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,42 +17,54 @@
|
|||||||
package com.cloud.storage;
|
package com.cloud.storage;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertNull;
|
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
||||||
|
import org.apache.cloudstack.framework.config.impl.ConfigurationVO;
|
||||||
import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
|
import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
|
||||||
import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao;
|
import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao;
|
||||||
import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
|
import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.cloud.capacity.CapacityManager;
|
||||||
|
|
||||||
public class ImageStoreDetailsUtilTest {
|
public class ImageStoreDetailsUtilTest {
|
||||||
|
|
||||||
private final static long STORE_ID = 1l;
|
private final static long STORE_ID = 1l;
|
||||||
private final static String STORE_UUID = "aaaa-aaaa-aaaa-aaaa";
|
private final static String STORE_UUID = "aaaa-aaaa-aaaa-aaaa";
|
||||||
private final static Integer NFS_VERSION = 3;
|
private final static Integer NFS_VERSION = 3;
|
||||||
|
private final static Integer NFS_VERSION_DEFAULT = 2;
|
||||||
|
|
||||||
ImageStoreDetailsUtil imageStoreDetailsUtil = new ImageStoreDetailsUtil();
|
ImageStoreDetailsUtil imageStoreDetailsUtil = new ImageStoreDetailsUtil();
|
||||||
|
|
||||||
ImageStoreDao imgStoreDao = mock(ImageStoreDao.class);
|
ImageStoreDao imgStoreDao = mock(ImageStoreDao.class);
|
||||||
ImageStoreDetailsDao imgStoreDetailsDao = mock(ImageStoreDetailsDao.class);
|
ImageStoreDetailsDao imgStoreDetailsDao = mock(ImageStoreDetailsDao.class);
|
||||||
|
ConfigurationDao configurationDao = mock(ConfigurationDao.class);
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setup() throws Exception {
|
public void setup() throws Exception {
|
||||||
Map<String, String> imgStoreDetails = new HashMap<String, String>();
|
Map<String, String> imgStoreDetails = new HashMap<String, String>();
|
||||||
imgStoreDetails.put("nfs.version", String.valueOf(NFS_VERSION));
|
String nfsVersionKey = CapacityManager.ImageStoreNFSVersion.key();
|
||||||
|
imgStoreDetails.put(nfsVersionKey, String.valueOf(NFS_VERSION));
|
||||||
when(imgStoreDetailsDao.getDetails(STORE_ID)).thenReturn(imgStoreDetails);
|
when(imgStoreDetailsDao.getDetails(STORE_ID)).thenReturn(imgStoreDetails);
|
||||||
|
|
||||||
ImageStoreVO imgStoreVO = mock(ImageStoreVO.class);
|
ImageStoreVO imgStoreVO = mock(ImageStoreVO.class);
|
||||||
when(imgStoreVO.getId()).thenReturn(Long.valueOf(STORE_ID));
|
when(imgStoreVO.getId()).thenReturn(Long.valueOf(STORE_ID));
|
||||||
when(imgStoreDao.findByUuid(STORE_UUID)).thenReturn(imgStoreVO);
|
when(imgStoreDao.findByUuid(STORE_UUID)).thenReturn(imgStoreVO);
|
||||||
|
|
||||||
|
ConfigurationVO confVO = mock(ConfigurationVO.class);
|
||||||
|
String defaultValue = (NFS_VERSION_DEFAULT == null ? null : String.valueOf(NFS_VERSION_DEFAULT));
|
||||||
|
when(confVO.getValue()).thenReturn(defaultValue);
|
||||||
|
when(configurationDao.findByName(nfsVersionKey)).thenReturn(confVO);
|
||||||
|
|
||||||
imageStoreDetailsUtil.imageStoreDao = imgStoreDao;
|
imageStoreDetailsUtil.imageStoreDao = imgStoreDao;
|
||||||
imageStoreDetailsUtil.imageStoreDetailsDao = imgStoreDetailsDao;
|
imageStoreDetailsUtil.imageStoreDetailsDao = imgStoreDetailsDao;
|
||||||
|
imageStoreDetailsUtil.configurationDao = configurationDao;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -68,7 +80,7 @@ public class ImageStoreDetailsUtilTest {
|
|||||||
when(imgStoreDetailsDao.getDetails(STORE_ID)).thenReturn(imgStoreDetails);
|
when(imgStoreDetailsDao.getDetails(STORE_ID)).thenReturn(imgStoreDetails);
|
||||||
|
|
||||||
Integer nfsVersion = imageStoreDetailsUtil.getNfsVersion(STORE_ID);
|
Integer nfsVersion = imageStoreDetailsUtil.getNfsVersion(STORE_ID);
|
||||||
assertNull(nfsVersion);
|
assertEquals(NFS_VERSION_DEFAULT, nfsVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -77,7 +89,7 @@ public class ImageStoreDetailsUtilTest {
|
|||||||
when(imgStoreDetailsDao.getDetails(STORE_ID)).thenReturn(imgStoreDetails);
|
when(imgStoreDetailsDao.getDetails(STORE_ID)).thenReturn(imgStoreDetails);
|
||||||
|
|
||||||
Integer nfsVersion = imageStoreDetailsUtil.getNfsVersion(STORE_ID);
|
Integer nfsVersion = imageStoreDetailsUtil.getNfsVersion(STORE_ID);
|
||||||
assertNull(nfsVersion);
|
assertEquals(NFS_VERSION_DEFAULT, nfsVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -90,6 +102,12 @@ public class ImageStoreDetailsUtilTest {
|
|||||||
public void testGetNfsVersionByUuidNoImgStore(){
|
public void testGetNfsVersionByUuidNoImgStore(){
|
||||||
when(imgStoreDao.findByUuid(STORE_UUID)).thenReturn(null);
|
when(imgStoreDao.findByUuid(STORE_UUID)).thenReturn(null);
|
||||||
Integer nfsVersion = imageStoreDetailsUtil.getNfsVersionByUuid(STORE_UUID);
|
Integer nfsVersion = imageStoreDetailsUtil.getNfsVersionByUuid(STORE_UUID);
|
||||||
assertNull(nfsVersion);
|
assertEquals(NFS_VERSION_DEFAULT, nfsVersion);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@Test
|
||||||
|
public void testGetGlobalDefaultNfsVersion(){
|
||||||
|
Integer globalDefaultNfsVersion = imageStoreDetailsUtil.getGlobalDefaultNfsVersion();
|
||||||
|
assertEquals(NFS_VERSION_DEFAULT, globalDefaultNfsVersion);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -41,6 +41,8 @@ import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
|||||||
import org.apache.cloudstack.region.PortableIpDaoImpl;
|
import org.apache.cloudstack.region.PortableIpDaoImpl;
|
||||||
import org.apache.cloudstack.region.PortableIpRangeDaoImpl;
|
import org.apache.cloudstack.region.PortableIpRangeDaoImpl;
|
||||||
import org.apache.cloudstack.region.dao.RegionDaoImpl;
|
import org.apache.cloudstack.region.dao.RegionDaoImpl;
|
||||||
|
import org.apache.cloudstack.storage.datastore.db.ImageStoreDaoImpl;
|
||||||
|
import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDaoImpl;
|
||||||
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDaoImpl;
|
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDaoImpl;
|
||||||
import org.apache.cloudstack.test.utils.SpringUtils;
|
import org.apache.cloudstack.test.utils.SpringUtils;
|
||||||
|
|
||||||
@ -131,7 +133,7 @@ import com.cloud.vm.dao.VMInstanceDaoImpl;
|
|||||||
NetworkDomainDaoImpl.class, HostDetailsDaoImpl.class, HostTagsDaoImpl.class, ClusterDaoImpl.class, FirewallRulesDaoImpl.class,
|
NetworkDomainDaoImpl.class, HostDetailsDaoImpl.class, HostTagsDaoImpl.class, ClusterDaoImpl.class, FirewallRulesDaoImpl.class,
|
||||||
FirewallRulesCidrsDaoImpl.class, PhysicalNetworkDaoImpl.class, PhysicalNetworkTrafficTypeDaoImpl.class, PhysicalNetworkServiceProviderDaoImpl.class,
|
FirewallRulesCidrsDaoImpl.class, PhysicalNetworkDaoImpl.class, PhysicalNetworkTrafficTypeDaoImpl.class, PhysicalNetworkServiceProviderDaoImpl.class,
|
||||||
LoadBalancerDaoImpl.class, NetworkServiceMapDaoImpl.class, PrimaryDataStoreDaoImpl.class, StoragePoolDetailsDaoImpl.class,
|
LoadBalancerDaoImpl.class, NetworkServiceMapDaoImpl.class, PrimaryDataStoreDaoImpl.class, StoragePoolDetailsDaoImpl.class,
|
||||||
PortableIpRangeDaoImpl.class, RegionDaoImpl.class, PortableIpDaoImpl.class, AccountGuestVlanMapDaoImpl.class},
|
PortableIpRangeDaoImpl.class, RegionDaoImpl.class, PortableIpDaoImpl.class, AccountGuestVlanMapDaoImpl.class, ImageStoreDaoImpl.class, ImageStoreDetailsDaoImpl.class},
|
||||||
includeFilters = {@Filter(value = ChildTestConfiguration.Library.class, type = FilterType.CUSTOM)},
|
includeFilters = {@Filter(value = ChildTestConfiguration.Library.class, type = FilterType.CUSTOM)},
|
||||||
useDefaultFilters = false)
|
useDefaultFilters = false)
|
||||||
public class
|
public class
|
||||||
|
|||||||
@ -545,3 +545,6 @@ INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervis
|
|||||||
INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(), 'VMware', '5.0', 'centos64Guest', 228, now(), 0);
|
INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(), 'VMware', '5.0', 'centos64Guest', 228, now(), 0);
|
||||||
INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(), 'VMware', '5.1', 'centos64Guest', 228, now(), 0);
|
INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(), 'VMware', '5.1', 'centos64Guest', 228, now(), 0);
|
||||||
INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(), 'VMware', '5.5', 'centos64Guest', 228, now(), 0);
|
INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) VALUES (UUID(), 'VMware', '5.5', 'centos64Guest', 228, now(), 0);
|
||||||
|
|
||||||
|
ALTER TABLE `cloud`.`image_store_details` CHANGE COLUMN `value` `value` VARCHAR(255) NULL DEFAULT NULL COMMENT 'value of the detail', ADD COLUMN `display` tinyint(1) NOT
|
||||||
|
NULL DEFAULT '1' COMMENT 'True if the detail can be displayed to the end user' AFTER `value`;
|
||||||
|
|||||||
@ -20,12 +20,13 @@
|
|||||||
from marvin.cloudstackTestCase import cloudstackTestCase
|
from marvin.cloudstackTestCase import cloudstackTestCase
|
||||||
from marvin.cloudstackAPI import (stopSystemVm,
|
from marvin.cloudstackAPI import (stopSystemVm,
|
||||||
rebootSystemVm,
|
rebootSystemVm,
|
||||||
destroySystemVm)
|
destroySystemVm, updateConfiguration)
|
||||||
from marvin.lib.utils import (cleanup_resources,
|
from marvin.lib.utils import (cleanup_resources,
|
||||||
get_process_status,
|
get_process_status,
|
||||||
get_host_credentials)
|
get_host_credentials,
|
||||||
|
wait_until)
|
||||||
from marvin.lib.base import (PhysicalNetwork,
|
from marvin.lib.base import (PhysicalNetwork,
|
||||||
NetScaler)
|
NetScaler, ImageStore)
|
||||||
from marvin.lib.common import (get_zone,
|
from marvin.lib.common import (get_zone,
|
||||||
list_hosts,
|
list_hosts,
|
||||||
list_ssvms,
|
list_ssvms,
|
||||||
@ -33,6 +34,7 @@ from marvin.lib.common import (get_zone,
|
|||||||
list_vlan_ipranges)
|
list_vlan_ipranges)
|
||||||
from nose.plugins.attrib import attr
|
from nose.plugins.attrib import attr
|
||||||
import telnetlib
|
import telnetlib
|
||||||
|
import logging
|
||||||
|
|
||||||
# Import System modules
|
# Import System modules
|
||||||
import time
|
import time
|
||||||
@ -42,12 +44,19 @@ _multiprocess_shared_ = True
|
|||||||
class TestSSVMs(cloudstackTestCase):
|
class TestSSVMs(cloudstackTestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
test_case = super(TestSSVMs, self)
|
||||||
self.apiclient = self.testClient.getApiClient()
|
self.apiclient = self.testClient.getApiClient()
|
||||||
self.hypervisor = self.testClient.getHypervisorInfo()
|
self.hypervisor = self.testClient.getHypervisorInfo()
|
||||||
self.cleanup = []
|
self.cleanup = []
|
||||||
|
self.config = test_case.getClsConfig()
|
||||||
self.services = self.testClient.getParsedTestDataConfig()
|
self.services = self.testClient.getParsedTestDataConfig()
|
||||||
self.zone = get_zone(self.apiclient, self.testClient.getZoneForTests())
|
self.zone = get_zone(self.apiclient, self.testClient.getZoneForTests())
|
||||||
|
|
||||||
|
self.logger = logging.getLogger('TestSSVMs')
|
||||||
|
self.stream_handler = logging.StreamHandler()
|
||||||
|
self.logger.setLevel(logging.DEBUG)
|
||||||
|
self.logger.addHandler(self.stream_handler)
|
||||||
|
|
||||||
# Default sleep is set to 90 seconds, which is too long if the SSVM takes up to 2min to start.
|
# Default sleep is set to 90 seconds, which is too long if the SSVM takes up to 2min to start.
|
||||||
# Second sleep in the loop will waste test time.
|
# Second sleep in the loop will waste test time.
|
||||||
self.services["sleep"] = 30
|
self.services["sleep"] = 30
|
||||||
@ -1197,3 +1206,162 @@ class TestSSVMs(cloudstackTestCase):
|
|||||||
# Call to verify cloud process is running
|
# Call to verify cloud process is running
|
||||||
self.test_04_cpvm_internals()
|
self.test_04_cpvm_internals()
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@attr(
|
||||||
|
tags=[
|
||||||
|
"advanced",
|
||||||
|
"advancedns",
|
||||||
|
"smoke",
|
||||||
|
"basic",
|
||||||
|
"sg"],
|
||||||
|
required_hardware="true")
|
||||||
|
def test_11_ss_nfs_version_on_ssvm(self):
|
||||||
|
"""Test NFS Version on Secondary Storage mounted properly on SSVM
|
||||||
|
"""
|
||||||
|
|
||||||
|
# 1) List SSVM in zone
|
||||||
|
# 2) Get id and url from mounted nfs store
|
||||||
|
# 3) Update NFS version for previous image store
|
||||||
|
# 4) Stop SSVM
|
||||||
|
# 5) Check NFS version of mounted nfs store after SSVM starts
|
||||||
|
|
||||||
|
nfs_version = self.config.nfsVersion
|
||||||
|
if nfs_version == None:
|
||||||
|
self.skipTest('No NFS version provided in test data')
|
||||||
|
|
||||||
|
#List SSVM for zone id
|
||||||
|
list_ssvm_response = list_ssvms(
|
||||||
|
self.apiclient,
|
||||||
|
systemvmtype='secondarystoragevm',
|
||||||
|
state='Running',
|
||||||
|
zoneid=self.zone.id
|
||||||
|
)
|
||||||
|
self.assertNotEqual(
|
||||||
|
list_ssvm_response,
|
||||||
|
None
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
isinstance(list_ssvm_response, list),
|
||||||
|
True,
|
||||||
|
"Check list response returns a valid list"
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
len(list_ssvm_response),
|
||||||
|
1,
|
||||||
|
"Check list System VMs response"
|
||||||
|
)
|
||||||
|
|
||||||
|
ssvm = list_ssvm_response[0]
|
||||||
|
image_stores_response = ImageStore.list(self.apiclient,zoneid=self.zone.id)
|
||||||
|
|
||||||
|
if self.hypervisor.lower() in ('vmware', 'hyperv'):
|
||||||
|
# SSH into SSVMs is done via management server for Vmware and Hyper-V
|
||||||
|
result = get_process_status(
|
||||||
|
self.apiclient.connection.mgtSvr,
|
||||||
|
22,
|
||||||
|
self.apiclient.connection.user,
|
||||||
|
self.apiclient.connection.passwd,
|
||||||
|
ssvm.privateip,
|
||||||
|
"mount | grep 'type nfs'",
|
||||||
|
hypervisor=self.hypervisor)
|
||||||
|
|
||||||
|
for res in result:
|
||||||
|
split_res = res.split("on")
|
||||||
|
mounted_img_store_url = split_res[0].strip()
|
||||||
|
for img_store in image_stores_response:
|
||||||
|
img_store_url = str(img_store.url)
|
||||||
|
if img_store_url.startswith("nfs://"):
|
||||||
|
img_store_url = img_store_url[6:]
|
||||||
|
#Add colon after ip address to match output from mount command
|
||||||
|
first_slash = img_store_url.find('/')
|
||||||
|
img_store_url = img_store_url[0:first_slash] + ':' + img_store_url[first_slash:]
|
||||||
|
if img_store_url == mounted_img_store_url:
|
||||||
|
img_store_id = img_store.id
|
||||||
|
break
|
||||||
|
|
||||||
|
self.assertNotEqual(
|
||||||
|
img_store_id,
|
||||||
|
None,
|
||||||
|
"Check image store id mounted on SSVM"
|
||||||
|
)
|
||||||
|
|
||||||
|
#Update NFS version for image store mounted on SSVM
|
||||||
|
updateConfigurationCmd = updateConfiguration.updateConfigurationCmd()
|
||||||
|
updateConfigurationCmd.name = "secstorage.nfs.version"
|
||||||
|
updateConfigurationCmd.value = nfs_version
|
||||||
|
updateConfigurationCmd.imagestoreuuid = img_store_id
|
||||||
|
|
||||||
|
updateConfigurationResponse = self.apiclient.updateConfiguration(updateConfigurationCmd)
|
||||||
|
self.logger.debug("updated the parameter %s with value %s"%(updateConfigurationResponse.name, updateConfigurationResponse.value))
|
||||||
|
|
||||||
|
#Stop SSVM
|
||||||
|
self.debug("Stopping SSVM: %s" % ssvm.id)
|
||||||
|
cmd = stopSystemVm.stopSystemVmCmd()
|
||||||
|
cmd.id = ssvm.id
|
||||||
|
self.apiclient.stopSystemVm(cmd)
|
||||||
|
|
||||||
|
def checkForRunningSSVM():
|
||||||
|
new_list_ssvm_response = list_ssvms(
|
||||||
|
self.apiclient,
|
||||||
|
id=ssvm.id
|
||||||
|
)
|
||||||
|
if isinstance(new_list_ssvm_response, list):
|
||||||
|
return new_list_ssvm_response[0].state == 'Running', None
|
||||||
|
|
||||||
|
res, _ = wait_until(self.services["sleep"], self.services["timeout"], checkForRunningSSVM)
|
||||||
|
if not res:
|
||||||
|
self.fail("List SSVM call failed!")
|
||||||
|
|
||||||
|
new_list_ssvm_response = list_ssvms(
|
||||||
|
self.apiclient,
|
||||||
|
id=ssvm.id
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertNotEqual(
|
||||||
|
new_list_ssvm_response,
|
||||||
|
None
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
isinstance(new_list_ssvm_response, list),
|
||||||
|
True,
|
||||||
|
"Check list response returns a valid list"
|
||||||
|
)
|
||||||
|
ssvm = new_list_ssvm_response[0]
|
||||||
|
self.debug("SSVM state after debug: %s" % ssvm.state)
|
||||||
|
self.assertEqual(
|
||||||
|
ssvm.state,
|
||||||
|
'Running',
|
||||||
|
"Check whether SSVM is running or not"
|
||||||
|
)
|
||||||
|
# Wait for the agent to be up
|
||||||
|
self.waitForSystemVMAgent(ssvm.name)
|
||||||
|
|
||||||
|
#Check NFS version on mounted image store
|
||||||
|
result = get_process_status(
|
||||||
|
self.apiclient.connection.mgtSvr,
|
||||||
|
22,
|
||||||
|
self.apiclient.connection.user,
|
||||||
|
self.apiclient.connection.passwd,
|
||||||
|
ssvm.privateip,
|
||||||
|
"mount | grep '%s'"%mounted_img_store_url,
|
||||||
|
hypervisor=self.hypervisor)
|
||||||
|
|
||||||
|
self.assertNotEqual(
|
||||||
|
result,
|
||||||
|
None
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
len(result),
|
||||||
|
1,
|
||||||
|
"Check result length"
|
||||||
|
)
|
||||||
|
|
||||||
|
res = result[0]
|
||||||
|
mounted_nfs_version = res.split("vers=")[1][0:1]
|
||||||
|
self.assertEqual(
|
||||||
|
int(mounted_nfs_version),
|
||||||
|
int(nfs_version),
|
||||||
|
"Check mounted NFS version to be the same as provided"
|
||||||
|
)
|
||||||
|
|
||||||
|
return
|
||||||
|
|||||||
@ -19974,28 +19974,58 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Granular settings for storage pool for secondary storage is not required
|
|
||||||
/* settings: {
|
|
||||||
title: 'label.menu.global.settings',
|
|
||||||
custom: cloudStack.uiCustom.granularSettings({
|
|
||||||
dataProvider: function(args) {
|
|
||||||
args.response.success({
|
|
||||||
data: [
|
|
||||||
{ name: 'config.param.1', value: 1 },
|
|
||||||
{ name: 'config.param.2', value: 2 }
|
|
||||||
]
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
actions: {
|
|
||||||
edit: function(args) {
|
// Granular settings for image store
|
||||||
// call updateStorageLevelParameters
|
settings: {
|
||||||
args.response.success();
|
title: 'label.settings',
|
||||||
}
|
custom: cloudStack.uiCustom.granularSettings({
|
||||||
}
|
dataProvider: function (args) {
|
||||||
})
|
|
||||||
} */
|
$.ajax({
|
||||||
|
url: createURL('listConfigurations&imagestoreuuid=' + args.context.secondaryStorage[0].id),
|
||||||
|
data: listViewDataProvider(args, {
|
||||||
|
},
|
||||||
|
{
|
||||||
|
searchBy: 'name'
|
||||||
|
}),
|
||||||
|
success: function (json) {
|
||||||
|
args.response.success({
|
||||||
|
data: json.listconfigurationsresponse.configuration
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
error: function (json) {
|
||||||
|
args.response.error(parseXMLHttpResponse(json));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
edit: function (args) {
|
||||||
|
// call updateStorageLevelParameters
|
||||||
|
var data = {
|
||||||
|
name: args.data.jsonObj.name,
|
||||||
|
value: args.data.value
|
||||||
|
};
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: createURL('updateConfiguration&imagestoreuuid=' + args.context.secondaryStorage[0].id),
|
||||||
|
data: data,
|
||||||
|
success: function (json) {
|
||||||
|
var item = json.updateconfigurationresponse.configuration;
|
||||||
|
args.response.success({
|
||||||
|
data: item
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
error: function (json) {
|
||||||
|
args.response.error(parseXMLHttpResponse(json));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user