From 5efc1817d66ffd59946d89c635e89d55b9769dfa Mon Sep 17 00:00:00 2001 From: Rasmus John Pedersen Date: Tue, 8 Dec 2020 09:06:28 +0100 Subject: [PATCH] Add unattended upgrade support --- src/Umbraco.Core/Runtime/CoreRuntime.cs | 22 ++++++++++++++++++++++ src/Umbraco.Core/RuntimeOptions.cs | 10 ++++++++++ src/Umbraco.Core/RuntimeState.cs | 4 ++-- 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Core/Runtime/CoreRuntime.cs b/src/Umbraco.Core/Runtime/CoreRuntime.cs index 81738151f3..ba2e38f80f 100644 --- a/src/Umbraco.Core/Runtime/CoreRuntime.cs +++ b/src/Umbraco.Core/Runtime/CoreRuntime.cs @@ -13,6 +13,7 @@ using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Logging.Serilog; using Umbraco.Core.Migrations.Install; +using Umbraco.Core.Migrations.Upgrade; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.Mappers; using Umbraco.Core.Sync; @@ -189,6 +190,16 @@ namespace Umbraco.Core.Runtime // create the factory _factory = Current.Factory = composition.CreateFactory(); + // if level is Run and reason is UpgradeMigrations, that means we need to perform an unattended upgrade + if (_state.Reason == RuntimeLevelReason.UpgradeMigrations && _state.Level == RuntimeLevel.Run) + { + // do the upgrade + DoUnattendedUpgrade(_factory.GetInstance()); + + // upgrade is done, set reason to Run + _state.Reason = RuntimeLevelReason.Run; + } + // create & initialize the components _components = _factory.GetInstance(); _components.Initialize(); @@ -288,6 +299,17 @@ namespace Umbraco.Core.Runtime } } + private void DoUnattendedUpgrade(DatabaseBuilder databaseBuilder) + { + var plan = new UmbracoPlan(); + Logger.Info("Starting unattended upgrade."); + var result = databaseBuilder.UpgradeSchemaAndData(plan); + Logger.Info("Unattended upgrade completed."); + + if (result.Success == false) + throw new UnattendedInstallException("An error occurred while running the unattended upgrade.\n" + result.Message); + } + protected virtual void ConfigureUnhandledException() { //take care of unhandled exceptions - there is nothing we can do to diff --git a/src/Umbraco.Core/RuntimeOptions.cs b/src/Umbraco.Core/RuntimeOptions.cs index 0d64d36849..6183f62c1c 100644 --- a/src/Umbraco.Core/RuntimeOptions.cs +++ b/src/Umbraco.Core/RuntimeOptions.cs @@ -23,6 +23,7 @@ namespace Umbraco.Core private static bool? _installMissingDatabase; private static bool? _installEmptyDatabase; private static bool? _installUnattended; + private static bool? _upgradeUnattended; // reads a boolean appSetting private static bool BoolSetting(string key, bool missing) => ConfigurationManager.AppSettings[key]?.InvariantEquals("true") ?? missing; @@ -66,6 +67,15 @@ namespace Umbraco.Core set => _installUnattended = value; } + /// + /// Gets a value indicating whether unattended upgrade is enabled. + /// + public static bool UpgradeUnattended + { + get => _upgradeUnattended ?? BoolSetting("Umbraco.Core.RuntimeState.UpgradeUnattended", false); + set => _upgradeUnattended = value; + } + /// /// Executes the RuntimeBoot handlers. /// diff --git a/src/Umbraco.Core/RuntimeState.cs b/src/Umbraco.Core/RuntimeState.cs index 4a10b48dd6..c7a1a18d44 100644 --- a/src/Umbraco.Core/RuntimeState.cs +++ b/src/Umbraco.Core/RuntimeState.cs @@ -130,7 +130,7 @@ namespace Umbraco.Core { var localVersion = UmbracoVersion.LocalVersion; // the local, files, version var codeVersion = SemanticVersion; // the executing code version - + if (localVersion == null) { // there is no local version, we are not installed @@ -202,7 +202,7 @@ namespace Umbraco.Core // although the files version matches the code version, the database version does not // which means the local files have been upgraded but not the database - need to upgrade _logger.Debug("Has not reached the final upgrade step, need to upgrade Umbraco."); - Level = RuntimeLevel.Upgrade; + Level = RuntimeOptions.UpgradeUnattended ? RuntimeLevel.Run : RuntimeLevel.Upgrade; Reason = RuntimeLevelReason.UpgradeMigrations; } break;