From c72ce0b7598b332aa9650a76986201896a7d2e6f Mon Sep 17 00:00:00 2001 From: Stephan Date: Thu, 29 Mar 2018 11:31:33 +0200 Subject: [PATCH] Fix Examine PR, fix migrations and upgrades --- src/Umbraco.Core/IRuntimeState.cs | 10 ++++++ .../Migrations/Upgrade/UmbracoPlan.cs | 2 +- src/Umbraco.Core/Runtime/CoreRuntime.cs | 36 ++++++++++--------- src/Umbraco.Core/RuntimeState.cs | 6 ++++ .../src/installer/steps/upgrade.html | 11 +++--- src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 5 +-- src/Umbraco.Web.UI/packages.config | 2 +- .../Install/InstallSteps/UpgradeStep.cs | 28 ++++++++------- src/Umbraco.Web/Search/ExamineComponent.cs | 9 ++--- 9 files changed, 64 insertions(+), 45 deletions(-) diff --git a/src/Umbraco.Core/IRuntimeState.cs b/src/Umbraco.Core/IRuntimeState.cs index 5c0c01ef3b..5fcfab1518 100644 --- a/src/Umbraco.Core/IRuntimeState.cs +++ b/src/Umbraco.Core/IRuntimeState.cs @@ -57,6 +57,16 @@ namespace Umbraco.Core /// RuntimeLevel Level { get; } + /// + /// Gets the current migration state. + /// + string CurrentMigrationState { get; } + + /// + /// Gets the final migration state. + /// + string FinalMigrationState { get; } + /// /// Gets the exception that caused the boot to fail. /// diff --git a/src/Umbraco.Core/Migrations/Upgrade/UmbracoPlan.cs b/src/Umbraco.Core/Migrations/Upgrade/UmbracoPlan.cs index db3b918241..f8cd4b0f78 100644 --- a/src/Umbraco.Core/Migrations/Upgrade/UmbracoPlan.cs +++ b/src/Umbraco.Core/Migrations/Upgrade/UmbracoPlan.cs @@ -112,7 +112,7 @@ namespace Umbraco.Core.Migrations.Upgrade Chain("{8640C9E4-A1C0-4C59-99BB-609B4E604981}"); Chain("{DD1B99AF-8106-4E00-BAC7-A43003EA07F8}"); Chain("{9DF05B77-11D1-475C-A00A-B656AF7E0908}"); - Chain("{CA7DB949-3EF4-403D-8464-F9BA36A52E87}"); + Chain("{6FE3EF34-44A0-4992-B379-B40BC4EF1C4D}"); Chain("{7F59355A-0EC9-4438-8157-EB517E6D2727}"); // must chain to v8 final state (see at end of file) diff --git a/src/Umbraco.Core/Runtime/CoreRuntime.cs b/src/Umbraco.Core/Runtime/CoreRuntime.cs index 7d28ffcf57..44d7ad3f68 100644 --- a/src/Umbraco.Core/Runtime/CoreRuntime.cs +++ b/src/Umbraco.Core/Runtime/CoreRuntime.cs @@ -138,7 +138,7 @@ namespace Umbraco.Core.Runtime try { var dbfactory = container.GetInstance(); - SetRuntimeStateLevel(_state, dbfactory, Logger); + SetRuntimeStateLevel(dbfactory, Logger); Logger.Debug($"Runtime level: {_state.Level}"); } catch @@ -233,38 +233,38 @@ namespace Umbraco.Core.Runtime builder.AddCore(); } - private void SetRuntimeStateLevel(RuntimeState runtimeState, IUmbracoDatabaseFactory databaseFactory, ILogger logger) + private void SetRuntimeStateLevel(IUmbracoDatabaseFactory databaseFactory, ILogger logger) { var localVersion = UmbracoVersion.Local; // the local, files, version - var codeVersion = runtimeState.SemanticVersion; // the executing code version + var codeVersion = _state.SemanticVersion; // the executing code version var connect = false; // we don't know yet - runtimeState.Level = RuntimeLevel.Unknown; + _state.Level = RuntimeLevel.Unknown; if (localVersion == null) { // there is no local version, we are not installed logger.Debug("No local version, need to install Umbraco."); - runtimeState.Level = RuntimeLevel.Install; + _state.Level = RuntimeLevel.Install; } else if (localVersion != codeVersion) { // there *is* a local version, but it does not match the code version // need to upgrade logger.Debug($"Local version \"{localVersion}\" != code version \"{codeVersion}\", need to upgrade Umbraco."); - runtimeState.Level = RuntimeLevel.Upgrade; + _state.Level = RuntimeLevel.Upgrade; } else if (databaseFactory.Configured == false) { // local version *does* match code version, but the database is not configured // install (again? this is a weird situation...) logger.Debug("Database is not configured, need to install Umbraco."); - runtimeState.Level = RuntimeLevel.Install; + _state.Level = RuntimeLevel.Install; } // install? not going to test anything else - if (runtimeState.Level == RuntimeLevel.Install) + if (_state.Level == RuntimeLevel.Install) return; // else, keep going, @@ -284,14 +284,14 @@ namespace Umbraco.Core.Runtime { // cannot connect to configured database, this is bad, fail logger.Debug("Could not connect to database."); - runtimeState.Level = RuntimeLevel.BootFailed; + _state.Level = RuntimeLevel.BootFailed; // in fact, this is bad enough that we want to throw throw new BootFailedException("A connection string is configured but Umbraco could not connect to the database."); } // if we already know we want to upgrade, no need to look for migrations... - if (runtimeState.Level == RuntimeLevel.Upgrade) + if (_state.Level == RuntimeLevel.Upgrade) return; // else @@ -302,18 +302,19 @@ namespace Umbraco.Core.Runtime { exists = EnsureUmbracoUpgradeState(databaseFactory, logger); } - catch + catch (Exception e) { // can connect to the database but cannot access the migration table... need to install + logger.Warn(e, "Could not check the upgrade state."); logger.Debug("Could not check the upgrade state, need to install Umbraco."); - runtimeState.Level = RuntimeLevel.Install; + _state.Level = RuntimeLevel.Install; return; } if (exists) { // the database version matches the code & files version, all clear, can run - runtimeState.Level = RuntimeLevel.Run; + _state.Level = RuntimeLevel.Run; return; } @@ -323,7 +324,7 @@ namespace Umbraco.Core.Runtime // 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."); - runtimeState.Level = RuntimeLevel.Upgrade; + _state.Level = RuntimeLevel.Upgrade; } protected virtual bool EnsureUmbracoUpgradeState(IUmbracoDatabaseFactory databaseFactory, ILogger logger) @@ -343,11 +344,12 @@ namespace Umbraco.Core.Runtime state = database.FirstOrDefault(sql)?.Value; } - var finalState = umbracoPlan.FinalState; + _state.CurrentMigrationState = state; + _state.FinalMigrationState = umbracoPlan.FinalState; - logger.Debug($"Final upgrade state is \"{finalState}\", database contains \"{state ?? ""}\"."); + logger.Debug($"Final upgrade state is \"{_state.FinalMigrationState}\", database contains \"{state ?? ""}\"."); - return state == finalState; + return state == _state.FinalMigrationState; } #region Locals diff --git a/src/Umbraco.Core/RuntimeState.cs b/src/Umbraco.Core/RuntimeState.cs index 3c3ebdbd84..d740352649 100644 --- a/src/Umbraco.Core/RuntimeState.cs +++ b/src/Umbraco.Core/RuntimeState.cs @@ -85,6 +85,12 @@ namespace Umbraco.Core /// This is either "/" or eg "/virtual". public string ApplicationVirtualPath { get; } = HttpRuntime.AppDomainAppVirtualPath; + /// + public string CurrentMigrationState { get; internal set; } + + /// + public string FinalMigrationState { get; internal set; } + /// /// Gets the runtime level of execution. /// diff --git a/src/Umbraco.Web.UI.Client/src/installer/steps/upgrade.html b/src/Umbraco.Web.UI.Client/src/installer/steps/upgrade.html index 4edf2eda25..472ceb7135 100644 --- a/src/Umbraco.Web.UI.Client/src/installer/steps/upgrade.html +++ b/src/Umbraco.Web.UI.Client/src/installer/steps/upgrade.html @@ -1,18 +1,19 @@ 

