| /* |
| * 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.volume.datastore; |
| |
| import java.io.UnsupportedEncodingException; |
| import java.net.URLEncoder; |
| import java.util.ArrayList; |
| import java.util.List; |
| import java.util.Map; |
| |
| import javax.inject.Inject; |
| |
| import org.apache.cloudstack.annotation.AnnotationService; |
| import org.apache.cloudstack.annotation.dao.AnnotationDao; |
| import org.apache.log4j.Logger; |
| import org.springframework.stereotype.Component; |
| |
| 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.HostScope; |
| import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreParameters; |
| import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; |
| import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; |
| |
| import com.cloud.agent.api.StoragePoolInfo; |
| import com.cloud.capacity.Capacity; |
| import com.cloud.capacity.CapacityVO; |
| import com.cloud.capacity.dao.CapacityDao; |
| import com.cloud.hypervisor.Hypervisor.HypervisorType; |
| import com.cloud.exception.InvalidParameterValueException; |
| import com.cloud.storage.DataStoreRole; |
| import com.cloud.storage.ScopeType; |
| import com.cloud.storage.StorageManager; |
| import com.cloud.storage.StoragePoolHostVO; |
| import com.cloud.storage.StoragePoolStatus; |
| import com.cloud.storage.Storage.StoragePoolType; |
| import com.cloud.storage.dao.StoragePoolHostDao; |
| import com.cloud.utils.crypt.DBEncryptionUtil; |
| import com.cloud.utils.db.TransactionLegacy; |
| import com.cloud.utils.exception.CloudRuntimeException; |
| |
| @Component |
| public class PrimaryDataStoreHelper { |
| private static final Logger s_logger = Logger.getLogger(PrimaryDataStoreHelper.class); |
| @Inject |
| private PrimaryDataStoreDao dataStoreDao; |
| @Inject |
| DataStoreManager dataStoreMgr; |
| @Inject |
| StorageManager storageMgr; |
| @Inject |
| protected CapacityDao _capacityDao; |
| @Inject |
| protected StoragePoolHostDao storagePoolHostDao; |
| @Inject |
| private AnnotationDao annotationDao; |
| |
| public DataStore createPrimaryDataStore(PrimaryDataStoreParameters params) { |
| if(params == null) |
| { |
| throw new InvalidParameterValueException("createPrimaryDataStore: Input params is null, please check"); |
| } |
| StoragePoolVO dataStoreVO = dataStoreDao.findPoolByUUID(params.getUuid()); |
| if (dataStoreVO != null) { |
| throw new CloudRuntimeException("duplicate uuid: " + params.getUuid()); |
| } |
| dataStoreVO = new StoragePoolVO(); |
| dataStoreVO.setStorageProviderName(params.getProviderName()); |
| dataStoreVO.setHostAddress(params.getHost()); |
| dataStoreVO.setPoolType(params.getType()); |
| dataStoreVO.setPath(params.getPath()); |
| dataStoreVO.setPort(params.getPort()); |
| dataStoreVO.setName(params.getName()); |
| dataStoreVO.setUuid(params.getUuid()); |
| dataStoreVO.setDataCenterId(params.getZoneId()); |
| dataStoreVO.setPodId(params.getPodId()); |
| dataStoreVO.setClusterId(params.getClusterId()); |
| dataStoreVO.setStatus(StoragePoolStatus.Initialized); |
| dataStoreVO.setUserInfo(params.getUserInfo()); |
| dataStoreVO.setManaged(params.isManaged()); |
| dataStoreVO.setCapacityIops(params.getCapacityIops()); |
| dataStoreVO.setCapacityBytes(params.getCapacityBytes()); |
| dataStoreVO.setUsedBytes(params.getUsedBytes()); |
| dataStoreVO.setHypervisor(params.getHypervisorType()); |
| |
| Map<String, String> details = params.getDetails(); |
| if (params.getType() == StoragePoolType.SMB && details != null) { |
| String user = details.get("user"); |
| String password = details.get("password"); |
| String domain = details.get("domain"); |
| String updatedPath = params.getPath(); |
| |
| if (user == null || password == null) { |
| String errMsg = "Missing cifs user and password details. Add them as details parameter."; |
| s_logger.warn(errMsg); |
| throw new InvalidParameterValueException(errMsg); |
| } else { |
| try { |
| password = DBEncryptionUtil.encrypt(URLEncoder.encode(password, "UTF-8")); |
| details.put("password", password); |
| updatedPath += "?user=" + user + "&password=" + password + "&domain=" + domain; |
| } catch (UnsupportedEncodingException e) { |
| throw new CloudRuntimeException("Error while generating the cifs url. " + e.getMessage()); |
| } |
| } |
| |
| dataStoreVO.setPath(updatedPath); |
| } |
| String tags = params.getTags(); |
| List<String> storageTags = new ArrayList<String>(); |
| |
| if (tags != null) { |
| String[] tokens = tags.split(","); |
| |
| for (String tag : tokens) { |
| tag = tag.trim(); |
| if (tag.length() == 0) { |
| continue; |
| } |
| storageTags.add(tag); |
| } |
| } |
| dataStoreVO = dataStoreDao.persist(dataStoreVO, details, storageTags); |
| return dataStoreMgr.getDataStore(dataStoreVO.getId(), DataStoreRole.Primary); |
| } |
| |
| public DataStore attachHost(DataStore store, HostScope scope, StoragePoolInfo existingInfo) { |
| StoragePoolHostVO poolHost = storagePoolHostDao.findByPoolHost(store.getId(), scope.getScopeId()); |
| if (poolHost == null) { |
| poolHost = new StoragePoolHostVO(store.getId(), scope.getScopeId(), existingInfo.getLocalPath()); |
| storagePoolHostDao.persist(poolHost); |
| } |
| |
| StoragePoolVO pool = this.dataStoreDao.findById(store.getId()); |
| pool.setScope(scope.getScopeType()); |
| pool.setUsedBytes(existingInfo.getCapacityBytes() - existingInfo.getAvailableBytes()); |
| pool.setCapacityBytes(existingInfo.getCapacityBytes()); |
| pool.setStatus(StoragePoolStatus.Up); |
| this.dataStoreDao.update(pool.getId(), pool); |
| this.storageMgr.createCapacityEntry(pool, Capacity.CAPACITY_TYPE_LOCAL_STORAGE, pool.getUsedBytes()); |
| return dataStoreMgr.getDataStore(pool.getId(), DataStoreRole.Primary); |
| } |
| |
| public DataStore attachCluster(DataStore store) { |
| StoragePoolVO pool = this.dataStoreDao.findById(store.getId()); |
| |
| storageMgr.createCapacityEntry(pool.getId()); |
| |
| pool.setScope(ScopeType.CLUSTER); |
| pool.setStatus(StoragePoolStatus.Up); |
| this.dataStoreDao.update(pool.getId(), pool); |
| if(pool.getPoolType() == StoragePoolType.DatastoreCluster && pool.getParent() == 0) { |
| List<StoragePoolVO> childDatastores = dataStoreDao.listChildStoragePoolsInDatastoreCluster(pool.getId()); |
| for (StoragePoolVO child : childDatastores) { |
| child.setScope(ScopeType.CLUSTER); |
| this.dataStoreDao.update(child.getId(), child); |
| } |
| } |
| return dataStoreMgr.getDataStore(store.getId(), DataStoreRole.Primary); |
| } |
| |
| public DataStore attachZone(DataStore store) { |
| StoragePoolVO pool = this.dataStoreDao.findById(store.getId()); |
| storageMgr.createCapacityEntry(pool.getId()); |
| pool.setScope(ScopeType.ZONE); |
| pool.setStatus(StoragePoolStatus.Up); |
| this.dataStoreDao.update(pool.getId(), pool); |
| return dataStoreMgr.getDataStore(store.getId(), DataStoreRole.Primary); |
| } |
| |
| public DataStore attachZone(DataStore store, HypervisorType hypervisor) { |
| StoragePoolVO pool = this.dataStoreDao.findById(store.getId()); |
| storageMgr.createCapacityEntry(pool.getId()); |
| pool.setScope(ScopeType.ZONE); |
| pool.setHypervisor(hypervisor); |
| pool.setStatus(StoragePoolStatus.Up); |
| this.dataStoreDao.update(pool.getId(), pool); |
| if(pool.getPoolType() == StoragePoolType.DatastoreCluster && pool.getParent() == 0) { |
| List<StoragePoolVO> childDatastores = dataStoreDao.listChildStoragePoolsInDatastoreCluster(pool.getId()); |
| for (StoragePoolVO child : childDatastores) { |
| child.setScope(ScopeType.ZONE); |
| this.dataStoreDao.update(child.getId(), child); |
| } |
| } |
| return dataStoreMgr.getDataStore(store.getId(), DataStoreRole.Primary); |
| } |
| |
| public boolean maintain(DataStore store) { |
| StoragePoolVO pool = this.dataStoreDao.findById(store.getId()); |
| pool.setStatus(StoragePoolStatus.Maintenance); |
| this.dataStoreDao.update(pool.getId(), pool); |
| return true; |
| } |
| |
| public boolean cancelMaintain(DataStore store) { |
| StoragePoolVO pool = this.dataStoreDao.findById(store.getId()); |
| pool.setStatus(StoragePoolStatus.Up); |
| dataStoreDao.update(store.getId(), pool); |
| return true; |
| } |
| |
| public boolean disable(DataStore store) { |
| StoragePoolVO pool = this.dataStoreDao.findById(store.getId()); |
| pool.setStatus(StoragePoolStatus.Disabled); |
| this.dataStoreDao.update(pool.getId(), pool); |
| return true; |
| } |
| |
| public boolean enable(DataStore store) { |
| StoragePoolVO pool = this.dataStoreDao.findById(store.getId()); |
| pool.setStatus(StoragePoolStatus.Up); |
| dataStoreDao.update(pool.getId(), pool); |
| return true; |
| } |
| |
| protected boolean deletePoolStats(Long poolId) { |
| CapacityVO capacity1 = _capacityDao.findByHostIdType(poolId, Capacity.CAPACITY_TYPE_STORAGE); |
| CapacityVO capacity2 = _capacityDao.findByHostIdType(poolId, Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED); |
| if (capacity1 != null) { |
| _capacityDao.remove(capacity1.getId()); |
| } |
| |
| if (capacity2 != null) { |
| _capacityDao.remove(capacity2.getId()); |
| } |
| |
| return true; |
| } |
| |
| public boolean deletePrimaryDataStore(DataStore store) { |
| List<StoragePoolHostVO> hostPoolRecords = this.storagePoolHostDao.listByPoolId(store.getId()); |
| StoragePoolVO poolVO = this.dataStoreDao.findById(store.getId()); |
| TransactionLegacy txn = TransactionLegacy.currentTxn(); |
| txn.start(); |
| for (StoragePoolHostVO host : hostPoolRecords) { |
| storagePoolHostDao.deleteStoragePoolHostDetails(host.getHostId(), host.getPoolId()); |
| } |
| poolVO.setUuid(null); |
| this.dataStoreDao.update(poolVO.getId(), poolVO); |
| dataStoreDao.remove(poolVO.getId()); |
| dataStoreDao.deletePoolTags(poolVO.getId()); |
| annotationDao.removeByEntityType(AnnotationService.EntityType.PRIMARY_STORAGE.name(), poolVO.getUuid()); |
| deletePoolStats(poolVO.getId()); |
| // Delete op_host_capacity entries |
| this._capacityDao.removeBy(Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED, null, null, null, poolVO.getId()); |
| txn.commit(); |
| |
| s_logger.debug("Storage pool id=" + poolVO.getId() + " is removed successfully"); |
| return true; |
| } |
| |
| } |