diff options
| author | Mark Monteiro <marknr.monteiro@protonmail.com> | 2020-05-14 11:08:08 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-05-14 11:08:08 -0400 |
| commit | 2e09311a93cbf7b4d0629e058974a84e70c4b800 (patch) | |
| tree | 9217bb9d15df7f1a516afcbc2f531bbc35161a53 /Jellyfin.Server | |
| parent | 3623aafcb60dec4f4f5055046717d895b7597b60 (diff) | |
| parent | 11dd96f6c715b0f701903e636f08ee910c9a08eb (diff) | |
Merge branch 'master' into websocket
Diffstat (limited to 'Jellyfin.Server')
| -rw-r--r-- | Jellyfin.Server/Migrations/IMigrationRoutine.cs | 4 | ||||
| -rw-r--r-- | Jellyfin.Server/Migrations/MigrationRunner.cs | 19 | ||||
| -rw-r--r-- | Jellyfin.Server/Migrations/Routines/CreateUserLoggingConfigFile.cs | 11 | ||||
| -rw-r--r-- | Jellyfin.Server/Migrations/Routines/DisableTranscodingThrottling.cs | 17 | ||||
| -rw-r--r-- | Jellyfin.Server/Program.cs | 109 |
5 files changed, 108 insertions, 52 deletions
diff --git a/Jellyfin.Server/Migrations/IMigrationRoutine.cs b/Jellyfin.Server/Migrations/IMigrationRoutine.cs index eab995d67e..b79fdeac03 100644 --- a/Jellyfin.Server/Migrations/IMigrationRoutine.cs +++ b/Jellyfin.Server/Migrations/IMigrationRoutine.cs @@ -21,8 +21,6 @@ namespace Jellyfin.Server.Migrations /// <summary> /// Execute the migration routine. /// </summary> - /// <param name="host">Host that hosts current version.</param> - /// <param name="logger">Host logger.</param> - public void Perform(CoreAppHost host, ILogger logger); + public void Perform(); } } diff --git a/Jellyfin.Server/Migrations/MigrationRunner.cs b/Jellyfin.Server/Migrations/MigrationRunner.cs index b5ea04dcac..ca17482820 100644 --- a/Jellyfin.Server/Migrations/MigrationRunner.cs +++ b/Jellyfin.Server/Migrations/MigrationRunner.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using MediaBrowser.Common.Configuration; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; namespace Jellyfin.Server.Migrations @@ -13,10 +14,10 @@ namespace Jellyfin.Server.Migrations /// <summary> /// The list of known migrations, in order of applicability. /// </summary> - internal static readonly IMigrationRoutine[] Migrations = + private static readonly Type[] _migrationTypes = { - new Routines.DisableTranscodingThrottling(), - new Routines.CreateUserLoggingConfigFile() + typeof(Routines.DisableTranscodingThrottling), + typeof(Routines.CreateUserLoggingConfigFile) }; /// <summary> @@ -27,6 +28,10 @@ namespace Jellyfin.Server.Migrations public static void Run(CoreAppHost host, ILoggerFactory loggerFactory) { var logger = loggerFactory.CreateLogger<MigrationRunner>(); + var migrations = _migrationTypes + .Select(m => ActivatorUtilities.CreateInstance(host.ServiceProvider, m)) + .OfType<IMigrationRoutine>() + .ToArray(); var migrationOptions = ((IConfigurationManager)host.ServerConfigurationManager).GetConfiguration<MigrationOptions>(MigrationsListStore.StoreKey); if (!host.ServerConfigurationManager.Configuration.IsStartupWizardCompleted && migrationOptions.Applied.Count == 0) @@ -34,16 +39,16 @@ namespace Jellyfin.Server.Migrations // If startup wizard is not finished, this is a fresh install. // Don't run any migrations, just mark all of them as applied. logger.LogInformation("Marking all known migrations as applied because this is a fresh install"); - migrationOptions.Applied.AddRange(Migrations.Select(m => (m.Id, m.Name))); + migrationOptions.Applied.AddRange(migrations.Select(m => (m.Id, m.Name))); host.ServerConfigurationManager.SaveConfiguration(MigrationsListStore.StoreKey, migrationOptions); return; } var appliedMigrationIds = migrationOptions.Applied.Select(m => m.Id).ToHashSet(); - for (var i = 0; i < Migrations.Length; i++) + for (var i = 0; i < migrations.Length; i++) { - var migrationRoutine = Migrations[i]; + var migrationRoutine = migrations[i]; if (appliedMigrationIds.Contains(migrationRoutine.Id)) { logger.LogDebug("Skipping migration '{Name}' since it is already applied", migrationRoutine.Name); @@ -54,7 +59,7 @@ namespace Jellyfin.Server.Migrations try { - migrationRoutine.Perform(host, logger); + migrationRoutine.Perform(); } catch (Exception ex) { diff --git a/Jellyfin.Server/Migrations/Routines/CreateUserLoggingConfigFile.cs b/Jellyfin.Server/Migrations/Routines/CreateUserLoggingConfigFile.cs index 3bc32c0478..89514c89b7 100644 --- a/Jellyfin.Server/Migrations/Routines/CreateUserLoggingConfigFile.cs +++ b/Jellyfin.Server/Migrations/Routines/CreateUserLoggingConfigFile.cs @@ -36,6 +36,13 @@ namespace Jellyfin.Server.Migrations.Routines @"{""Serilog"":{""MinimumLevel"":""Information"",""WriteTo"":[{""Name"":""Console"",""Args"":{""outputTemplate"":""[{Timestamp:HH:mm:ss}] [{Level:u3}] [{ThreadId}] {SourceContext}: {Message:lj}{NewLine}{Exception}""}},{""Name"":""Async"",""Args"":{""configure"":[{""Name"":""File"",""Args"":{""path"":""%JELLYFIN_LOG_DIR%//log_.log"",""rollingInterval"":""Day"",""retainedFileCountLimit"":3,""rollOnFileSizeLimit"":true,""fileSizeLimitBytes"":100000000,""outputTemplate"":""[{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz}] [{Level:u3}] [{ThreadId}] {SourceContext}:{Message}{NewLine}{Exception}""}}]}}],""Enrich"":[""FromLogContext"",""WithThreadId""]}}", }; + private readonly IApplicationPaths _appPaths; + + public CreateUserLoggingConfigFile(IApplicationPaths appPaths) + { + _appPaths = appPaths; + } + /// <inheritdoc/> public Guid Id => Guid.Parse("{EF103419-8451-40D8-9F34-D1A8E93A1679}"); @@ -43,9 +50,9 @@ namespace Jellyfin.Server.Migrations.Routines public string Name => "CreateLoggingConfigHeirarchy"; /// <inheritdoc/> - public void Perform(CoreAppHost host, ILogger logger) + public void Perform() { - var logDirectory = host.Resolve<IApplicationPaths>().ConfigurationDirectoryPath; + var logDirectory = _appPaths.ConfigurationDirectoryPath; var existingConfigPath = Path.Combine(logDirectory, "logging.json"); // If the existing logging.json config file is unmodified, then 'reset' it by moving it to 'logging.old.json' diff --git a/Jellyfin.Server/Migrations/Routines/DisableTranscodingThrottling.cs b/Jellyfin.Server/Migrations/Routines/DisableTranscodingThrottling.cs index 6f8e4a8ffb..b2e957d5bb 100644 --- a/Jellyfin.Server/Migrations/Routines/DisableTranscodingThrottling.cs +++ b/Jellyfin.Server/Migrations/Routines/DisableTranscodingThrottling.cs @@ -10,6 +10,15 @@ namespace Jellyfin.Server.Migrations.Routines /// </summary> internal class DisableTranscodingThrottling : IMigrationRoutine { + private readonly ILogger _logger; + private readonly IConfigurationManager _configManager; + + public DisableTranscodingThrottling(ILogger<DisableTranscodingThrottling> logger, IConfigurationManager configManager) + { + _logger = logger; + _configManager = configManager; + } + /// <inheritdoc/> public Guid Id => Guid.Parse("{4124C2CD-E939-4FFB-9BE9-9B311C413638}"); @@ -17,16 +26,16 @@ namespace Jellyfin.Server.Migrations.Routines public string Name => "DisableTranscodingThrottling"; /// <inheritdoc/> - public void Perform(CoreAppHost host, ILogger logger) + public void Perform() { // Set EnableThrottling to false since it wasn't used before and may introduce issues - var encoding = ((IConfigurationManager)host.ServerConfigurationManager).GetConfiguration<EncodingOptions>("encoding"); + var encoding = _configManager.GetConfiguration<EncodingOptions>("encoding"); if (encoding.EnableThrottling) { - logger.LogInformation("Disabling transcoding throttling during migration"); + _logger.LogInformation("Disabling transcoding throttling during migration"); encoding.EnableThrottling = false; - host.ServerConfigurationManager.SaveConfiguration("encoding", encoding); + _configManager.SaveConfiguration("encoding", encoding); } } } diff --git a/Jellyfin.Server/Program.cs b/Jellyfin.Server/Program.cs index 9635cc6ec2..b9895386f5 100644 --- a/Jellyfin.Server/Program.cs +++ b/Jellyfin.Server/Program.cs @@ -10,14 +10,11 @@ using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using CommandLine; -using Emby.Drawing; using Emby.Server.Implementations; using Emby.Server.Implementations.HttpServer; using Emby.Server.Implementations.IO; using Emby.Server.Implementations.Networking; -using Jellyfin.Drawing.Skia; using MediaBrowser.Common.Configuration; -using MediaBrowser.Controller.Drawing; using MediaBrowser.Controller.Extensions; using MediaBrowser.WebDashboard.Api; using Microsoft.AspNetCore.Hosting; @@ -161,23 +158,7 @@ namespace Jellyfin.Server ApplicationHost.LogEnvironmentInfo(_logger, appPaths); - // Make sure we have all the code pages we can get - // Ref: https://docs.microsoft.com/en-us/dotnet/api/system.text.codepagesencodingprovider.instance?view=netcore-3.0#remarks - Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); - - // Increase the max http request limit - // The default connection limit is 10 for ASP.NET hosted applications and 2 for all others. - ServicePointManager.DefaultConnectionLimit = Math.Max(96, ServicePointManager.DefaultConnectionLimit); - - // Disable the "Expect: 100-Continue" header by default - // http://stackoverflow.com/questions/566437/http-post-returns-the-error-417-expectation-failed-c - ServicePointManager.Expect100Continue = false; - - Batteries_V2.Init(); - if (raw.sqlite3_enable_shared_cache(1) != raw.SQLITE_OK) - { - _logger.LogWarning("Failed to enable shared cache for SQLite"); - } + PerformStaticInitialization(); var appHost = new CoreAppHost( appPaths, @@ -205,7 +186,7 @@ namespace Jellyfin.Server ServiceCollection serviceCollection = new ServiceCollection(); appHost.Init(serviceCollection); - var webHost = CreateWebHostBuilder(appHost, serviceCollection, options, startupConfig, appPaths).Build(); + var webHost = new WebHostBuilder().ConfigureWebHostBuilder(appHost, serviceCollection, options, startupConfig, appPaths).Build(); // Re-use the web host service provider in the app host since ASP.NET doesn't allow a custom service collection. appHost.ServiceProvider = webHost.Services; @@ -250,14 +231,49 @@ namespace Jellyfin.Server } } - private static IWebHostBuilder CreateWebHostBuilder( + /// <summary> + /// Call static initialization methods for the application. + /// </summary> + public static void PerformStaticInitialization() + { + // Make sure we have all the code pages we can get + // Ref: https://docs.microsoft.com/en-us/dotnet/api/system.text.codepagesencodingprovider.instance?view=netcore-3.0#remarks + Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); + + // Increase the max http request limit + // The default connection limit is 10 for ASP.NET hosted applications and 2 for all others. + ServicePointManager.DefaultConnectionLimit = Math.Max(96, ServicePointManager.DefaultConnectionLimit); + + // Disable the "Expect: 100-Continue" header by default + // http://stackoverflow.com/questions/566437/http-post-returns-the-error-417-expectation-failed-c + ServicePointManager.Expect100Continue = false; + + Batteries_V2.Init(); + if (raw.sqlite3_enable_shared_cache(1) != raw.SQLITE_OK) + { + _logger.LogWarning("Failed to enable shared cache for SQLite"); + } + } + + /// <summary> + /// Configure the web host builder. + /// </summary> + /// <param name="builder">The builder to configure.</param> + /// <param name="appHost">The application host.</param> + /// <param name="serviceCollection">The application service collection.</param> + /// <param name="commandLineOpts">The command line options passed to the application.</param> + /// <param name="startupConfig">The application configuration.</param> + /// <param name="appPaths">The application paths.</param> + /// <returns>The configured web host builder.</returns> + public static IWebHostBuilder ConfigureWebHostBuilder( + this IWebHostBuilder builder, ApplicationHost appHost, IServiceCollection serviceCollection, StartupOptions commandLineOpts, IConfiguration startupConfig, IApplicationPaths appPaths) { - return new WebHostBuilder() + return builder .UseKestrel((builderContext, options) => { var addresses = appHost.ServerConfigurationManager @@ -278,8 +294,7 @@ namespace Jellyfin.Server { _logger.LogInformation("Kestrel listening on {IpAddress}", address); options.Listen(address, appHost.HttpPort); - - if (appHost.EnableHttps && appHost.Certificate != null) + if (appHost.ListenWithHttps) { options.Listen(address, appHost.HttpsPort, listenOptions => { @@ -289,11 +304,18 @@ namespace Jellyfin.Server } else if (builderContext.HostingEnvironment.IsDevelopment()) { - options.Listen(address, appHost.HttpsPort, listenOptions => + try { - listenOptions.UseHttps(); - listenOptions.Protocols = HttpProtocols.Http1AndHttp2; - }); + options.Listen(address, appHost.HttpsPort, listenOptions => + { + listenOptions.UseHttps(); + listenOptions.Protocols = HttpProtocols.Http1AndHttp2; + }); + } + catch (InvalidOperationException ex) + { + _logger.LogError(ex, "Failed to listen to HTTPS using the ASP.NET Core HTTPS development certificate. Please ensure it has been installed and set as trusted."); + } } } } @@ -302,7 +324,7 @@ namespace Jellyfin.Server _logger.LogInformation("Kestrel listening on all interfaces"); options.ListenAnyIP(appHost.HttpPort); - if (appHost.EnableHttps && appHost.Certificate != null) + if (appHost.ListenWithHttps) { options.ListenAnyIP(appHost.HttpsPort, listenOptions => { @@ -312,11 +334,18 @@ namespace Jellyfin.Server } else if (builderContext.HostingEnvironment.IsDevelopment()) { - options.ListenAnyIP(appHost.HttpsPort, listenOptions => + try { - listenOptions.UseHttps(); - listenOptions.Protocols = HttpProtocols.Http1AndHttp2; - }); + options.ListenAnyIP(appHost.HttpsPort, listenOptions => + { + listenOptions.UseHttps(); + listenOptions.Protocols = HttpProtocols.Http1AndHttp2; + }); + } + catch (InvalidOperationException ex) + { + _logger.LogError(ex, "Failed to listen to HTTPS using the ASP.NET Core HTTPS development certificate. Please ensure it has been installed and set as trusted."); + } } } }) @@ -496,7 +525,9 @@ namespace Jellyfin.Server /// Initialize the logging configuration file using the bundled resource file as a default if it doesn't exist /// already. /// </summary> - private static async Task InitLoggingConfigFile(IApplicationPaths appPaths) + /// <param name="appPaths">The application paths.</param> + /// <returns>A task representing the creation of the configuration file, or a completed task if the file already exists.</returns> + public static async Task InitLoggingConfigFile(IApplicationPaths appPaths) { // Do nothing if the config file already exists string configPath = Path.Combine(appPaths.ConfigurationDirectoryPath, LoggingConfigFileDefault); @@ -516,7 +547,13 @@ namespace Jellyfin.Server await resource.CopyToAsync(dst).ConfigureAwait(false); } - private static IConfiguration CreateAppConfiguration(StartupOptions commandLineOpts, IApplicationPaths appPaths) + /// <summary> + /// Create the application configuration. + /// </summary> + /// <param name="commandLineOpts">The command line options passed to the program.</param> + /// <param name="appPaths">The application paths.</param> + /// <returns>The application configuration.</returns> + public static IConfiguration CreateAppConfiguration(StartupOptions commandLineOpts, IApplicationPaths appPaths) { return new ConfigurationBuilder() .ConfigureAppConfiguration(commandLineOpts, appPaths) |
