Example #1
0
        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);
        }
Example #2
0
        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);
        }