Merge pull request #10337 from barronpm/system-manager

pull/10379/head
Bond-009 1 year ago committed by GitHub
commit fc1f0a31a1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -101,7 +101,6 @@ using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Prometheus.DotNetRuntime; using Prometheus.DotNetRuntime;
using static MediaBrowser.Controller.Extensions.ConfigurationExtensions; using static MediaBrowser.Controller.Extensions.ConfigurationExtensions;
@ -133,7 +132,7 @@ namespace Emby.Server.Implementations
/// <value>All concrete types.</value> /// <value>All concrete types.</value>
private Type[] _allConcreteTypes; private Type[] _allConcreteTypes;
private bool _disposed = false; private bool _disposed;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="ApplicationHost"/> class. /// Initializes a new instance of the <see cref="ApplicationHost"/> class.
@ -184,26 +183,16 @@ namespace Emby.Server.Implementations
public bool CoreStartupHasCompleted { get; private set; } public bool CoreStartupHasCompleted { get; private set; }
public virtual bool CanLaunchWebBrowser => Environment.UserInteractive
&& !_startupOptions.IsService
&& (OperatingSystem.IsWindows() || OperatingSystem.IsMacOS());
/// <summary> /// <summary>
/// Gets the <see cref="INetworkManager"/> singleton instance. /// Gets the <see cref="INetworkManager"/> singleton instance.
/// </summary> /// </summary>
public INetworkManager NetManager { get; private set; } public INetworkManager NetManager { get; private set; }
/// <summary>
/// Gets a value indicating whether this instance has changes that require the entire application to restart.
/// </summary>
/// <value><c>true</c> if this instance has pending application restart; otherwise, <c>false</c>.</value>
public bool HasPendingRestart { get; private set; }
/// <inheritdoc /> /// <inheritdoc />
public bool IsShuttingDown { get; private set; } public bool HasPendingRestart { get; private set; }
/// <inheritdoc /> /// <inheritdoc />
public bool ShouldRestart { get; private set; } public bool ShouldRestart { get; set; }
/// <summary> /// <summary>
/// Gets the logger. /// Gets the logger.
@ -507,6 +496,8 @@ namespace Emby.Server.Implementations
serviceCollection.AddSingleton<IFileSystem, ManagedFileSystem>(); serviceCollection.AddSingleton<IFileSystem, ManagedFileSystem>();
serviceCollection.AddSingleton<IShortcutHandler, MbLinkShortcutHandler>(); serviceCollection.AddSingleton<IShortcutHandler, MbLinkShortcutHandler>();
serviceCollection.AddScoped<ISystemManager, SystemManager>();
serviceCollection.AddSingleton<TmdbClientManager>(); serviceCollection.AddSingleton<TmdbClientManager>();
serviceCollection.AddSingleton(NetManager); serviceCollection.AddSingleton(NetManager);
@ -850,24 +841,6 @@ namespace Emby.Server.Implementations
} }
} }
/// <inheritdoc />
public void Restart()
{
ShouldRestart = true;
Shutdown();
}
/// <inheritdoc />
public void Shutdown()
{
Task.Run(async () =>
{
await Task.Delay(100).ConfigureAwait(false);
IsShuttingDown = true;
Resolve<IHostApplicationLifetime>().StopApplication();
});
}
/// <summary> /// <summary>
/// Gets the composable part assemblies. /// Gets the composable part assemblies.
/// </summary> /// </summary>
@ -923,49 +896,6 @@ namespace Emby.Server.Implementations
protected abstract IEnumerable<Assembly> GetAssembliesWithPartsInternal(); protected abstract IEnumerable<Assembly> GetAssembliesWithPartsInternal();
/// <summary>
/// Gets the system status.
/// </summary>
/// <param name="request">Where this request originated.</param>
/// <returns>SystemInfo.</returns>
public SystemInfo GetSystemInfo(HttpRequest request)
{
return new SystemInfo
{
HasPendingRestart = HasPendingRestart,
IsShuttingDown = IsShuttingDown,
Version = ApplicationVersionString,
WebSocketPortNumber = HttpPort,
CompletedInstallations = Resolve<IInstallationManager>().CompletedInstallations.ToArray(),
Id = SystemId,
ProgramDataPath = ApplicationPaths.ProgramDataPath,
WebPath = ApplicationPaths.WebPath,
LogPath = ApplicationPaths.LogDirectoryPath,
ItemsByNamePath = ApplicationPaths.InternalMetadataPath,
InternalMetadataPath = ApplicationPaths.InternalMetadataPath,
CachePath = ApplicationPaths.CachePath,
CanLaunchWebBrowser = CanLaunchWebBrowser,
TranscodingTempPath = ConfigurationManager.GetTranscodePath(),
ServerName = FriendlyName,
LocalAddress = GetSmartApiUrl(request),
SupportsLibraryMonitor = true,
PackageName = _startupOptions.PackageName
};
}
public PublicSystemInfo GetPublicSystemInfo(HttpRequest request)
{
return new PublicSystemInfo
{
Version = ApplicationVersionString,
ProductName = ApplicationProductName,
Id = SystemId,
ServerName = FriendlyName,
LocalAddress = GetSmartApiUrl(request),
StartupWizardCompleted = ConfigurationManager.CommonConfiguration.IsStartupWizardCompleted
};
}
/// <inheritdoc/> /// <inheritdoc/>
public string GetSmartApiUrl(IPAddress remoteAddr) public string GetSmartApiUrl(IPAddress remoteAddr)
{ {

@ -0,0 +1,108 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.Updates;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Model.System;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Hosting;
namespace Emby.Server.Implementations;
/// <inheritdoc />
public class SystemManager : ISystemManager
{
private readonly IHostApplicationLifetime _applicationLifetime;
private readonly IServerApplicationHost _applicationHost;
private readonly IServerApplicationPaths _applicationPaths;
private readonly IServerConfigurationManager _configurationManager;
private readonly IStartupOptions _startupOptions;
private readonly IInstallationManager _installationManager;
/// <summary>
/// Initializes a new instance of the <see cref="SystemManager"/> class.
/// </summary>
/// <param name="applicationLifetime">Instance of <see cref="IHostApplicationLifetime"/>.</param>
/// <param name="applicationHost">Instance of <see cref="IServerApplicationHost"/>.</param>
/// <param name="applicationPaths">Instance of <see cref="IServerApplicationPaths"/>.</param>
/// <param name="configurationManager">Instance of <see cref="IServerConfigurationManager"/>.</param>
/// <param name="startupOptions">Instance of <see cref="IStartupOptions"/>.</param>
/// <param name="installationManager">Instance of <see cref="IInstallationManager"/>.</param>
public SystemManager(
IHostApplicationLifetime applicationLifetime,
IServerApplicationHost applicationHost,
IServerApplicationPaths applicationPaths,
IServerConfigurationManager configurationManager,
IStartupOptions startupOptions,
IInstallationManager installationManager)
{
_applicationLifetime = applicationLifetime;
_applicationHost = applicationHost;
_applicationPaths = applicationPaths;
_configurationManager = configurationManager;
_startupOptions = startupOptions;
_installationManager = installationManager;
}
private bool CanLaunchWebBrowser => Environment.UserInteractive
&& !_startupOptions.IsService
&& (OperatingSystem.IsWindows() || OperatingSystem.IsMacOS());
/// <inheritdoc />
public SystemInfo GetSystemInfo(HttpRequest request)
{
return new SystemInfo
{
HasPendingRestart = _applicationHost.HasPendingRestart,
IsShuttingDown = _applicationLifetime.ApplicationStopping.IsCancellationRequested,
Version = _applicationHost.ApplicationVersionString,
WebSocketPortNumber = _applicationHost.HttpPort,
CompletedInstallations = _installationManager.CompletedInstallations.ToArray(),
Id = _applicationHost.SystemId,
ProgramDataPath = _applicationPaths.ProgramDataPath,
WebPath = _applicationPaths.WebPath,
LogPath = _applicationPaths.LogDirectoryPath,
ItemsByNamePath = _applicationPaths.InternalMetadataPath,
InternalMetadataPath = _applicationPaths.InternalMetadataPath,
CachePath = _applicationPaths.CachePath,
CanLaunchWebBrowser = CanLaunchWebBrowser,
TranscodingTempPath = _configurationManager.GetTranscodePath(),
ServerName = _applicationHost.FriendlyName,
LocalAddress = _applicationHost.GetSmartApiUrl(request),
SupportsLibraryMonitor = true,
PackageName = _startupOptions.PackageName
};
}
/// <inheritdoc />
public PublicSystemInfo GetPublicSystemInfo(HttpRequest request)
{
return new PublicSystemInfo
{
Version = _applicationHost.ApplicationVersionString,
ProductName = _applicationHost.Name,
Id = _applicationHost.SystemId,
ServerName = _applicationHost.FriendlyName,
LocalAddress = _applicationHost.GetSmartApiUrl(request),
StartupWizardCompleted = _configurationManager.CommonConfiguration.IsStartupWizardCompleted
};
}
/// <inheritdoc />
public void Restart() => ShutdownInternal(true);
/// <inheritdoc />
public void Shutdown() => ShutdownInternal(false);
private void ShutdownInternal(bool restart)
{
Task.Run(async () =>
{
await Task.Delay(100).ConfigureAwait(false);
_applicationHost.ShouldRestart = restart;
_applicationLifetime.StopApplication();
});
}
}

@ -10,7 +10,6 @@ using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.Extensions; using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Net; using MediaBrowser.Common.Net;
using MediaBrowser.Controller; using MediaBrowser.Controller;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Model.IO; using MediaBrowser.Model.IO;
using MediaBrowser.Model.Net; using MediaBrowser.Model.Net;
using MediaBrowser.Model.System; using MediaBrowser.Model.System;
@ -26,32 +25,36 @@ namespace Jellyfin.Api.Controllers;
/// </summary> /// </summary>
public class SystemController : BaseJellyfinApiController public class SystemController : BaseJellyfinApiController
{ {
private readonly ILogger<SystemController> _logger;
private readonly IServerApplicationHost _appHost; private readonly IServerApplicationHost _appHost;
private readonly IApplicationPaths _appPaths; private readonly IApplicationPaths _appPaths;
private readonly IFileSystem _fileSystem; private readonly IFileSystem _fileSystem;
private readonly INetworkManager _network; private readonly INetworkManager _networkManager;
private readonly ILogger<SystemController> _logger; private readonly ISystemManager _systemManager;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="SystemController"/> class. /// Initializes a new instance of the <see cref="SystemController"/> class.
/// </summary> /// </summary>
/// <param name="serverConfigurationManager">Instance of <see cref="IServerConfigurationManager"/> interface.</param> /// <param name="logger">Instance of <see cref="ILogger{SystemController}"/> interface.</param>
/// <param name="appPaths">Instance of <see cref="IServerApplicationPaths"/> interface.</param>
/// <param name="appHost">Instance of <see cref="IServerApplicationHost"/> interface.</param> /// <param name="appHost">Instance of <see cref="IServerApplicationHost"/> interface.</param>
/// <param name="fileSystem">Instance of <see cref="IFileSystem"/> interface.</param> /// <param name="fileSystem">Instance of <see cref="IFileSystem"/> interface.</param>
/// <param name="network">Instance of <see cref="INetworkManager"/> interface.</param> /// <param name="networkManager">Instance of <see cref="INetworkManager"/> interface.</param>
/// <param name="logger">Instance of <see cref="ILogger{SystemController}"/> interface.</param> /// <param name="systemManager">Instance of <see cref="ISystemManager"/> interface.</param>
public SystemController( public SystemController(
IServerConfigurationManager serverConfigurationManager, ILogger<SystemController> logger,
IServerApplicationHost appHost, IServerApplicationHost appHost,
IServerApplicationPaths appPaths,
IFileSystem fileSystem, IFileSystem fileSystem,
INetworkManager network, INetworkManager networkManager,
ILogger<SystemController> logger) ISystemManager systemManager)
{ {
_appPaths = serverConfigurationManager.ApplicationPaths; _logger = logger;
_appHost = appHost; _appHost = appHost;
_appPaths = appPaths;
_fileSystem = fileSystem; _fileSystem = fileSystem;
_network = network; _networkManager = networkManager;
_logger = logger; _systemManager = systemManager;
} }
/// <summary> /// <summary>
@ -65,9 +68,7 @@ public class SystemController : BaseJellyfinApiController
[ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status403Forbidden)]
public ActionResult<SystemInfo> GetSystemInfo() public ActionResult<SystemInfo> GetSystemInfo()
{ => _systemManager.GetSystemInfo(Request);
return _appHost.GetSystemInfo(Request);
}
/// <summary> /// <summary>
/// Gets public information about the server. /// Gets public information about the server.
@ -77,9 +78,7 @@ public class SystemController : BaseJellyfinApiController
[HttpGet("Info/Public")] [HttpGet("Info/Public")]
[ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status200OK)]
public ActionResult<PublicSystemInfo> GetPublicSystemInfo() public ActionResult<PublicSystemInfo> GetPublicSystemInfo()
{ => _systemManager.GetPublicSystemInfo(Request);
return _appHost.GetPublicSystemInfo(Request);
}
/// <summary> /// <summary>
/// Pings the system. /// Pings the system.
@ -90,9 +89,7 @@ public class SystemController : BaseJellyfinApiController
[HttpPost("Ping", Name = "PostPingSystem")] [HttpPost("Ping", Name = "PostPingSystem")]
[ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status200OK)]
public ActionResult<string> PingSystem() public ActionResult<string> PingSystem()
{ => _appHost.Name;
return _appHost.Name;
}
/// <summary> /// <summary>
/// Restarts the application. /// Restarts the application.
@ -106,7 +103,7 @@ public class SystemController : BaseJellyfinApiController
[ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status403Forbidden)]
public ActionResult RestartApplication() public ActionResult RestartApplication()
{ {
_appHost.Restart(); _systemManager.Restart();
return NoContent(); return NoContent();
} }
@ -122,7 +119,7 @@ public class SystemController : BaseJellyfinApiController
[ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status403Forbidden)]
public ActionResult ShutdownApplication() public ActionResult ShutdownApplication()
{ {
_appHost.Shutdown(); _systemManager.Shutdown();
return NoContent(); return NoContent();
} }
@ -180,7 +177,7 @@ public class SystemController : BaseJellyfinApiController
return new EndPointInfo return new EndPointInfo
{ {
IsLocal = HttpContext.IsLocal(), IsLocal = HttpContext.IsLocal(),
IsInNetwork = _network.IsInLocalNetwork(HttpContext.GetNormalizedRemoteIP()) IsInNetwork = _networkManager.IsInLocalNetwork(HttpContext.GetNormalizedRemoteIP())
}; };
} }
@ -218,7 +215,7 @@ public class SystemController : BaseJellyfinApiController
[ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status200OK)]
public ActionResult<IEnumerable<WakeOnLanInfo>> GetWakeOnLanInfo() public ActionResult<IEnumerable<WakeOnLanInfo>> GetWakeOnLanInfo()
{ {
var result = _network.GetMacAddresses() var result = _networkManager.GetMacAddresses()
.Select(i => new WakeOnLanInfo(i)); .Select(i => new WakeOnLanInfo(i));
return Ok(result); return Ok(result);
} }

