mirror of
https://github.com/apache/cloudstack.git
synced 2025-11-02 20:02:29 +01:00
Merge from 4.3: CLOUDSTACK-4810: Enable hypervisor snapshots for CloudStack-managed storage (for XenServer and VMware)
This commit is contained in:
parent
a354d969ce
commit
68fda5a8dd
@ -272,16 +272,39 @@ public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver {
|
||||
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, true);
|
||||
|
||||
SolidFireUtil.modifySolidFireVag(sfConnection.getManagementVip(), sfConnection.getManagementPort(),
|
||||
sfConnection.getClusterAdminUsername(), sfConnection.getClusterAdminPassword(), sfVag.getId(),
|
||||
getIqnsFromHosts(hosts), volumeIds);
|
||||
hostIqns, volumeIds);
|
||||
}
|
||||
else {
|
||||
long lVagId = SolidFireUtil.createSolidFireVag(sfConnection.getManagementVip(), sfConnection.getManagementPort(),
|
||||
sfConnection.getClusterAdminUsername(), sfConnection.getClusterAdminPassword(), "CloudStack-" + UUID.randomUUID().toString(),
|
||||
getIqnsFromHosts(hosts), new long[] { sfVolumeId });
|
||||
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));
|
||||
|
||||
@ -291,6 +314,48 @@ public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver {
|
||||
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)
|
||||
@ -317,11 +382,12 @@ public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver {
|
||||
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.modifySolidFireVag(sfConnection.getManagementVip(), sfConnection.getManagementPort(),
|
||||
sfConnection.getClusterAdminUsername(), sfConnection.getClusterAdminPassword(), sfVag.getId(),
|
||||
getIqnsFromHosts(hosts), volumeIds);
|
||||
hostIqns, volumeIds);
|
||||
}
|
||||
}
|
||||
|
||||
@ -339,6 +405,26 @@ public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver {
|
||||
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);
|
||||
|
||||
@ -267,7 +267,8 @@ public class SolidFireUtil {
|
||||
}
|
||||
}
|
||||
|
||||
public static long createSolidFireAccount(String strSfMvip, int iSfPort, String strSfAdmin, String strSfPassword, String strAccountName) {
|
||||
public static long createSolidFireAccount(String strSfMvip, int iSfPort, String strSfAdmin, String strSfPassword, String strAccountName)
|
||||
{
|
||||
final Gson gson = new GsonBuilder().create();
|
||||
|
||||
AccountToAdd accountToAdd = new AccountToAdd(strAccountName);
|
||||
@ -283,8 +284,7 @@ public class SolidFireUtil {
|
||||
return accountAddResult.result.accountID;
|
||||
}
|
||||
|
||||
public static SolidFireAccount getSolidFireAccountById(String strSfMvip, int iSfPort, String strSfAdmin, String strSfPassword,
|
||||
long lSfAccountId)
|
||||
public static SolidFireAccount getSolidFireAccountById(String strSfMvip, int iSfPort, String strSfAdmin, String strSfPassword, long lSfAccountId)
|
||||
{
|
||||
final Gson gson = new GsonBuilder().create();
|
||||
|
||||
@ -305,7 +305,8 @@ public class SolidFireUtil {
|
||||
return new SolidFireAccount(lSfAccountId, strSfAccountName, strSfAccountInitiatorSecret, strSfAccountTargetSecret);
|
||||
}
|
||||
|
||||
public static SolidFireAccount getSolidFireAccountByName(String strSfMvip, int iSfPort, String strSfAdmin, String strSfPassword, String strSfAccountName) {
|
||||
public static SolidFireAccount getSolidFireAccountByName(String strSfMvip, int iSfPort, String strSfAdmin, String strSfPassword, String strSfAccountName)
|
||||
{
|
||||
final Gson gson = new GsonBuilder().create();
|
||||
|
||||
AccountToGetByName accountToGetByName = new AccountToGetByName(strSfAccountName);
|
||||
@ -325,8 +326,7 @@ public class SolidFireUtil {
|
||||
return new SolidFireAccount(lSfAccountId, strSfAccountName, strSfAccountInitiatorSecret, strSfAccountTargetSecret);
|
||||
}
|
||||
|
||||
public static void deleteSolidFireAccount(String strSfMvip, int iSfPort, String strSfAdmin, String strSfPassword,
|
||||
long lAccountId)
|
||||
public static void deleteSolidFireAccount(String strSfMvip, int iSfPort, String strSfAdmin, String strSfPassword, long lAccountId)
|
||||
{
|
||||
final Gson gson = new GsonBuilder().create();
|
||||
|
||||
@ -449,7 +449,35 @@ public class SolidFireUtil {
|
||||
return new SolidFireVag(lVagId, vagIqns, vagVolumeIds);
|
||||
}
|
||||
|
||||
public static void deleteSolidFireVag(String strSfMvip, int iSfPort, String strSfAdmin, String strSfPassword, long lVagId) {
|
||||
public static List<SolidFireVag> getAllSolidFireVags(String strSfMvip, int iSfPort, String strSfAdmin, String strSfPassword)
|
||||
{
|
||||
final Gson gson = new GsonBuilder().create();
|
||||
|
||||
AllVags allVags = new AllVags();
|
||||
|
||||
String strAllVagsJson = gson.toJson(allVags);
|
||||
|
||||
String strAllVagsGetResultJson = executeJsonRpc(strAllVagsJson, strSfMvip, iSfPort, strSfAdmin, strSfPassword);
|
||||
|
||||
VagGetResult allVagsGetResult = gson.fromJson(strAllVagsGetResultJson, VagGetResult.class);
|
||||
|
||||
verifyResult(allVagsGetResult.result, strAllVagsGetResultJson, gson);
|
||||
|
||||
List<SolidFireVag> lstSolidFireVags = new ArrayList<SolidFireVag>();
|
||||
|
||||
if (allVagsGetResult.result.volumeAccessGroups != null ) {
|
||||
for (VagGetResult.Result.Vag vag : allVagsGetResult.result.volumeAccessGroups) {
|
||||
SolidFireVag sfVag = new SolidFireVag(vag.volumeAccessGroupID, vag.initiators, vag.volumes);
|
||||
|
||||
lstSolidFireVags.add(sfVag);
|
||||
}
|
||||
}
|
||||
|
||||
return lstSolidFireVags;
|
||||
}
|
||||
|
||||
public static void deleteSolidFireVag(String strSfMvip, int iSfPort, String strSfAdmin, String strSfPassword, long lVagId)
|
||||
{
|
||||
final Gson gson = new GsonBuilder().create();
|
||||
|
||||
VagToDelete vagToDelete = new VagToDelete(lVagId);
|
||||
@ -817,7 +845,23 @@ public class SolidFireUtil {
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static final class VagToDelete {
|
||||
private static final class AllVags
|
||||
{
|
||||
private final String method = "ListVolumeAccessGroups";
|
||||
private final VagToGetParams params;
|
||||
|
||||
private AllVags()
|
||||
{
|
||||
params = new VagToGetParams();
|
||||
}
|
||||
|
||||
private static final class VagToGetParams
|
||||
{}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static final class VagToDelete
|
||||
{
|
||||
private final String method = "DeleteVolumeAccessGroup";
|
||||
private final VagToDeleteParams params;
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user