diff --git a/server/src/com/cloud/upgrade/dao/Upgrade2214to30.java b/server/src/com/cloud/upgrade/dao/Upgrade2214to30.java index 3d279c13bbe..8469a51c560 100644 --- a/server/src/com/cloud/upgrade/dao/Upgrade2214to30.java +++ b/server/src/com/cloud/upgrade/dao/Upgrade2214to30.java @@ -531,24 +531,136 @@ public class Upgrade2214to30 implements DbUpgrade { } private void updateSystemVms(Connection conn){ - //XenServer - //Get 3.0.0 xenserer system Vm template Id - PreparedStatement pstmt = null; - ResultSet rs = null; - try { - pstmt = conn.prepareStatement("select id from vm_template where name = 'systemvm-xenserver-3.0.0' and removed is null"); - rs = pstmt.executeQuery(); - if(rs.next()){ - long templateId = rs.getLong(1); - pstmt = conn.prepareStatement("update vm_instance set vm_template_id = ? where type <> 'User' and hypervisor_type = 'XenServer'"); - pstmt.setLong(1, templateId); - pstmt.executeUpdate(); - } else { - throw new CloudRuntimeException("3.0.0 XenServer SystemVm template not found. Cannout upgrade system Vms"); - } - } catch (SQLException e) { - throw new CloudRuntimeException("Error while updating XenServer systemVm template", e); - } + PreparedStatement pstmt = null; + ResultSet rs = null; + boolean xenserver = false; + boolean kvm = false; + boolean VMware = false; + s_logger.debug("Updating System Vm template IDs"); + try{ + //Get all hypervisors in use + try { + pstmt = conn.prepareStatement("select distinct(hypervisor_type) from `cloud`.`cluster`"); + rs = pstmt.executeQuery(); + while(rs.next()){ + if("XenServer".equals(rs.getString(1))){ + xenserver = true; + } else if("KVM".equals(rs.getString(1))){ + kvm = true; + } else if("VMware".equals(rs.getString(1))){ + VMware = true; + } + } + } catch (SQLException e) { + throw new CloudRuntimeException("Error while listing hypervisors in use", e); + } + + s_logger.debug("Updating XenSever System Vms"); + //XenServer + try { + //Get 3.0.0 xenserer system Vm template Id + pstmt = conn.prepareStatement("select id from `cloud`.`vm_template` where name = 'systemvm-xenserver-3.0.0' and removed is null"); + rs = pstmt.executeQuery(); + if(rs.next()){ + long templateId = rs.getLong(1); + rs.close(); + pstmt.close(); + // change template type to SYSTEM + pstmt = conn.prepareStatement("update `cloud`.`vm_template` set type='SYSTEM' where id = ?"); + pstmt.setLong(1, templateId); + pstmt.executeUpdate(); + pstmt.close(); + // update templete ID of system Vms + pstmt = conn.prepareStatement("update `cloud`.`vm_instance` set vm_template_id = ? where type <> 'User' and hypervisor_type = 'XenServer'"); + pstmt.setLong(1, templateId); + pstmt.executeUpdate(); + pstmt.close(); + } else { + if (xenserver){ + throw new CloudRuntimeException("3.0.0 XenServer SystemVm template not found. Cannot upgrade system Vms"); + } else { + s_logger.warn("3.0.0 XenServer SystemVm template not found. XenServer hypervisor is not used, so not failing upgrade"); + } + } + } catch (SQLException e) { + throw new CloudRuntimeException("Error while updating XenServer systemVm template", e); + } + + //KVM + s_logger.debug("Updating KVM System Vms"); + try { + //Get 3.0.0 KVM system Vm template Id + pstmt = conn.prepareStatement("select id from `cloud`.`vm_template` where name = 'systemvm-kvm-3.0.0' and removed is null"); + rs = pstmt.executeQuery(); + if(rs.next()){ + long templateId = rs.getLong(1); + rs.close(); + pstmt.close(); + // change template type to SYSTEM + pstmt = conn.prepareStatement("update `cloud`.`vm_template` set type='SYSTEM' where id = ?"); + pstmt.setLong(1, templateId); + pstmt.executeUpdate(); + pstmt.close(); + // update templete ID of system Vms + pstmt = conn.prepareStatement("update `cloud`.`vm_instance` set vm_template_id = ? where type <> 'User' and hypervisor_type = 'KVM'"); + pstmt.setLong(1, templateId); + pstmt.executeUpdate(); + pstmt.close(); + } else { + if (kvm){ + throw new CloudRuntimeException("3.0.0 KVM SystemVm template not found. Cannot upgrade system Vms"); + } else { + s_logger.warn("3.0.0 KVM SystemVm template not found. KVM hypervisor is not used, so not failing upgrade"); + } + } + } catch (SQLException e) { + throw new CloudRuntimeException("Error while updating KVM systemVm template", e); + } + + //VMware + s_logger.debug("Updating VMware System Vms"); + try { + //Get 3.0.0 VMware system Vm template Id + pstmt = conn.prepareStatement("select id from `cloud`.`vm_template` where name = 'systemvm-vmware-3.0.0' and removed is null"); + rs = pstmt.executeQuery(); + if(rs.next()){ + long templateId = rs.getLong(1); + rs.close(); + pstmt.close(); + // change template type to SYSTEM + pstmt = conn.prepareStatement("update `cloud`.`vm_template` set type='SYSTEM' where id = ?"); + pstmt.setLong(1, templateId); + pstmt.executeUpdate(); + pstmt.close(); + // update templete ID of system Vms + pstmt = conn.prepareStatement("update `cloud`.`vm_instance` set vm_template_id = ? where type <> 'User' and hypervisor_type = 'VMware'"); + pstmt.setLong(1, templateId); + pstmt.executeUpdate(); + pstmt.close(); + } else { + if (VMware){ + throw new CloudRuntimeException("3.0.0 VMware SystemVm template not found. Cannot upgrade system Vms"); + } else { + s_logger.warn("3.0.0 VMware SystemVm template not found. VMware hypervisor is not used, so not failing upgrade"); + } + } + } catch (SQLException e) { + throw new CloudRuntimeException("Error while updating VMware systemVm template", e); + } + s_logger.debug("Updating System Vm Template IDs Complete"); + } + finally { + try { + if (rs != null) { + rs.close(); + } + + if (pstmt != null) { + pstmt.close(); + } + } catch (SQLException e) { + } + } } private void createNetworkOfferingServices(Connection conn) { diff --git a/server/test/com/cloud/upgrade/Template2214To30UpgradeTest.java b/server/test/com/cloud/upgrade/Template2214To30UpgradeTest.java new file mode 100644 index 00000000000..9759dfbf5e8 --- /dev/null +++ b/server/test/com/cloud/upgrade/Template2214To30UpgradeTest.java @@ -0,0 +1,123 @@ +/** + * Copyright (C) 2011 Cloud.com, Inc. All rights reserved. + * + * This software is licensed under the GNU General Public License v3 or later. + * + * It is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +package com.cloud.upgrade; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +import junit.framework.TestCase; + +import org.apache.log4j.Logger; +import org.junit.After; +import org.junit.Before; + +import com.cloud.utils.component.ComponentLocator; +import com.cloud.utils.db.DbTestUtils; +import com.cloud.utils.db.Transaction; +import com.cloud.utils.exception.CloudRuntimeException; + +public class Template2214To30UpgradeTest extends TestCase { + private static final Logger s_logger = Logger + .getLogger(Template2214To30UpgradeTest.class); + + @Override + @Before + public void setUp() throws Exception { + DbTestUtils.executeScript("PreviousDatabaseSchema/clean-db.sql", false, + true); + } + + @Override + @After + public void tearDown() throws Exception { + } + + public void test2214to30Upgrade() throws SQLException { + s_logger.debug("Finding sample data from 2.2.14"); + DbTestUtils.executeScript( + "PreviousDatabaseSchema/2.2.14/template_upgrade.sql", false, + true); + + DatabaseUpgradeChecker checker = ComponentLocator + .inject(DatabaseUpgradeChecker.class); + + checker.upgrade("2.2.14", "3.0.0"); + + Connection conn = Transaction.getStandaloneConnection(); + + try { + checkSystemVm(conn); + } finally { + try { + conn.close(); + } catch (SQLException e) { + } + } + } + + protected void checkSystemVm(Connection conn) throws SQLException { + PreparedStatement pstmt; + + pstmt = conn + .prepareStatement("SELECT version FROM `cloud`.`version` ORDER BY id DESC LIMIT 1"); + ResultSet rs = pstmt.executeQuery(); + assert rs.next() : "No version selected"; + assert rs.getString(1).equals("3.0.0") : "VERSION stored is not 3.0.0: " + + rs.getString(1); + rs.close(); + pstmt.close(); + + pstmt = conn.prepareStatement("select id from vm_template where name='systemvm-xenserver-3.0.0' and removed is null"); + rs = pstmt.executeQuery(); + long templateId1 = rs.getLong(1); + rs.close(); + pstmt.close(); + + pstmt = conn.prepareStatement("select distinct(vm_template_id) from vm_instance where type <> 'USER' and hypervisor_type = 'XenServer'"); + rs = pstmt.executeQuery(); + long templateId = rs.getLong(1); + rs.close(); + pstmt.close(); + + assert (templateId == templateId1) : "XenServer System Vms not using 3.0.0 template"; + rs.close(); + pstmt.close(); + + pstmt = conn.prepareStatement("select id from vm_template where name='systemvm-kvm-3.0.0' and removed is null"); + rs = pstmt.executeQuery(); + long templateId3 = rs.getLong(1); + rs.close(); + pstmt.close(); + + pstmt = conn.prepareStatement("select distinct(vm_template_id) from vm_instance where type <> 'USER' and hypervisor_type = 'KVM'"); + rs = pstmt.executeQuery(); + long templateId4 = rs.getLong(1); + rs.close(); + pstmt.close(); + + assert (templateId3 == templateId4) : "KVM System Vms not using 3.0.0 template"; + rs.close(); + pstmt.close(); + + } + +}