You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by mt...@apache.org on 2014/06/16 20:15:58 UTC
[2/2] git commit: updated refs/heads/master to 42d00ca
SolidFire (shared-access) Provider
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/42d00cae
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/42d00cae
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/42d00cae
Branch: refs/heads/master
Commit: 42d00cae584348f012d34418cbb0b8e6f020e12c
Parents: 520ff00
Author: Mike Tutkowski <mi...@solidfire.com>
Authored: Tue May 20 10:58:28 2014 -0600
Committer: Mike Tutkowski <mi...@solidfire.com>
Committed: Mon Jun 16 12:15:29 2014 -0600
----------------------------------------------------------------------
.../agent/api/CreateStoragePoolCommand.java | 25 +
.../agent/api/DeleteStoragePoolCommand.java | 47 +-
.../vmware/resource/VmwareResource.java | 36 +-
.../resource/VmwareStorageProcessor.java | 17 +-
.../resource/XenServerStorageProcessor.java | 147 -----
plugins/storage/volume/solidfire/pom.xml | 5 +
.../spring-storage-volume-solidfire-context.xml | 4 +-
.../SolidFireSharedPrimaryDataStoreDriver.java | 65 +++
.../driver/SolidfirePrimaryDataStoreDriver.java | 514 ++---------------
.../SolidFirePrimaryDataStoreLifeCycle.java | 137 +----
...olidFireSharedPrimaryDataStoreLifeCycle.java | 548 +++++++++++++++++++
.../provider/SolidFireSharedHostListener.java | 92 ++++
...SolidFireSharedPrimaryDataStoreProvider.java | 83 +++
.../storage/datastore/util/SolidFireUtil.java | 519 ++++++++++++++++--
.../com/cloud/hypervisor/vmware/mo/HostMO.java | 2 +-
15 files changed, 1427 insertions(+), 814 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/42d00cae/core/src/com/cloud/agent/api/CreateStoragePoolCommand.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/agent/api/CreateStoragePoolCommand.java b/core/src/com/cloud/agent/api/CreateStoragePoolCommand.java
index 891ea2c..f2f742a 100644
--- a/core/src/com/cloud/agent/api/CreateStoragePoolCommand.java
+++ b/core/src/com/cloud/agent/api/CreateStoragePoolCommand.java
@@ -18,7 +18,16 @@ package com.cloud.agent.api;
import com.cloud.storage.StoragePool;
+import java.util.Map;
+
public class CreateStoragePoolCommand extends ModifyStoragePoolCommand {
+ public static final String DATASTORE_NAME = "datastoreName";
+ public static final String IQN = "iqn";
+ public static final String STORAGE_HOST = "storageHost";
+ public static final String STORAGE_PORT = "storagePort";
+
+ private boolean _createDatastore;
+ private Map<String, String> _details;
public CreateStoragePoolCommand() {
}
@@ -26,4 +35,20 @@ public class CreateStoragePoolCommand extends ModifyStoragePoolCommand {
public CreateStoragePoolCommand(boolean add, StoragePool pool) {
super(add, pool);
}
+
+ public void setCreateDatastore(boolean createDatastore) {
+ _createDatastore = createDatastore;
+ }
+
+ public boolean getCreateDatastore() {
+ return _createDatastore;
+ }
+
+ public void setDetails(Map<String, String> details) {
+ _details = details;
+ }
+
+ public Map<String, String> getDetails() {
+ return _details;
+ }
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/42d00cae/core/src/com/cloud/agent/api/DeleteStoragePoolCommand.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/agent/api/DeleteStoragePoolCommand.java b/core/src/com/cloud/agent/api/DeleteStoragePoolCommand.java
index f80accb..dae5678 100644
--- a/core/src/com/cloud/agent/api/DeleteStoragePoolCommand.java
+++ b/core/src/com/cloud/agent/api/DeleteStoragePoolCommand.java
@@ -17,45 +17,68 @@
package com.cloud.agent.api;
import java.io.File;
+import java.util.Map;
import java.util.UUID;
import com.cloud.agent.api.to.StorageFilerTO;
import com.cloud.storage.StoragePool;
public class DeleteStoragePoolCommand extends Command {
+ public static final String DATASTORE_NAME = "datastoreName";
+ public static final String IQN = "iqn";
+ public static final String STORAGE_HOST = "storageHost";
+ public static final String STORAGE_PORT = "storagePort";
- StorageFilerTO pool;
public static final String LOCAL_PATH_PREFIX = "/mnt/";
- String localPath;
+
+ private StorageFilerTO _pool;
+ private String _localPath;
+ private boolean _removeDatastore;
+ private Map<String, String> _details;
public DeleteStoragePoolCommand() {
}
public DeleteStoragePoolCommand(StoragePool pool, String localPath) {
- this.pool = new StorageFilerTO(pool);
- this.localPath = localPath;
+ _pool = new StorageFilerTO(pool);
+ _localPath = localPath;
}
public DeleteStoragePoolCommand(StoragePool pool) {
this(pool, LOCAL_PATH_PREFIX + File.separator + UUID.nameUUIDFromBytes((pool.getHostAddress() + pool.getPath()).getBytes()));
}
+ public void setPool(StoragePool pool) {
+ _pool = new StorageFilerTO(pool);
+ }
+
public StorageFilerTO getPool() {
- return pool;
+ return _pool;
}
- public void setPool(StoragePool pool) {
- this.pool = new StorageFilerTO(pool);
+ public String getLocalPath() {
+ return _localPath;
}
- @Override
- public boolean executeInSequence() {
- return false;
+ public void setRemoveDatastore(boolean removeDatastore) {
+ _removeDatastore = removeDatastore;
}
- public String getLocalPath() {
- return localPath;
+ public boolean getRemoveDatastore() {
+ return _removeDatastore;
+ }
+
+ public void setDetails(Map<String, String> details) {
+ _details = details;
+ }
+
+ public Map<String, String> getDetails() {
+ return _details;
}
+ @Override
+ public boolean executeInSequence() {
+ return false;
+ }
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/42d00cae/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java
index 52421fa..8dc2784 100755
--- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java
+++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java
@@ -3177,6 +3177,18 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
}
protected Answer execute(CreateStoragePoolCommand cmd) {
+ if (cmd.getCreateDatastore()) {
+ try {
+ VmwareContext context = getServiceContext();
+
+ _storageProcessor.prepareManagedDatastore(context, getHyperHost(context),
+ cmd.getDetails().get(CreateStoragePoolCommand.DATASTORE_NAME), cmd.getDetails().get(CreateStoragePoolCommand.IQN),
+ cmd.getDetails().get(CreateStoragePoolCommand.STORAGE_HOST), Integer.parseInt(cmd.getDetails().get(CreateStoragePoolCommand.STORAGE_PORT)));
+ } catch (Exception ex) {
+ return new Answer(cmd, false, "Issue creating datastore");
+ }
+ }
+
return new Answer(cmd, true, "success");
}
@@ -3223,22 +3235,32 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
s_logger.info("Executing resource DeleteStoragePoolCommand: " + _gson.toJson(cmd));
}
- StorageFilerTO pool = cmd.getPool();
try {
- // We will leave datastore cleanup management to vCenter. Since for cluster VMFS datastore, it will always
- // be mounted by vCenter.
+ if (cmd.getRemoveDatastore()) {
+ _storageProcessor.handleDatastoreAndVmdkDetach(cmd.getDetails().get(DeleteStoragePoolCommand.DATASTORE_NAME), cmd.getDetails().get(DeleteStoragePoolCommand.IQN),
+ cmd.getDetails().get(DeleteStoragePoolCommand.STORAGE_HOST), Integer.parseInt(cmd.getDetails().get(DeleteStoragePoolCommand.STORAGE_PORT)));
- // VmwareHypervisorHost hyperHost = this.getHyperHost(getServiceContext());
- // hyperHost.unmountDatastore(pool.getUuid());
- Answer answer = new Answer(cmd, true, "success");
- return answer;
+ return new Answer(cmd, true, "success");
+ }
+ else {
+ // We will leave datastore cleanup management to vCenter. Since for cluster VMFS datastore, it will always
+ // be mounted by vCenter.
+
+ // VmwareHypervisorHost hyperHost = this.getHyperHost(getServiceContext());
+ // hyperHost.unmountDatastore(pool.getUuid());
+
+ return new Answer(cmd, true, "success");
+ }
} catch (Throwable e) {
if (e instanceof RemoteException) {
s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
+
invalidateServiceContext();
}
+ StorageFilerTO pool = cmd.getPool();
String msg = "DeleteStoragePoolCommand (pool: " + pool.getHost() + ", path: " + pool.getPath() + ") failed due to " + VmwareHelper.getExceptionMessage(e);
+
return new Answer(cmd, false, msg);
}
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/42d00cae/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java
index 7bc5bd3..77ee4ce 100644
--- a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java
+++ b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java
@@ -1688,6 +1688,11 @@ public class VmwareStorageProcessor implements StorageProcessor {
}
}
+ public ManagedObjectReference prepareManagedDatastore(VmwareContext context, VmwareHypervisorHost hyperHost, String datastoreName,
+ String iScsiName, String storageHost, int storagePort) throws Exception {
+ return getVmfsDatastore(context, hyperHost, datastoreName, storageHost, storagePort, trimIqn(iScsiName), null, null, null, null);
+ }
+
private ManagedObjectReference prepareManagedDatastore(VmwareContext context, VmwareHypervisorHost hyperHost, String iScsiName,
String storageHost, int storagePort, String chapInitiatorUsername, String chapInitiatorSecret,
String chapTargetUsername, String chapTargetSecret) throws Exception {
@@ -1800,8 +1805,8 @@ public class VmwareStorageProcessor implements StorageProcessor {
return null;
}
- private void removeVmfsDatastore(VmwareHypervisorHost hyperHost, String volumeUuid, String storageIpAddress, int storagePortNumber, String iqn) throws Exception {
- // hyperHost.unmountDatastore(volumeUuid);
+ private void removeVmfsDatastore(VmwareHypervisorHost hyperHost, String datastoreName, String storageIpAddress, int storagePortNumber, String iqn) throws Exception {
+ // hyperHost.unmountDatastore(datastoreName);
VmwareContext context = hostService.getServiceContext(null);
ManagedObjectReference morCluster = hyperHost.getHyperHostCluster();
@@ -1990,11 +1995,15 @@ public class VmwareStorageProcessor implements StorageProcessor {
return morDs;
}
- private void handleDatastoreAndVmdkDetach(String iqn, String storageHost, int storagePort) throws Exception {
+ public void handleDatastoreAndVmdkDetach(String datastoreName, String iqn, String storageHost, int storagePort) throws Exception {
VmwareContext context = hostService.getServiceContext(null);
VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, null);
- removeVmfsDatastore(hyperHost, VmwareResource.getDatastoreName(iqn), storageHost, storagePort, trimIqn(iqn));
+ removeVmfsDatastore(hyperHost, datastoreName, storageHost, storagePort, trimIqn(iqn));
+ }
+
+ private void handleDatastoreAndVmdkDetach(String iqn, String storageHost, int storagePort) throws Exception {
+ handleDatastoreAndVmdkDetach(VmwareResource.getDatastoreName(iqn), iqn, storageHost, storagePort);
}
private void removeManagedTargetsFromCluster(List<String> iqns) throws Exception {
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/42d00cae/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServerStorageProcessor.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServerStorageProcessor.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServerStorageProcessor.java
index 9c86fbe..e96ebf4 100644
--- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServerStorageProcessor.java
+++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServerStorageProcessor.java
@@ -53,7 +53,6 @@ import org.apache.log4j.Logger;
import org.apache.xmlrpc.XmlRpcException;
import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.CreateStoragePoolCommand;
import com.cloud.agent.api.to.DataObjectType;
import com.cloud.agent.api.to.DataStoreTO;
import com.cloud.agent.api.to.DataTO;
@@ -66,7 +65,6 @@ import com.cloud.exception.InternalErrorException;
import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase.SRType;
import com.cloud.storage.DataStoreRole;
import com.cloud.storage.Storage.ImageFormat;
-import com.cloud.storage.Storage.StoragePoolType;
import com.cloud.storage.resource.StorageProcessor;
import com.cloud.utils.S3Utils;
import com.cloud.utils.exception.CloudRuntimeException;
@@ -76,7 +74,6 @@ import com.cloud.utils.storage.encoding.Decoder;
import com.xensource.xenapi.Connection;
import com.xensource.xenapi.Host;
import com.xensource.xenapi.PBD;
-import com.xensource.xenapi.Pool;
import com.xensource.xenapi.SR;
import com.xensource.xenapi.Types;
import com.xensource.xenapi.Types.BadServerResponse;
@@ -572,150 +569,6 @@ public class XenServerStorageProcessor implements StorageProcessor {
}
}
- protected SR getIscsiSR(Connection conn, StorageFilerTO pool) {
- synchronized (pool.getUuid().intern()) {
- Map<String, String> deviceConfig = new HashMap<String, String>();
- try {
- String target = pool.getHost();
- String path = pool.getPath();
- if (path.endsWith("/")) {
- path = path.substring(0, path.length() - 1);
- }
-
- String tmp[] = path.split("/");
- if (tmp.length != 3) {
- String msg = "Wrong iscsi path " + pool.getPath() + " it should be /targetIQN/LUN";
- s_logger.warn(msg);
- throw new CloudRuntimeException(msg);
- }
- String targetiqn = tmp[1].trim();
- String lunid = tmp[2].trim();
- String scsiid = "";
-
- Set<SR> srs = SR.getByNameLabel(conn, pool.getUuid());
- for (SR sr : srs) {
- if (!SRType.LVMOISCSI.equals(sr.getType(conn))) {
- continue;
- }
- Set<PBD> pbds = sr.getPBDs(conn);
- if (pbds.isEmpty()) {
- continue;
- }
- PBD pbd = pbds.iterator().next();
- Map<String, String> dc = pbd.getDeviceConfig(conn);
- if (dc == null) {
- continue;
- }
- if (dc.get("target") == null) {
- continue;
- }
- if (dc.get("targetIQN") == null) {
- continue;
- }
- if (dc.get("lunid") == null) {
- continue;
- }
- if (target.equals(dc.get("target")) && targetiqn.equals(dc.get("targetIQN")) && lunid.equals(dc.get("lunid"))) {
- throw new CloudRuntimeException("There is a SR using the same configuration target:" + dc.get("target") + ", targetIQN:" + dc.get("targetIQN") +
- ", lunid:" + dc.get("lunid") + " for pool " + pool.getUuid() + "on host:" + hypervisorResource.getHost().uuid);
- }
- }
- deviceConfig.put("target", target);
- deviceConfig.put("targetIQN", targetiqn);
-
- Host host = Host.getByUuid(conn, hypervisorResource.getHost().uuid);
- Map<String, String> smConfig = new HashMap<String, String>();
- String type = SRType.LVMOISCSI.toString();
- String poolId = Long.toString(pool.getId());
- SR sr = null;
- try {
- sr = SR.create(conn, host, deviceConfig, new Long(0), pool.getUuid(), poolId, type, "user", true, smConfig);
- } catch (XenAPIException e) {
- String errmsg = e.toString();
- if (errmsg.contains("SR_BACKEND_FAILURE_107")) {
- String lun[] = errmsg.split("<LUN>");
- boolean found = false;
- for (int i = 1; i < lun.length; i++) {
- int blunindex = lun[i].indexOf("<LUNid>") + 7;
- int elunindex = lun[i].indexOf("</LUNid>");
- String ilun = lun[i].substring(blunindex, elunindex);
- ilun = ilun.trim();
- if (ilun.equals(lunid)) {
- int bscsiindex = lun[i].indexOf("<SCSIid>") + 8;
- int escsiindex = lun[i].indexOf("</SCSIid>");
- scsiid = lun[i].substring(bscsiindex, escsiindex);
- scsiid = scsiid.trim();
- found = true;
- break;
- }
- }
- if (!found) {
- String msg = "can not find LUN " + lunid + " in " + errmsg;
- s_logger.warn(msg);
- throw new CloudRuntimeException(msg);
- }
- } else {
- String msg = "Unable to create Iscsi SR " + deviceConfig + " due to " + e.toString();
- s_logger.warn(msg, e);
- throw new CloudRuntimeException(msg, e);
- }
- }
- deviceConfig.put("SCSIid", scsiid);
-
- String result = SR.probe(conn, host, deviceConfig, type, smConfig);
- String pooluuid = null;
- if (result.indexOf("<UUID>") != -1) {
- pooluuid = result.substring(result.indexOf("<UUID>") + 6, result.indexOf("</UUID>")).trim();
- }
- if (pooluuid == null || pooluuid.length() != 36) {
- sr = SR.create(conn, host, deviceConfig, new Long(0), pool.getUuid(), poolId, type, "user", true, smConfig);
- } else {
- sr = SR.introduce(conn, pooluuid, pool.getUuid(), poolId, type, "user", true, smConfig);
- Pool.Record pRec = XenServerConnectionPool.getPoolRecord(conn);
- PBD.Record rec = new PBD.Record();
- rec.deviceConfig = deviceConfig;
- rec.host = pRec.master;
- rec.SR = sr;
- PBD pbd = PBD.create(conn, rec);
- pbd.plug(conn);
- }
- sr.scan(conn);
- return sr;
- } catch (XenAPIException e) {
- String msg = "Unable to create Iscsi SR " + deviceConfig + " due to " + e.toString();
- s_logger.warn(msg, e);
- throw new CloudRuntimeException(msg, e);
- } catch (Exception e) {
- String msg = "Unable to create Iscsi SR " + deviceConfig + " due to " + e.getMessage();
- s_logger.warn(msg, e);
- throw new CloudRuntimeException(msg, e);
- }
- }
- }
-
- protected Answer execute(CreateStoragePoolCommand cmd) {
- Connection conn = hypervisorResource.getConnection();
- StorageFilerTO pool = cmd.getPool();
- try {
- if (pool.getType() == StoragePoolType.NetworkFilesystem) {
- getNfsSR(conn, pool);
- } else if (pool.getType() == StoragePoolType.IscsiLUN) {
- getIscsiSR(conn, pool);
- } else if (pool.getType() == StoragePoolType.PreSetup) {
- } else {
- return new Answer(cmd, false, "The pool type: " + pool.getType().name() + " is not supported.");
- }
- return new Answer(cmd, true, "success");
- } catch (Exception e) {
- String msg =
- "Catch Exception " + e.getClass().getName() + ", create StoragePool failed due to " + e.toString() + " on host:" +
- hypervisorResource.getHost().uuid + " pool: " + pool.getHost() + pool.getPath();
- s_logger.warn(msg, e);
- return new Answer(cmd, false, msg);
- }
-
- }
-
protected Answer directDownloadHttpTemplate(CopyCommand cmd, DecodedDataObject srcObj, DecodedDataObject destObj) {
Connection conn = hypervisorResource.getConnection();
SR poolsr = null;
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/42d00cae/plugins/storage/volume/solidfire/pom.xml
----------------------------------------------------------------------
diff --git a/plugins/storage/volume/solidfire/pom.xml b/plugins/storage/volume/solidfire/pom.xml
index c3cd11f..1803925 100644
--- a/plugins/storage/volume/solidfire/pom.xml
+++ b/plugins/storage/volume/solidfire/pom.xml
@@ -22,6 +22,11 @@
<dependencies>
<dependency>
<groupId>org.apache.cloudstack</groupId>
+ <artifactId>cloud-plugin-storage-volume-default</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-engine-storage-volume</artifactId>
<version>${project.version}</version>
</dependency>
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/42d00cae/plugins/storage/volume/solidfire/resources/META-INF/cloudstack/storage-volume-solidfire/spring-storage-volume-solidfire-context.xml
----------------------------------------------------------------------
diff --git a/plugins/storage/volume/solidfire/resources/META-INF/cloudstack/storage-volume-solidfire/spring-storage-volume-solidfire-context.xml b/plugins/storage/volume/solidfire/resources/META-INF/cloudstack/storage-volume-solidfire/spring-storage-volume-solidfire-context.xml
index a83e3ca..df32f1e 100644
--- a/plugins/storage/volume/solidfire/resources/META-INF/cloudstack/storage-volume-solidfire/spring-storage-volume-solidfire-context.xml
+++ b/plugins/storage/volume/solidfire/resources/META-INF/cloudstack/storage-volume-solidfire/spring-storage-volume-solidfire-context.xml
@@ -29,5 +29,7 @@
<bean id="solidFireDataStoreProvider"
class="org.apache.cloudstack.storage.datastore.provider.SolidfirePrimaryDataStoreProvider" />
-
+ <bean id="solidFireSharedDataStoreProvider"
+ class="org.apache.cloudstack.storage.datastore.provider.SolidFireSharedPrimaryDataStoreProvider" />
+
</beans>
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/42d00cae/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidFireSharedPrimaryDataStoreDriver.java
----------------------------------------------------------------------
diff --git a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidFireSharedPrimaryDataStoreDriver.java b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidFireSharedPrimaryDataStoreDriver.java
new file mode 100644
index 0000000..a16408e
--- /dev/null
+++ b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidFireSharedPrimaryDataStoreDriver.java
@@ -0,0 +1,65 @@
+// 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.datastore.driver;
+
+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.DataStore;
+import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
+import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
+import org.apache.cloudstack.storage.command.CommandResult;
+
+import com.cloud.agent.api.to.DataStoreTO;
+import com.cloud.agent.api.to.DataTO;
+
+public class SolidFireSharedPrimaryDataStoreDriver extends CloudStackPrimaryDataStoreDriverImpl {
+ @Override
+ public DataTO getTO(DataObject data) {
+ return null;
+ }
+
+ @Override
+ public DataStoreTO getStoreTO(DataStore store) {
+ return null;
+ }
+
+ @Override
+ public boolean canCopy(DataObject srcData, DataObject destData) {
+ return false;
+ }
+
+ @Override
+ public void copyAsync(DataObject srcdata, DataObject destData, AsyncCompletionCallback<CopyCommandResult> callback) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void resize(DataObject data, AsyncCompletionCallback<CreateCmdResult> callback) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void takeSnapshot(SnapshotInfo snapshot, AsyncCompletionCallback<CreateCmdResult> callback) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void revertSnapshot(SnapshotInfo snapshot, AsyncCompletionCallback<CommandResult> callback) {
+ throw new UnsupportedOperationException();
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/42d00cae/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java
----------------------------------------------------------------------
diff --git a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java
index 014413d..766e1f8 100644
--- a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java
+++ b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java
@@ -17,15 +17,11 @@
package org.apache.cloudstack.storage.datastore.driver;
import java.text.NumberFormat;
-import java.util.ArrayList;
import java.util.List;
import java.util.Map;
-import java.util.UUID;
import javax.inject.Inject;
-import org.apache.commons.lang.StringUtils;
-
import org.apache.cloudstack.engine.subsystem.api.storage.ChapInfo;
import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult;
import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult;
@@ -57,23 +53,20 @@ import com.cloud.storage.StoragePool;
import com.cloud.storage.Volume;
import com.cloud.storage.VolumeVO;
import com.cloud.storage.dao.VolumeDao;
-import com.cloud.storage.dao.VolumeDetailsDao;
import com.cloud.user.AccountDetailVO;
import com.cloud.user.AccountDetailsDao;
import com.cloud.user.AccountVO;
import com.cloud.user.dao.AccountDao;
-import com.cloud.utils.exception.CloudRuntimeException;
public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver {
- @Inject private PrimaryDataStoreDao _storagePoolDao;
- @Inject private StoragePoolDetailsDao _storagePoolDetailsDao;
- @Inject private VolumeDao _volumeDao;
- @Inject private VolumeDetailsDao _volumeDetailsDao;
- @Inject private DataCenterDao _zoneDao;
@Inject private AccountDao _accountDao;
@Inject private AccountDetailsDao _accountDetailsDao;
@Inject private ClusterDetailsDao _clusterDetailsDao;
+ @Inject private DataCenterDao _zoneDao;
@Inject private HostDao _hostDao;
+ @Inject private PrimaryDataStoreDao _storagePoolDao;
+ @Inject private StoragePoolDetailsDao _storagePoolDetailsDao;
+ @Inject private VolumeDao _volumeDao;
@Override
public Map<String, String> getCapabilities() {
@@ -90,131 +83,10 @@ public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver {
return null;
}
- private static class SolidFireConnection {
- private final String _managementVip;
- private final int _managementPort;
- private final String _clusterAdminUsername;
- private final String _clusterAdminPassword;
-
- public SolidFireConnection(String managementVip, int managementPort, String clusterAdminUsername, String clusterAdminPassword) {
- _managementVip = managementVip;
- _managementPort = managementPort;
- _clusterAdminUsername = clusterAdminUsername;
- _clusterAdminPassword = clusterAdminPassword;
- }
-
- public String getManagementVip() {
- return _managementVip;
- }
-
- public int getManagementPort() {
- return _managementPort;
- }
-
- public String getClusterAdminUsername() {
- return _clusterAdminUsername;
- }
-
- public String getClusterAdminPassword() {
- return _clusterAdminPassword;
- }
- }
-
- private SolidFireConnection getSolidFireConnection(long storagePoolId) {
- StoragePoolDetailVO storagePoolDetail = _storagePoolDetailsDao.findDetail(storagePoolId, SolidFireUtil.MANAGEMENT_VIP);
-
- String mVip = storagePoolDetail.getValue();
-
- storagePoolDetail = _storagePoolDetailsDao.findDetail(storagePoolId, SolidFireUtil.MANAGEMENT_PORT);
-
- int mPort = Integer.parseInt(storagePoolDetail.getValue());
-
- storagePoolDetail = _storagePoolDetailsDao.findDetail(storagePoolId, SolidFireUtil.CLUSTER_ADMIN_USERNAME);
-
- String clusterAdminUsername = storagePoolDetail.getValue();
-
- storagePoolDetail = _storagePoolDetailsDao.findDetail(storagePoolId, SolidFireUtil.CLUSTER_ADMIN_PASSWORD);
-
- String clusterAdminPassword = storagePoolDetail.getValue();
-
- return new SolidFireConnection(mVip, mPort, clusterAdminUsername, clusterAdminPassword);
- }
-
- private SolidFireUtil.SolidFireAccount createSolidFireAccount(String sfAccountName, SolidFireConnection sfConnection) {
- String mVip = sfConnection.getManagementVip();
- int mPort = sfConnection.getManagementPort();
- String clusterAdminUsername = sfConnection.getClusterAdminUsername();
- String clusterAdminPassword = sfConnection.getClusterAdminPassword();
-
- long accountNumber = SolidFireUtil.createSolidFireAccount(mVip, mPort, clusterAdminUsername, clusterAdminPassword, sfAccountName);
-
- return SolidFireUtil.getSolidFireAccountById(mVip, mPort, clusterAdminUsername, clusterAdminPassword, accountNumber);
- }
-
- private void updateCsDbWithAccountInfo(long csAccountId, SolidFireUtil.SolidFireAccount sfAccount) {
- AccountDetailVO accountDetail = new AccountDetailVO(csAccountId,
- SolidFireUtil.ACCOUNT_ID,
- String.valueOf(sfAccount.getId()));
-
- _accountDetailsDao.persist(accountDetail);
-
- accountDetail = new AccountDetailVO(csAccountId,
- SolidFireUtil.CHAP_INITIATOR_USERNAME,
- String.valueOf(sfAccount.getName()));
-
- _accountDetailsDao.persist(accountDetail);
-
- accountDetail = new AccountDetailVO(csAccountId,
- SolidFireUtil.CHAP_INITIATOR_SECRET,
- String.valueOf(sfAccount.getInitiatorSecret()));
-
- _accountDetailsDao.persist(accountDetail);
-
- accountDetail = new AccountDetailVO(csAccountId,
- SolidFireUtil.CHAP_TARGET_USERNAME,
- sfAccount.getName());
-
- _accountDetailsDao.persist(accountDetail);
-
- accountDetail = new AccountDetailVO(csAccountId,
- SolidFireUtil.CHAP_TARGET_SECRET,
- sfAccount.getTargetSecret());
-
- _accountDetailsDao.persist(accountDetail);
- }
-
- private class ChapInfoImpl implements ChapInfo {
- private final String _initiatorUsername;
- private final String _initiatorSecret;
- private final String _targetUsername;
- private final String _targetSecret;
-
- public ChapInfoImpl(String initiatorUsername, String initiatorSecret, String targetUsername, String targetSecret) {
- _initiatorUsername = initiatorUsername;
- _initiatorSecret = initiatorSecret;
- _targetUsername = targetUsername;
- _targetSecret = targetSecret;
- }
-
- @Override
- public String getInitiatorUsername() {
- return _initiatorUsername;
- }
-
- @Override
- public String getInitiatorSecret() {
- return _initiatorSecret;
- }
-
- @Override
- public String getTargetUsername() {
- return _targetUsername;
- }
+ private SolidFireUtil.SolidFireAccount createSolidFireAccount(SolidFireUtil.SolidFireConnection sfConnection, String sfAccountName) {
+ long accountNumber = SolidFireUtil.createSolidFireAccount(sfConnection, sfAccountName);
- @Override
- public String getTargetSecret() {
- return _targetSecret;
- }
+ return SolidFireUtil.getSolidFireAccountById(sfConnection, accountNumber);
}
@Override
@@ -222,38 +94,13 @@ public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver {
return null;
}
- /*
- @Override
- public ChapInfo getChapInfo(VolumeInfo volumeInfo) {
- long accountId = volumeInfo.getAccountId();
-
- AccountDetailVO accountDetail = _accountDetailsDao.findDetail(accountId, SolidFireUtil.CHAP_INITIATOR_USERNAME);
-
- String chapInitiatorUsername = accountDetail.getValue();
-
- accountDetail = _accountDetailsDao.findDetail(accountId, SolidFireUtil.CHAP_INITIATOR_SECRET);
-
- String chapInitiatorSecret = accountDetail.getValue();
-
- accountDetail = _accountDetailsDao.findDetail(accountId, SolidFireUtil.CHAP_TARGET_USERNAME);
-
- String chapTargetUsername = accountDetail.getValue();
-
- accountDetail = _accountDetailsDao.findDetail(accountId, SolidFireUtil.CHAP_TARGET_SECRET);
-
- String chapTargetSecret = accountDetail.getValue();
-
- return new ChapInfoImpl(chapInitiatorUsername, chapInitiatorSecret, chapTargetUsername, chapTargetSecret);
- }
- */
-
// get the VAG associated with volumeInfo's cluster, if any (ListVolumeAccessGroups)
// if the VAG exists
// update the VAG to contain all IQNs of the hosts (ModifyVolumeAccessGroup)
// if the ID of volumeInfo in not in the VAG, add it (ModifyVolumeAccessGroup)
// if the VAG doesn't exist, create it with the IQNs of the hosts and the ID of volumeInfo (CreateVolumeAccessGroup)
@Override
- public boolean connectVolumeToHost(VolumeInfo volumeInfo, Host host, DataStore dataStore)
+ public synchronized boolean connectVolumeToHost(VolumeInfo volumeInfo, Host host, DataStore dataStore)
{
if (volumeInfo == null || host == null || dataStore == null) {
return false;
@@ -263,111 +110,38 @@ public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver {
long clusterId = host.getClusterId();
long storagePoolId = dataStore.getId();
- ClusterDetailsVO clusterDetail = _clusterDetailsDao.findDetail(clusterId, getVagKey(storagePoolId));
+ ClusterDetailsVO clusterDetail = _clusterDetailsDao.findDetail(clusterId, SolidFireUtil.getVagKey(storagePoolId));
String vagId = clusterDetail != null ? clusterDetail.getValue() : null;
List<HostVO> hosts = _hostDao.findByClusterId(clusterId);
- if (!hostsSupport_iScsi(hosts)) {
+ if (!SolidFireUtil.hostsSupport_iScsi(hosts)) {
return false;
}
- SolidFireConnection sfConnection = getSolidFireConnection(storagePoolId);
+ SolidFireUtil.SolidFireConnection sfConnection = SolidFireUtil.getSolidFireConnection(storagePoolId, _storagePoolDetailsDao);
if (vagId != null) {
- SolidFireUtil.SolidFireVag sfVag = SolidFireUtil.getSolidFireVag(sfConnection.getManagementVip(), sfConnection.getManagementPort(),
- sfConnection.getClusterAdminUsername(), sfConnection.getClusterAdminPassword(), Long.parseLong(vagId));
+ SolidFireUtil.SolidFireVag sfVag = SolidFireUtil.getSolidFireVag(sfConnection, Long.parseLong(vagId));
- String[] hostIqns = getNewHostIqns(sfVag.getInitiators(), getIqnsFromHosts(hosts));
- long[] volumeIds = getNewVolumeIds(sfVag.getVolumeIds(), sfVolumeId, true);
+ String[] hostIqns = SolidFireUtil.getNewHostIqns(sfVag.getInitiators(), SolidFireUtil.getIqnsFromHosts(hosts));
+ long[] volumeIds = SolidFireUtil.getNewVolumeIds(sfVag.getVolumeIds(), sfVolumeId, true);
- SolidFireUtil.modifySolidFireVag(sfConnection.getManagementVip(), sfConnection.getManagementPort(),
- sfConnection.getClusterAdminUsername(), sfConnection.getClusterAdminPassword(), sfVag.getId(),
- hostIqns, volumeIds);
+ SolidFireUtil.modifySolidFireVag(sfConnection, sfVag.getId(), hostIqns, volumeIds);
}
else {
- long lVagId;
-
- try {
- lVagId = SolidFireUtil.createSolidFireVag(sfConnection.getManagementVip(), sfConnection.getManagementPort(),
- sfConnection.getClusterAdminUsername(), sfConnection.getClusterAdminPassword(), "CloudStack-" + UUID.randomUUID().toString(),
- getIqnsFromHosts(hosts), new long[] { sfVolumeId });
- }
- catch (Exception ex) {
- String iqnInVagAlready = "Exceeded maximum number of Volume Access Groups per initiator";
-
- if (!ex.getMessage().contains(iqnInVagAlready)) {
- throw new CloudRuntimeException(ex.getMessage());
- }
-
- // getCompatibleVag throws an exception if an existing VAG can't be located
- SolidFireUtil.SolidFireVag sfVag = getCompatibleVag(hosts, sfConnection);
-
- long[] volumeIds = getNewVolumeIds(sfVag.getVolumeIds(), sfVolumeId, true);
-
- SolidFireUtil.modifySolidFireVag(sfConnection.getManagementVip(), sfConnection.getManagementPort(),
- sfConnection.getClusterAdminUsername(), sfConnection.getClusterAdminPassword(), sfVag.getId(),
- sfVag.getInitiators(), volumeIds);
-
- lVagId = sfVag.getId();
- }
-
- clusterDetail = new ClusterDetailsVO(clusterId, getVagKey(storagePoolId), String.valueOf(lVagId));
-
- _clusterDetailsDao.persist(clusterDetail);
+ SolidFireUtil.placeVolumeInVolumeAccessGroup(sfConnection, sfVolumeId, storagePoolId, hosts, _clusterDetailsDao);
}
return true;
}
- // this method takes in a collection of hosts and tries to find an existing VAG that has all three of them in it
- // if successful, the VAG is returned; else, a CloudRuntimeException is thrown and this issue should be corrected by an admin
- private SolidFireUtil.SolidFireVag getCompatibleVag(List<HostVO> hosts, SolidFireConnection sfConnection) {
- List<SolidFireUtil.SolidFireVag> sfVags = SolidFireUtil.getAllSolidFireVags(sfConnection.getManagementVip(), sfConnection.getManagementPort(),
- sfConnection.getClusterAdminUsername(), sfConnection.getClusterAdminPassword());
-
- if (sfVags != null) {
- List<String> hostIqns = new ArrayList<String>();
-
- // where the method we're in is called, hosts should not be null
- for (HostVO host : hosts) {
- // where the method we're in is called, host.getStorageUrl() should not be null (it actually should start with "iqn")
- hostIqns.add(host.getStorageUrl().toLowerCase());
- }
-
- for (SolidFireUtil.SolidFireVag sfVag : sfVags) {
- List<String> lstInitiators = getStringArrayAsLowerCaseStringList(sfVag.getInitiators());
-
- // lstInitiators should not be returned from getStringArrayAsLowerCaseStringList as null
- if (lstInitiators.containsAll(hostIqns)) {
- return sfVag;
- }
- }
- }
-
- throw new CloudRuntimeException("Unable to locate the appropriate SolidFire Volume Access Group");
- }
-
- private List<String> getStringArrayAsLowerCaseStringList(String[] aString) {
- List<String> lstLowerCaseString = new ArrayList<String>();
-
- if (aString != null) {
- for (String str : aString) {
- if (str != null) {
- lstLowerCaseString.add(str.toLowerCase());
- }
- }
- }
-
- return lstLowerCaseString;
- }
-
// get the VAG associated with volumeInfo's cluster, if any (ListVolumeAccessGroups) // might not exist if using CHAP
// if the VAG exists
// remove the ID of volumeInfo from the VAG (ModifyVolumeAccessGroup)
@Override
- public void disconnectVolumeFromHost(VolumeInfo volumeInfo, Host host, DataStore dataStore)
+ public synchronized void disconnectVolumeFromHost(VolumeInfo volumeInfo, Host host, DataStore dataStore)
{
if (volumeInfo == null || host == null || dataStore == null) {
return;
@@ -377,133 +151,22 @@ public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver {
long clusterId = host.getClusterId();
long storagePoolId = dataStore.getId();
- ClusterDetailsVO clusterDetail = _clusterDetailsDao.findDetail(clusterId, getVagKey(storagePoolId));
+ ClusterDetailsVO clusterDetail = _clusterDetailsDao.findDetail(clusterId, SolidFireUtil.getVagKey(storagePoolId));
String vagId = clusterDetail != null ? clusterDetail.getValue() : null;
if (vagId != null) {
List<HostVO> hosts = _hostDao.findByClusterId(clusterId);
- SolidFireConnection sfConnection = getSolidFireConnection(storagePoolId);
-
- SolidFireUtil.SolidFireVag sfVag = SolidFireUtil.getSolidFireVag(sfConnection.getManagementVip(), sfConnection.getManagementPort(),
- sfConnection.getClusterAdminUsername(), sfConnection.getClusterAdminPassword(), Long.parseLong(vagId));
-
- String[] hostIqns = getNewHostIqns(sfVag.getInitiators(), getIqnsFromHosts(hosts));
- long[] volumeIds = getNewVolumeIds(sfVag.getVolumeIds(), sfVolumeId, false);
+ SolidFireUtil.SolidFireConnection sfConnection = SolidFireUtil.getSolidFireConnection(storagePoolId, _storagePoolDetailsDao);
- SolidFireUtil.modifySolidFireVag(sfConnection.getManagementVip(), sfConnection.getManagementPort(),
- sfConnection.getClusterAdminUsername(), sfConnection.getClusterAdminPassword(), sfVag.getId(),
- hostIqns, volumeIds);
- }
- }
+ SolidFireUtil.SolidFireVag sfVag = SolidFireUtil.getSolidFireVag(sfConnection, Long.parseLong(vagId));
- private boolean hostsSupport_iScsi(List<HostVO> hosts) {
- if (hosts == null || hosts.size() == 0) {
- return false;
- }
+ String[] hostIqns = SolidFireUtil.getNewHostIqns(sfVag.getInitiators(), SolidFireUtil.getIqnsFromHosts(hosts));
+ long[] volumeIds = SolidFireUtil.getNewVolumeIds(sfVag.getVolumeIds(), sfVolumeId, false);
- for (Host host : hosts) {
- if (host == null || host.getStorageUrl() == null || host.getStorageUrl().trim().length() == 0 || !host.getStorageUrl().startsWith("iqn")) {
- return false;
- }
+ SolidFireUtil.modifySolidFireVag(sfConnection, sfVag.getId(), hostIqns, volumeIds);
}
-
- return true;
- }
-
- private String[] getNewHostIqns(String[] currentIqns, String[] newIqns) {
- List<String> lstIqns = new ArrayList<String>();
-
- if (currentIqns != null) {
- for (String currentIqn : currentIqns) {
- lstIqns.add(currentIqn);
- }
- }
-
- if (newIqns != null) {
- for (String newIqn : newIqns) {
- if (!lstIqns.contains(newIqn)) {
- lstIqns.add(newIqn);
- }
- }
- }
-
- return lstIqns.toArray(new String[0]);
- }
-
- private long[] getNewVolumeIds(long[] volumeIds, long volumeIdToAddOrRemove, boolean add) {
- if (add) {
- return getNewVolumeIdsAdd(volumeIds, volumeIdToAddOrRemove);
- }
-
- return getNewVolumeIdsRemove(volumeIds, volumeIdToAddOrRemove);
- }
-
- private long[] getNewVolumeIdsAdd(long[] volumeIds, long volumeIdToAdd) {
- List<Long> lstVolumeIds = new ArrayList<Long>();
-
- if (volumeIds != null) {
- for (long volumeId : volumeIds) {
- lstVolumeIds.add(volumeId);
- }
- }
-
- if (lstVolumeIds.contains(volumeIdToAdd)) {
- return volumeIds;
- }
-
- lstVolumeIds.add(volumeIdToAdd);
-
- return convertArray(lstVolumeIds);
- }
-
- private long[] getNewVolumeIdsRemove(long[] volumeIds, long volumeIdToRemove) {
- List<Long> lstVolumeIds = new ArrayList<Long>();
-
- if (volumeIds != null) {
- for (long volumeId : volumeIds) {
- lstVolumeIds.add(volumeId);
- }
- }
-
- lstVolumeIds.remove(volumeIdToRemove);
-
- return convertArray(lstVolumeIds);
- }
-
- private long[] convertArray(List<Long> items) {
- if (items == null) {
- return new long[0];
- }
-
- long[] outArray = new long[items.size()];
-
- for (int i = 0; i < items.size(); i++) {
- Long value = items.get(i);
-
- outArray[i] = value;
- }
-
- return outArray;
- }
-
- private String getVagKey(long storagePoolId) {
- return "sfVolumeAccessGroup_" + storagePoolId;
- }
-
- private String[] getIqnsFromHosts(List<? extends Host> hosts) {
- if (hosts == null || hosts.size() == 0) {
- throw new CloudRuntimeException("There do not appear to be any hosts in this cluster.");
- }
-
- List<String> lstIqns = new ArrayList<String>();
-
- for (Host host : hosts) {
- lstIqns.add(host.getStorageUrl());
- }
-
- return lstIqns.toArray(new String[0]);
}
private long getDefaultMinIops(long storagePoolId) {
@@ -532,12 +195,7 @@ public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver {
return (long)(maxIops * fClusterDefaultBurstIopsPercentOfMaxIops);
}
- private SolidFireUtil.SolidFireVolume createSolidFireVolume(VolumeInfo volumeInfo, SolidFireConnection sfConnection) {
- String mVip = sfConnection.getManagementVip();
- int mPort = sfConnection.getManagementPort();
- String clusterAdminUsername = sfConnection.getClusterAdminUsername();
- String clusterAdminPassword = sfConnection.getClusterAdminPassword();
-
+ private SolidFireUtil.SolidFireVolume createSolidFireVolume(SolidFireUtil.SolidFireConnection sfConnection, VolumeInfo volumeInfo) {
AccountDetailVO accountDetail = _accountDetailsDao.findDetail(volumeInfo.getAccountId(), SolidFireUtil.ACCOUNT_ID);
long sfAccountId = Long.parseLong(accountDetail.getValue());
@@ -558,12 +216,10 @@ public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver {
long volumeSize = getVolumeSizeIncludingHypervisorSnapshotReserve(volumeInfo, _storagePoolDao.findById(storagePoolId));
- long sfVolumeId = SolidFireUtil.createSolidFireVolume(mVip, mPort, clusterAdminUsername, clusterAdminPassword,
- getSolidFireVolumeName(volumeInfo.getName()), sfAccountId, volumeSize, true,
- NumberFormat.getInstance().format(volumeInfo.getSize()),
- iops.getMinIops(), iops.getMaxIops(), iops.getBurstIops());
+ long sfVolumeId = SolidFireUtil.createSolidFireVolume(sfConnection, SolidFireUtil.getSolidFireVolumeName(volumeInfo.getName()), sfAccountId, volumeSize, true,
+ NumberFormat.getInstance().format(volumeInfo.getSize()), iops.getMinIops(), iops.getMaxIops(), iops.getBurstIops());
- return SolidFireUtil.getSolidFireVolume(mVip, mPort, clusterAdminUsername, clusterAdminPassword, sfVolumeId);
+ return SolidFireUtil.getSolidFireVolume(sfConnection, sfVolumeId);
}
@Override
@@ -582,24 +238,6 @@ public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver {
return volumeSize;
}
- private String getSolidFireVolumeName(String strCloudStackVolumeName) {
- final String specialChar = "-";
-
- StringBuilder strSolidFireVolumeName = new StringBuilder();
-
- for (int i = 0; i < strCloudStackVolumeName.length(); i++) {
- String strChar = strCloudStackVolumeName.substring(i, i + 1);
-
- if (StringUtils.isAlphanumeric(strChar)) {
- strSolidFireVolumeName.append(strChar);
- } else {
- strSolidFireVolumeName.append(specialChar);
- }
- }
-
- return strSolidFireVolumeName.toString();
- }
-
private static class Iops {
private final long _minIops;
private final long _maxIops;
@@ -636,7 +274,7 @@ public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver {
}
}
- private SolidFireUtil.SolidFireVolume deleteSolidFireVolume(VolumeInfo volumeInfo, SolidFireConnection sfConnection)
+ private SolidFireUtil.SolidFireVolume deleteSolidFireVolume(SolidFireUtil.SolidFireConnection sfConnection, VolumeInfo volumeInfo)
{
Long storagePoolId = volumeInfo.getPoolId();
@@ -644,33 +282,9 @@ public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver {
return null; // this volume was never assigned to a storage pool, so no SAN volume should exist for it
}
- String mVip = sfConnection.getManagementVip();
- int mPort = sfConnection.getManagementPort();
- String clusterAdminUsername = sfConnection.getClusterAdminUsername();
- String clusterAdminPassword = sfConnection.getClusterAdminPassword();
-
long sfVolumeId = Long.parseLong(volumeInfo.getFolder());
- return SolidFireUtil.deleteSolidFireVolume(mVip, mPort, clusterAdminUsername, clusterAdminPassword, sfVolumeId);
- }
-
- private String getSfAccountName(String csAccountUuid, long csAccountId) {
- return "CloudStack_" + csAccountUuid + "_" + csAccountId;
- }
-
- private boolean sfAccountExists(String sfAccountName, SolidFireConnection sfConnection) {
- String mVip = sfConnection.getManagementVip();
- int mPort = sfConnection.getManagementPort();
- String clusterAdminUsername = sfConnection.getClusterAdminUsername();
- String clusterAdminPassword = sfConnection.getClusterAdminPassword();
-
- try {
- SolidFireUtil.getSolidFireAccountByName(mVip, mPort, clusterAdminUsername, clusterAdminPassword, sfAccountName);
- } catch (Exception ex) {
- return false;
- }
-
- return true;
+ return SolidFireUtil.deleteSolidFireVolume(sfConnection, sfVolumeId);
}
@Override
@@ -681,18 +295,18 @@ public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver {
if (dataObject.getType() == DataObjectType.VOLUME) {
VolumeInfo volumeInfo = (VolumeInfo)dataObject;
AccountVO account = _accountDao.findById(volumeInfo.getAccountId());
- String sfAccountName = getSfAccountName(account.getUuid(), account.getAccountId());
+ String sfAccountName = SolidFireUtil.getSolidFireAccountName(account.getUuid(), account.getAccountId());
long storagePoolId = dataStore.getId();
- SolidFireConnection sfConnection = getSolidFireConnection(storagePoolId);
+ SolidFireUtil.SolidFireConnection sfConnection = SolidFireUtil.getSolidFireConnection(storagePoolId, _storagePoolDetailsDao);
- if (!sfAccountExists(sfAccountName, sfConnection)) {
- SolidFireUtil.SolidFireAccount sfAccount = createSolidFireAccount(sfAccountName, sfConnection);
+ if (SolidFireUtil.getSolidFireAccount(sfConnection, sfAccountName) == null) {
+ SolidFireUtil.SolidFireAccount sfAccount = createSolidFireAccount(sfConnection, sfAccountName);
- updateCsDbWithAccountInfo(account.getId(), sfAccount);
+ SolidFireUtil.updateCsDbWithSolidFireAccountInfo(account.getId(), sfAccount, _accountDetailsDao);
}
- SolidFireUtil.SolidFireVolume sfVolume = createSolidFireVolume(volumeInfo, sfConnection);
+ SolidFireUtil.SolidFireVolume sfVolume = createSolidFireVolume(sfConnection, volumeInfo);
iqn = sfVolume.getIqn();
@@ -728,74 +342,20 @@ public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver {
callback.complete(result);
}
- /*
- private void deleteSolidFireAccount(long sfAccountId, SolidFireConnection sfConnection) {
- String mVip = sfConnection.getManagementVip();
- int mPort = sfConnection.getManagementPort();
- String clusterAdminUsername = sfConnection.getClusterAdminUsername();
- String clusterAdminPassword = sfConnection.getClusterAdminPassword();
-
- List<SolidFireUtil.SolidFireVolume> sfVolumes = SolidFireUtil.getDeletedVolumes(mVip, mPort, clusterAdminUsername, clusterAdminPassword);
-
- // if there are volumes for this account in the trash, delete them (so the account can be deleted)
- if (sfVolumes != null) {
- for (SolidFireUtil.SolidFireVolume sfVolume : sfVolumes) {
- if (sfVolume.getAccountId() == sfAccountId) {
- SolidFireUtil.purgeSolidFireVolume(mVip, mPort, clusterAdminUsername, clusterAdminPassword, sfVolume.getId());
- }
- }
- }
-
- SolidFireUtil.deleteSolidFireAccount(mVip, mPort, clusterAdminUsername, clusterAdminPassword, sfAccountId);
- }
-
- private boolean sfAccountHasVolume(long sfAccountId, SolidFireConnection sfConnection) {
- String mVip = sfConnection.getManagementVip();
- int mPort = sfConnection.getManagementPort();
- String clusterAdminUsername = sfConnection.getClusterAdminUsername();
- String clusterAdminPassword = sfConnection.getClusterAdminPassword();
-
- List<SolidFireUtil.SolidFireVolume> sfVolumes =
- SolidFireUtil.getSolidFireVolumesForAccountId(mVip, mPort, clusterAdminUsername, clusterAdminPassword, sfAccountId);
-
- if (sfVolumes != null) {
- for (SolidFireUtil.SolidFireVolume sfVolume : sfVolumes) {
- if (sfVolume.isActive()) {
- return true;
- }
- }
- }
-
- return false;
- }
- */
-
@Override
public void deleteAsync(DataStore dataStore, DataObject dataObject, AsyncCompletionCallback<CommandResult> callback) {
String errMsg = null;
if (dataObject.getType() == DataObjectType.VOLUME) {
VolumeInfo volumeInfo = (VolumeInfo)dataObject;
- // AccountVO account = _accountDao.findById(volumeInfo.getAccountId());
- // AccountDetailVO accountDetails = _accountDetailsDao.findDetail(account.getAccountId(), SolidFireUtil.ACCOUNT_ID);
- // long sfAccountId = Long.parseLong(accountDetails.getValue());
long storagePoolId = dataStore.getId();
- SolidFireConnection sfConnection = getSolidFireConnection(storagePoolId);
+ SolidFireUtil.SolidFireConnection sfConnection = SolidFireUtil.getSolidFireConnection(storagePoolId, _storagePoolDetailsDao);
- SolidFireUtil.SolidFireVolume sfVolume = deleteSolidFireVolume(volumeInfo, sfConnection);
+ SolidFireUtil.SolidFireVolume sfVolume = deleteSolidFireVolume(sfConnection, volumeInfo);
_volumeDao.deleteVolumesByInstance(volumeInfo.getId());
- // if (!sfAccountHasVolume(sfAccountId, sfConnection)) {
- // // delete the account from the SolidFire SAN
- // deleteSolidFireAccount(sfAccountId, sfConnection);
- //
- // // delete the info in the account_details table
- // // that's related to the SolidFire account
- // _accountDetailsDao.deleteDetails(account.getAccountId());
- // }
-
StoragePoolVO storagePool = _storagePoolDao.findById(storagePoolId);
long usedBytes = storagePool.getUsedBytes();
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/42d00cae/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/lifecycle/SolidFirePrimaryDataStoreLifeCycle.java
----------------------------------------------------------------------
diff --git a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/lifecycle/SolidFirePrimaryDataStoreLifeCycle.java b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/lifecycle/SolidFirePrimaryDataStoreLifeCycle.java
index d30374f..7fc3436 100644
--- a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/lifecycle/SolidFirePrimaryDataStoreLifeCycle.java
+++ b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/lifecycle/SolidFirePrimaryDataStoreLifeCycle.java
@@ -21,7 +21,6 @@ package org.apache.cloudstack.storage.datastore.lifecycle;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
-import java.util.StringTokenizer;
import javax.inject.Inject;
@@ -34,7 +33,6 @@ import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreLifeCy
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreParameters;
import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao;
import org.apache.cloudstack.storage.datastore.util.SolidFireUtil;
import org.apache.cloudstack.storage.volume.datastore.PrimaryDataStoreHelper;
@@ -61,14 +59,9 @@ public class SolidFirePrimaryDataStoreLifeCycle implements PrimaryDataStoreLifeC
@Inject
private ResourceManager _resourceMgr;
@Inject
- StorageManager _storageMgr;
+ private StorageManager _storageMgr;
@Inject
private StoragePoolAutomation storagePoolAutomation;
- @Inject
- private StoragePoolDetailsDao storagePoolDetailsDao;
-
- private static final int DEFAULT_MANAGEMENT_PORT = 443;
- private static final int DEFAULT_STORAGE_PORT = 3260;
// invoked to add primary storage that is based on the SolidFire plug-in
@Override
@@ -80,10 +73,11 @@ public class SolidFirePrimaryDataStoreLifeCycle implements PrimaryDataStoreLifeC
Long capacityBytes = (Long)dsInfos.get("capacityBytes");
Long capacityIops = (Long)dsInfos.get("capacityIops");
String tags = (String)dsInfos.get("tags");
+ @SuppressWarnings("unchecked")
Map<String, String> details = (Map<String, String>)dsInfos.get("details");
- String storageVip = getStorageVip(url);
- int storagePort = getStoragePort(url);
+ String storageVip = SolidFireUtil.getStorageVip(url);
+ int storagePort = SolidFireUtil.getStoragePort(url);
DataCenterVO zone = zoneDao.findById(zoneId);
@@ -101,7 +95,7 @@ public class SolidFirePrimaryDataStoreLifeCycle implements PrimaryDataStoreLifeC
parameters.setHost(storageVip);
parameters.setPort(storagePort);
- parameters.setPath(getModifiedUrl(url));
+ parameters.setPath(SolidFireUtil.getModifiedUrl(url));
parameters.setType(StoragePoolType.Iscsi);
parameters.setUuid(uuid);
parameters.setZoneId(zoneId);
@@ -115,14 +109,14 @@ public class SolidFirePrimaryDataStoreLifeCycle implements PrimaryDataStoreLifeC
parameters.setTags(tags);
parameters.setDetails(details);
- String managementVip = getManagementVip(url);
- int managementPort = getManagementPort(url);
+ String managementVip = SolidFireUtil.getManagementVip(url);
+ int managementPort = SolidFireUtil.getManagementPort(url);
details.put(SolidFireUtil.MANAGEMENT_VIP, managementVip);
details.put(SolidFireUtil.MANAGEMENT_PORT, String.valueOf(managementPort));
- String clusterAdminUsername = getValue(SolidFireUtil.CLUSTER_ADMIN_USERNAME, url);
- String clusterAdminPassword = getValue(SolidFireUtil.CLUSTER_ADMIN_PASSWORD, url);
+ String clusterAdminUsername = SolidFireUtil.getValue(SolidFireUtil.CLUSTER_ADMIN_USERNAME, url);
+ String clusterAdminPassword = SolidFireUtil.getValue(SolidFireUtil.CLUSTER_ADMIN_PASSWORD, url);
details.put(SolidFireUtil.CLUSTER_ADMIN_USERNAME, clusterAdminUsername);
details.put(SolidFireUtil.CLUSTER_ADMIN_PASSWORD, clusterAdminPassword);
@@ -132,7 +126,7 @@ public class SolidFirePrimaryDataStoreLifeCycle implements PrimaryDataStoreLifeC
float fClusterDefaultBurstIopsPercentOfMaxIops = 1.5f;
try {
- String clusterDefaultMinIops = getValue(SolidFireUtil.CLUSTER_DEFAULT_MIN_IOPS, url);
+ String clusterDefaultMinIops = SolidFireUtil.getValue(SolidFireUtil.CLUSTER_DEFAULT_MIN_IOPS, url);
if (clusterDefaultMinIops != null && clusterDefaultMinIops.trim().length() > 0) {
lClusterDefaultMinIops = Long.parseLong(clusterDefaultMinIops);
@@ -144,7 +138,7 @@ public class SolidFirePrimaryDataStoreLifeCycle implements PrimaryDataStoreLifeC
}
try {
- String clusterDefaultMaxIops = getValue(SolidFireUtil.CLUSTER_DEFAULT_MAX_IOPS, url);
+ String clusterDefaultMaxIops = SolidFireUtil.getValue(SolidFireUtil.CLUSTER_DEFAULT_MAX_IOPS, url);
if (clusterDefaultMaxIops != null && clusterDefaultMaxIops.trim().length() > 0) {
lClusterDefaultMaxIops = Long.parseLong(clusterDefaultMaxIops);
@@ -156,7 +150,7 @@ public class SolidFirePrimaryDataStoreLifeCycle implements PrimaryDataStoreLifeC
}
try {
- String clusterDefaultBurstIopsPercentOfMaxIops = getValue(SolidFireUtil.CLUSTER_DEFAULT_BURST_IOPS_PERCENT_OF_MAX_IOPS, url);
+ String clusterDefaultBurstIopsPercentOfMaxIops = SolidFireUtil.getValue(SolidFireUtil.CLUSTER_DEFAULT_BURST_IOPS_PERCENT_OF_MAX_IOPS, url);
if (clusterDefaultBurstIopsPercentOfMaxIops != null && clusterDefaultBurstIopsPercentOfMaxIops.trim().length() > 0) {
fClusterDefaultBurstIopsPercentOfMaxIops = Float.parseFloat(clusterDefaultBurstIopsPercentOfMaxIops);
@@ -168,7 +162,7 @@ public class SolidFirePrimaryDataStoreLifeCycle implements PrimaryDataStoreLifeC
}
if (lClusterDefaultMinIops > lClusterDefaultMaxIops) {
- throw new CloudRuntimeException("The parameter '" + SolidFireUtil.CLUSTER_DEFAULT_MIN_IOPS + "' must be less than " + "or equal to the parameter '" +
+ throw new CloudRuntimeException("The parameter '" + SolidFireUtil.CLUSTER_DEFAULT_MIN_IOPS + "' must be less than or equal to the parameter '" +
SolidFireUtil.CLUSTER_DEFAULT_MAX_IOPS + "'.");
}
@@ -184,111 +178,6 @@ public class SolidFirePrimaryDataStoreLifeCycle implements PrimaryDataStoreLifeC
return dataStoreHelper.createPrimaryDataStore(parameters);
}
- // remove the clusterAdmin and password key/value pairs
- private String getModifiedUrl(String originalUrl) {
- StringBuilder sb = new StringBuilder();
-
- String delimiter = ";";
-
- StringTokenizer st = new StringTokenizer(originalUrl, delimiter);
-
- while (st.hasMoreElements()) {
- String token = st.nextElement().toString().toUpperCase();
-
- if (token.startsWith(SolidFireUtil.MANAGEMENT_VIP.toUpperCase()) || token.startsWith(SolidFireUtil.STORAGE_VIP.toUpperCase())) {
- sb.append(token).append(delimiter);
- }
- }
-
- String modifiedUrl = sb.toString();
- int lastIndexOf = modifiedUrl.lastIndexOf(delimiter);
-
- if (lastIndexOf == (modifiedUrl.length() - delimiter.length())) {
- return modifiedUrl.substring(0, lastIndexOf);
- }
-
- return modifiedUrl;
- }
-
- private String getManagementVip(String url) {
- return getVip(SolidFireUtil.MANAGEMENT_VIP, url);
- }
-
- private String getStorageVip(String url) {
- return getVip(SolidFireUtil.STORAGE_VIP, url);
- }
-
- private int getManagementPort(String url) {
- return getPort(SolidFireUtil.MANAGEMENT_VIP, url, DEFAULT_MANAGEMENT_PORT);
- }
-
- private int getStoragePort(String url) {
- return getPort(SolidFireUtil.STORAGE_VIP, url, DEFAULT_STORAGE_PORT);
- }
-
- private String getVip(String keyToMatch, String url) {
- String delimiter = ":";
-
- String storageVip = getValue(keyToMatch, url);
-
- int index = storageVip.indexOf(delimiter);
-
- if (index != -1) {
- return storageVip.substring(0, index);
- }
-
- return storageVip;
- }
-
- private int getPort(String keyToMatch, String url, int defaultPortNumber) {
- String delimiter = ":";
-
- String storageVip = getValue(keyToMatch, url);
-
- int index = storageVip.indexOf(delimiter);
-
- int portNumber = defaultPortNumber;
-
- if (index != -1) {
- String port = storageVip.substring(index + delimiter.length());
-
- try {
- portNumber = Integer.parseInt(port);
- } catch (NumberFormatException ex) {
- throw new IllegalArgumentException("Invalid URL format (port is not an integer)");
- }
- }
-
- return portNumber;
- }
-
- private String getValue(String keyToMatch, String url) {
- String delimiter1 = ";";
- String delimiter2 = "=";
-
- StringTokenizer st = new StringTokenizer(url, delimiter1);
-
- while (st.hasMoreElements()) {
- String token = st.nextElement().toString();
-
- int index = token.indexOf(delimiter2);
-
- if (index == -1) {
- throw new RuntimeException("Invalid URL format");
- }
-
- String key = token.substring(0, index);
-
- if (key.equalsIgnoreCase(keyToMatch)) {
- String valueToReturn = token.substring(index + delimiter2.length());
-
- return valueToReturn;
- }
- }
-
- throw new RuntimeException("Key not found in URL");
- }
-
// do not implement this method for SolidFire's plug-in
@Override
public boolean attachHost(DataStore store, HostScope scope, StoragePoolInfo existingInfo) {