/* * 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.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; 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); return dataStoreMgr.getDataStore(store.getId(), DataStoreRole.Primary); } public DataStore attachZone(DataStore store) { StoragePoolVO pool = this.dataStoreDao.findById(store.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()); pool.setScope(ScopeType.ZONE); pool.setHypervisor(hypervisor); pool.setStatus(StoragePoolStatus.Up); this.dataStoreDao.update(pool.getId(), pool); 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()); 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; } }