From 5cc2db26e71cc5833968d67f72ec6be35b2e1f68 Mon Sep 17 00:00:00 2001 From: Taloth Saldono Date: Sat, 6 Mar 2021 22:47:02 +0100 Subject: [PATCH] Added mechanism for package maintainers to produce a health check error. Fixes #2049 (cherry picked from commit 7da02c236aa03e6aef011130526040c1cb8399fc) (cherry picked from commit 024000275df3b2d3b884c2c2fbf0b86bd36a631a) --- src/NzbDrone.Console/ConsoleApp.cs | 4 +- .../UpdateTests/UpdateServiceFixture.cs | 21 ++++++++- .../Configuration/DeploymentInfoProvider.cs | 3 ++ .../Checks/PackageGlobalMessageCheck.cs | 43 +++++++++++++++++++ .../Update/InstallUpdateService.cs | 14 ++++-- 5 files changed, 79 insertions(+), 6 deletions(-) create mode 100644 src/NzbDrone.Core/HealthCheck/Checks/PackageGlobalMessageCheck.cs diff --git a/src/NzbDrone.Console/ConsoleApp.cs b/src/NzbDrone.Console/ConsoleApp.cs index 60ea9f204..7e616ffb6 100644 --- a/src/NzbDrone.Console/ConsoleApp.cs +++ b/src/NzbDrone.Console/ConsoleApp.cs @@ -53,7 +53,7 @@ namespace NzbDrone.Console { System.Console.WriteLine(""); System.Console.WriteLine(""); - Logger.Fatal(ex.Message + ". This can happen if another instance of Lidarr is already running another application is using the same port (default: 8989) or the user has insufficient permissions"); + Logger.Fatal(ex.Message + ". This can happen if another instance of Lidarr is already running another application is using the same port (default: 8686) or the user has insufficient permissions"); Exit(ExitCodes.RecoverableFailure, startupArgs); } catch (IOException ex) @@ -62,7 +62,7 @@ namespace NzbDrone.Console { System.Console.WriteLine(""); System.Console.WriteLine(""); - Logger.Fatal(ex.Message + " This can happen if another instance of Radarr is already running another application is using the same port (default: 7878) or the user has insufficient permissions"); + Logger.Fatal(ex.Message + " This can happen if another instance of Lidarr is already running another application is using the same port (default: 8686) or the user has insufficient permissions"); Exit(ExitCodes.RecoverableFailure, startupArgs); } else diff --git a/src/NzbDrone.Core.Test/UpdateTests/UpdateServiceFixture.cs b/src/NzbDrone.Core.Test/UpdateTests/UpdateServiceFixture.cs index 3470710b2..e2abfe8d6 100644 --- a/src/NzbDrone.Core.Test/UpdateTests/UpdateServiceFixture.cs +++ b/src/NzbDrone.Core.Test/UpdateTests/UpdateServiceFixture.cs @@ -68,6 +68,10 @@ namespace NzbDrone.Core.Test.UpdateTests .Setup(c => c.FolderWritable(It.IsAny())) .Returns(true); + Mocker.GetMock() + .Setup(v => v.FileExists(It.Is(s => s.EndsWith("Lidarr.Update.exe")))) + .Returns(true); + _sandboxFolder = Mocker.GetMock().Object.GetUpdateSandboxFolder(); } @@ -149,7 +153,7 @@ namespace NzbDrone.Core.Test.UpdateTests } [Test] - public void should_start_update_client() + public void should_start_update_client_if_updater_exists() { Subject.Execute(new ApplicationUpdateCommand()); @@ -157,6 +161,21 @@ namespace NzbDrone.Core.Test.UpdateTests .Verify(c => c.Start(It.IsAny(), It.Is(s => s.StartsWith("12")), null, null, null), Times.Once()); } + [Test] + public void should_return_with_warning_if_updater_doesnt_exists() + { + Mocker.GetMock() + .Setup(v => v.FileExists(It.Is(s => s.EndsWith("Lidarr.Update.exe")))) + .Returns(false); + + Subject.Execute(new ApplicationUpdateCommand()); + + Mocker.GetMock() + .Verify(c => c.Start(It.IsAny(), It.IsAny(), null, null, null), Times.Never()); + + ExceptionVerification.ExpectedWarns(1); + } + [Test] public void should_return_without_error_or_warnings_when_no_updates_are_available() { diff --git a/src/NzbDrone.Core/Configuration/DeploymentInfoProvider.cs b/src/NzbDrone.Core/Configuration/DeploymentInfoProvider.cs index bb11ec3ff..ab2b5ec27 100644 --- a/src/NzbDrone.Core/Configuration/DeploymentInfoProvider.cs +++ b/src/NzbDrone.Core/Configuration/DeploymentInfoProvider.cs @@ -12,6 +12,7 @@ namespace NzbDrone.Core.Configuration { string PackageVersion { get; } string PackageAuthor { get; } + string PackageGlobalMessage { get; } string PackageBranch { get; } UpdateMechanism PackageUpdateMechanism { get; } string PackageUpdateMechanismMessage { get; } @@ -41,6 +42,7 @@ namespace NzbDrone.Core.Configuration PackageVersion = ReadValue(data, "PackageVersion"); PackageAuthor = ReadValue(data, "PackageAuthor"); + PackageGlobalMessage = ReadValue(data, "PackageGlobalMessage"); PackageUpdateMechanism = ReadEnumValue(data, "UpdateMethod", UpdateMechanism.BuiltIn); PackageUpdateMechanismMessage = ReadValue(data, "UpdateMethodMessage"); PackageBranch = ReadValue(data, "Branch"); @@ -94,6 +96,7 @@ namespace NzbDrone.Core.Configuration public string PackageVersion { get; private set; } public string PackageAuthor { get; private set; } + public string PackageGlobalMessage { get; private set; } public string PackageBranch { get; private set; } public UpdateMechanism PackageUpdateMechanism { get; private set; } public string PackageUpdateMechanismMessage { get; private set; } diff --git a/src/NzbDrone.Core/HealthCheck/Checks/PackageGlobalMessageCheck.cs b/src/NzbDrone.Core/HealthCheck/Checks/PackageGlobalMessageCheck.cs new file mode 100644 index 000000000..6c9ce8995 --- /dev/null +++ b/src/NzbDrone.Core/HealthCheck/Checks/PackageGlobalMessageCheck.cs @@ -0,0 +1,43 @@ +using System; +using System.Linq; +using System.Text.RegularExpressions; +using NLog; +using NzbDrone.Common.Extensions; +using NzbDrone.Core.Configuration; + +namespace NzbDrone.Core.HealthCheck.Checks +{ + public class PackageGlobalMessageCheck : HealthCheckBase + { + private readonly IDeploymentInfoProvider _deploymentInfoProvider; + + public PackageGlobalMessageCheck(IDeploymentInfoProvider deploymentInfoProvider) + { + _deploymentInfoProvider = deploymentInfoProvider; + } + + public override HealthCheck Check() + { + if (_deploymentInfoProvider.PackageGlobalMessage.IsNullOrWhiteSpace()) + { + return new HealthCheck(GetType()); + } + + var message = _deploymentInfoProvider.PackageGlobalMessage; + HealthCheckResult result = HealthCheckResult.Notice; + + if (message.StartsWith("Error:")) + { + message = message.Substring(6); + result = HealthCheckResult.Error; + } + else if (message.StartsWith("Warn:")) + { + message = message.Substring(5); + result = HealthCheckResult.Warning; + } + + return new HealthCheck(GetType(), result, message, "#package_maintainer_message"); + } + } +} diff --git a/src/NzbDrone.Core/Update/InstallUpdateService.cs b/src/NzbDrone.Core/Update/InstallUpdateService.cs index d46a9992f..7c1cdd390 100644 --- a/src/NzbDrone.Core/Update/InstallUpdateService.cs +++ b/src/NzbDrone.Core/Update/InstallUpdateService.cs @@ -146,16 +146,24 @@ namespace NzbDrone.Core.Update _logger.Info("Preparing client"); _diskTransferService.TransferFolder(_appFolderInfo.GetUpdateClientFolder(), updateSandboxFolder, TransferMode.Move); + var updateClientExePath = _appFolderInfo.GetUpdateClientExePath(updatePackage.Runtime); + + if (!_diskProvider.FileExists(updateClientExePath)) + { + _logger.Warn("Update client {0} does not exist, aborting update.", updateClientExePath); + return false; + } + // Set executable flag on update app if (OsInfo.IsOsx || (OsInfo.IsLinux && PlatformInfo.IsNetCore)) { - _diskProvider.SetFilePermissions(_appFolderInfo.GetUpdateClientExePath(updatePackage.Runtime), "755", null); + _diskProvider.SetFilePermissions(updateClientExePath, "755", null); } - _logger.Info("Starting update client {0}", _appFolderInfo.GetUpdateClientExePath(updatePackage.Runtime)); + _logger.Info("Starting update client {0}", updateClientExePath); _logger.ProgressInfo("Lidarr will restart shortly."); - _processProvider.Start(_appFolderInfo.GetUpdateClientExePath(updatePackage.Runtime), GetUpdaterArgs(updateSandboxFolder)); + _processProvider.Start(updateClientExePath, GetUpdaterArgs(updateSandboxFolder)); return true; }