diff options
Diffstat (limited to 'Jellyfin.Server/Migrations/JellyfinMigrationService.cs')
| -rw-r--r-- | Jellyfin.Server/Migrations/JellyfinMigrationService.cs | 41 |
1 files changed, 23 insertions, 18 deletions
diff --git a/Jellyfin.Server/Migrations/JellyfinMigrationService.cs b/Jellyfin.Server/Migrations/JellyfinMigrationService.cs index 5c5c64ec3..5331b43e3 100644 --- a/Jellyfin.Server/Migrations/JellyfinMigrationService.cs +++ b/Jellyfin.Server/Migrations/JellyfinMigrationService.cs @@ -10,13 +10,13 @@ using Emby.Server.Implementations.Serialization; using Jellyfin.Database.Implementations; using Jellyfin.Server.Implementations.SystemBackupService; using Jellyfin.Server.Migrations.Stages; +using Jellyfin.Server.ServerSetupApp; using MediaBrowser.Common.Configuration; using MediaBrowser.Controller.SystemBackupService; using MediaBrowser.Model.Configuration; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; namespace Jellyfin.Server.Migrations; @@ -29,6 +29,7 @@ internal class JellyfinMigrationService private const string DbFilename = "library.db"; private readonly IDbContextFactory<JellyfinDbContext> _dbContextFactory; private readonly ILoggerFactory _loggerFactory; + private readonly IStartupLogger _startupLogger; private readonly IBackupService? _backupService; private readonly IJellyfinDatabaseProvider? _jellyfinDatabaseProvider; private readonly IApplicationPaths _applicationPaths; @@ -39,18 +40,21 @@ internal class JellyfinMigrationService /// </summary> /// <param name="dbContextFactory">Provides access to the jellyfin database.</param> /// <param name="loggerFactory">The logger factory.</param> + /// <param name="startupLogger">The startup logger for Startup UI intigration.</param> /// <param name="applicationPaths">Application paths for library.db backup.</param> /// <param name="backupService">The jellyfin backup service.</param> /// <param name="jellyfinDatabaseProvider">The jellyfin database provider.</param> public JellyfinMigrationService( IDbContextFactory<JellyfinDbContext> dbContextFactory, ILoggerFactory loggerFactory, + IStartupLogger startupLogger, IApplicationPaths applicationPaths, IBackupService? backupService = null, IJellyfinDatabaseProvider? jellyfinDatabaseProvider = null) { _dbContextFactory = dbContextFactory; _loggerFactory = loggerFactory; + _startupLogger = startupLogger; _backupService = backupService; _jellyfinDatabaseProvider = jellyfinDatabaseProvider; _applicationPaths = applicationPaths; @@ -80,14 +84,14 @@ internal class JellyfinMigrationService private interface IInternalMigration { - Task PerformAsync(ILogger logger); + Task PerformAsync(IStartupLogger logger); } private HashSet<MigrationStage> Migrations { get; set; } public async Task CheckFirstTimeRunOrMigration(IApplicationPaths appPaths) { - var logger = _loggerFactory.CreateLogger<JellyfinMigrationService>(); + var logger = _startupLogger.With(_loggerFactory.CreateLogger<JellyfinMigrationService>()).BeginGroup($"Migration Startup"); logger.LogInformation("Initialise Migration service."); var xmlSerializer = new MyXmlSerializer(); var serverConfig = File.Exists(appPaths.SystemConfigurationFilePath) @@ -173,8 +177,7 @@ internal class JellyfinMigrationService public async Task MigrateStepAsync(JellyfinMigrationStageTypes stage, IServiceProvider? serviceProvider) { - var logger = _loggerFactory.CreateLogger<JellyfinMigrationService>(); - logger.LogInformation("Migrate stage {Stage}.", stage); + var logger = _startupLogger.With(_loggerFactory.CreateLogger<JellyfinMigrationService>()).BeginGroup($"Migrate stage {stage}."); ICollection<CodeMigration> migrationStage = (Migrations.FirstOrDefault(e => e.Stage == stage) as ICollection<CodeMigration>) ?? []; var dbContext = await _dbContextFactory.CreateDbContextAsync().ConfigureAwait(false); @@ -202,21 +205,23 @@ internal class JellyfinMigrationService foreach (var item in migrations) { + var migrationLogger = logger.With(_loggerFactory.CreateLogger(item.Migration.GetType().Name)).BeginGroup($"{item.Key}"); try { - logger.LogInformation("Perform migration {Name}", item.Key); - await item.Migration.PerformAsync(_loggerFactory.CreateLogger(item.GetType().Name)).ConfigureAwait(false); - logger.LogInformation("Migration {Name} was successfully applied", item.Key); + migrationLogger.LogInformation("Perform migration {Name}", item.Key); + await item.Migration.PerformAsync(migrationLogger).ConfigureAwait(false); + migrationLogger.LogInformation("Migration {Name} was successfully applied", item.Key); } catch (Exception ex) { - logger.LogCritical(ex, "Migration {Name} failed, migration service will attempt to roll back.", item.Key); + migrationLogger.LogCritical("Error: {Error}", ex.Message); + migrationLogger.LogError(ex, "Migration {Name} failed", item.Key); if (_backupKey != default && _backupService is not null && _jellyfinDatabaseProvider is not null) { if (_backupKey.LibraryDb is not null) { - logger.LogInformation("Attempt to rollback librarydb."); + migrationLogger.LogInformation("Attempt to rollback librarydb."); try { var libraryDbPath = Path.Combine(_applicationPaths.DataPath, DbFilename); @@ -224,33 +229,33 @@ internal class JellyfinMigrationService } catch (Exception inner) { - logger.LogCritical(inner, "Could not rollback {LibraryPath}. Manual intervention might be required to restore a operational state.", _backupKey.LibraryDb); + migrationLogger.LogCritical(inner, "Could not rollback {LibraryPath}. Manual intervention might be required to restore a operational state.", _backupKey.LibraryDb); } } if (_backupKey.JellyfinDb is not null) { - logger.LogInformation("Attempt to rollback JellyfinDb."); + migrationLogger.LogInformation("Attempt to rollback JellyfinDb."); try { await _jellyfinDatabaseProvider.RestoreBackupFast(_backupKey.JellyfinDb, CancellationToken.None).ConfigureAwait(false); } catch (Exception inner) { - logger.LogCritical(inner, "Could not rollback {LibraryPath}. Manual intervention might be required to restore a operational state.", _backupKey.JellyfinDb); + migrationLogger.LogCritical(inner, "Could not rollback {LibraryPath}. Manual intervention might be required to restore a operational state.", _backupKey.JellyfinDb); } } if (_backupKey.FullBackup is not null) { - logger.LogInformation("Attempt to rollback from backup."); + migrationLogger.LogInformation("Attempt to rollback from backup."); try { await _backupService.RestoreBackupAsync(_backupKey.FullBackup.Path).ConfigureAwait(false); } catch (Exception inner) { - logger.LogCritical(inner, "Could not rollback from backup {Backup}. Manual intervention might be required to restore a operational state.", _backupKey.FullBackup.Path); + migrationLogger.LogCritical(inner, "Could not rollback from backup {Backup}. Manual intervention might be required to restore a operational state.", _backupKey.FullBackup.Path); } } } @@ -416,9 +421,9 @@ internal class JellyfinMigrationService _dbContext = dbContext; } - public async Task PerformAsync(ILogger logger) + public async Task PerformAsync(IStartupLogger logger) { - await _codeMigration.Perform(_serviceProvider, CancellationToken.None).ConfigureAwait(false); + await _codeMigration.Perform(_serviceProvider, logger, CancellationToken.None).ConfigureAwait(false); var historyRepository = _dbContext.GetService<IHistoryRepository>(); var createScript = historyRepository.GetInsertScript(new HistoryRow(_codeMigration.BuildCodeMigrationId(), GetJellyfinVersion())); @@ -437,7 +442,7 @@ internal class JellyfinMigrationService _jellyfinDbContext = jellyfinDbContext; } - public async Task PerformAsync(ILogger logger) + public async Task PerformAsync(IStartupLogger logger) { var migrator = _jellyfinDbContext.GetService<IMigrator>(); await migrator.MigrateAsync(_databaseMigrationInfo.Key).ConfigureAwait(false); |