Upgrading Umbraco

- Welcome to the Umbraco installer. You see this screen because your Umbraco installation needs a quick upgrade of its database and files, which will ensure your website is kept as fast, secure and up to date as possible. + Welcome to the Umbraco installer. You see this screen because your Umbraco installation needs a quick upgrade + of its database and files, which will ensure your website is kept as fast, secure and up to date as possible.

-

- To read a report of changes between your current version {{installer.current.model.currentVersion}} and this version you're upgrading to {{installer.current.model.newVersion}} + Detected current version {{installer.current.model.currentVersion}} ({{installer.current.model.currentState}}), + which needs to be upgraded to {{installer.current.model.newVersion}} ({{installer.current.model.newState}}). + To compare versions and read a report of changes between versions, use the View Report button below.

View Report

-

- Simply click continue below to be guided through the rest of the upgrade + Simply click continue below to be guided through the rest of the upgrade.

diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index 8d60ae38e6..15656718f3 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -54,11 +54,12 @@ ..\packages\AutoMapper.6.1.1\lib\net45\AutoMapper.dll - - ..\packages\Examine.1.0.0-beta020\lib\net45\Examine.dll ..\packages\ClientDependency.1.9.6\lib\net45\ClientDependency.Core.dll + + ..\packages\Examine.1.0.0-beta024\lib\net45\Examine.dll + ..\packages\ImageProcessor.Web.4.8.4\lib\net45\ImageProcessor.Web.dll diff --git a/src/Umbraco.Web.UI/packages.config b/src/Umbraco.Web.UI/packages.config index 63f9690512..98b3d56f79 100644 --- a/src/Umbraco.Web.UI/packages.config +++ b/src/Umbraco.Web.UI/packages.config @@ -4,7 +4,7 @@ - + diff --git a/src/Umbraco.Web/Install/InstallSteps/UpgradeStep.cs b/src/Umbraco.Web/Install/InstallSteps/UpgradeStep.cs index 75b027f69f..1d36fe9e12 100644 --- a/src/Umbraco.Web/Install/InstallSteps/UpgradeStep.cs +++ b/src/Umbraco.Web/Install/InstallSteps/UpgradeStep.cs @@ -1,4 +1,6 @@ -using Umbraco.Core.Configuration; +using System; +using Umbraco.Core.Composing; +using Umbraco.Core.Configuration; using Umbraco.Web.Install.Models; namespace Umbraco.Web.Install.InstallSteps @@ -9,26 +11,28 @@ namespace Umbraco.Web.Install.InstallSteps [InstallSetupStep(InstallationType.Upgrade, "Upgrade", "upgrade", 1, "Upgrading Umbraco to the latest and greatest version.")] internal class UpgradeStep : InstallSetupStep { - public override bool RequiresExecution(object model) - { - return true; - } + public override bool RequiresExecution(object model) => true; - public override InstallSetupResult Execute(object model) - { - return null; - } + public override InstallSetupResult Execute(object model) => null; public override object ViewModel { get { - // fixme where is the "detected current version"? var currentVersion = UmbracoVersion.Local.ToString(); - var newVersion = UmbracoVersion.Current.ToString(); + var newVersion = UmbracoVersion.SemanticVersion.ToString(); + + var state = Current.RuntimeState; // fixme inject + var currentState = state.CurrentMigrationState; + if (string.IsNullOrWhiteSpace(currentState)) currentState = "unknown"; + var newState = state.FinalMigrationState?.Trim('{', '}'); + if (string.IsNullOrWhiteSpace(newState)) newState = "unknown"; + else if (Guid.TryParse(newState, out _)) + newState = newState.Substring(0, 8); + var reportUrl = $"https://our.umbraco.org/contribute/releases/compare?from={currentVersion}&to={newVersion}¬es=1"; - return new { currentVersion, newVersion, reportUrl }; + return new { currentVersion, newVersion, currentState, newState, reportUrl }; } } } diff --git a/src/Umbraco.Web/Search/ExamineComponent.cs b/src/Umbraco.Web/Search/ExamineComponent.cs index af0ddc33ef..278f124344 100644 --- a/src/Umbraco.Web/Search/ExamineComponent.cs +++ b/src/Umbraco.Web/Search/ExamineComponent.cs @@ -48,18 +48,13 @@ namespace Umbraco.Web.Search // but greater that SafeXmlReaderWriter priority which is 60 private const int EnlistPriority = 80; - public void Initialize(IRuntimeState runtime, PropertyEditorCollection propertyEditors, IExamineManager examineManager, ProfilingLogger profilingLogger, IScopeProvider scopeProvider, UrlSegmentProviderCollection urlSegmentProviderCollection, ServiceContext services) + internal void Initialize(IRuntimeState runtime, MainDom mainDom, PropertyEditorCollection propertyEditors, IExamineManager examineManager, ProfilingLogger profilingLogger, IScopeProvider scopeProvider, UrlSegmentProviderCollection urlSegmentProviderCollection, ServiceContext services) { _services = services; _urlSegmentProviders = urlSegmentProviderCollection; _scopeProvider = scopeProvider; _examineManager = examineManager; - //fixme we cannot inject MainDom since it's internal, so thsi is the only way we can get it, alternatively we can add the container to the container and resolve - //directly from the container but that's not nice either - if (!(runtime is RuntimeState coreRuntime)) - throw new NotSupportedException($"Unsupported IRuntimeState implementation {runtime.GetType().FullName}, expecting {typeof(RuntimeState).FullName}."); - //We want to manage Examine's appdomain shutdown sequence ourselves so first we'll disable Examine's default behavior //and then we'll use MainDom to control Examine's shutdown ExamineManager.DisableDefaultHostingEnvironmentRegistration(); @@ -74,7 +69,7 @@ namespace Umbraco.Web.Search }; //let's deal with shutting down Examine with MainDom - var examineShutdownRegistered = coreRuntime.MainDom.Register(() => + var examineShutdownRegistered = mainDom.Register(() => { using (profilingLogger.TraceDuration("Examine shutting down")) {