diff --git a/api/src/com/cloud/storage/StorageService.java b/api/src/com/cloud/storage/StorageService.java index ee1a9565be4..869b2960e1c 100644 --- a/api/src/com/cloud/storage/StorageService.java +++ b/api/src/com/cloud/storage/StorageService.java @@ -20,6 +20,7 @@ import java.net.UnknownHostException; import org.apache.cloudstack.api.command.admin.storage.AddImageStoreCmd; import org.apache.cloudstack.api.command.admin.storage.CancelPrimaryStorageMaintenanceCmd; +import org.apache.cloudstack.api.command.admin.storage.CreateCacheStoreCmd; import org.apache.cloudstack.api.command.admin.storage.CreateStoragePoolCmd; import org.apache.cloudstack.api.command.admin.storage.DeleteImageStoreCmd; import org.apache.cloudstack.api.command.admin.storage.DeletePoolCmd; @@ -47,6 +48,8 @@ public interface StorageService{ */ StoragePool createPool(CreateStoragePoolCmd cmd) throws ResourceInUseException, IllegalArgumentException, UnknownHostException, ResourceUnavailableException; + + ImageStore createCacheStore(CreateCacheStoreCmd cmd); /** * Delete the storage pool diff --git a/api/src/org/apache/cloudstack/api/command/admin/storage/CreateCacheStoreCmd.java b/api/src/org/apache/cloudstack/api/command/admin/storage/CreateCacheStoreCmd.java new file mode 100644 index 00000000000..ff01a40c1fa --- /dev/null +++ b/api/src/org/apache/cloudstack/api/command/admin/storage/CreateCacheStoreCmd.java @@ -0,0 +1,123 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cloudstack.api.command.admin.storage; + +import java.util.Map; + +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.ApiErrorCode; +import org.apache.cloudstack.api.BaseCmd; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.BaseCmd.CommandType; +import org.apache.cloudstack.api.response.ImageStoreResponse; +import org.apache.cloudstack.api.response.ZoneResponse; +import org.apache.log4j.Logger; + +import com.cloud.exception.DiscoveryException; +import com.cloud.storage.ImageStore; +import com.cloud.user.Account; + +@APICommand(name = "createCacheStore", description="create cache store.", responseObject=ImageStoreResponse.class) +public class CreateCacheStoreCmd extends BaseCmd { + public static final Logger s_logger = Logger.getLogger(AddImageStoreCmd.class.getName()); + private static final String s_name = "createcachestoreresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @Parameter(name=ApiConstants.URL, type=CommandType.STRING, required=true, description="the URL for the cache store") + private String url; + + @Parameter(name=ApiConstants.ZONE_ID, type=CommandType.UUID, entityType=ZoneResponse.class, + description="the Zone ID for the image store") + private Long zoneId; + + + @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 only for now") + private String scope; + + @Parameter(name=ApiConstants.PROVIDER, type=CommandType.STRING, + required=false, description="the cache store provider name") + private String providerName; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public String getUrl() { + return url; + } + + public Long getZoneId() { + return zoneId; + } + + public Map getDetails() { + return details; + } + + public String getScope() { + return this.scope; + } + + public String getProviderName() { + return this.providerName; + } + + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + return Account.ACCOUNT_ID_SYSTEM; + } + + @Override + public void execute(){ + try{ + ImageStore result = _storageService.createCacheStore(this); + ImageStoreResponse storeResponse = null; + if (result != null ) { + storeResponse = _responseGenerator.createImageStoreResponse(result); + storeResponse.setResponseName(getCommandName()); + storeResponse.setObjectName("secondarystorage"); + this.setResponseObject(storeResponse); + } else { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add secondary storage"); + } + } catch (Exception ex) { + s_logger.warn("Exception: ", ex); + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage()); + } + } +} diff --git a/engine/storage/src/org/apache/cloudstack/storage/motion/DataMotionService.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataMotionService.java similarity index 84% rename from engine/storage/src/org/apache/cloudstack/storage/motion/DataMotionService.java rename to engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataMotionService.java index db36f6492e8..adeeecbeed3 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/motion/DataMotionService.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataMotionService.java @@ -16,10 +16,8 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.cloudstack.storage.motion; +package org.apache.cloudstack.engine.subsystem.api.storage; -import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; -import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; public interface DataMotionService { diff --git a/engine/storage/src/org/apache/cloudstack/storage/motion/DataMotionStrategy.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataMotionStrategy.java similarity index 85% rename from engine/storage/src/org/apache/cloudstack/storage/motion/DataMotionStrategy.java rename to engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataMotionStrategy.java index ba40c6dcbce..e2cc2a06211 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/motion/DataMotionStrategy.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataMotionStrategy.java @@ -16,10 +16,8 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.cloudstack.storage.motion; +package org.apache.cloudstack.engine.subsystem.api.storage; -import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; -import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; public interface DataMotionStrategy { 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 def3b96d331..1a36c8ca45d 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 @@ -28,5 +28,6 @@ public interface DataStoreManager { public DataStore getDataStore(String uuid, DataStoreRole role); public List getImageStoresByScope(ZoneScope scope); public List getImageStoresByProvider(String provider); + public List getImageCacheStores(Scope scope); 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 083c7d39b67..c0c1f76a30f 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 @@ -27,7 +27,8 @@ import java.util.Set; public interface DataStoreProvider { public static enum DataStoreProviderType { PRIMARY, - IMAGE + IMAGE, + ImageCache } public DataStoreLifeCycle getDataStoreLifeCycle(); public DataStoreDriver getDataStoreDriver(); diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreProviderManager.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreProviderManager.java index 8dd8c3a0824..6872bdfc726 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreProviderManager.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreProviderManager.java @@ -27,6 +27,7 @@ public interface DataStoreProviderManager extends Manager, DataStoreProviderApiS public DataStoreProvider getDataStoreProvider(String name); public DataStoreProvider getDefaultPrimaryDataStoreProvider(); public DataStoreProvider getDefaultImageDataStoreProvider(); + public DataStoreProvider getDefaultCacheDataStoreProvider(); public List getDataStoreProviders(); } diff --git a/engine/storage/backup/src/org/apache/cloudstack/storage/backup/BackupMotionService.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StorageCacheManager.java similarity index 83% rename from engine/storage/backup/src/org/apache/cloudstack/storage/backup/BackupMotionService.java rename to engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StorageCacheManager.java index cb49027f3bf..0fdec110661 100644 --- a/engine/storage/backup/src/org/apache/cloudstack/storage/backup/BackupMotionService.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StorageCacheManager.java @@ -16,8 +16,9 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.cloudstack.storage.backup; +package org.apache.cloudstack.engine.subsystem.api.storage; -public interface BackupMotionService { - boolean copySnapshot(String snapshotUri, String destSnapshotUri); + +public interface StorageCacheManager { + public DataStore getCacheStorage(Scope scope); } diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreVO.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreVO.java index 7f950362fd8..5503df069dd 100644 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreVO.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreVO.java @@ -28,6 +28,8 @@ import javax.persistence.Id; import javax.persistence.Table; import javax.persistence.TableGenerator; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreRole; + import com.cloud.storage.ImageStore; @@ -69,6 +71,18 @@ public class ImageStoreVO implements ImageStore { @Column(name=GenericDao.REMOVED_COLUMN) private Date removed; + + @Column(name = "role") + @Enumerated(value = EnumType.STRING) + private DataStoreRole role; + + public DataStoreRole getRole() { + return role; + } + + public void setRole(DataStoreRole role) { + this.role = role; + } public long getId() { return this.id; diff --git a/engine/pom.xml b/engine/pom.xml index 1a3d896d50d..3b686f2399e 100644 --- a/engine/pom.xml +++ b/engine/pom.xml @@ -39,8 +39,8 @@ storage storage/volume storage/image - storage/imagemotion - storage/backup + storage/datamotion + storage/cache storage/snapshot storage/integration-test components-api diff --git a/engine/storage/backup/src/org/apache/cloudstack/storage/backup/BackupService.java b/engine/storage/backup/src/org/apache/cloudstack/storage/backup/BackupService.java deleted file mode 100644 index 67924d2ce73..00000000000 --- a/engine/storage/backup/src/org/apache/cloudstack/storage/backup/BackupService.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.cloudstack.storage.backup; - -import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; - -public interface BackupService { - public boolean backupSnapshot(SnapshotInfo snapshot, long backupStoreId); - public SnapshotOnBackupStoreInfo getSnapshot(long snapshotId); -} diff --git a/engine/storage/backup/pom.xml b/engine/storage/cache/pom.xml similarity index 94% rename from engine/storage/backup/pom.xml rename to engine/storage/cache/pom.xml index 019e09c7204..f00f6cd1498 100644 --- a/engine/storage/backup/pom.xml +++ b/engine/storage/cache/pom.xml @@ -11,8 +11,8 @@ 4.0.0 - cloud-engine-storage-backup - Apache CloudStack Engine Storage Backup Component + cloud-engine-storage-cache + Apache CloudStack Engine Storage Cache Component org.apache.cloudstack cloud-engine diff --git a/engine/storage/imagemotion/src/org/apache/cloudstack/storage/image/motion/ImageMotionStrategy.java b/engine/storage/cache/src/org/apache/cloudstack/storage/cache/allocator/StorageCacheAllocator.java similarity index 74% rename from engine/storage/imagemotion/src/org/apache/cloudstack/storage/image/motion/ImageMotionStrategy.java rename to engine/storage/cache/src/org/apache/cloudstack/storage/cache/allocator/StorageCacheAllocator.java index 7a476367d37..4259d9ed03f 100644 --- a/engine/storage/imagemotion/src/org/apache/cloudstack/storage/image/motion/ImageMotionStrategy.java +++ b/engine/storage/cache/src/org/apache/cloudstack/storage/cache/allocator/StorageCacheAllocator.java @@ -16,9 +16,11 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.cloudstack.storage.image.motion; +package org.apache.cloudstack.storage.cache.allocator; -import org.apache.cloudstack.storage.motion.DataMotionStrategy; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; +import org.apache.cloudstack.engine.subsystem.api.storage.Scope; -public interface ImageMotionStrategy extends DataMotionStrategy { +public interface StorageCacheAllocator { + DataStore getCacheStore(Scope scope); } diff --git a/engine/storage/cache/src/org/apache/cloudstack/storage/cache/allocator/StorageCacheRandomAllocator.java b/engine/storage/cache/src/org/apache/cloudstack/storage/cache/allocator/StorageCacheRandomAllocator.java new file mode 100644 index 00000000000..c357d239026 --- /dev/null +++ b/engine/storage/cache/src/org/apache/cloudstack/storage/cache/allocator/StorageCacheRandomAllocator.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cloudstack.storage.cache.allocator; + +import java.util.List; + +import javax.inject.Inject; + +import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; +import org.apache.cloudstack.engine.subsystem.api.storage.Scope; + +import com.cloud.storage.ScopeType; +import com.cloud.utils.exception.CloudRuntimeException; + +import edu.emory.mathcs.backport.java.util.Collections; + +public class StorageCacheRandomAllocator implements StorageCacheAllocator { + @Inject + DataStoreManager dataStoreMgr; + @Override + public DataStore getCacheStore(Scope scope) { + if (scope.getScopeType() != ScopeType.ZONE) { + throw new CloudRuntimeException("Can only support zone wide cache storage"); + } + + List cacheStores = dataStoreMgr.getImageCacheStores(scope); + if (cacheStores.size() <= 0) { + throw new CloudRuntimeException("Can't find cache storage in zone: " + scope.getScopeId()); + } + + Collections.shuffle(cacheStores); + return cacheStores.get(0); + } +} diff --git a/engine/storage/cache/src/org/apache/cloudstack/storage/cache/manager/StorageCacheManagerImpl.java b/engine/storage/cache/src/org/apache/cloudstack/storage/cache/manager/StorageCacheManagerImpl.java new file mode 100644 index 00000000000..c85565d8266 --- /dev/null +++ b/engine/storage/cache/src/org/apache/cloudstack/storage/cache/manager/StorageCacheManagerImpl.java @@ -0,0 +1,100 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cloudstack.storage.cache.manager; + +import java.util.List; +import java.util.Map; + +import javax.inject.Inject; +import javax.naming.ConfigurationException; + +import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; +import org.apache.cloudstack.engine.subsystem.api.storage.Scope; +import org.apache.cloudstack.engine.subsystem.api.storage.StorageCacheManager; +import org.apache.cloudstack.storage.cache.allocator.StorageCacheAllocator; + +import com.cloud.utils.component.Manager; + +public class StorageCacheManagerImpl implements StorageCacheManager, Manager { + @Inject + List storageCacheAllocator; + @Override + public DataStore getCacheStorage(Scope scope) { + for (StorageCacheAllocator allocator : storageCacheAllocator) { + DataStore store = allocator.getCacheStore(scope); + if (store != null) { + return store; + } + } + return null; + } + + @Override + public String getName() { + // TODO Auto-generated method stub + return null; + } + + @Override + public void setName(String name) { + // TODO Auto-generated method stub + + } + + @Override + public void setConfigParams(Map params) { + // TODO Auto-generated method stub + + } + + @Override + public Map getConfigParams() { + // TODO Auto-generated method stub + return null; + } + + @Override + public int getRunLevel() { + // TODO Auto-generated method stub + return 0; + } + + @Override + public void setRunLevel(int level) { + // TODO Auto-generated method stub + + } + + @Override + public boolean configure(String name, Map params) throws ConfigurationException { + // TODO Auto-generated method stub + return true; + } + + @Override + public boolean start() { + return true; + } + + @Override + public boolean stop() { + // TODO Auto-generated method stub + return true; + } +} \ No newline at end of file diff --git a/engine/storage/imagemotion/pom.xml b/engine/storage/datamotion/pom.xml similarity index 95% rename from engine/storage/imagemotion/pom.xml rename to engine/storage/datamotion/pom.xml index 9a7f3e017a2..8a3698c94d3 100644 --- a/engine/storage/imagemotion/pom.xml +++ b/engine/storage/datamotion/pom.xml @@ -11,8 +11,8 @@ 4.0.0 - cloud-engine-storage-imagemotion - Apache CloudStack Engine Storage Image Motion Component + cloud-engine-storage-datamotion + Apache CloudStack Engine Storage Data Motion Component org.apache.cloudstack cloud-engine diff --git a/engine/storage/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java similarity index 99% rename from engine/storage/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java rename to engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java index 3602bb16baf..1d164cdddf7 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java +++ b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java @@ -24,6 +24,7 @@ import java.util.List; import javax.inject.Inject; import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; +import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionStrategy; import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; diff --git a/engine/storage/src/org/apache/cloudstack/storage/motion/DataMotionDriver.java b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/DataMotionDriver.java similarity index 100% rename from engine/storage/src/org/apache/cloudstack/storage/motion/DataMotionDriver.java rename to engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/DataMotionDriver.java diff --git a/engine/storage/src/org/apache/cloudstack/storage/motion/DataMotionServiceImpl.java b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/DataMotionServiceImpl.java similarity index 93% rename from engine/storage/src/org/apache/cloudstack/storage/motion/DataMotionServiceImpl.java rename to engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/DataMotionServiceImpl.java index 343140fb98e..93ab4124fcd 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/motion/DataMotionServiceImpl.java +++ b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/DataMotionServiceImpl.java @@ -23,6 +23,8 @@ import java.util.List; import javax.inject.Inject; import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; +import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionService; +import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionStrategy; import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.springframework.stereotype.Component; 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 dbcfb765e1d..a1096d31fad 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 @@ -28,6 +28,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.DataStoreRole; import org.apache.cloudstack.engine.subsystem.api.storage.ImageStoreProvider; import org.apache.cloudstack.engine.subsystem.api.storage.Scope; import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; @@ -37,12 +38,18 @@ import org.apache.cloudstack.storage.image.ImageStoreDriver; import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity; import org.apache.cloudstack.storage.image.datastore.ImageStoreProviderManager; import org.apache.cloudstack.storage.image.store.ImageStoreImpl; +import org.apache.log4j.Logger; import org.springframework.stereotype.Component; +import com.cloud.storage.ScopeType; import com.cloud.storage.dao.VMTemplateDao; +import com.cloud.utils.db.SearchCriteria.Op; +import com.cloud.utils.db.SearchCriteria2; +import com.cloud.utils.db.SearchCriteriaService; @Component public class ImageStoreProviderManagerImpl implements ImageStoreProviderManager { + private static final Logger s_logger = Logger.getLogger(ImageStoreProviderManagerImpl.class); @Inject ImageStoreDao dataStoreDao; @Inject @@ -115,4 +122,21 @@ public class ImageStoreProviderManagerImpl implements ImageStoreProviderManager + @Override + public List listImageCacheStores(Scope scope) { + List imageStores = new ArrayList(); + if (scope.getScopeType() != ScopeType.ZONE) { + s_logger.debug("only support zone wide image cache stores"); + return imageStores; + } + SearchCriteriaService sc = SearchCriteria2.create(ImageStoreVO.class); + sc.addAnd(sc.getEntity().getScope(), Op.EQ, ScopeType.ZONE); + sc.addAnd(sc.getEntity().getDataCenterId(), Op.EQ, scope.getScopeId()); + sc.addAnd(sc.getEntity().getRole(), Op.EQ, DataStoreRole.ImageCache); + List cacheStores = sc.list(); + for (ImageStoreVO store : cacheStores) { + imageStores.add(getImageStore(store.getId())); + } + return imageStores; + } } diff --git a/engine/storage/imagemotion/src/org/apache/cloudstack/storage/image/motion/DefaultImageMotionStrategy.java b/engine/storage/imagemotion/src/org/apache/cloudstack/storage/image/motion/DefaultImageMotionStrategy.java deleted file mode 100644 index c49a521a3ca..00000000000 --- a/engine/storage/imagemotion/src/org/apache/cloudstack/storage/image/motion/DefaultImageMotionStrategy.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.cloudstack.storage.image.motion; - -import javax.inject.Inject; - -import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; -import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; -import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; -import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; -import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher; -import org.apache.cloudstack.framework.async.AsyncCompletionCallback; -import org.apache.cloudstack.framework.async.AsyncRpcConext; -import org.apache.cloudstack.storage.command.CopyCmd; -import org.apache.cloudstack.storage.command.CopyCmdAnswer; -import org.apache.cloudstack.storage.endpoint.EndPointSelector; -import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreInfo; - -import com.cloud.agent.api.Answer; - -//At least one of datastore is coming from image store or image cache store - -public class DefaultImageMotionStrategy implements ImageMotionStrategy { - @Inject - EndPointSelector selector; - private class CreateTemplateContext extends AsyncRpcConext { - private final TemplateOnPrimaryDataStoreInfo template; - public CreateTemplateContext(AsyncCompletionCallback callback, TemplateOnPrimaryDataStoreInfo template) { - super(callback); - this.template = template; - } - - public TemplateOnPrimaryDataStoreInfo getTemplate() { - return this.template; - } - - } -/* - @Override - public void copyTemplateAsync(String destUri, String srcUri, EndPoint ep, AsyncCompletionCallback callback) { - - CopyCmd copyCommand = new CopyCmd(destUri, srcUri); - CreateTemplateContext context = new CreateTemplateContext(callback, null); - AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); - caller.setCallback(caller.getTarget().copyTemplateCallBack(null, null)) - .setContext(context); - - ep.sendMessageAsync(copyCommand, caller); - } - - public Object copyTemplateCallBack(AsyncCallbackDispatcher callback, CreateTemplateContext context) { - AsyncCompletionCallback parentCall = context.getParentCallback(); - CopyTemplateToPrimaryStorageAnswer answer = (CopyTemplateToPrimaryStorageAnswer)callback.getResult(); - CommandResult result = new CommandResult(); - - if (!answer.getResult()) { - result.setSucess(answer.getResult()); - result.setResult(answer.getDetails()); - } else { - TemplateOnPrimaryDataStoreInfo templateStore = context.getTemplate(); - templateStore.setPath(answer.getPath()); - result.setSucess(true); - } - - parentCall.complete(result); - return null; - }*/ - - @Override - public boolean canHandle(DataObject srcData, DataObject destData) { - /* - DataStore destStore = destData.getDataStore(); - DataStore srcStore = srcData.getDataStore(); - if (destStore.getRole() == DataStoreRole.Image || destStore.getRole() == DataStoreRole.ImageCache - || srcStore.getRole() == DataStoreRole.Image - || srcStore.getRole() == DataStoreRole.ImageCache) { - return true; - }*/ - return false; - } - - @Override - public Void copyAsync(DataObject srcData, DataObject destData, - AsyncCompletionCallback callback) { - DataStore destStore = destData.getDataStore(); - DataStore srcStore = srcData.getDataStore(); - EndPoint ep = selector.select(srcData, destData); - CopyCommandResult result = new CopyCommandResult("", null); - if (ep == null) { - result.setResult("can't find end point"); - callback.complete(result); - return null; - } - - String srcUri = srcStore.getDriver().grantAccess(srcData, ep); - String destUri = destStore.getDriver().grantAccess(destData, ep); - CopyCmd cmd = new CopyCmd(srcUri, destUri); - - CreateTemplateContext context = new CreateTemplateContext(callback, null); - AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); - caller.setCallback(caller.getTarget().copyAsyncCallback(null, null)) - .setContext(context); - - ep.sendMessageAsync(cmd, caller); - return null; - } - - protected Void copyAsyncCallback(AsyncCallbackDispatcher callback, CreateTemplateContext context) { - AsyncCompletionCallback parentCall = context.getParentCallback(); - Answer answer = (Answer)callback.getResult(); - if (!answer.getResult()) { - CopyCommandResult result = new CopyCommandResult("", null); - result.setResult(answer.getDetails()); - parentCall.complete(result); - } else { - CopyCmdAnswer ans = (CopyCmdAnswer)answer; - CopyCommandResult result = new CopyCommandResult(ans.getPath(), null); - parentCall.complete(result); - } - return null; - - } - -} diff --git a/engine/storage/imagemotion/src/org/apache/cloudstack/storage/image/motion/ImageMotionServiceImpl.java b/engine/storage/imagemotion/src/org/apache/cloudstack/storage/image/motion/ImageMotionServiceImpl.java deleted file mode 100644 index 93ba4a5ad64..00000000000 --- a/engine/storage/imagemotion/src/org/apache/cloudstack/storage/image/motion/ImageMotionServiceImpl.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.cloudstack.storage.image.motion; - -import java.util.List; - -import javax.inject.Inject; - -import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult; -import org.apache.cloudstack.engine.subsystem.api.storage.ImageService; -import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; -import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService; -import org.apache.cloudstack.framework.async.AsyncCompletionCallback; - - -public class ImageMotionServiceImpl implements ImageMotionService { - @Inject - List motionStrategies; - @Inject - VolumeService volumeService; - @Inject - ImageService imageService; - - @Override - public boolean copyIso(String isoUri, String destIsoUri) { - // TODO Auto-generated method stub - return false; - } - - - - @Override - public void copyTemplateAsync(TemplateInfo destTemplate, TemplateInfo srcTemplate, AsyncCompletionCallback callback) { - /* ImageMotionStrategy ims = null; - for (ImageMotionStrategy strategy : motionStrategies) { - if (strategy.canHandle(srcTemplate)) { - ims = strategy; - break; - } - } - - if (ims == null) { - throw new CloudRuntimeException("Can't find proper image motion strategy"); - } - - EndPoint ep = ims.getEndPoint(destTemplate, srcTemplate); - String srcUri = srcTemplate.getDataStore().grantAccess(srcTemplate, ep); - String destUri = destTemplate.getDataStore().grantAccess(destTemplate, ep); - - ims.copyTemplateAsync(destUri, srcUri, ep, callback);*/ - } - - -} diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockStorageMotionStrategy.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockStorageMotionStrategy.java index b619ee9240f..53051314122 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockStorageMotionStrategy.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockStorageMotionStrategy.java @@ -19,9 +19,9 @@ package org.apache.cloudstack.storage.test; import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; +import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionStrategy; import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; -import org.apache.cloudstack.storage.motion.DataMotionStrategy; public class MockStorageMotionStrategy implements DataMotionStrategy { 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 3863481fb90..7eddb34943d 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 @@ -25,7 +25,7 @@ import javax.inject.Inject; import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; -import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; +import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionService; import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; @@ -45,23 +45,15 @@ import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.framework.async.AsyncRpcConext; import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; -import org.apache.cloudstack.storage.motion.DataMotionService; import org.apache.cloudstack.storage.snapshot.SnapshotObject; import org.apache.cloudstack.storage.snapshot.SnapshotStateMachineManager; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; -import com.cloud.agent.api.Answer; import com.cloud.agent.api.BackupSnapshotAnswer; -import com.cloud.agent.api.DeleteSnapshotBackupCommand; -import com.cloud.agent.api.to.S3TO; -import com.cloud.agent.api.to.SwiftTO; -import com.cloud.configuration.Resource.ResourceType; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.dc.ClusterVO; import com.cloud.dc.dao.ClusterDao; -import com.cloud.event.EventTypes; -import com.cloud.event.UsageEventUtils; import com.cloud.exception.InvalidParameterValueException; import com.cloud.host.HostVO; import com.cloud.hypervisor.Hypervisor.HypervisorType; @@ -73,12 +65,9 @@ import com.cloud.storage.VolumeManager; import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.SnapshotDao; import com.cloud.storage.dao.VolumeDao; -import com.cloud.storage.s3.S3Manager; import com.cloud.storage.snapshot.SnapshotManager; -import com.cloud.storage.swift.SwiftManager; import com.cloud.utils.NumbersUtil; import com.cloud.utils.db.DB; -import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.fsm.NoTransitionException; import com.cloud.vm.UserVmVO; diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/DataObjectManagerImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/DataObjectManagerImpl.java index 218f9013a17..566da62389e 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/DataObjectManagerImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/DataObjectManagerImpl.java @@ -23,6 +23,7 @@ import javax.inject.Inject; import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; +import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionService; import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; @@ -31,7 +32,6 @@ import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreState import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.framework.async.AsyncRpcConext; -import org.apache.cloudstack.storage.motion.DataMotionService; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; 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 eb233aa3f8b..adc7250cc73 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/DataStoreManagerImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/DataStoreManagerImpl.java @@ -46,6 +46,8 @@ public class DataStoreManagerImpl implements DataStoreManager { return primaryStorMgr.getPrimaryDataStore(storeId); } else if (role == DataStoreRole.Image) { return imageDataStoreMgr.getImageStore(storeId); + } else if (role == DataStoreRole.ImageCache) { + return imageDataStoreMgr.getImageStore(storeId); } throw new CloudRuntimeException("un recognized type" + role); } @@ -81,5 +83,8 @@ public class DataStoreManagerImpl implements DataStoreManager { public DataStore getPrimaryDataStore(long storeId) { return primaryStorMgr.getPrimaryDataStore(storeId); } - + @Override + public List getImageCacheStores(Scope scope) { + return imageDataStoreMgr.listImageCacheStores(scope); + } } diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java index 80badc54d30..9f98d5d518d 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java @@ -161,11 +161,7 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager { this.stateMachines.transitTo(obj, event, null, templatePoolDao); } catch (NoTransitionException e) { - if (event == Event.CreateOnlyRequested || event == Event.OperationSuccessed) { - s_logger.debug("allow muliple create requests"); - } else { throw e; - } } } else { throw new CloudRuntimeException("Invalid data or store type: " + data.getType() + " " + data.getDataStore().getRole()); 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 b7ed53dfcf6..e34a35ef2c1 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 @@ -34,8 +34,8 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProviderManag import org.apache.cloudstack.engine.subsystem.api.storage.ImageStoreProvider; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreProvider; -import org.apache.cloudstack.storage.image.ImageStoreDriver; import org.apache.cloudstack.storage.datastore.PrimaryDataStoreProviderManager; +import org.apache.cloudstack.storage.image.ImageStoreDriver; import org.apache.cloudstack.storage.image.datastore.ImageStoreProviderManager; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -68,7 +68,7 @@ public class DataStoreProviderManagerImpl extends ManagerBase implements DataSto public List getPrimaryDataStoreProviders() { List providers = new ArrayList(); for (DataStoreProvider provider : providerMap.values()) { - if (provider instanceof PrimaryDataStoreProvider) { + if (provider.getTypes().contains(DataStoreProviderType.PRIMARY)) { StorageProviderResponse response = new StorageProviderResponse(); response.setName(provider.getName()); response.setType(DataStoreProvider.DataStoreProviderType.PRIMARY.toString()); @@ -81,7 +81,7 @@ public class DataStoreProviderManagerImpl extends ManagerBase implements DataSto public List getImageDataStoreProviders() { List providers = new ArrayList(); for (DataStoreProvider provider : providerMap.values()) { - if (provider instanceof ImageStoreProvider) { + if (provider.getTypes().contains(DataStoreProviderType.IMAGE)) { StorageProviderResponse response = new StorageProviderResponse(); response.setName(provider.getName()); response.setType(DataStoreProvider.DataStoreProviderType.IMAGE.toString()); @@ -90,6 +90,19 @@ public class DataStoreProviderManagerImpl extends ManagerBase implements DataSto } return providers; } + + public List getCacheDataStoreProviders() { + List providers = new ArrayList(); + for (DataStoreProvider provider : providerMap.values()) { + if (provider.getTypes().contains(DataStoreProviderType.ImageCache)) { + StorageProviderResponse response = new StorageProviderResponse(); + response.setName(provider.getName()); + response.setType(DataStoreProviderType.ImageCache.toString()); + providers.add(response); + } + } + return providers; + } @Override public boolean configure(String name, Map params) @@ -125,6 +138,7 @@ public class DataStoreProviderManagerImpl extends ManagerBase implements DataSto } catch(Exception e) { s_logger.debug("configure provider failed", e); providerMap.remove(providerName); + return false; } } @@ -141,6 +155,11 @@ public class DataStoreProviderManagerImpl extends ManagerBase implements DataSto public DataStoreProvider getDefaultImageDataStoreProvider() { return this.getDataStoreProvider("CloudStack ImageStore Provider"); } + + @Override + public DataStoreProvider getDefaultCacheDataStoreProvider() { + return this.getDataStoreProvider("cloudstack image store provider"); + } @Override public List getDataStoreProviders(String type) { @@ -151,6 +170,8 @@ public class DataStoreProviderManagerImpl extends ManagerBase implements DataSto return this.getPrimaryDataStoreProviders(); } else if (type.equalsIgnoreCase(DataStoreProvider.DataStoreProviderType.IMAGE.toString())) { return this.getImageDataStoreProviders(); + } else if (type.equalsIgnoreCase(DataStoreProvider.DataStoreProviderType.ImageCache.toString())) { + return this.getCacheDataStoreProviders(); } else { throw new InvalidParameterValueException("Invalid parameter: " + type); } diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreHelper.java b/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreHelper.java index 33fda486c36..a4d3db93718 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreHelper.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreHelper.java @@ -23,6 +23,7 @@ import java.util.Map; import javax.inject.Inject; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreRole; import org.apache.cloudstack.storage.datastore.db.ImageStoreDao; import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailVO; import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao; @@ -52,6 +53,7 @@ public class ImageStoreHelper { store.setScope((ScopeType)params.get("scope")); store.setUuid((String)params.get("uuid")); store.setUrl((String)params.get("url")); + store.setRole(DataStoreRole.getRole((String)params.get("role"))); store = imageStoreDao.persist(store); return store; } @@ -68,6 +70,7 @@ public class ImageStoreHelper { store.setScope((ScopeType)params.get("scope")); store.setUuid((String)params.get("uuid")); store.setUrl((String)params.get("url")); + store.setRole(DataStoreRole.getRole((String)params.get("role"))); store = imageStoreDao.persist(store); // persist details 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 2026346ccdc..f8fa28176a0 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 @@ -31,5 +31,6 @@ public interface ImageStoreProviderManager { List listImageStores(); List listImageStoresByScope(ZoneScope scope); List listImageStoreByProvider(String provider); + List listImageCacheStores(Scope scope); boolean registerDriver(String uuid, ImageStoreDriver driver); } diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/TemplateInstallStrategyImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/TemplateInstallStrategyImpl.java index 5f1735c180a..69979e5a16a 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/TemplateInstallStrategyImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/TemplateInstallStrategyImpl.java @@ -20,12 +20,12 @@ package org.apache.cloudstack.storage.volume; import javax.inject.Inject; +import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionService; import org.apache.cloudstack.engine.subsystem.api.storage.ImageDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager; import org.apache.cloudstack.storage.datastore.PrimaryDataStore; -import org.apache.cloudstack.storage.motion.DataMotionService; import org.apache.cloudstack.storage.volume.VolumeServiceImpl.CreateBaseImageResult; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java index 32e7d274f01..ff504ebe0e9 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java @@ -24,6 +24,7 @@ import org.apache.cloudstack.engine.cloud.entity.api.VolumeEntity; import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; +import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionService; import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event; @@ -40,7 +41,6 @@ import org.apache.cloudstack.storage.datastore.DataObjectManager; import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager; import org.apache.cloudstack.storage.datastore.PrimaryDataStore; import org.apache.cloudstack.storage.datastore.PrimaryDataStoreProviderManager; -import org.apache.cloudstack.storage.motion.DataMotionService; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -52,7 +52,6 @@ import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.VolumeDao; import com.cloud.storage.snapshot.SnapshotManager; import com.cloud.utils.db.DB; -import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.VirtualMachine; import com.cloud.vm.dao.VMInstanceDao; 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 e025cf4de4a..fdeba4d7c73 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 @@ -83,6 +83,7 @@ public class CloudStackImageStoreProviderImpl implements ImageStoreProvider { public Set getTypes() { Set types = new HashSet(); types.add(DataStoreProviderType.IMAGE); + types.add(DataStoreProviderType.ImageCache); return types; } diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index 77249680170..78b26bb69fd 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -42,6 +42,7 @@ import javax.naming.ConfigurationException; import org.apache.cloudstack.api.command.admin.storage.AddImageStoreCmd; import org.apache.cloudstack.api.command.admin.storage.CancelPrimaryStorageMaintenanceCmd; +import org.apache.cloudstack.api.command.admin.storage.CreateCacheStoreCmd; import org.apache.cloudstack.api.command.admin.storage.CreateStoragePoolCmd; import org.apache.cloudstack.api.command.admin.storage.DeleteImageStoreCmd; import org.apache.cloudstack.api.command.admin.storage.DeletePoolCmd; @@ -1966,6 +1967,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C params.put("details", details); params.put("scope", scopeType); params.put("providerName", storeProvider.getName()); + params.put("role", DataStoreRole.Image); DataStoreLifeCycle lifeCycle = storeProvider.getDataStoreLifeCycle(); DataStore store = null; @@ -2017,6 +2019,74 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C txn.commit(); return true; } + @Override + public ImageStore createCacheStore(CreateCacheStoreCmd cmd) { + String providerName = cmd.getProviderName(); + DataStoreProvider storeProvider = _dataStoreProviderMgr.getDataStoreProvider(providerName); + + if (storeProvider == null) { + storeProvider = _dataStoreProviderMgr.getDefaultCacheDataStoreProvider(); + if (storeProvider == null) { + throw new InvalidParameterValueException("can't find cache store provider: " + providerName); + } + } + + Long dcId = cmd.getZoneId(); + + 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); + } + + if (scopeType != ScopeType.ZONE) { + throw new InvalidParameterValueException("Only zone wide cache storage is supported"); + } + } + + if (scopeType == ScopeType.ZONE && dcId == null) { + throw new InvalidParameterValueException("zone id can't be null, if scope is zone"); + } + + + // Check if the zone exists in the system + DataCenterVO zone = _dcDao.findById(dcId); + if (zone == null) { + throw new InvalidParameterValueException("Can't find zone by id " + dcId); + } + + Account account = UserContext.current().getCaller(); + if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(account.getType())) { + PermissionDeniedException ex = new PermissionDeniedException( + "Cannot perform this operation, Zone with specified id is currently disabled"); + ex.addProxyObject(zone, dcId, "dcId"); + throw ex; + } + + Map params = new HashMap(); + params.put("zoneId", dcId); + params.put("url", cmd.getUrl()); + params.put("name", cmd.getUrl()); + params.put("details", cmd.getDetails()); + params.put("scope", scopeType); + params.put("providerName", storeProvider.getName()); + params.put("role", DataStoreRole.ImageCache); + + DataStoreLifeCycle lifeCycle = storeProvider.getDataStoreLifeCycle(); + DataStore store = null; + try { + store = lifeCycle.initialize(params); + } catch (Exception e) { + s_logger.debug("Failed to add data store", e); + throw new CloudRuntimeException("Failed to add data store", e); + } + + return (ImageStore) _dataStoreMgr.getDataStore(store.getId(), DataStoreRole.ImageCache); + } } diff --git a/tools/apidoc/gen_toc.py b/tools/apidoc/gen_toc.py index ab2456dd3eb..e41e883066a 100644 --- a/tools/apidoc/gen_toc.py +++ b/tools/apidoc/gen_toc.py @@ -95,6 +95,7 @@ known_categories = { 'InstanceGroup': 'VM Group', 'StorageMaintenance': 'Storage Pool', 'StoragePool': 'Storage Pool', + 'CacheStore': 'Storage Pool', 'StorageProvider': 'Storage Pool', 'SecurityGroup': 'Security Group', 'SSH': 'SSH',