aboutsummaryrefslogtreecommitdiff
path: root/Jellyfin.Server
diff options
context:
space:
mode:
authorMark Monteiro <marknr.monteiro@protonmail.com>2020-05-14 11:08:08 -0400
committerGitHub <noreply@github.com>2020-05-14 11:08:08 -0400
commit2e09311a93cbf7b4d0629e058974a84e70c4b800 (patch)
tree9217bb9d15df7f1a516afcbc2f531bbc35161a53 /Jellyfin.Server
parent3623aafcb60dec4f4f5055046717d895b7597b60 (diff)
parent11dd96f6c715b0f701903e636f08ee910c9a08eb (diff)
Merge branch 'master' into websocket
Diffstat (limited to 'Jellyfin.Server')
-rw-r--r--Jellyfin.Server/Migrations/IMigrationRoutine.cs4
-rw-r--r--Jellyfin.Server/Migrations/MigrationRunner.cs19
-rw-r--r--Jellyfin.Server/Migrations/Routines/CreateUserLoggingConfigFile.cs11
-rw-r--r--Jellyfin.Server/Migrations/Routines/DisableTranscodingThrottling.cs17
-rw-r--r--Jellyfin.Server/Program.cs109
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)