@ -35,21 +35,15 @@ namespace MediaBrowser.Common
string SystemId { get; } string SystemId { get; }
/// <summary> /// <summary>
/// Gets a value indicating whether this instance has pending kernel reload. /// Gets a value indicating whether this instance has pending changes requiring a restart.
/// </summary> /// </summary>
/// <value><c>true</c> if this instance has pending kernel reload; otherwise, <c>false</c>.</value> /// <value><c>true</c> if this instance has a pending restart; otherwise, <c>false</c>.</value>
bool HasPendingRestart { get; } bool HasPendingRestart { get; }
/// <summary> /// <summary>
/// Gets a value indicating whether this instance is currently shutting down. /// Gets or sets a value indicating whether the application should restart.
/// </summary> /// </summary>
/// <value><c>true</c> if this instance is shutting down; otherwise, <c>false</c>.</value> bool ShouldRestart { get; set; }
bool IsShuttingDown { get; }
/// <summary>
/// Gets a value indicating whether the application should restart.
/// </summary>
bool ShouldRestart { get; }
/// <summary> /// <summary>
/// Gets the application version. /// Gets the application version.
@ -91,11 +85,6 @@ namespace MediaBrowser.Common
/// </summary> /// </summary>
void NotifyPendingRestart(); void NotifyPendingRestart();
/// <summary>
/// Restarts this instance.
/// </summary>
void Restart();
/// <summary> /// <summary>
/// Gets the exports. /// Gets the exports.
/// </summary> /// </summary>
@ -127,11 +116,6 @@ namespace MediaBrowser.Common
/// <returns>``0.</returns> /// <returns>``0.</returns>
T Resolve<T>(); T Resolve<T>();
/// <summary>
/// Shuts down.
/// </summary>
void Shutdown();
/// <summary> /// <summary>
/// Initializes this instance. /// Initializes this instance.
/// </summary> /// </summary>

