aboutsummaryrefslogtreecommitdiff
path: root/Jellyfin.Server/ServerSetupApp/SetupServer.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Jellyfin.Server/ServerSetupApp/SetupServer.cs')
-rw-r--r--Jellyfin.Server/ServerSetupApp/SetupServer.cs87
1 files changed, 23 insertions, 64 deletions
diff --git a/Jellyfin.Server/ServerSetupApp/SetupServer.cs b/Jellyfin.Server/ServerSetupApp/SetupServer.cs
index 37bb1abe71..598de5aa5f 100644
--- a/Jellyfin.Server/ServerSetupApp/SetupServer.cs
+++ b/Jellyfin.Server/ServerSetupApp/SetupServer.cs
@@ -14,7 +14,6 @@ using Jellyfin.Server.Extensions;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller;
-using MediaBrowser.Model.IO;
using MediaBrowser.Model.System;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
@@ -25,9 +24,6 @@ using Microsoft.Extensions.Diagnostics.HealthChecks;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Primitives;
-using Morestachio;
-using Morestachio.Framework.IO.SingleStream;
-using Morestachio.Rendering;
using Serilog;
using ILogger = Microsoft.Extensions.Logging.ILogger;
@@ -44,7 +40,8 @@ public sealed class SetupServer : IDisposable
private readonly ILoggerFactory _loggerFactory;
private readonly IConfiguration _startupConfiguration;
private readonly ServerConfigurationManager _configurationManager;
- private IRenderer? _startupUiRenderer;
+ private static volatile string _currentActivity = StartupActivity.Starting;
+ private StartupUiRenderer? _startupUiRenderer;
private IHost? _startupServer;
private bool _disposed;
private bool _isUnhealthy;
@@ -77,6 +74,12 @@ public sealed class SetupServer : IDisposable
internal static ConcurrentQueue<StartupLogTopic>? LogQueue { get; set; } = new();
/// <summary>
+ /// Gets a generic, non-identifying summary of what startup is currently doing. This is shown in the
+ /// always-visible header of the startup UI to unauthenticated clients, so it never contains server specific details.
+ /// </summary>
+ internal static string CurrentActivity => _currentActivity;
+
+ /// <summary>
/// Gets a value indicating whether Startup server is currently running.
/// </summary>
public bool IsAlive { get; internal set; }
@@ -87,64 +90,9 @@ public sealed class SetupServer : IDisposable
/// <returns>A Task.</returns>
public async Task RunAsync()
{
- var fileTemplate = await File.ReadAllTextAsync(Path.Combine(AppContext.BaseDirectory, "ServerSetupApp", "index.mstemplate.html")).ConfigureAwait(false);
- _startupUiRenderer = (await ParserOptionsBuilder.New()
- .WithTemplate(fileTemplate)
- .WithFormatter(
- (Version version, int arg) =>
- {
- // version type does not for some stupid reason implement IFormattable which morestachio relies on for ToString support therefor we need to do it manually.
- return version.ToString(arg);
- },
- "ToString")
- .WithFormatter(
- (StartupLogTopic logEntry, IEnumerable<StartupLogTopic> children) =>
- {
- if (children.Any())
- {
- var maxLevel = logEntry.LogLevel;
- var stack = new Stack<StartupLogTopic>(children);
-
- while (maxLevel != LogLevel.Error && stack.Count > 0 && (logEntry = stack.Pop()) is not null) // error is the highest inherted error level.
- {
- maxLevel = maxLevel < logEntry.LogLevel ? logEntry.LogLevel : maxLevel;
- foreach (var child in logEntry.Children)
- {
- stack.Push(child);
- }
- }
-
- return maxLevel;
- }
-
- return logEntry.LogLevel;
- },
- "FormatLogLevel")
- .WithFormatter(
- (LogLevel logLevel) =>
- {
- switch (logLevel)
- {
- case LogLevel.Trace:
- case LogLevel.Debug:
- case LogLevel.None:
- return "success";
- case LogLevel.Information:
- return "info";
- case LogLevel.Warning:
- return "warn";
- case LogLevel.Error:
- return "danger";
- case LogLevel.Critical:
- return "danger-strong";
- }
-
- return string.Empty;
- },
- "ToString")
- .BuildAndParseAsync()
- .ConfigureAwait(false))
- .CreateCompiledRenderer();
+ ReportActivity(StartupActivity.Starting);
+ _startupUiRenderer = await StartupUiRenderer.CreateAsync(
+ Path.Combine(AppContext.BaseDirectory, "ServerSetupApp", "index.mstemplate.html")).ConfigureAwait(false);
ThrowIfDisposed();
var retryAfterValue = TimeSpan.FromSeconds(5);
@@ -257,13 +205,14 @@ public sealed class SetupServer : IDisposable
new Dictionary<string, object>()
{
{ "isInReportingMode", _isUnhealthy },
+ { "currentActivity", CurrentActivity },
{ "retryValue", retryAfterValue },
{ "version", version },
{ "logs", startupLogEntries },
{ "networkManagerReady", networkManager is not null },
{ "localNetworkRequest", networkManager is not null && context.Connection.RemoteIpAddress is not null && networkManager.IsInLocalNetwork(context.Connection.RemoteIpAddress) }
},
- new ByteCounterStream(context.Response.BodyWriter.AsStream(), IODefaults.FileStreamBufferSize, true, _startupUiRenderer.ParserOptions))
+ context.Response.BodyWriter.AsStream())
.ConfigureAwait(false);
});
});
@@ -309,6 +258,16 @@ public sealed class SetupServer : IDisposable
ObjectDisposedException.ThrowIf(_disposed, this);
}
+ /// <summary>
+ /// Reports the current startup activity shown to all clients in the startup UI header.
+ /// Only pass generic, non-identifying text from <see cref="StartupActivity"/>.
+ /// </summary>
+ /// <param name="activity">A generic description such as <see cref="StartupActivity.PreparingMigrations"/>.</param>
+ internal static void ReportActivity(string activity)
+ {
+ _currentActivity = activity;
+ }
+
internal void SoftStop()
{
_isUnhealthy = true;