aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Emby.Server.Implementations/ApplicationHost.cs20
-rw-r--r--Jellyfin.Server/CoreAppHost.cs7
-rw-r--r--Jellyfin.Server/Program.cs75
-rw-r--r--MediaBrowser.Common/IApplicationHost.cs6
-rw-r--r--MediaBrowser.Common/MediaBrowser.Common.csproj1
5 files changed, 59 insertions, 50 deletions
diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs
index d51e74a4d..3d79cae1e 100644
--- a/Emby.Server.Implementations/ApplicationHost.cs
+++ b/Emby.Server.Implementations/ApplicationHost.cs
@@ -325,8 +325,6 @@ namespace Emby.Server.Implementations
private IMediaSourceManager MediaSourceManager { get; set; }
- private readonly IConfiguration _configuration;
-
/// <summary>
/// Gets the installation manager.
/// </summary>
@@ -364,11 +362,8 @@ namespace Emby.Server.Implementations
IStartupOptions options,
IFileSystem fileSystem,
IImageEncoder imageEncoder,
- INetworkManager networkManager,
- IConfiguration configuration)
+ INetworkManager networkManager)
{
- _configuration = configuration;
-
XmlSerializer = new MyXmlSerializer();
NetworkManager = networkManager;
@@ -584,7 +579,8 @@ namespace Emby.Server.Implementations
}
}
- public async Task InitAsync(IServiceCollection serviceCollection)
+ /// <inheritdoc/>
+ public async Task InitAsync(IServiceCollection serviceCollection, IConfiguration startupConfig)
{
HttpPort = ServerConfigurationManager.Configuration.HttpServerPortNumber;
HttpsPort = ServerConfigurationManager.Configuration.HttpsPortNumber;
@@ -617,7 +613,7 @@ namespace Emby.Server.Implementations
DiscoverTypes();
- await RegisterResources(serviceCollection).ConfigureAwait(false);
+ await RegisterResources(serviceCollection, startupConfig).ConfigureAwait(false);
ContentRoot = ServerConfigurationManager.Configuration.DashboardSourcePath;
if (string.IsNullOrEmpty(ContentRoot))
@@ -656,7 +652,7 @@ namespace Emby.Server.Implementations
/// <summary>
/// Registers resources that classes will depend on
/// </summary>
- protected async Task RegisterResources(IServiceCollection serviceCollection)
+ protected async Task RegisterResources(IServiceCollection serviceCollection, IConfiguration startupConfig)
{
serviceCollection.AddMemoryCache();
@@ -665,8 +661,6 @@ namespace Emby.Server.Implementations
serviceCollection.AddSingleton<IApplicationPaths>(ApplicationPaths);
- serviceCollection.AddSingleton<IConfiguration>(_configuration);
-
serviceCollection.AddSingleton(JsonSerializer);
// TODO: Support for injecting ILogger should be deprecated in favour of ILogger<T> and this removed
@@ -758,7 +752,7 @@ namespace Emby.Server.Implementations
ProcessFactory,
LocalizationManager,
() => SubtitleEncoder,
- _configuration,
+ startupConfig,
StartupOptions.FFmpegPath);
serviceCollection.AddSingleton(MediaEncoder);
@@ -780,7 +774,7 @@ namespace Emby.Server.Implementations
this,
LoggerFactory.CreateLogger<HttpListenerHost>(),
ServerConfigurationManager,
- _configuration,
+ startupConfig,
NetworkManager,
JsonSerializer,
XmlSerializer,
diff --git a/Jellyfin.Server/CoreAppHost.cs b/Jellyfin.Server/CoreAppHost.cs
index 8b4b61e29..ed5968ad6 100644
--- a/Jellyfin.Server/CoreAppHost.cs
+++ b/Jellyfin.Server/CoreAppHost.cs
@@ -23,23 +23,20 @@ namespace Jellyfin.Server
/// <param name="fileSystem">The <see cref="IFileSystem" /> to be used by the <see cref="CoreAppHost" />.</param>
/// <param name="imageEncoder">The <see cref="IImageEncoder" /> to be used by the <see cref="CoreAppHost" />.</param>
/// <param name="networkManager">The <see cref="INetworkManager" /> to be used by the <see cref="CoreAppHost" />.</param>
- /// <param name="configuration">The <see cref="IConfiguration" /> to be used by the <see cref="CoreAppHost" />.</param>
public CoreAppHost(
ServerApplicationPaths applicationPaths,
ILoggerFactory loggerFactory,
StartupOptions options,
IFileSystem fileSystem,
IImageEncoder imageEncoder,
- INetworkManager networkManager,
- IConfiguration configuration)
+ INetworkManager networkManager)
: base(
applicationPaths,
loggerFactory,
options,
fileSystem,
imageEncoder,
- networkManager,
- configuration)
+ networkManager)
{
}
diff --git a/Jellyfin.Server/Program.cs b/Jellyfin.Server/Program.cs
index 7c3d0f277..e9e852349 100644
--- a/Jellyfin.Server/Program.cs
+++ b/Jellyfin.Server/Program.cs
@@ -112,10 +112,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 startupConfig = CreateAppConfiguration(appPaths);
+ // Initialize logging framework
+ InitializeLoggingFramework(startupConfig, appPaths);
_logger = _loggerFactory.CreateLogger("Main");
// Log uncaught exceptions to the logging instead of std error
@@ -180,23 +182,22 @@ namespace Jellyfin.Server
options,
new ManagedFileSystem(_loggerFactory.CreateLogger<ManagedFileSystem>(), appPaths),
GetImageEncoder(appPaths),
- new NetworkManager(_loggerFactory.CreateLogger<NetworkManager>()),
- appConfig);
+ new NetworkManager(_loggerFactory.CreateLogger<NetworkManager>()));
try
{
ServiceCollection serviceCollection = new ServiceCollection();
- await appHost.InitAsync(serviceCollection).ConfigureAwait(false);
+ await appHost.InitAsync(serviceCollection, startupConfig).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();
Migrations.MigrationRunner.Run(appHost, _loggerFactory);
try
{
- await host.StartAsync().ConfigureAwait(false);
+ await webHost.StartAsync().ConfigureAwait(false);
}
catch
{
@@ -232,7 +233,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 =>
@@ -272,6 +273,7 @@ namespace Jellyfin.Server
}
}
})
+ .ConfigureAppConfiguration(config => config.ConfigureAppConfiguration(appPaths))
.UseSerilog()
.UseContentRoot(appHost.ContentRoot)
.ConfigureServices(services =>
@@ -445,38 +447,51 @@ 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, LoggingConfigFileDefault);
-
- 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));
- }
-
- await using Stream dst = File.Open(configPath, FileMode.CreateNew);
- await resource.CopyToAsync(dst).ConfigureAwait(false);
+ return;
}
+ // 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)
+ ?? throw new InvalidOperationException($"Invalid resource path: '{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(LoggingConfigFileDefault, optional: false, reloadOnChange: true)
.AddJsonFile(LoggingConfigFileSystem, optional: true, reloadOnChange: 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
{
diff --git a/MediaBrowser.Common/IApplicationHost.cs b/MediaBrowser.Common/IApplicationHost.cs
index 68a24aaba..0e282cf53 100644
--- a/MediaBrowser.Common/IApplicationHost.cs
+++ b/MediaBrowser.Common/IApplicationHost.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Threading.Tasks;
using MediaBrowser.Common.Plugins;
using MediaBrowser.Model.Updates;
+using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
namespace MediaBrowser.Common
@@ -121,11 +122,12 @@ namespace MediaBrowser.Common
void RemovePlugin(IPlugin plugin);
/// <summary>
- /// Inits this instance.
+ /// Initializes this instance.
/// </summary>
/// <param name="serviceCollection">The service collection.</param>
+ /// <param name="startupConfig">The configuration to use for initialization.</param>
/// <returns>A task.</returns>
- Task InitAsync(IServiceCollection serviceCollection);
+ Task InitAsync(IServiceCollection serviceCollection, IConfiguration startupConfig);
/// <summary>
/// Creates the instance.
diff --git a/MediaBrowser.Common/MediaBrowser.Common.csproj b/MediaBrowser.Common/MediaBrowser.Common.csproj
index 3da864404..04e0ee67a 100644
--- a/MediaBrowser.Common/MediaBrowser.Common.csproj
+++ b/MediaBrowser.Common/MediaBrowser.Common.csproj
@@ -12,6 +12,7 @@
</ItemGroup>
<ItemGroup>
+ <PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="3.1.1" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="3.1.1" />
<PackageReference Include="Microsoft.Net.Http.Headers" Version="2.2.8" />
</ItemGroup>