Repository: cloudstack Updated Branches: refs/heads/master 8cf94c9ec -> 8e112858d
CLOUDSTACK-7071. Upgrade to CCP 4.2 fails in case a VMware setup has multiple zones mapping to the same VMware datacenter. If 2 or more CloudStack zones map to the same VMware datacenter, mark the zones as legacy zones. Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/8e112858 Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/8e112858 Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/8e112858 Branch: refs/heads/master Commit: 8e112858d35a77943e154e69736caaf2e5b94e7d Parents: 8cf94c9 Author: Likitha Shetty <likitha.she...@citrix.com> Authored: Fri Jul 4 12:24:25 2014 +0530 Committer: Likitha Shetty <likitha.she...@citrix.com> Committed: Mon Jul 7 16:38:56 2014 +0530 ---------------------------------------------------------------------- .../com/cloud/upgrade/dao/Upgrade410to420.java | 163 +++++++++++++------ 1 file changed, 117 insertions(+), 46 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8e112858/engine/schema/src/com/cloud/upgrade/dao/Upgrade410to420.java ---------------------------------------------------------------------- diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade410to420.java b/engine/schema/src/com/cloud/upgrade/dao/Upgrade410to420.java index 671cbb7..097f6c5 100755 --- a/engine/schema/src/com/cloud/upgrade/dao/Upgrade410to420.java +++ b/engine/schema/src/com/cloud/upgrade/dao/Upgrade410to420.java @@ -863,14 +863,14 @@ public class Upgrade410to420 implements DbUpgrade { private void persistLegacyZones(Connection conn) { List<Long> listOfLegacyZones = new ArrayList<Long>(); + List<Long> listOfNonLegacyZones = new ArrayList<Long>(); + Map<String, ArrayList<Long>> dcToZoneMap = new HashMap<String, ArrayList<Long>>(); PreparedStatement pstmt = null; PreparedStatement clustersQuery = null; PreparedStatement clusterDetailsQuery = null; ResultSet rs = null; ResultSet clusters = null; ResultSet clusterDetails = null; - ResultSet dcInfo = null; - Long vmwareDcId = 1L; Long zoneId; Long clusterId; String clusterHypervisorType; @@ -881,13 +881,8 @@ public class Upgrade410to420 implements DbUpgrade { String dcOfCurrentCluster = null; String[] tokens; String url; - String user = ""; - String password = ""; String vc = ""; String dcName = ""; - String guid; - String key; - String value; try { pstmt = conn.prepareStatement("select id from `cloud`.`data_center` where removed is NULL"); @@ -899,6 +894,7 @@ public class Upgrade410to420 implements DbUpgrade { clustersQuery.setLong(1, zoneId); legacyZone = false; ignoreZone = true; + ArrayList<String> dcList = new ArrayList<String>(); count = 0L; // Legacy zone term is meant only for VMware // Legacy zone is a zone with atleast 2 clusters & with multiple DCs or VCs @@ -923,6 +919,9 @@ public class Upgrade410to420 implements DbUpgrade { dcName = tokens[3]; dcOfPreviousCluster = dcOfCurrentCluster; dcOfCurrentCluster = dcName + "@" + vc; + if (!dcList.contains(dcOfCurrentCluster)) { + dcList.add(dcOfCurrentCluster); + } if (count > 0) { if (!dcOfPreviousCluster.equalsIgnoreCase(dcOfCurrentCluster)) { legacyZone = true; @@ -942,47 +941,30 @@ public class Upgrade410to420 implements DbUpgrade { if (legacyZone) { listOfLegacyZones.add(zoneId); } else { - assert (clusterDetails != null) : "Couldn't retrieve details of cluster!"; - s_logger.debug("Discovered non-legacy zone " + zoneId + ". Processing the zone to associate with VMware datacenter."); - - clusterDetailsQuery = conn.prepareStatement("select name, value from `cloud`.`cluster_details` where cluster_id=?"); - clusterDetailsQuery.setLong(1, clusterId); - clusterDetails = clusterDetailsQuery.executeQuery(); - while (clusterDetails.next()) { - key = clusterDetails.getString(1); - value = clusterDetails.getString(2); - if (key.equalsIgnoreCase("username")) { - user = value; - } else if (key.equalsIgnoreCase("password")) { - password = value; - } + listOfNonLegacyZones.add(zoneId); + } + for (String dc : dcList) { + ArrayList<Long> dcZones = new ArrayList<Long>(); + if (dcToZoneMap.get(dc) != null) { + dcZones = dcToZoneMap.get(dc); } - guid = dcName + "@" + vc; - - pstmt = - conn.prepareStatement("INSERT INTO `cloud`.`vmware_data_center` (uuid, name, guid, vcenter_host, username, password) values(?, ?, ?, ?, ?, ?)"); - pstmt.setString(1, UUID.randomUUID().toString()); - pstmt.setString(2, dcName); - pstmt.setString(3, guid); - pstmt.setString(4, vc); - pstmt.setString(5, user); - pstmt.setString(6, password); - pstmt.executeUpdate(); - - pstmt = conn.prepareStatement("SELECT id FROM `cloud`.`vmware_data_center` where guid=?"); - pstmt.setString(1, guid); - dcInfo = pstmt.executeQuery(); - if (dcInfo.next()) { - vmwareDcId = dcInfo.getLong("id"); + dcZones.add(zoneId); + dcToZoneMap.put(dc, dcZones); + } + } + // If a VMware datacenter in a vCenter maps to more than 1 CloudStack zone, mark all the zones it is mapped to as legacy + for (Map.Entry<String, ArrayList<Long>> entry : dcToZoneMap.entrySet()) { + if (entry.getValue().size() > 1) { + for (Long newLegacyZone : entry.getValue()) { + if (listOfNonLegacyZones.contains(newLegacyZone)) { + listOfNonLegacyZones.remove(newLegacyZone); + listOfLegacyZones.add(newLegacyZone); + } } - - pstmt = conn.prepareStatement("INSERT INTO `cloud`.`vmware_data_center_zone_map` (zone_id, vmware_data_center_id) values(?, ?)"); - pstmt.setLong(1, zoneId); - pstmt.setLong(2, vmwareDcId); - pstmt.executeUpdate(); } } updateLegacyZones(conn, listOfLegacyZones); + updateNonLegacyZones(conn, listOfNonLegacyZones); } catch (SQLException e) { String msg = "Unable to discover legacy zones." + e.getMessage(); s_logger.error(msg); @@ -995,9 +977,6 @@ public class Upgrade410to420 implements DbUpgrade { if (pstmt != null) { pstmt.close(); } - if (dcInfo != null) { - dcInfo.close(); - } if (clusters != null) { clusters.close(); } @@ -1037,6 +1016,98 @@ public class Upgrade410to420 implements DbUpgrade { } } + private void updateNonLegacyZones(Connection conn, List<Long> zones) { + PreparedStatement clustersQuery = null; + PreparedStatement clusterDetailsQuery = null; + PreparedStatement pstmt = null; + ResultSet clusters = null; + ResultSet clusterDetails = null; + ResultSet dcInfo = null; + try { + for (Long zoneId : zones) { + s_logger.debug("Discovered non-legacy zone " + zoneId + ". Processing the zone to associate with VMware datacenter."); + + // All clusters in a non legacy zone will belong to the same VMware DC, hence pick the first cluster + clustersQuery = conn.prepareStatement("select id from `cloud`.`cluster` where removed is NULL AND data_center_id=?"); + clustersQuery.setLong(1, zoneId); + clusters = clustersQuery.executeQuery(); + clusters.next(); + Long clusterId = clusters.getLong("id"); + + // Get VMware datacenter details from cluster_details table + String user = null; + String password = null; + String url = null; + clusterDetailsQuery = conn.prepareStatement("select name, value from `cloud`.`cluster_details` where cluster_id=?"); + clusterDetailsQuery.setLong(1, clusterId); + clusterDetails = clusterDetailsQuery.executeQuery(); + while (clusterDetails.next()) { + String key = clusterDetails.getString(1); + String value = clusterDetails.getString(2); + if (key.equalsIgnoreCase("username")) { + user = value; + } else if (key.equalsIgnoreCase("password")) { + password = value; + } else if (key.equalsIgnoreCase("url")) { + url = value; + } + } + String[] tokens = url.split("/"); // url format - http://vcenter/dc/cluster + String vc = tokens[2]; + String dcName = tokens[3]; + String guid = dcName + "@" + vc; + + pstmt = conn.prepareStatement("INSERT INTO `cloud`.`vmware_data_center` (uuid, name, guid, vcenter_host, username, password) values(?, ?, ?, ?, ?, ?)"); + pstmt.setString(1, UUID.randomUUID().toString()); + pstmt.setString(2, dcName); + pstmt.setString(3, guid); + pstmt.setString(4, vc); + pstmt.setString(5, user); + pstmt.setString(6, password); + pstmt.executeUpdate(); + + pstmt = conn.prepareStatement("SELECT id FROM `cloud`.`vmware_data_center` where guid=?"); + pstmt.setString(1, guid); + dcInfo = pstmt.executeQuery(); + Long vmwareDcId = -1L; + if (dcInfo.next()) { + vmwareDcId = dcInfo.getLong("id"); + } + + pstmt = conn.prepareStatement("INSERT INTO `cloud`.`vmware_data_center_zone_map` (zone_id, vmware_data_center_id) values(?, ?)"); + pstmt.setLong(1, zoneId); + pstmt.setLong(2, vmwareDcId); + pstmt.executeUpdate(); + } + } catch (SQLException e) { + String msg = "Unable to update non legacy zones." + e.getMessage(); + s_logger.error(msg); + throw new CloudRuntimeException(msg, e); + } finally { + try { + if (clustersQuery != null) { + clustersQuery.close(); + } + if (clusterDetails != null) { + clusterDetails.close(); + } + if (clusterDetailsQuery != null) { + clusterDetailsQuery.close(); + } + if (clusters != null) { + clusters.close(); + } + if (dcInfo != null) { + dcInfo.close(); + } + if (pstmt != null) { + pstmt.close(); + } + } catch (SQLException e) { + } + } + } + private void createPlaceHolderNics(Connection conn) { PreparedStatement pstmt = null; ResultSet rs = null;