diff --git a/engine/schema/src/main/java/com/cloud/upgrade/DatabaseUpgradeChecker.java b/engine/schema/src/main/java/com/cloud/upgrade/DatabaseUpgradeChecker.java index abf860439375..1e473b14063f 100644 --- a/engine/schema/src/main/java/com/cloud/upgrade/DatabaseUpgradeChecker.java +++ b/engine/schema/src/main/java/com/cloud/upgrade/DatabaseUpgradeChecker.java @@ -123,7 +123,10 @@ import com.cloud.utils.crypt.DBEncryptionUtil; import com.cloud.utils.db.GlobalLock; import com.cloud.utils.db.ScriptRunner; +import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionCallback; import com.cloud.utils.db.TransactionLegacy; +import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.exception.CloudRuntimeException; import com.google.common.annotations.VisibleForTesting; @@ -448,39 +451,71 @@ public void check() { throw new CloudRuntimeException("Unable to acquire lock to check for database integrity."); } - try { - initializeDatabaseEncryptors(); + // not sure about the right moment to do this yet + checkIfStandalone(); + doUpgrades(lock); + } finally { + lock.releaseRef(); + } + } + private void checkIfStandalone() throws CloudRuntimeException { + boolean standalone = Transaction.execute(new TransactionCallback<>() { + @Override + public Boolean doInTransaction(TransactionStatus status) { + String sql = "SELECT COUNT(*) FROM `cloud`.`mshost` WHERE `state` = 'UP'"; + try (Connection conn = TransactionLegacy.getStandaloneConnection(); + PreparedStatement pstmt = conn.prepareStatement(sql); + ResultSet rs = pstmt.executeQuery()) { + if (rs.next()) { + int count = rs.getInt(1); + return count == 0; + } + } catch (SQLException e) { + String errorMessage = "Unable to check if the management server is running in standalone mode."; + LOGGER.error(errorMessage, e); + throw new CloudRuntimeException(errorMessage, e); + } + return true; + } + }); + if (! standalone) { + String msg = "CloudStack is running multiple management servers while attempting to upgrade. Upgrades can only be run in standalone mode. Aborting."; + LOGGER.info(msg); + throw new CloudRuntimeException(msg); + } + } - final CloudStackVersion dbVersion = CloudStackVersion.parse(_dao.getCurrentVersion()); - final String currentVersionValue = this.getClass().getPackage().getImplementationVersion(); + private void doUpgrades(GlobalLock lock) { + try { + initializeDatabaseEncryptors(); - if (StringUtils.isBlank(currentVersionValue)) { - return; - } + final CloudStackVersion dbVersion = CloudStackVersion.parse(_dao.getCurrentVersion()); + final String currentVersionValue = this.getClass().getPackage().getImplementationVersion(); - String csVersion = SystemVmTemplateRegistration.parseMetadataFile(); - final CloudStackVersion sysVmVersion = CloudStackVersion.parse(csVersion); - final CloudStackVersion currentVersion = CloudStackVersion.parse(currentVersionValue); - SystemVmTemplateRegistration.CS_MAJOR_VERSION = String.valueOf(sysVmVersion.getMajorRelease()) + "." + String.valueOf(sysVmVersion.getMinorRelease()); - SystemVmTemplateRegistration.CS_TINY_VERSION = String.valueOf(sysVmVersion.getPatchRelease()); + if (StringUtils.isBlank(currentVersionValue)) { + return; + } - LOGGER.info("DB version = " + dbVersion + " Code Version = " + currentVersion); + String csVersion = SystemVmTemplateRegistration.parseMetadataFile(); + final CloudStackVersion sysVmVersion = CloudStackVersion.parse(csVersion); + final CloudStackVersion currentVersion = CloudStackVersion.parse(currentVersionValue); + SystemVmTemplateRegistration.CS_MAJOR_VERSION = String.valueOf(sysVmVersion.getMajorRelease()) + "." + String.valueOf(sysVmVersion.getMinorRelease()); + SystemVmTemplateRegistration.CS_TINY_VERSION = String.valueOf(sysVmVersion.getPatchRelease()); - if (dbVersion.compareTo(currentVersion) > 0) { - throw new CloudRuntimeException("Database version " + dbVersion + " is higher than management software version " + currentVersionValue); - } + LOGGER.info("DB version = " + dbVersion + " Code Version = " + currentVersion); - if (dbVersion.compareTo(currentVersion) == 0) { - LOGGER.info("DB version and code version matches so no upgrade needed."); - return; - } + if (dbVersion.compareTo(currentVersion) > 0) { + throw new CloudRuntimeException("Database version " + dbVersion + " is higher than management software version " + currentVersionValue); + } - upgrade(dbVersion, currentVersion); - } finally { - lock.unlock(); + if (dbVersion.compareTo(currentVersion) == 0) { + LOGGER.info("DB version and code version matches so no upgrade needed."); + return; } + + upgrade(dbVersion, currentVersion); } finally { - lock.releaseRef(); + lock.unlock(); } }