@Override public boolean attachCluster(DataStore store, ClusterScope scope) { PrimaryDataStoreInfo primarystore = (PrimaryDataStoreInfo) store; // Check if there is host up in this cluster List<HostVO> allHosts = _resourceMgr.listAllUpAndEnabledHosts( Host.Type.Routing, primarystore.getClusterId(), primarystore.getPodId(), primarystore.getDataCenterId()); if (allHosts.isEmpty()) { primaryDataStoreDao.expunge(primarystore.getId()); throw new CloudRuntimeException( "No host up to associate a storage pool with in cluster " + primarystore.getClusterId()); } if (primarystore.getPoolType() == StoragePoolType.OCFS2 && !_ocfs2Mgr.prepareNodes(allHosts, primarystore)) { s_logger.warn( "Can not create storage pool " + primarystore + " on cluster " + primarystore.getClusterId()); primaryDataStoreDao.expunge(primarystore.getId()); return false; } boolean success = false; for (HostVO h : allHosts) { success = createStoragePool(h.getId(), primarystore); if (success) { break; } } s_logger.debug("In createPool Adding the pool to each of the hosts"); List<HostVO> poolHosts = new ArrayList<HostVO>(); for (HostVO h : allHosts) { try { storageMgr.connectHostToSharedPool(h.getId(), primarystore.getId()); poolHosts.add(h); } catch (Exception e) { s_logger.warn("Unable to establish a connection between " + h + " and " + primarystore, e); } } if (poolHosts.isEmpty()) { s_logger.warn( "No host can access storage pool " + primarystore + " on cluster " + primarystore.getClusterId()); primaryDataStoreDao.expunge(primarystore.getId()); throw new CloudRuntimeException("Failed to access storage pool"); } dataStoreHelper.attachCluster(store); return true; }
@DB @Override public boolean deleteDataStore(DataStore store) { List<StoragePoolHostVO> hostPoolRecords = _storagePoolHostDao.listByPoolId(store.getId()); StoragePool pool = (StoragePool) store; boolean deleteFlag = false; // find the hypervisor where the storage is attached to. HypervisorType hType = null; if (hostPoolRecords.size() > 0) { hType = getHypervisorType(hostPoolRecords.get(0).getHostId()); } // Remove the SR associated with the Xenserver for (StoragePoolHostVO host : hostPoolRecords) { DeleteStoragePoolCommand deleteCmd = new DeleteStoragePoolCommand(pool); final Answer answer = agentMgr.easySend(host.getHostId(), deleteCmd); if (answer != null && answer.getResult()) { deleteFlag = true; // if host is KVM hypervisor then send deleteStoragepoolcmd to all the kvm hosts. if (HypervisorType.KVM != hType) { break; } } else { if (answer != null) { s_logger.debug("Failed to delete storage pool: " + answer.getResult()); } } } if (!deleteFlag) { throw new CloudRuntimeException("Failed to delete storage pool on host"); } return dataStoreHelper.deletePrimaryDataStore(store); }
@Override public boolean attachHost(DataStore store, HostScope scope, StoragePoolInfo existingInfo) { dataStoreHelper.attachHost(store, scope, existingInfo); return true; }
@SuppressWarnings("unchecked") @Override public DataStore initialize(Map<String, Object> dsInfos) { Long clusterId = (Long) dsInfos.get("clusterId"); Long podId = (Long) dsInfos.get("podId"); Long zoneId = (Long) dsInfos.get("zoneId"); String url = (String) dsInfos.get("url"); String providerName = (String) dsInfos.get("providerName"); if (clusterId != null && podId == null) { throw new InvalidParameterValueException("Cluster id requires pod id"); } PrimaryDataStoreParameters parameters = new PrimaryDataStoreParameters(); URI uri = null; try { uri = new URI(UriUtils.encodeURIComponent(url)); if (uri.getScheme() == null) { throw new InvalidParameterValueException( "scheme is null " + url + ", add nfs:// as a prefix"); } else if (uri.getScheme().equalsIgnoreCase("nfs")) { String uriHost = uri.getHost(); String uriPath = uri.getPath(); if (uriHost == null || uriPath == null || uriHost.trim().isEmpty() || uriPath.trim().isEmpty()) { throw new InvalidParameterValueException( "host or path is null, should be nfs://hostname/path"); } } else if (uri.getScheme().equalsIgnoreCase("sharedMountPoint")) { String uriPath = uri.getPath(); if (uriPath == null) { throw new InvalidParameterValueException( "host or path is null, should be sharedmountpoint://localhost/path"); } } else if (uri.getScheme().equalsIgnoreCase("rbd")) { String uriPath = uri.getPath(); if (uriPath == null) { throw new InvalidParameterValueException( "host or path is null, should be rbd://hostname/pool"); } } } catch (URISyntaxException e) { throw new InvalidParameterValueException(url + " is not a valid uri"); } String tags = (String) dsInfos.get("tags"); Map<String, String> details = (Map<String, String>) dsInfos.get("details"); parameters.setTags(tags); parameters.setDetails(details); String scheme = uri.getScheme(); String storageHost = uri.getHost(); String hostPath = uri.getPath(); Object localStorage = dsInfos.get("localStorage"); if (localStorage != null) { hostPath = hostPath.replaceFirst("/", ""); } String userInfo = uri.getUserInfo(); int port = uri.getPort(); if (s_logger.isDebugEnabled()) { s_logger.debug( "createPool Params @ scheme - " + scheme + " storageHost - " + storageHost + " hostPath - " + hostPath + " port - " + port); } if (scheme.equalsIgnoreCase("nfs")) { if (port == -1) { port = 2049; } parameters.setType(StoragePoolType.NetworkFilesystem); parameters.setHost(storageHost); parameters.setPort(port); parameters.setPath(hostPath); } else if (scheme.equalsIgnoreCase("file")) { if (port == -1) { port = 0; } parameters.setType(StoragePoolType.Filesystem); parameters.setHost("localhost"); parameters.setPort(0); parameters.setPath(hostPath); } else if (scheme.equalsIgnoreCase("sharedMountPoint")) { parameters.setType(StoragePoolType.SharedMountPoint); parameters.setHost(storageHost); parameters.setPort(0); parameters.setPath(hostPath); } else if (scheme.equalsIgnoreCase("clvm")) { parameters.setType(StoragePoolType.CLVM); parameters.setHost(storageHost); parameters.setPort(0); parameters.setPath(hostPath.replaceFirst("/", "")); } else if (scheme.equalsIgnoreCase("rbd")) { if (port == -1) { port = 6789; } parameters.setType(StoragePoolType.RBD); parameters.setHost(storageHost); parameters.setPort(port); parameters.setPath(hostPath.replaceFirst("/", "")); parameters.setUserInfo(userInfo); } else if (scheme.equalsIgnoreCase("PreSetup")) { parameters.setType(StoragePoolType.PreSetup); parameters.setHost(storageHost); parameters.setPort(0); parameters.setPath(hostPath); } else if (scheme.equalsIgnoreCase("iscsi")) { String[] tokens = hostPath.split("/"); int lun = NumbersUtil.parseInt(tokens[tokens.length - 1], -1); if (port == -1) { port = 3260; } if (lun != -1) { if (clusterId == null) { throw new IllegalArgumentException("IscsiLUN need to have clusters specified"); } hostPath.replaceFirst("/", ""); parameters.setType(StoragePoolType.IscsiLUN); parameters.setHost(storageHost); parameters.setPort(port); parameters.setPath(hostPath); } else { for (StoragePoolDiscoverer discoverer : _discoverers) { Map<? extends StoragePool, Map<String, String>> pools; try { pools = discoverer.find(zoneId, podId, uri, details); } catch (DiscoveryException e) { throw new IllegalArgumentException("Not enough information for discovery " + uri, e); } if (pools != null) { Map.Entry<? extends StoragePool, Map<String, String>> entry = pools.entrySet().iterator().next(); details = entry.getValue(); break; } } } } else if (scheme.equalsIgnoreCase("iso")) { if (port == -1) { port = 2049; } parameters.setType(StoragePoolType.ISO); parameters.setHost(storageHost); parameters.setPort(port); parameters.setPath(hostPath); } else if (scheme.equalsIgnoreCase("vmfs")) { parameters.setType(StoragePoolType.VMFS); parameters.setHost("VMFS datastore: " + hostPath); parameters.setPort(0); parameters.setPath(hostPath); } else if (scheme.equalsIgnoreCase("ocfs2")) { port = 7777; parameters.setType(StoragePoolType.OCFS2); parameters.setHost("clustered"); parameters.setPort(port); parameters.setPath(hostPath); } else { StoragePoolType type = Enum.valueOf(StoragePoolType.class, scheme); if (type != null) { parameters.setType(type); parameters.setHost(storageHost); parameters.setPort(0); parameters.setPath(hostPath); } else { s_logger.warn("Unable to figure out the scheme for URI: " + uri); throw new IllegalArgumentException("Unable to figure out the scheme for URI: " + uri); } } if (localStorage == null) { List<StoragePoolVO> pools = primaryDataStoreDao.listPoolByHostPath(storageHost, hostPath); if (!pools.isEmpty() && !scheme.equalsIgnoreCase("sharedmountpoint")) { Long oldPodId = pools.get(0).getPodId(); throw new CloudRuntimeException( "Storage pool " + uri + " already in use by another pod (id=" + oldPodId + ")"); } } Object existingUuid = dsInfos.get("uuid"); String uuid = null; if (existingUuid != null) { uuid = (String) existingUuid; } else if (scheme.equalsIgnoreCase("sharedmountpoint") || scheme.equalsIgnoreCase("clvm")) { uuid = UUID.randomUUID().toString(); } else if (scheme.equalsIgnoreCase("PreSetup")) { uuid = hostPath.replace("/", ""); } else { uuid = UUID.nameUUIDFromBytes(new String(storageHost + hostPath).getBytes()).toString(); } List<StoragePoolVO> spHandles = primaryDataStoreDao.findIfDuplicatePoolsExistByUUID(uuid); if ((spHandles != null) && (spHandles.size() > 0)) { if (s_logger.isDebugEnabled()) { s_logger.debug("Another active pool with the same uuid already exists"); } throw new CloudRuntimeException("Another active pool with the same uuid already exists"); } String poolName = (String) dsInfos.get("name"); parameters.setUuid(uuid); parameters.setZoneId(zoneId); parameters.setPodId(podId); parameters.setName(poolName); parameters.setClusterId(clusterId); parameters.setProviderName(providerName); return dataStoreHelper.createPrimaryDataStore(parameters); }