Add check in addImageStoreCmd to guarantee our assumption of homogeneous

image stores.
This commit is contained in:
Min Chen 2013-04-09 16:36:02 -07:00
parent b2d5535bba
commit 3897590bb1
17 changed files with 147 additions and 45 deletions

View File

@ -48,17 +48,15 @@ public class AddImageStoreCmd extends BaseCmd {
description="the Zone ID for the image store")
private Long zoneId;
@Parameter(name=ApiConstants.PROVIDER, type=CommandType.STRING,
required=true, description="the image store provider name")
private String providerName;
@Parameter(name=ApiConstants.DETAILS, type=CommandType.MAP, description="the details for the image store")
private Map<String, String> details;
@Parameter(name=ApiConstants.SCOPE, type=CommandType.STRING,
required=false, description="the scope of the image store: zone or region")
private String scope;
@Parameter(name=ApiConstants.PROVIDER, type=CommandType.STRING,
required=false, description="the image store provider name")
private String providerName;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
@ -76,10 +74,6 @@ public class AddImageStoreCmd extends BaseCmd {
return details;
}
public String getScope() {
return this.scope;
}
public String getProviderName() {
return this.providerName;
}

View File

@ -26,6 +26,7 @@ public interface DataStoreManager {
public DataStore getDataStore(long storeId, DataStoreRole role);
public DataStore getPrimaryDataStore(long storeId);
public DataStore getDataStore(String uuid, DataStoreRole role);
public List<DataStore> getImageStores(Scope scope);
public List<DataStore> getImageStoresByScope(Scope scope);
public List<DataStore> getImageStoresByProvider(String provider);
public DataStore registerDataStore(Map<String, String> params, String providerUuid);
}

View File

