diff --git a/api/src/org/apache/cloudstack/api/command/admin/storage/AddImageStoreCmd.java b/api/src/org/apache/cloudstack/api/command/admin/storage/AddImageStoreCmd.java index c5a8c4a66b8..7221f4ee90f 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/storage/AddImageStoreCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/storage/AddImageStoreCmd.java @@ -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 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; } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreManager.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreManager.java index 15e49e133fb..f940e8e9803 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreManager.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreManager.java @@ -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 getImageStores(Scope scope); + public List getImageStoresByScope(Scope scope); + public List getImageStoresByProvider(String provider); public DataStore registerDataStore(Map params, String providerUuid); } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreProvider.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreProvider.java index 115a52f92ac..083c7d39b67 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreProvider.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreProvider.java @@ -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 params); public Set getTypes(); - + + } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ImageStoreProvider.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ImageStoreProvider.java index 9a1f69f3a5b..9b4b937b18a 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ImageStoreProvider.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ImageStoreProvider.java @@ -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); } diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDao.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDao.java index 595e498ebf0..fbd09884d1f 100644 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDao.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDao.java @@ -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 { public ImageStoreVO findByName(String name); + public List findByProvider(String provider); + public List findByScope(ScopeType scope); } diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageStoreProviderManagerImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageStoreProviderManagerImpl.java index 9694a4cf703..642821f77b5 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageStoreProviderManagerImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageStoreProviderManagerImpl.java @@ -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(); } - + @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 getList() { + public List listImageStores() { List stores = dataStoreDao.listAll(); List imageStores = new ArrayList(); for (ImageStoreVO store : stores) { @@ -91,4 +92,26 @@ public class ImageStoreProviderManagerImpl implements ImageStoreProviderManager return imageStores; } + @Override + public List listImageStoresByScope(Scope scope) { + List stores = dataStoreDao.findByScope(scope.getScopeType()); + List imageStores = new ArrayList(); + for (ImageStoreVO store : stores) { + imageStores.add(getImageStore(store.getId())); + } + return imageStores; + } + + @Override + public List listImageStoreByProvider(String provider) { + List stores = dataStoreDao.findByProvider(provider); + List imageStores = new ArrayList(); + for (ImageStoreVO store : stores) { + imageStores.add(getImageStore(store.getId())); + } + return imageStores; + } + + + } diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/strategy/AncientSnapshotStrategy.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/strategy/AncientSnapshotStrategy.java index 9e666d21515..3863481fb90 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/strategy/AncientSnapshotStrategy.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/strategy/AncientSnapshotStrategy.java @@ -406,7 +406,7 @@ public class AncientSnapshotStrategy implements SnapshotStrategy { snapObj.processEvent(Snapshot.Event.BackupToSecondary); ZoneScope scope = new ZoneScope(snapshot.getDataCenterId()); - List stores = this.dataStoreMgr.getImageStores(scope); + List stores = this.dataStoreMgr.getImageStoresByScope(scope); if (stores.size() != 1) { throw new CloudRuntimeException("find out more than one image stores"); } diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/DataStoreManagerImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/DataStoreManagerImpl.java index 8c22767377a..8f8d3c92c52 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/DataStoreManagerImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/DataStoreManagerImpl.java @@ -62,10 +62,18 @@ public class DataStoreManagerImpl implements DataStoreManager { } throw new CloudRuntimeException("un recognized type" + role); } + @Override - public List getImageStores(Scope scope) { - return imageDataStoreMgr.getList(); + public List getImageStoresByScope(Scope scope) { + return imageDataStoreMgr.listImageStoresByScope(scope); } + + + @Override + public List getImageStoresByProvider(String provider) { + return imageDataStoreMgr.listImageStoreByProvider(provider); + } + @Override public DataStore getPrimaryDataStore(long storeId) { return primaryStorMgr.getPrimaryDataStore(storeId); diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/DataStoreProviderManagerImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/DataStoreProviderManagerImpl.java index 624c7c7c7d0..b7ed53dfcf6 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/DataStoreProviderManagerImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/DataStoreProviderManagerImpl.java @@ -65,7 +65,7 @@ public class DataStoreProviderManagerImpl extends ManagerBase implements DataSto return null; } - public List getPrimayrDataStoreProviders() { + public List getPrimaryDataStoreProviders() { List providers = new ArrayList(); 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 { diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreProviderManager.java b/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreProviderManager.java index d9a733d300f..bb5e20fdea0 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreProviderManager.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreProviderManager.java @@ -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 getList(); + List listImageStores(); + List listImageStoresByScope(Scope scope); + List listImageStoreByProvider(String provider); boolean registerDriver(String uuid, ImageStoreDriver driver); } diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java index 605ac5bd5c6..ab41a4b0deb 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java @@ -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 implements ImageStoreDao { private static final Logger s_logger = Logger.getLogger(ImageStoreDaoImpl.class); private SearchBuilder nameSearch; + private SearchBuilder providerSearch; + private SearchBuilder scopeSearch; @Override @@ -53,6 +51,14 @@ public class ImageStoreDaoImpl extends GenericDaoBase 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 implem return findOneBy(sc); } + @Override + public List findByProvider(String provider) { + SearchCriteria sc = providerSearch.create(); + sc.setParameters("providerName", provider); + return listBy(sc); + } + + @Override + public List findByScope(ScopeType scope) { + SearchCriteria sc = scopeSearch.create(); + sc.setParameters("scope", scope); + return listBy(sc); + } + } diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/provider/CloudStackImageStoreProviderImpl.java b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/provider/CloudStackImageStoreProviderImpl.java index 058dd27a039..e025cf4de4a 100644 --- a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/provider/CloudStackImageStoreProviderImpl.java +++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/provider/CloudStackImageStoreProviderImpl.java @@ -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; + } + + } diff --git a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/provider/S3ImageStoreProviderImpl.java b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/provider/S3ImageStoreProviderImpl.java index 820882dd75a..ba27d617838 100644 --- a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/provider/S3ImageStoreProviderImpl.java +++ b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/provider/S3ImageStoreProviderImpl.java @@ -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; + } + + } diff --git a/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/provider/SampleImageStoreProviderImpl.java b/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/provider/SampleImageStoreProviderImpl.java index 073a157cb3d..eadb01df8f7 100644 --- a/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/provider/SampleImageStoreProviderImpl.java +++ b/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/provider/SampleImageStoreProviderImpl.java @@ -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; + } + + } diff --git a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/provider/SwiftImageStoreProviderImpl.java b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/provider/SwiftImageStoreProviderImpl.java index 625fcffb7ff..09f09c4ef98 100644 --- a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/provider/SwiftImageStoreProviderImpl.java +++ b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/provider/SwiftImageStoreProviderImpl.java @@ -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; + } + + } diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index ca4c636ed74..77249680170 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -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 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) { diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index 2892e0081c2..f4ad36e64ed 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -325,7 +325,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, if (storeUuid != null) { imageStore = this.dataStoreMgr.getDataStore(storeUuid, DataStoreRole.Image); } else { - List stores = this.dataStoreMgr.getImageStores(new ZoneScope(zoneId)); + List 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 store = this.dataStoreMgr.getImageStores(scope); + List store = this.dataStoreMgr.getImageStoresByScope(scope); if (store.size() > 1) { throw new CloudRuntimeException("muliple image data store, don't know which one to use"); }