public Task HandleAsync(RuntimeUnattendedUpgradeNotification notification, CancellationToken cancellationToken) { if (_runtimeState.RunUnattendedBootLogic()) { switch (_runtimeState.Reason) { case RuntimeLevelReason.UpgradeMigrations: { var plan = new UmbracoPlan(_umbracoVersion); using (_profilingLogger.TraceDuration <UnattendedUpgrader>( "Starting unattended upgrade.", "Unattended upgrade completed.")) { DatabaseBuilder.Result result = _databaseBuilder.UpgradeSchemaAndData(plan); if (result.Success == false) { var innerException = new UnattendedInstallException("An error occurred while running the unattended upgrade.\n" + result.Message); _runtimeState.Configure(Core.RuntimeLevel.BootFailed, Core.RuntimeLevelReason.BootFailedOnException, innerException); } notification.UnattendedUpgradeResult = RuntimeUnattendedUpgradeNotification.UpgradeResult.CoreUpgradeComplete; } } break; case RuntimeLevelReason.UpgradePackageMigrations: { if (!_runtimeState.StartupState.TryGetValue(RuntimeState.PendingPacakgeMigrationsStateKey, out var pm) || pm is not IReadOnlyList <string> pendingMigrations) { throw new InvalidOperationException($"The required key {RuntimeState.PendingPacakgeMigrationsStateKey} does not exist in startup state"); } if (pendingMigrations.Count == 0) { throw new InvalidOperationException("No pending migrations found but the runtime level reason is " + Core.RuntimeLevelReason.UpgradePackageMigrations); } try { IEnumerable <ExecutedMigrationPlan> result = _packageMigrationRunner.RunPackagePlans(pendingMigrations); notification.UnattendedUpgradeResult = RuntimeUnattendedUpgradeNotification.UpgradeResult.PackageMigrationComplete; } catch (Exception ex) { SetRuntimeError(ex); notification.UnattendedUpgradeResult = RuntimeUnattendedUpgradeNotification.UpgradeResult.HasErrors; } } break; default: throw new InvalidOperationException("Invalid reason " + _runtimeState.Reason); } } return(Task.CompletedTask); }
public Task HandleAsync(RuntimeUnattendedInstallNotification notification, CancellationToken cancellationToken) { // unattended install is not enabled if (_unattendedSettings.Value.InstallUnattended == false) { return(Task.CompletedTask); } // no connection string set if (_databaseFactory.Configured == false) { return(Task.CompletedTask); } _runtimeState.DetermineRuntimeLevel(); if (_runtimeState.Reason == RuntimeLevelReason.InstallMissingDatabase) { _dbProviderFactoryCreator.CreateDatabase(_databaseFactory.ProviderName, _databaseFactory.ConnectionString); } bool connect; try { for (var i = 0; ;) { connect = _databaseFactory.CanConnect; if (connect || ++i == 5) { break; } _logger.LogDebug("Could not immediately connect to database, trying again."); Thread.Sleep(1000); } } catch (Exception ex) { _logger.LogInformation(ex, "Error during unattended install."); var innerException = new UnattendedInstallException("Unattended installation failed.", ex); _runtimeState.Configure(Core.RuntimeLevel.BootFailed, Core.RuntimeLevelReason.BootFailedOnException, innerException); return(Task.CompletedTask); } // could not connect to the database if (connect == false) { return(Task.CompletedTask); } IUmbracoDatabase database = null; try { using (database = _databaseFactory.CreateDatabase()) { var hasUmbracoTables = database.IsUmbracoInstalled(); // database has umbraco tables, assume Umbraco is already installed if (hasUmbracoTables) { return(Task.CompletedTask); } // all conditions fulfilled, do the install _logger.LogInformation("Starting unattended install."); database.BeginTransaction(); DatabaseSchemaCreator creator = _databaseSchemaCreatorFactory.Create(database); creator.InitializeDatabaseSchema(); database.CompleteTransaction(); _logger.LogInformation("Unattended install completed."); // Emit an event with EventAggregator that unattended install completed // Then this event can be listened for and create an unattended user _eventAggregator.Publish(new UnattendedInstallNotification()); } } catch (Exception ex) { _logger.LogInformation(ex, "Error during unattended install."); database?.AbortTransaction(); var innerException = new UnattendedInstallException( "The database configuration failed." + "\n Please check log file for additional information (can be found in '/Umbraco/Data/Logs/')", ex); _runtimeState.Configure(Core.RuntimeLevel.BootFailed, Core.RuntimeLevelReason.BootFailedOnException, innerException); } return(Task.CompletedTask); }