@ -22,6 +22,8 @@ import java.util.Map;
import java.util.Set;
public interface DataStoreProvider {
public static enum DataStoreProviderType {
PRIMARY,
@ -33,5 +35,6 @@ public interface DataStoreProvider {
public String getName();
public boolean configure(Map<String, Object> params);
public Set<DataStoreProviderType> getTypes();
}

View File

@ -18,7 +18,10 @@
*/
package org.apache.cloudstack.engine.subsystem.api.storage;
import com.cloud.storage.ScopeType;
public interface ImageStoreProvider extends DataStoreProvider {
public boolean isScopeSupported(ScopeType scope);
}

View File

@ -18,9 +18,15 @@
*/
package org.apache.cloudstack.storage.datastore.db;
import java.util.List;
import com.cloud.storage.ScopeType;
import com.cloud.utils.db.GenericDao;
public interface ImageStoreDao extends GenericDao<ImageStoreVO, Long> {
public ImageStoreVO findByName(String name);
public List<ImageStoreVO> findByProvider(String provider);
public List<ImageStoreVO> findByScope(ScopeType scope);
}

View File

@ -29,6 +29,7 @@ import javax.inject.Inject;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProviderManager;
import org.apache.cloudstack.engine.subsystem.api.storage.ImageStoreProvider;
import org.apache.cloudstack.engine.subsystem.api.storage.Scope;
import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
import org.apache.cloudstack.storage.image.ImageStoreDriver;
@ -53,13 +54,13 @@ public class ImageStoreProviderManagerImpl implements ImageStoreProviderManager
public void config() {
driverMaps = new HashMap<String, ImageStoreDriver>();
}
@Override
public ImageStoreEntity getImageStore(long dataStoreId) {
ImageStoreVO dataStore = dataStoreDao.findById(dataStoreId);
String providerName = dataStore.getProviderName();
ImageStoreProvider provider = (ImageStoreProvider)providerManager.getDataStoreProvider(providerName);
ImageStoreEntity imgStore = ImageStoreImpl.getDataStore(dataStore,
ImageStoreEntity imgStore = ImageStoreImpl.getDataStore(dataStore,
driverMaps.get(provider.getName()), provider
);
// TODO Auto-generated method stub
@ -82,7 +83,7 @@ public class ImageStoreProviderManagerImpl implements ImageStoreProviderManager
}
@Override
public List<DataStore> getList() {
public List<DataStore> listImageStores() {
List<ImageStoreVO> stores = dataStoreDao.listAll();
List<DataStore> imageStores = new ArrayList<DataStore>();
for (ImageStoreVO store : stores) {
@ -91,4 +92,26 @@ public class ImageStoreProviderManagerImpl implements ImageStoreProviderManager
return imageStores;
}
@Override
public List<DataStore> listImageStoresByScope(Scope scope) {
List<ImageStoreVO> stores = dataStoreDao.findByScope(scope.getScopeType());
List<DataStore> imageStores = new ArrayList<DataStore>();
for (ImageStoreVO store : stores) {
imageStores.add(getImageStore(store.getId()));
}
return imageStores;
}
@Override
public List<DataStore> listImageStoreByProvider(String provider) {
List<ImageStoreVO> stores = dataStoreDao.findByProvider(provider);
List<DataStore> imageStores = new ArrayList<DataStore>();
for (ImageStoreVO store : stores) {
imageStores.add(getImageStore(store.getId()));
}
return imageStores;
}
}

View File

@ -406,7 +406,7 @@ public class AncientSnapshotStrategy implements SnapshotStrategy {
snapObj.processEvent(Snapshot.Event.BackupToSecondary);
ZoneScope scope = new ZoneScope(snapshot.getDataCenterId());
List<DataStore> stores = this.dataStoreMgr.getImageStores(scope);
List<DataStore> stores = this.dataStoreMgr.getImageStoresByScope(scope);
if (stores.size() != 1) {
throw new CloudRuntimeException("find out more than one image stores");
}

View File

@ -62,10 +62,18 @@ public class DataStoreManagerImpl implements DataStoreManager {
}
throw new CloudRuntimeException("un recognized type" + role);
}
@Override
public List<DataStore> getImageStores(Scope scope) {
return imageDataStoreMgr.getList();
public List<DataStore> getImageStoresByScope(Scope scope) {
return imageDataStoreMgr.listImageStoresByScope(scope);
}
@Override
public List<DataStore> getImageStoresByProvider(String provider) {
return imageDataStoreMgr.listImageStoreByProvider(provider);
}
@Override
public DataStore getPrimaryDataStore(long storeId) {
return primaryStorMgr.getPrimaryDataStore(storeId);

View File

@ -65,7 +65,7 @@ public class DataStoreProviderManagerImpl extends ManagerBase implements DataSto
return null;
}
public List<StorageProviderResponse> getPrimayrDataStoreProviders() {
public List<StorageProviderResponse> getPrimaryDataStoreProviders() {
List<StorageProviderResponse> providers = new ArrayList<StorageProviderResponse>();
for (DataStoreProvider provider : providerMap.values()) {
if (provider instanceof PrimaryDataStoreProvider) {
@ -139,7 +139,7 @@ public class DataStoreProviderManagerImpl extends ManagerBase implements DataSto
@Override
public DataStoreProvider getDefaultImageDataStoreProvider() {
return this.getDataStoreProvider("cloudstack image store provider");
return this.getDataStoreProvider("CloudStack ImageStore Provider");
}
@Override
@ -148,7 +148,7 @@ public class DataStoreProviderManagerImpl extends ManagerBase implements DataSto
throw new InvalidParameterValueException("Invalid parameter, need to specify type: either primary or image");
}
if (type.equalsIgnoreCase(DataStoreProvider.DataStoreProviderType.PRIMARY.toString())) {
return this.getPrimayrDataStoreProviders();
return this.getPrimaryDataStoreProviders();
} else if (type.equalsIgnoreCase(DataStoreProvider.DataStoreProviderType.IMAGE.toString())) {
return this.getImageDataStoreProviders();
} else {

View File

@ -21,11 +21,14 @@ package org.apache.cloudstack.storage.image.datastore;
import java.util.List;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
import org.apache.cloudstack.engine.subsystem.api.storage.Scope;
import org.apache.cloudstack.storage.image.ImageStoreDriver;
public interface ImageStoreProviderManager {
ImageStoreEntity getImageStore(long dataStoreId);
ImageStoreEntity getImageStore(String uuid);
List<DataStore> getList();
List<DataStore> listImageStores();
List<DataStore> listImageStoresByScope(Scope scope);
List<DataStore> listImageStoreByProvider(String provider);
boolean registerDriver(String uuid, ImageStoreDriver driver);
}

View File

@ -18,31 +18,29 @@
*/
package org.apache.cloudstack.storage.image.db;
import java.util.List;
import java.util.Map;
import javax.naming.ConfigurationException;
import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import com.cloud.storage.ImageStore;
import com.cloud.user.AccountVO;
import com.cloud.utils.db.DB;
import com.cloud.storage.ScopeType;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.SearchCriteria2;
import com.cloud.utils.db.SearchCriteriaService;
import com.cloud.utils.db.SearchCriteria.Op;
@Component
public class ImageStoreDaoImpl extends GenericDaoBase<ImageStoreVO, Long> implements ImageStoreDao {
private static final Logger s_logger = Logger.getLogger(ImageStoreDaoImpl.class);
private SearchBuilder<ImageStoreVO> nameSearch;
private SearchBuilder<ImageStoreVO> providerSearch;
private SearchBuilder<ImageStoreVO> scopeSearch;
@Override
@ -53,6 +51,14 @@ public class ImageStoreDaoImpl extends GenericDaoBase<ImageStoreVO, Long> implem
nameSearch.and("name", nameSearch.entity().getName(), SearchCriteria.Op.EQ);
nameSearch.done();
providerSearch = createSearchBuilder();
providerSearch.and("providerName", providerSearch.entity().getProviderName(), SearchCriteria.Op.EQ);
providerSearch.done();
scopeSearch = createSearchBuilder();
scopeSearch.and("scope", scopeSearch.entity().getScope(), SearchCriteria.Op.EQ);
scopeSearch.done();
return true;
}
@ -63,5 +69,19 @@ public class ImageStoreDaoImpl extends GenericDaoBase<ImageStoreVO, Long> implem
return findOneBy(sc);
}
@Override
public List<ImageStoreVO> findByProvider(String provider) {
SearchCriteria<ImageStoreVO> sc = providerSearch.create();
sc.setParameters("providerName", provider);
return listBy(sc);
}
@Override
public List<ImageStoreVO> findByScope(ScopeType scope) {
SearchCriteria<ImageStoreVO> sc = scopeSearch.create();
sc.setParameters("scope", scope);
return listBy(sc);
}
}

View File

@ -35,12 +35,13 @@ import org.apache.cloudstack.storage.image.datastore.ImageStoreProviderManager;
import org.apache.cloudstack.storage.image.store.lifecycle.ImageStoreLifeCycle;
import org.springframework.stereotype.Component;
import com.cloud.storage.ScopeType;
import com.cloud.utils.component.ComponentContext;
@Component
public class CloudStackImageStoreProviderImpl implements ImageStoreProvider {
private final String providerName = "cloudstack image store provider";
private final String providerName = "CloudStack ImageStore Provider";
protected ImageStoreLifeCycle lifeCycle;
protected ImageStoreDriver driver;
@Inject
@ -85,4 +86,12 @@ public class CloudStackImageStoreProviderImpl implements ImageStoreProvider {
return types;
}
@Override
public boolean isScopeSupported(ScopeType scope) {
if ( scope == ScopeType.ZONE)
return true;
return false;
}
}

View File

@ -44,7 +44,7 @@ import com.cloud.utils.component.ComponentContext;
@Component
public class S3ImageStoreProviderImpl implements ImageStoreProvider {
private final String providerName = "S3 image store provider";
private final String providerName = "S3";
protected ImageStoreLifeCycle lifeCycle;
protected ImageStoreDriver driver;
@Inject
@ -87,4 +87,12 @@ public class S3ImageStoreProviderImpl implements ImageStoreProvider {
return types;
}
@Override
public boolean isScopeSupported(ScopeType scope) {
if ( scope == ScopeType.REGION )
return true;
return false;
}
}

View File

@ -34,6 +34,7 @@ import org.apache.cloudstack.storage.image.ImageStoreDriver;
import org.apache.cloudstack.storage.image.datastore.ImageStoreProviderManager;
import org.apache.cloudstack.storage.image.store.lifecycle.ImageStoreLifeCycle;
import com.cloud.storage.ScopeType;
import com.cloud.utils.component.ComponentContext;
public class SampleImageStoreProviderImpl implements ImageStoreProvider {
@ -79,4 +80,13 @@ public class SampleImageStoreProviderImpl implements ImageStoreProvider {
public HypervisorHostListener getHostListener() {
return null;
}
@Override
public boolean isScopeSupported(ScopeType scope) {
if ( scope == ScopeType.ZONE)
return true;
return false;
}
}

View File

@ -44,7 +44,7 @@ import com.cloud.utils.component.ComponentContext;
@Component
public class SwiftImageStoreProviderImpl implements ImageStoreProvider {
private final String providerName = "Swift image store provider";
private final String providerName = "Swift";
protected ImageStoreLifeCycle lifeCycle;
protected ImageStoreDriver driver;
@Inject
@ -89,4 +89,12 @@ public class SwiftImageStoreProviderImpl implements ImageStoreProvider {
return types;
}
@Override
public boolean isScopeSupported(ScopeType scope) {
if ( scope == ScopeType.REGION )
return true;
return false;
}
}

View File

@ -56,6 +56,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreRole;
import org.apache.cloudstack.engine.subsystem.api.storage.HostScope;
import org.apache.cloudstack.engine.subsystem.api.storage.HypervisorHostListener;
import org.apache.cloudstack.engine.subsystem.api.storage.ImageDataFactory;
import org.apache.cloudstack.engine.subsystem.api.storage.ImageStoreProvider;
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo;
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory;
import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator;
@ -1922,18 +1923,23 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
Long dcId = cmd.getZoneId();
String url = cmd.getUrl();
Map details = cmd.getDetails();
ScopeType scopeType = null;
String scope = cmd.getScope();
if (scope != null) {
try {
scopeType = Enum.valueOf(ScopeType.class, scope.toUpperCase());
} catch (Exception e) {
throw new InvalidParameterValueException("invalid scope" + scope);
}
ScopeType scopeType = ScopeType.ZONE;
if ( dcId == null ){
scopeType = ScopeType.REGION;
}
if (scopeType == ScopeType.ZONE && dcId == null) {
throw new InvalidParameterValueException("zone id can't be null, if scope is zone");
// check if scope is supported by store provider
if ( !((ImageStoreProvider)storeProvider).isScopeSupported(scopeType)){
throw new InvalidParameterValueException("Image store provider " + providerName + " does not support scope " + scopeType);
}
// check if we have already image stores from other different providers, we currently are not supporting image stores from different
// providers co-existing
List<ImageStoreVO> imageStores = _imageStoreDao.listAll();
for ( ImageStoreVO store : imageStores){
if (!store.getProviderName().equalsIgnoreCase(providerName)){
throw new InvalidParameterValueException("You can only add new image stores from the same provider " + store.getProviderName() + " already added");
}
}
if (dcId != null) {

View File

@ -325,7 +325,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
if (storeUuid != null) {
imageStore = this.dataStoreMgr.getDataStore(storeUuid, DataStoreRole.Image);
} else {
List<DataStore> stores = this.dataStoreMgr.getImageStores(new ZoneScope(zoneId));
List<DataStore> stores = this.dataStoreMgr.getImageStoresByScope(new ZoneScope(zoneId));
if (stores.size() > 1) {
throw new CloudRuntimeException("multiple image stores, don't know which one to use");
}
@ -1718,7 +1718,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
TemplateInfo tmplInfo = this.tmplFactory.getTemplate(templateId);
snapshot = _snapshotDao.findById(snapshotId);
ZoneScope scope = new ZoneScope(snapshot.getDataCenterId());
List<DataStore> store = this.dataStoreMgr.getImageStores(scope);
List<DataStore> store = this.dataStoreMgr.getImageStoresByScope(scope);
if (store.size() > 1) {
throw new CloudRuntimeException("muliple image data store, don't know which one to use");
}