From 1e7acec01799e3cfe6fd2a8630dbd8f6e3338251 Mon Sep 17 00:00:00 2001 From: JPVenson Date: Sat, 26 Oct 2024 10:31:01 +0000 Subject: [PATCH 1/8] Added Setup overlay app to communicate status of startup --- Jellyfin.Server/Program.cs | 25 +++- Jellyfin.Server/ServerSetupApp/SetupServer.cs | 131 ++++++++++++++++++ .../Manager/NetworkManager.cs | 23 ++- 3 files changed, 167 insertions(+), 12 deletions(-) create mode 100644 Jellyfin.Server/ServerSetupApp/SetupServer.cs diff --git a/Jellyfin.Server/Program.cs b/Jellyfin.Server/Program.cs index 295fb8112f..0bbcfa6a64 100644 --- a/Jellyfin.Server/Program.cs +++ b/Jellyfin.Server/Program.cs @@ -7,10 +7,13 @@ using System.Reflection; using System.Threading.Tasks; using CommandLine; using Emby.Server.Implementations; +using Jellyfin.Networking.Manager; using Jellyfin.Server.Extensions; using Jellyfin.Server.Helpers; using Jellyfin.Server.Implementations; +using Jellyfin.Server.ServerSetupApp; using MediaBrowser.Common.Configuration; +using MediaBrowser.Common.Net; using MediaBrowser.Controller; using Microsoft.AspNetCore.Hosting; using Microsoft.EntityFrameworkCore; @@ -42,6 +45,9 @@ namespace Jellyfin.Server public const string LoggingConfigFileSystem = "logging.json"; private static readonly SerilogLoggerFactory _loggerFactory = new SerilogLoggerFactory(); + private static SetupServer? _setupServer = new(); + + private static IHost? _jfHost = null; private static long _startTimestamp; private static ILogger _logger = NullLogger.Instance; private static bool _restartOnShutdown; @@ -68,6 +74,7 @@ namespace Jellyfin.Server { _startTimestamp = Stopwatch.GetTimestamp(); ServerApplicationPaths appPaths = StartupHelpers.CreateApplicationPaths(options); + await _setupServer!.RunAsync(static () => _jfHost?.Services?.GetService(), appPaths).ConfigureAwait(false); // $JELLYFIN_LOG_DIR needs to be set for the logger configuration manager Environment.SetEnvironmentVariable("JELLYFIN_LOG_DIR", appPaths.LogDirectoryPath); @@ -122,6 +129,8 @@ namespace Jellyfin.Server if (_restartOnShutdown) { _startTimestamp = Stopwatch.GetTimestamp(); + _setupServer = new SetupServer(); + await _setupServer.RunAsync(static () => _jfHost?.Services?.GetService(), appPaths).ConfigureAwait(false); } } while (_restartOnShutdown); } @@ -133,11 +142,9 @@ namespace Jellyfin.Server _loggerFactory, options, startupConfig); - - IHost? host = null; try { - host = Host.CreateDefaultBuilder() + _jfHost = Host.CreateDefaultBuilder() .UseConsoleLifetime() .ConfigureServices(services => appHost.Init(services)) .ConfigureWebHostDefaults(webHostBuilder => @@ -154,14 +161,18 @@ namespace Jellyfin.Server .Build(); // Re-use the host service provider in the app host since ASP.NET doesn't allow a custom service collection. - appHost.ServiceProvider = host.Services; + appHost.ServiceProvider = _jfHost.Services; await appHost.InitializeServices().ConfigureAwait(false); Migrations.MigrationRunner.Run(appHost, _loggerFactory); try { - await host.StartAsync().ConfigureAwait(false); + await Task.Delay(50000).ConfigureAwait(false); + await _setupServer!.StopAsync().ConfigureAwait(false); + _setupServer.Dispose(); + _setupServer = null!; + await _jfHost.StartAsync().ConfigureAwait(false); if (!OperatingSystem.IsWindows() && startupConfig.UseUnixSocket()) { @@ -180,7 +191,7 @@ namespace Jellyfin.Server _logger.LogInformation("Startup complete {Time:g}", Stopwatch.GetElapsedTime(_startTimestamp)); - await host.WaitForShutdownAsync().ConfigureAwait(false); + await _jfHost.WaitForShutdownAsync().ConfigureAwait(false); _restartOnShutdown = appHost.ShouldRestart; } catch (Exception ex) @@ -205,7 +216,7 @@ namespace Jellyfin.Server } } - host?.Dispose(); + _jfHost?.Dispose(); } } diff --git a/Jellyfin.Server/ServerSetupApp/SetupServer.cs b/Jellyfin.Server/ServerSetupApp/SetupServer.cs new file mode 100644 index 0000000000..61fe0fdd8c --- /dev/null +++ b/Jellyfin.Server/ServerSetupApp/SetupServer.cs @@ -0,0 +1,131 @@ +using System; +using System.IO; +using System.Linq; +using System.Net; +using System.Threading; +using System.Threading.Tasks; +using Jellyfin.Networking.Manager; +using MediaBrowser.Common.Configuration; +using MediaBrowser.Common.Net; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Diagnostics.HealthChecks; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Diagnostics.HealthChecks; +using Microsoft.Extensions.Hosting; +using SQLitePCL; + +namespace Jellyfin.Server.ServerSetupApp; + +/// +/// Creates a fake application pipeline that will only exist for as long as the main app is not started. +/// +public sealed class SetupServer : IDisposable +{ + private IHost? _startupServer; + private bool _disposed; + + /// + /// Starts the Bind-All Setup aspcore server to provide a reflection on the current core setup. + /// + /// The networkmanager. + /// The application paths. + /// A Task. + public async Task RunAsync(Func networkManagerFactory, IApplicationPaths applicationPaths) + { + ThrowIfDisposed(); + _startupServer = Host.CreateDefaultBuilder() + .UseConsoleLifetime() + .ConfigureServices(serv => + { + serv.AddHealthChecks() + .AddCheck("StartupCheck"); + }) + .ConfigureWebHostDefaults(webHostBuilder => + { + webHostBuilder + .UseKestrel() + .Configure(app => + { + app.UseHealthChecks("/health"); + + app.Map("/startup/logger", loggerRoute => + { + loggerRoute.Run(async context => + { + var networkManager = networkManagerFactory(); + if (context.Connection.RemoteIpAddress is null || networkManager is null || !networkManager.IsInLocalNetwork(context.Connection.RemoteIpAddress)) + { + context.Response.StatusCode = (int)HttpStatusCode.Unauthorized; + return; + } + + var logfilePath = Directory.EnumerateFiles(applicationPaths.LogDirectoryPath).Select(e => new FileInfo(e)).OrderBy(f => f.CreationTimeUtc).FirstOrDefault()?.FullName; + if (logfilePath is not null) + { + await context.Response.SendFileAsync(logfilePath, CancellationToken.None).ConfigureAwait(false); + } + }); + }); + + app.Run((context) => + { + context.Response.StatusCode = (int)HttpStatusCode.ServiceUnavailable; + context.Response.Headers.RetryAfter = new Microsoft.Extensions.Primitives.StringValues("60"); + context.Response.WriteAsync("

Jellyfin Server still starting. Please wait.

"); + var networkManager = networkManagerFactory(); + if (networkManager is not null && context.Connection.RemoteIpAddress is not null && networkManager.IsInLocalNetwork(context.Connection.RemoteIpAddress)) + { + context.Response.WriteAsync("

You can download the current logfiles here.

"); + } + + return Task.CompletedTask; + }); + }); + }) + .Build(); + await _startupServer.StartAsync().ConfigureAwait(false); + } + + /// + /// Stops the Setup server. + /// + /// A task. Duh. + public async Task StopAsync() + { + ThrowIfDisposed(); + if (_startupServer is null) + { + throw new InvalidOperationException("Tried to stop a non existing startup server"); + } + + await _startupServer.StopAsync().ConfigureAwait(false); + _startupServer.Dispose(); + } + + /// + public void Dispose() + { + if (_disposed) + { + return; + } + + _disposed = true; + _startupServer?.Dispose(); + } + + private void ThrowIfDisposed() + { + ObjectDisposedException.ThrowIf(_disposed, this); + } + + private class SetupHealthcheck : IHealthCheck + { + public Task CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default) + { + return Task.FromResult(HealthCheckResult.Degraded("Server is still starting up.")); + } + } +} diff --git a/src/Jellyfin.Networking/Manager/NetworkManager.cs b/src/Jellyfin.Networking/Manager/NetworkManager.cs index 5a13cc4173..7a22dd8526 100644 --- a/src/Jellyfin.Networking/Manager/NetworkManager.cs +++ b/src/Jellyfin.Networking/Manager/NetworkManager.cs @@ -921,6 +921,19 @@ public class NetworkManager : INetworkManager, IDisposable /// public bool IsInLocalNetwork(IPAddress address) + { + return NetworkManager.IsInLocalNetwork(address, TrustAllIPv6Interfaces, _lanSubnets, _excludedSubnets); + } + + /// + /// Checks a ip address to match any lansubnet given but not to be in any excluded subnet. + /// + /// The IP address to checl. + /// Whenever all IPV6 subnet address shall be permitted. + /// The list of subnets to permit. + /// The list of subnets to never permit. + /// The check if the given IP address is in any provided subnet. + public static bool IsInLocalNetwork(IPAddress address, bool trustAllIpv6, IReadOnlyList lanSubnets, IReadOnlyList excludedSubnets) { ArgumentNullException.ThrowIfNull(address); @@ -930,23 +943,23 @@ public class NetworkManager : INetworkManager, IDisposable address = address.MapToIPv4(); } - if ((TrustAllIPv6Interfaces && address.AddressFamily == AddressFamily.InterNetworkV6) + if ((trustAllIpv6 && address.AddressFamily == AddressFamily.InterNetworkV6) || IPAddress.IsLoopback(address)) { return true; } // As private addresses can be redefined by Configuration.LocalNetworkAddresses - return CheckIfLanAndNotExcluded(address); + return CheckIfLanAndNotExcluded(address, lanSubnets, excludedSubnets); } - private bool CheckIfLanAndNotExcluded(IPAddress address) + private static bool CheckIfLanAndNotExcluded(IPAddress address, IReadOnlyList lanSubnets, IReadOnlyList excludedSubnets) { - foreach (var lanSubnet in _lanSubnets) + foreach (var lanSubnet in lanSubnets) { if (lanSubnet.Contains(address)) { - foreach (var excludedSubnet in _excludedSubnets) + foreach (var excludedSubnet in excludedSubnets) { if (excludedSubnet.Contains(address)) { From cd81a698a6020a5ab4aa469e2350cbcc4e09e8a4 Mon Sep 17 00:00:00 2001 From: JPVenson Date: Sat, 26 Oct 2024 10:34:11 +0000 Subject: [PATCH 2/8] Reverted change to network manager --- .../Manager/NetworkManager.cs | 23 ++++--------------- 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/src/Jellyfin.Networking/Manager/NetworkManager.cs b/src/Jellyfin.Networking/Manager/NetworkManager.cs index 7a22dd8526..5a13cc4173 100644 --- a/src/Jellyfin.Networking/Manager/NetworkManager.cs +++ b/src/Jellyfin.Networking/Manager/NetworkManager.cs @@ -921,19 +921,6 @@ public class NetworkManager : INetworkManager, IDisposable /// public bool IsInLocalNetwork(IPAddress address) - { - return NetworkManager.IsInLocalNetwork(address, TrustAllIPv6Interfaces, _lanSubnets, _excludedSubnets); - } - - /// - /// Checks a ip address to match any lansubnet given but not to be in any excluded subnet. - /// - /// The IP address to checl. - /// Whenever all IPV6 subnet address shall be permitted. - /// The list of subnets to permit. - /// The list of subnets to never permit. - /// The check if the given IP address is in any provided subnet. - public static bool IsInLocalNetwork(IPAddress address, bool trustAllIpv6, IReadOnlyList lanSubnets, IReadOnlyList excludedSubnets) { ArgumentNullException.ThrowIfNull(address); @@ -943,23 +930,23 @@ public class NetworkManager : INetworkManager, IDisposable address = address.MapToIPv4(); } - if ((trustAllIpv6 && address.AddressFamily == AddressFamily.InterNetworkV6) + if ((TrustAllIPv6Interfaces && address.AddressFamily == AddressFamily.InterNetworkV6) || IPAddress.IsLoopback(address)) { return true; } // As private addresses can be redefined by Configuration.LocalNetworkAddresses - return CheckIfLanAndNotExcluded(address, lanSubnets, excludedSubnets); + return CheckIfLanAndNotExcluded(address); } - private static bool CheckIfLanAndNotExcluded(IPAddress address, IReadOnlyList lanSubnets, IReadOnlyList excludedSubnets) + private bool CheckIfLanAndNotExcluded(IPAddress address) { - foreach (var lanSubnet in lanSubnets) + foreach (var lanSubnet in _lanSubnets) { if (lanSubnet.Contains(address)) { - foreach (var excludedSubnet in excludedSubnets) + foreach (var excludedSubnet in _excludedSubnets) { if (excludedSubnet.Contains(address)) { From ebabaac6b1c4eca7203f4b477fa5e79bd786760c Mon Sep 17 00:00:00 2001 From: JPVenson Date: Sat, 26 Oct 2024 10:47:38 +0000 Subject: [PATCH 3/8] removed dbg timeout --- Jellyfin.Server/Program.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/Jellyfin.Server/Program.cs b/Jellyfin.Server/Program.cs index 0bbcfa6a64..a3b16d6a7d 100644 --- a/Jellyfin.Server/Program.cs +++ b/Jellyfin.Server/Program.cs @@ -168,7 +168,6 @@ namespace Jellyfin.Server try { - await Task.Delay(50000).ConfigureAwait(false); await _setupServer!.StopAsync().ConfigureAwait(false); _setupServer.Dispose(); _setupServer = null!; From dc029d549c0da8e0747d46f51a06621a16eb61df Mon Sep 17 00:00:00 2001 From: JPVenson Date: Sat, 26 Oct 2024 11:08:20 +0000 Subject: [PATCH 4/8] removed double dispose --- Jellyfin.Server/ServerSetupApp/SetupServer.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/Jellyfin.Server/ServerSetupApp/SetupServer.cs b/Jellyfin.Server/ServerSetupApp/SetupServer.cs index 61fe0fdd8c..fc0680e40f 100644 --- a/Jellyfin.Server/ServerSetupApp/SetupServer.cs +++ b/Jellyfin.Server/ServerSetupApp/SetupServer.cs @@ -101,7 +101,6 @@ public sealed class SetupServer : IDisposable } await _startupServer.StopAsync().ConfigureAwait(false); - _startupServer.Dispose(); } /// From 41c27d4e7e197308f3ff978c59e538028bbf4ef4 Mon Sep 17 00:00:00 2001 From: JPVenson Date: Sat, 26 Oct 2024 16:59:12 +0000 Subject: [PATCH 5/8] ATV requested endpoint mock --- Jellyfin.Server/Program.cs | 18 ++++---- Jellyfin.Server/ServerSetupApp/SetupServer.cs | 43 ++++++++++++++++++- 2 files changed, 52 insertions(+), 9 deletions(-) diff --git a/Jellyfin.Server/Program.cs b/Jellyfin.Server/Program.cs index a3b16d6a7d..922a06802a 100644 --- a/Jellyfin.Server/Program.cs +++ b/Jellyfin.Server/Program.cs @@ -46,7 +46,7 @@ namespace Jellyfin.Server private static readonly SerilogLoggerFactory _loggerFactory = new SerilogLoggerFactory(); private static SetupServer? _setupServer = new(); - + private static CoreAppHost? _appHost; private static IHost? _jfHost = null; private static long _startTimestamp; private static ILogger _logger = NullLogger.Instance; @@ -74,7 +74,7 @@ namespace Jellyfin.Server { _startTimestamp = Stopwatch.GetTimestamp(); ServerApplicationPaths appPaths = StartupHelpers.CreateApplicationPaths(options); - await _setupServer!.RunAsync(static () => _jfHost?.Services?.GetService(), appPaths).ConfigureAwait(false); + await _setupServer!.RunAsync(static () => _jfHost?.Services?.GetService(), appPaths, static () => _appHost).ConfigureAwait(false); // $JELLYFIN_LOG_DIR needs to be set for the logger configuration manager Environment.SetEnvironmentVariable("JELLYFIN_LOG_DIR", appPaths.LogDirectoryPath); @@ -130,18 +130,19 @@ namespace Jellyfin.Server { _startTimestamp = Stopwatch.GetTimestamp(); _setupServer = new SetupServer(); - await _setupServer.RunAsync(static () => _jfHost?.Services?.GetService(), appPaths).ConfigureAwait(false); + await _setupServer.RunAsync(static () => _jfHost?.Services?.GetService(), appPaths, static () => _appHost).ConfigureAwait(false); } } while (_restartOnShutdown); } private static async Task StartServer(IServerApplicationPaths appPaths, StartupOptions options, IConfiguration startupConfig) { - using var appHost = new CoreAppHost( - appPaths, - _loggerFactory, - options, - startupConfig); + using CoreAppHost appHost = new CoreAppHost( + appPaths, + _loggerFactory, + options, + startupConfig); + _appHost = appHost; try { _jfHost = Host.CreateDefaultBuilder() @@ -215,6 +216,7 @@ namespace Jellyfin.Server } } + _appHost = null; _jfHost?.Dispose(); } } diff --git a/Jellyfin.Server/ServerSetupApp/SetupServer.cs b/Jellyfin.Server/ServerSetupApp/SetupServer.cs index fc0680e40f..ea4804753b 100644 --- a/Jellyfin.Server/ServerSetupApp/SetupServer.cs +++ b/Jellyfin.Server/ServerSetupApp/SetupServer.cs @@ -7,6 +7,8 @@ using System.Threading.Tasks; using Jellyfin.Networking.Manager; using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Net; +using MediaBrowser.Controller; +using MediaBrowser.Model.System; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Diagnostics.HealthChecks; using Microsoft.AspNetCore.Hosting; @@ -31,8 +33,12 @@ public sealed class SetupServer : IDisposable /// /// The networkmanager. /// The application paths. + /// The servers application host. /// A Task. - public async Task RunAsync(Func networkManagerFactory, IApplicationPaths applicationPaths) + public async Task RunAsync( + Func networkManagerFactory, + IApplicationPaths applicationPaths, + Func serverApplicationHost) { ThrowIfDisposed(); _startupServer = Host.CreateDefaultBuilder() @@ -69,6 +75,41 @@ public sealed class SetupServer : IDisposable }); }); + app.Map("/System/Info/Public", systemRoute => + { + systemRoute.Run(async context => + { + var jfApplicationHost = serverApplicationHost(); + + var retryCounter = 0; + while (jfApplicationHost is null && retryCounter < 5) + { + await Task.Delay(500).ConfigureAwait(false); + jfApplicationHost = serverApplicationHost(); + retryCounter++; + } + + if (jfApplicationHost is null) + { + context.Response.StatusCode = (int)HttpStatusCode.ServiceUnavailable; + context.Response.Headers.RetryAfter = new Microsoft.Extensions.Primitives.StringValues("60"); + return; + } + + var sysInfo = new PublicSystemInfo + { + Version = jfApplicationHost.ApplicationVersionString, + ProductName = jfApplicationHost.Name, + Id = jfApplicationHost.SystemId, + ServerName = jfApplicationHost.FriendlyName, + LocalAddress = jfApplicationHost.GetSmartApiUrl(context.Request), + StartupWizardCompleted = false + }; + + await context.Response.WriteAsJsonAsync(sysInfo).ConfigureAwait(false); + }); + }); + app.Run((context) => { context.Response.StatusCode = (int)HttpStatusCode.ServiceUnavailable; From a05b3be1b3234102e4225aed57f24a598fd8edf1 Mon Sep 17 00:00:00 2001 From: JPVenson Date: Fri, 21 Feb 2025 11:00:01 +0000 Subject: [PATCH 6/8] Fixed nullability on startupService --- Jellyfin.Server/Program.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Jellyfin.Server/Program.cs b/Jellyfin.Server/Program.cs index 922a06802a..8523639e77 100644 --- a/Jellyfin.Server/Program.cs +++ b/Jellyfin.Server/Program.cs @@ -45,7 +45,7 @@ namespace Jellyfin.Server public const string LoggingConfigFileSystem = "logging.json"; private static readonly SerilogLoggerFactory _loggerFactory = new SerilogLoggerFactory(); - private static SetupServer? _setupServer = new(); + private static SetupServer _setupServer = new(); private static CoreAppHost? _appHost; private static IHost? _jfHost = null; private static long _startTimestamp; @@ -74,7 +74,7 @@ namespace Jellyfin.Server { _startTimestamp = Stopwatch.GetTimestamp(); ServerApplicationPaths appPaths = StartupHelpers.CreateApplicationPaths(options); - await _setupServer!.RunAsync(static () => _jfHost?.Services?.GetService(), appPaths, static () => _appHost).ConfigureAwait(false); + await _setupServer.RunAsync(static () => _jfHost?.Services?.GetService(), appPaths, static () => _appHost).ConfigureAwait(false); // $JELLYFIN_LOG_DIR needs to be set for the logger configuration manager Environment.SetEnvironmentVariable("JELLYFIN_LOG_DIR", appPaths.LogDirectoryPath); @@ -169,7 +169,7 @@ namespace Jellyfin.Server try { - await _setupServer!.StopAsync().ConfigureAwait(false); + await _setupServer.StopAsync().ConfigureAwait(false); _setupServer.Dispose(); _setupServer = null!; await _jfHost.StartAsync().ConfigureAwait(false); From 7735aafef5908f2d15f6dc2b3da3bb3795fd83d2 Mon Sep 17 00:00:00 2001 From: JPVenson Date: Fri, 21 Feb 2025 11:05:47 +0000 Subject: [PATCH 7/8] renaming of jfHost usings cleanup --- Jellyfin.Server/Program.cs | 17 ++++++++--------- Jellyfin.Server/ServerSetupApp/SetupServer.cs | 3 --- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/Jellyfin.Server/Program.cs b/Jellyfin.Server/Program.cs index 8523639e77..3d92caac46 100644 --- a/Jellyfin.Server/Program.cs +++ b/Jellyfin.Server/Program.cs @@ -7,7 +7,6 @@ using System.Reflection; using System.Threading.Tasks; using CommandLine; using Emby.Server.Implementations; -using Jellyfin.Networking.Manager; using Jellyfin.Server.Extensions; using Jellyfin.Server.Helpers; using Jellyfin.Server.Implementations; @@ -47,7 +46,7 @@ namespace Jellyfin.Server private static readonly SerilogLoggerFactory _loggerFactory = new SerilogLoggerFactory(); private static SetupServer _setupServer = new(); private static CoreAppHost? _appHost; - private static IHost? _jfHost = null; + private static IHost? _jellyfinHost = null; private static long _startTimestamp; private static ILogger _logger = NullLogger.Instance; private static bool _restartOnShutdown; @@ -74,7 +73,7 @@ namespace Jellyfin.Server { _startTimestamp = Stopwatch.GetTimestamp(); ServerApplicationPaths appPaths = StartupHelpers.CreateApplicationPaths(options); - await _setupServer.RunAsync(static () => _jfHost?.Services?.GetService(), appPaths, static () => _appHost).ConfigureAwait(false); + await _setupServer.RunAsync(static () => _jellyfinHost?.Services?.GetService(), appPaths, static () => _appHost).ConfigureAwait(false); // $JELLYFIN_LOG_DIR needs to be set for the logger configuration manager Environment.SetEnvironmentVariable("JELLYFIN_LOG_DIR", appPaths.LogDirectoryPath); @@ -130,7 +129,7 @@ namespace Jellyfin.Server { _startTimestamp = Stopwatch.GetTimestamp(); _setupServer = new SetupServer(); - await _setupServer.RunAsync(static () => _jfHost?.Services?.GetService(), appPaths, static () => _appHost).ConfigureAwait(false); + await _setupServer.RunAsync(static () => _jellyfinHost?.Services?.GetService(), appPaths, static () => _appHost).ConfigureAwait(false); } } while (_restartOnShutdown); } @@ -145,7 +144,7 @@ namespace Jellyfin.Server _appHost = appHost; try { - _jfHost = Host.CreateDefaultBuilder() + _jellyfinHost = Host.CreateDefaultBuilder() .UseConsoleLifetime() .ConfigureServices(services => appHost.Init(services)) .ConfigureWebHostDefaults(webHostBuilder => @@ -162,7 +161,7 @@ namespace Jellyfin.Server .Build(); // Re-use the host service provider in the app host since ASP.NET doesn't allow a custom service collection. - appHost.ServiceProvider = _jfHost.Services; + appHost.ServiceProvider = _jellyfinHost.Services; await appHost.InitializeServices().ConfigureAwait(false); Migrations.MigrationRunner.Run(appHost, _loggerFactory); @@ -172,7 +171,7 @@ namespace Jellyfin.Server await _setupServer.StopAsync().ConfigureAwait(false); _setupServer.Dispose(); _setupServer = null!; - await _jfHost.StartAsync().ConfigureAwait(false); + await _jellyfinHost.StartAsync().ConfigureAwait(false); if (!OperatingSystem.IsWindows() && startupConfig.UseUnixSocket()) { @@ -191,7 +190,7 @@ namespace Jellyfin.Server _logger.LogInformation("Startup complete {Time:g}", Stopwatch.GetElapsedTime(_startTimestamp)); - await _jfHost.WaitForShutdownAsync().ConfigureAwait(false); + await _jellyfinHost.WaitForShutdownAsync().ConfigureAwait(false); _restartOnShutdown = appHost.ShouldRestart; } catch (Exception ex) @@ -217,7 +216,7 @@ namespace Jellyfin.Server } _appHost = null; - _jfHost?.Dispose(); + _jellyfinHost?.Dispose(); } } diff --git a/Jellyfin.Server/ServerSetupApp/SetupServer.cs b/Jellyfin.Server/ServerSetupApp/SetupServer.cs index ea4804753b..09b7434eff 100644 --- a/Jellyfin.Server/ServerSetupApp/SetupServer.cs +++ b/Jellyfin.Server/ServerSetupApp/SetupServer.cs @@ -4,19 +4,16 @@ using System.Linq; using System.Net; using System.Threading; using System.Threading.Tasks; -using Jellyfin.Networking.Manager; using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Net; using MediaBrowser.Controller; using MediaBrowser.Model.System; using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Diagnostics.HealthChecks; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Diagnostics.HealthChecks; using Microsoft.Extensions.Hosting; -using SQLitePCL; namespace Jellyfin.Server.ServerSetupApp; From 963f2357a966dd7a5a6ab248155cc52ce066753b Mon Sep 17 00:00:00 2001 From: JPVenson Date: Fri, 21 Feb 2025 11:06:28 +0000 Subject: [PATCH 8/8] simplified logfile path --- Jellyfin.Server/ServerSetupApp/SetupServer.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Jellyfin.Server/ServerSetupApp/SetupServer.cs b/Jellyfin.Server/ServerSetupApp/SetupServer.cs index 09b7434eff..9e2cf5bc8b 100644 --- a/Jellyfin.Server/ServerSetupApp/SetupServer.cs +++ b/Jellyfin.Server/ServerSetupApp/SetupServer.cs @@ -64,10 +64,14 @@ public sealed class SetupServer : IDisposable return; } - var logfilePath = Directory.EnumerateFiles(applicationPaths.LogDirectoryPath).Select(e => new FileInfo(e)).OrderBy(f => f.CreationTimeUtc).FirstOrDefault()?.FullName; - if (logfilePath is not null) + var logFilePath = new DirectoryInfo(applicationPaths.LogDirectoryPath) + .EnumerateFiles() + .OrderBy(f => f.CreationTimeUtc) + .FirstOrDefault() + ?.FullName; + if (logFilePath is not null) { - await context.Response.SendFileAsync(logfilePath, CancellationToken.None).ConfigureAwait(false); + await context.Response.SendFileAsync(logFilePath, CancellationToken.None).ConfigureAwait(false); } }); });