@ -4,7 +4,6 @@
using System.Net; using System.Net;
using MediaBrowser.Common; using MediaBrowser.Common;
using MediaBrowser.Model.System;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
namespace MediaBrowser.Controller namespace MediaBrowser.Controller
@ -16,8 +15,6 @@ namespace MediaBrowser.Controller
{ {
bool CoreStartupHasCompleted { get; } bool CoreStartupHasCompleted { get; }
bool CanLaunchWebBrowser { get; }
/// <summary> /// <summary>
/// Gets the HTTP server port. /// Gets the HTTP server port.
/// </summary> /// </summary>
@ -41,15 +38,6 @@ namespace MediaBrowser.Controller
/// <value>The name of the friendly.</value> /// <value>The name of the friendly.</value>
string FriendlyName { get; } string FriendlyName { get; }
/// <summary>
/// Gets the system info.
/// </summary>
/// <param name="request">The HTTP request.</param>
/// <returns>SystemInfo.</returns>
SystemInfo GetSystemInfo(HttpRequest request);
PublicSystemInfo GetPublicSystemInfo(HttpRequest request);
/// <summary> /// <summary>
/// Gets a URL specific for the request. /// Gets a URL specific for the request.
/// </summary> /// </summary>

@ -0,0 +1,34 @@
using MediaBrowser.Model.System;
using Microsoft.AspNetCore.Http;
namespace MediaBrowser.Controller;
/// <summary>
/// A service for managing the application instance.
/// </summary>
public interface ISystemManager
{
/// <summary>
/// Gets the system info.
/// </summary>
/// <param name="request">The HTTP request.</param>
/// <returns>The <see cref="SystemInfo"/>.</returns>
SystemInfo GetSystemInfo(HttpRequest request);
/// <summary>
/// Gets the public system info.
/// </summary>
/// <param name="request">The HTTP request.</param>
/// <returns>The <see cref="PublicSystemInfo"/>.</returns>
PublicSystemInfo GetPublicSystemInfo(HttpRequest request);
/// <summary>
/// Starts the application restart process.
/// </summary>
void Restart();
/// <summary>
/// Starts the application shutdown process.
/// </summary>
void Shutdown();
}
Loading…
Cancel
Save