diff options
| author | Mark Monteiro <marknr.monteiro@protonmail.com> | 2020-02-28 23:18:22 +0100 |
|---|---|---|
| committer | Mark Monteiro <marknr.monteiro@protonmail.com> | 2020-02-28 23:18:22 +0100 |
| commit | a4e5a5ab314e10f0141dd6af0a1e1b08728a12fc (patch) | |
| tree | 9f408f4798c4d4edfbe79fa6d53e6401c69cd32c /Jellyfin.Server/Program.cs | |
| parent | 6261e4e7f67457a57c58e17cdd10e1f5b867261a (diff) | |
Register configuration correctly with application using 'ConfigureAppConfiguration()' in WebHostBuilder
Without this, the correct instance of IConfiguration is not injected into services that rely on it
Diffstat (limited to 'Jellyfin.Server/Program.cs')
| -rw-r--r-- | Jellyfin.Server/Program.cs | 74 |
1 files changed, 48 insertions, 26 deletions
diff --git a/Jellyfin.Server/Program.cs b/Jellyfin.Server/Program.cs index 1dd598236..1ca6a8a77 100644 --- a/Jellyfin.Server/Program.cs +++ b/Jellyfin.Server/Program.cs @@ -101,10 +101,12 @@ namespace Jellyfin.Server // $JELLYFIN_LOG_DIR needs to be set for the logger configuration manager Environment.SetEnvironmentVariable("JELLYFIN_LOG_DIR", appPaths.LogDirectoryPath); - IConfiguration appConfig = await CreateConfiguration(appPaths).ConfigureAwait(false); - - CreateLogger(appConfig, appPaths); + // Create an instance of the application configuration to use for application startup + await InitLoggingConfigFile(appPaths).ConfigureAwait(false); + IConfiguration appConfig = CreateAppConfiguration(appPaths); + // Initialize logging framework + InitializeLoggingFramework(appConfig, appPaths); _logger = _loggerFactory.CreateLogger("Main"); // Log uncaught exceptions to the logging instead of std error @@ -176,15 +178,15 @@ namespace Jellyfin.Server ServiceCollection serviceCollection = new ServiceCollection(); await appHost.InitAsync(serviceCollection).ConfigureAwait(false); - var host = CreateWebHostBuilder(appHost, serviceCollection).Build(); + var webHost = CreateWebHostBuilder(appHost, serviceCollection, appPaths).Build(); // A bit hacky to re-use service provider since ASP.NET doesn't allow a custom service collection. - appHost.ServiceProvider = host.Services; + appHost.ServiceProvider = webHost.Services; appHost.FindParts(); try { - await host.StartAsync().ConfigureAwait(false); + await webHost.StartAsync().ConfigureAwait(false); } catch { @@ -220,7 +222,7 @@ namespace Jellyfin.Server } } - private static IWebHostBuilder CreateWebHostBuilder(ApplicationHost appHost, IServiceCollection serviceCollection) + private static IWebHostBuilder CreateWebHostBuilder(ApplicationHost appHost, IServiceCollection serviceCollection, IApplicationPaths appPaths) { return new WebHostBuilder() .UseKestrel(options => @@ -260,6 +262,7 @@ namespace Jellyfin.Server } } }) + .ConfigureAppConfiguration(config => config.ConfigureAppConfiguration(appPaths)) .UseContentRoot(appHost.ContentRoot) .ConfigureServices(services => { @@ -432,37 +435,56 @@ namespace Jellyfin.Server return new ServerApplicationPaths(dataDir, logDir, configDir, cacheDir, webDir); } - private static async Task<IConfiguration> CreateConfiguration(IApplicationPaths appPaths) + /// <summary> + /// 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) { - const string ResourcePath = "Jellyfin.Server.Resources.Configuration.logging.json"; + // Do nothing if the config file already exists string configPath = Path.Combine(appPaths.ConfigurationDirectoryPath, "logging.json"); - - if (!File.Exists(configPath)) + if (File.Exists(configPath)) { - // For some reason the csproj name is used instead of the assembly name - await using Stream? resource = typeof(Program).Assembly.GetManifestResourceStream(ResourcePath); - if (resource == null) - { - throw new InvalidOperationException( - string.Format( - CultureInfo.InvariantCulture, - "Invalid resource path: '{0}'", - ResourcePath)); - } + return; + } - await using Stream dst = File.Open(configPath, FileMode.CreateNew); - await resource.CopyToAsync(dst).ConfigureAwait(false); + // Get a stream of the resource contents + // NOTE: The .csproj name is used instead of the assembly name in the resource path + const string ResourcePath = "Jellyfin.Server.Resources.Configuration.logging.json"; + await using Stream? resource = typeof(Program).Assembly.GetManifestResourceStream(ResourcePath); + + // Fail if the resource does not exist + if (resource == null) + { + throw new InvalidOperationException( + string.Format(CultureInfo.InvariantCulture, "Invalid resource path: '{0}'", ResourcePath)); } + // Copy the resource contents to the expected file path for the config file + await using Stream dst = File.Open(configPath, FileMode.CreateNew); + await resource.CopyToAsync(dst).ConfigureAwait(false); + } + + private static IConfiguration CreateAppConfiguration(IApplicationPaths appPaths) + { return new ConfigurationBuilder() + .ConfigureAppConfiguration(appPaths) + .Build(); + } + + private static IConfigurationBuilder ConfigureAppConfiguration(this IConfigurationBuilder config, IApplicationPaths appPaths) + { + return config .SetBasePath(appPaths.ConfigurationDirectoryPath) .AddInMemoryCollection(ConfigurationOptions.Configuration) .AddJsonFile("logging.json", false, true) - .AddEnvironmentVariables("JELLYFIN_") - .Build(); + .AddEnvironmentVariables("JELLYFIN_"); } - private static void CreateLogger(IConfiguration configuration, IApplicationPaths appPaths) + /// <summary> + /// Initialize Serilog using configuration and fall back to defaults on failure. + /// </summary> + private static void InitializeLoggingFramework(IConfiguration configuration, IApplicationPaths appPaths) { try { |
