mirror of
https://github.com/Sonarr/Sonarr
synced 2025-03-03 10:17:17 +00:00
fixed apptype detection during update
This commit is contained in:
parent
2573558321
commit
99f269cd95
11 changed files with 300 additions and 187 deletions
|
@ -5,38 +5,21 @@ using NUnit.Framework;
|
|||
using NzbDrone.Common;
|
||||
using NzbDrone.Common.Model;
|
||||
using NzbDrone.Test.Common;
|
||||
using NzbDrone.Update.Providers;
|
||||
using NzbDrone.Update.UpdateEngine;
|
||||
|
||||
namespace NzbDrone.Update.Test
|
||||
{
|
||||
[TestFixture]
|
||||
public class ProgramFixture : TestBase
|
||||
public class ProgramFixture : TestBase<Program>
|
||||
{
|
||||
private Program _program;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_program = Mocker.Resolve<Program>();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_throw_if_null_passed_in()
|
||||
{
|
||||
Assert.Throws<ArgumentException>(() => _program.Start(null));
|
||||
Assert.Throws<ArgumentOutOfRangeException>(() => Subject.Start(null));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_throw_if_less_than_two_arguments_arent_passed_in()
|
||||
{
|
||||
Assert.Throws<ArgumentException>(() => _program.Start(new[] { "" }));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_throw_if_more_than_two_arguments_arent_passed_in()
|
||||
{
|
||||
Assert.Throws<ArgumentException>(() => _program.Start(new[] { "", "", "" }));
|
||||
}
|
||||
|
||||
[TestCase("d", "")]
|
||||
[TestCase("", "")]
|
||||
|
@ -46,7 +29,7 @@ namespace NzbDrone.Update.Test
|
|||
[TestCase(".", "")]
|
||||
public void should_throw_if_first_arg_isnt_an_int(string arg1, string arg2)
|
||||
{
|
||||
Assert.Throws<ArgumentOutOfRangeException>(() => _program.Start(new[] { arg1, arg2 }));
|
||||
Assert.Throws<ArgumentOutOfRangeException>(() => Subject.Start(new[] { arg1, arg2 }));
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
@ -57,11 +40,11 @@ namespace NzbDrone.Update.Test
|
|||
Mocker.GetMock<IProcessProvider>().Setup(c => c.GetProcessById(12))
|
||||
.Returns(new ProcessInfo() { StartPath = ProcessPath });
|
||||
|
||||
|
||||
_program.Start(new[] { "12", "" });
|
||||
|
||||
|
||||
Mocker.GetMock<UpdateProvider>().Verify(c => c.Start(@"C:\NzbDrone"), Times.Once());
|
||||
Subject.Start(new[] { "12", "" });
|
||||
|
||||
|
||||
Mocker.GetMock<IInstallUpdateService>().Verify(c => c.Start(@"C:\NzbDrone"), Times.Once());
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System.Collections.Generic;
|
||||
/*
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using FizzWare.NBuilder;
|
||||
|
@ -7,7 +8,7 @@ using NUnit.Framework;
|
|||
using NzbDrone.Common;
|
||||
using NzbDrone.Common.Model;
|
||||
using NzbDrone.Test.Common;
|
||||
using NzbDrone.Update.Providers;
|
||||
using NzbDrone.Update.UpdateEngine;
|
||||
|
||||
namespace NzbDrone.Update.Test
|
||||
{
|
||||
|
@ -58,7 +59,7 @@ namespace NzbDrone.Update.Test
|
|||
WithServiceRunning(true);
|
||||
|
||||
|
||||
Mocker.Resolve<UpdateProvider>().Start(TARGET_FOLDER);
|
||||
Mocker.Resolve<InstallUpdateService>().Start(TARGET_FOLDER);
|
||||
|
||||
|
||||
Mocker.GetMock<IServiceProvider>().Verify(c => c.Stop(ServiceProvider.NZBDRONE_SERVICE_NAME), Times.Once());
|
||||
|
@ -71,7 +72,7 @@ namespace NzbDrone.Update.Test
|
|||
WithServiceRunning(false);
|
||||
|
||||
|
||||
Mocker.Resolve<UpdateProvider>().Start(TARGET_FOLDER);
|
||||
Mocker.Resolve<InstallUpdateService>().Start(TARGET_FOLDER);
|
||||
|
||||
|
||||
Mocker.GetMock<IServiceProvider>().Verify(c => c.Stop(ServiceProvider.NZBDRONE_SERVICE_NAME), Times.Never());
|
||||
|
@ -81,7 +82,7 @@ namespace NzbDrone.Update.Test
|
|||
public void should_not_stop_nzbdrone_service_if_service_isnt_installed()
|
||||
{
|
||||
|
||||
Mocker.Resolve<UpdateProvider>().Start(TARGET_FOLDER);
|
||||
Mocker.Resolve<InstallUpdateService>().Start(TARGET_FOLDER);
|
||||
|
||||
|
||||
Mocker.GetMock<IServiceProvider>().Verify(c => c.Stop(It.IsAny<string>()), Times.Never());
|
||||
|
@ -97,7 +98,7 @@ namespace NzbDrone.Update.Test
|
|||
.Returns(proccesses);
|
||||
|
||||
|
||||
Mocker.Resolve<UpdateProvider>().Start(TARGET_FOLDER);
|
||||
Mocker.Resolve<InstallUpdateService>().Start(TARGET_FOLDER);
|
||||
|
||||
|
||||
Mocker.GetMock<IProcessProvider>().Verify(c => c.KillAll(ProcessProvider.NzbDroneProcessName), Times.Once());
|
||||
|
@ -111,7 +112,7 @@ namespace NzbDrone.Update.Test
|
|||
.Returns(new List<ProcessInfo>());
|
||||
|
||||
|
||||
Mocker.Resolve<UpdateProvider>().Start(TARGET_FOLDER);
|
||||
Mocker.Resolve<InstallUpdateService>().Start(TARGET_FOLDER);
|
||||
|
||||
|
||||
Mocker.GetMock<IProcessProvider>().Verify(c => c.Kill(It.IsAny<int>()), Times.Never());
|
||||
|
@ -123,7 +124,7 @@ namespace NzbDrone.Update.Test
|
|||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(c => c.CopyDirectory(TARGET_FOLDER, BACKUP_FOLDER));
|
||||
|
||||
Mocker.Resolve<UpdateProvider>().Start(TARGET_FOLDER);
|
||||
Mocker.Resolve<InstallUpdateService>().Start(TARGET_FOLDER);
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
@ -135,7 +136,7 @@ namespace NzbDrone.Update.Test
|
|||
Mocker.GetMock<IDiskProvider>()
|
||||
.Setup(c => c.DeleteFolder(UPDATE_FOLDER, true));
|
||||
|
||||
Mocker.Resolve<UpdateProvider>().Start(TARGET_FOLDER);
|
||||
Mocker.Resolve<InstallUpdateService>().Start(TARGET_FOLDER);
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
@ -146,7 +147,7 @@ namespace NzbDrone.Update.Test
|
|||
.Throws(new IOException());
|
||||
|
||||
|
||||
Mocker.Resolve<UpdateProvider>().Start(TARGET_FOLDER);
|
||||
Mocker.Resolve<InstallUpdateService>().Start(TARGET_FOLDER);
|
||||
|
||||
|
||||
Mocker.GetMock<IDiskProvider>()
|
||||
|
@ -161,7 +162,7 @@ namespace NzbDrone.Update.Test
|
|||
WithServiceRunning(true);
|
||||
|
||||
|
||||
Mocker.Resolve<UpdateProvider>().Start(TARGET_FOLDER);
|
||||
Mocker.Resolve<InstallUpdateService>().Start(TARGET_FOLDER);
|
||||
|
||||
|
||||
VerifyServiceRestart();
|
||||
|
@ -174,7 +175,7 @@ namespace NzbDrone.Update.Test
|
|||
WithServiceRunning(false);
|
||||
|
||||
|
||||
Mocker.Resolve<UpdateProvider>().Start(TARGET_FOLDER);
|
||||
Mocker.Resolve<InstallUpdateService>().Start(TARGET_FOLDER);
|
||||
|
||||
|
||||
VerifyProcessRestart();
|
||||
|
@ -191,7 +192,7 @@ namespace NzbDrone.Update.Test
|
|||
.Throws(new IOException());
|
||||
|
||||
|
||||
Mocker.Resolve<UpdateProvider>().Start(TARGET_FOLDER);
|
||||
Mocker.Resolve<InstallUpdateService>().Start(TARGET_FOLDER);
|
||||
|
||||
|
||||
VerifyServiceRestart();
|
||||
|
@ -209,7 +210,7 @@ namespace NzbDrone.Update.Test
|
|||
.Throws(new IOException());
|
||||
|
||||
|
||||
Mocker.Resolve<UpdateProvider>().Start(TARGET_FOLDER);
|
||||
Mocker.Resolve<InstallUpdateService>().Start(TARGET_FOLDER);
|
||||
|
||||
|
||||
VerifyProcessRestart();
|
||||
|
@ -237,3 +238,4 @@ namespace NzbDrone.Update.Test
|
|||
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
|
|
@ -4,7 +4,7 @@ using FluentAssertions;
|
|||
using NUnit.Framework;
|
||||
using NzbDrone.Common;
|
||||
using NzbDrone.Test.Common;
|
||||
using NzbDrone.Update.Providers;
|
||||
using NzbDrone.Update.UpdateEngine;
|
||||
|
||||
namespace NzbDrone.Update.Test
|
||||
{
|
||||
|
@ -25,7 +25,7 @@ namespace NzbDrone.Update.Test
|
|||
[TestCase(" ")]
|
||||
public void update_should_throw_target_folder_is_blank(string target)
|
||||
{
|
||||
Assert.Throws<ArgumentException>(() => Mocker.Resolve<UpdateProvider>().Start(target))
|
||||
Assert.Throws<ArgumentException>(() => Mocker.Resolve<InstallUpdateService>().Start(target))
|
||||
.Message.Should().StartWith("Target folder can not be null or empty");
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,7 @@ namespace NzbDrone.Update.Test
|
|||
{
|
||||
string targetFolder = "c:\\NzbDrone\\";
|
||||
|
||||
Assert.Throws<DirectoryNotFoundException>(() => Mocker.Resolve<UpdateProvider>().Start(targetFolder))
|
||||
Assert.Throws<DirectoryNotFoundException>(() => Mocker.Resolve<InstallUpdateService>().Start(targetFolder))
|
||||
.Message.Should().StartWith("Target folder doesn't exist");
|
||||
}
|
||||
|
||||
|
@ -52,7 +52,7 @@ namespace NzbDrone.Update.Test
|
|||
.Setup(c => c.FolderExists(sandboxFolder))
|
||||
.Returns(false);
|
||||
|
||||
Assert.Throws<DirectoryNotFoundException>(() => Mocker.Resolve<UpdateProvider>().Start(targetFolder))
|
||||
Assert.Throws<DirectoryNotFoundException>(() => Mocker.Resolve<InstallUpdateService>().Start(targetFolder))
|
||||
.Message.Should().StartWith("Update folder doesn't exist");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -69,8 +69,12 @@
|
|||
<Compile Include="AppType.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Providers\UpdateProvider.cs" />
|
||||
<Compile Include="UpdateContainerBuilder.cs" />
|
||||
<Compile Include="UpdateEngine\BackupAndRestore.cs" />
|
||||
<Compile Include="UpdateEngine\DetectApplicationType.cs" />
|
||||
<Compile Include="UpdateEngine\InstallUpdateService.cs" />
|
||||
<Compile Include="UpdateEngine\StartNzbDrone.cs" />
|
||||
<Compile Include="UpdateEngine\TerminateNzbDrone.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="app.config" />
|
||||
|
@ -89,6 +93,7 @@
|
|||
<Name>NzbDrone.Common</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="$(SolutionDir)\.nuget\nuget.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
|
|
|
@ -3,21 +3,21 @@ using System.IO;
|
|||
using NLog;
|
||||
using NzbDrone.Common;
|
||||
using NzbDrone.Common.Composition;
|
||||
using NzbDrone.Update.Providers;
|
||||
using NzbDrone.Update.UpdateEngine;
|
||||
|
||||
namespace NzbDrone.Update
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
private readonly UpdateProvider _updateProvider;
|
||||
private readonly IInstallUpdateService _installUpdateService;
|
||||
private readonly IProcessProvider _processProvider;
|
||||
private static IContainer _container;
|
||||
|
||||
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
public Program(UpdateProvider updateProvider, IProcessProvider processProvider)
|
||||
public Program(IInstallUpdateService installUpdateService, IProcessProvider processProvider)
|
||||
{
|
||||
_updateProvider = updateProvider;
|
||||
_installUpdateService = installUpdateService;
|
||||
_processProvider = processProvider;
|
||||
}
|
||||
|
||||
|
@ -47,13 +47,13 @@ namespace NzbDrone.Update
|
|||
string targetFolder = exeFileInfo.Directory.FullName;
|
||||
|
||||
logger.Info("Starting update process. Target Path:{0}", targetFolder);
|
||||
_updateProvider.Start(targetFolder);
|
||||
_installUpdateService.Start(targetFolder);
|
||||
}
|
||||
|
||||
private int ParseProcessId(string[] args)
|
||||
{
|
||||
int id;
|
||||
if (!Int32.TryParse(args[0], out id) || id <= 0)
|
||||
if (args ==null || !Int32.TryParse(args[0], out id) || id <= 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("Invalid process id: " + args[0]);
|
||||
}
|
||||
|
|
|
@ -1,137 +0,0 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using NLog;
|
||||
using NzbDrone.Common;
|
||||
using IServiceProvider = NzbDrone.Common.IServiceProvider;
|
||||
|
||||
namespace NzbDrone.Update.Providers
|
||||
{
|
||||
public class UpdateProvider
|
||||
{
|
||||
private readonly IDiskProvider _diskProvider;
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private readonly IProcessProvider _processProvider;
|
||||
private readonly IEnvironmentProvider _environmentProvider;
|
||||
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
public UpdateProvider(IDiskProvider diskProvider, IServiceProvider serviceProvider,
|
||||
IProcessProvider processProvider, IEnvironmentProvider environmentProvider)
|
||||
{
|
||||
_diskProvider = diskProvider;
|
||||
_serviceProvider = serviceProvider;
|
||||
_processProvider = processProvider;
|
||||
_environmentProvider = environmentProvider;
|
||||
}
|
||||
|
||||
public UpdateProvider()
|
||||
{
|
||||
}
|
||||
|
||||
private void Verify(string targetFolder)
|
||||
{
|
||||
logger.Info("Verifying requirements before update...");
|
||||
|
||||
if (String.IsNullOrWhiteSpace(targetFolder))
|
||||
throw new ArgumentException("Target folder can not be null or empty");
|
||||
|
||||
if (!_diskProvider.FolderExists(targetFolder))
|
||||
throw new DirectoryNotFoundException("Target folder doesn't exist " + targetFolder);
|
||||
|
||||
logger.Info("Verifying Update Folder");
|
||||
if (!_diskProvider.FolderExists(_environmentProvider.GetUpdatePackageFolder()))
|
||||
throw new DirectoryNotFoundException("Update folder doesn't exist " + _environmentProvider.GetUpdatePackageFolder());
|
||||
}
|
||||
|
||||
public virtual void Start(string targetFolder)
|
||||
{
|
||||
Verify(targetFolder);
|
||||
var appType = AppType.Normal;
|
||||
|
||||
logger.Info("Stopping all running services");
|
||||
|
||||
if (_serviceProvider.ServiceExist(ServiceProvider.NZBDRONE_SERVICE_NAME)
|
||||
&& _serviceProvider.IsServiceRunning(ServiceProvider.NZBDRONE_SERVICE_NAME))
|
||||
{
|
||||
appType = AppType.Service;
|
||||
|
||||
try
|
||||
{
|
||||
_serviceProvider.Stop(ServiceProvider.NZBDRONE_SERVICE_NAME);
|
||||
|
||||
}
|
||||
catch (InvalidOperationException e)
|
||||
{
|
||||
logger.WarnException("couldn't stop service", e);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
appType = AppType.Normal;
|
||||
}
|
||||
|
||||
//TODO:Should be able to restart service if anything beyond this point fails
|
||||
logger.Info("Killing all running processes");
|
||||
|
||||
if (_processProvider.GetProcessByName(ProcessProvider.NzbDroneConsoleProcessName).Any())
|
||||
{
|
||||
appType = AppType.Console;
|
||||
_processProvider.KillAll(ProcessProvider.NzbDroneConsoleProcessName);
|
||||
}
|
||||
|
||||
_processProvider.KillAll(ProcessProvider.NzbDroneProcessName);
|
||||
|
||||
logger.Info("Creating backup of existing installation");
|
||||
_diskProvider.CopyDirectory(targetFolder, _environmentProvider.GetUpdateBackUpFolder());
|
||||
|
||||
logger.Info("Moving update package to target");
|
||||
|
||||
try
|
||||
{
|
||||
_diskProvider.CopyDirectory(_environmentProvider.GetUpdatePackageFolder(), targetFolder);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
RollBack(targetFolder);
|
||||
|
||||
foreach (var key in e.Data.Keys)
|
||||
{
|
||||
logger.Trace("Key: {0}, Value: {1}", key, e.Data[key]);
|
||||
}
|
||||
|
||||
logger.FatalException("Failed to copy upgrade package to target folder.", e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
StartNzbDrone(appType, targetFolder);
|
||||
}
|
||||
}
|
||||
|
||||
private void RollBack(string targetFolder)
|
||||
{
|
||||
//TODO:this should ignore single file failures.
|
||||
logger.Info("Attempting to rollback upgrade");
|
||||
_diskProvider.CopyDirectory(_environmentProvider.GetUpdateBackUpFolder(), targetFolder);
|
||||
}
|
||||
|
||||
private void StartNzbDrone(AppType appType, string targetFolder)
|
||||
{
|
||||
logger.Info("Starting NzbDrone");
|
||||
if (appType == AppType.Service)
|
||||
{
|
||||
logger.Info("Starting NzbDrone service");
|
||||
_serviceProvider.Start(ServiceProvider.NZBDRONE_SERVICE_NAME);
|
||||
}
|
||||
else if (appType == AppType.Console)
|
||||
{
|
||||
logger.Info("Starting NzbDrone with Console");
|
||||
_processProvider.Start(Path.Combine(targetFolder, "NzbDrone.Console.exe"));
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.Info("Starting NzbDrone without Console");
|
||||
_processProvider.Start(Path.Combine(targetFolder, "NzbDrone.exe"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
38
NzbDrone.Update/UpdateEngine/BackupAndRestore.cs
Normal file
38
NzbDrone.Update/UpdateEngine/BackupAndRestore.cs
Normal file
|
@ -0,0 +1,38 @@
|
|||
using NLog;
|
||||
using NzbDrone.Common;
|
||||
|
||||
namespace NzbDrone.Update.UpdateEngine
|
||||
{
|
||||
public interface IBackupAndRestore
|
||||
{
|
||||
void BackUp(string source);
|
||||
void Restore(string target);
|
||||
}
|
||||
|
||||
public class BackupAndRestore : IBackupAndRestore
|
||||
{
|
||||
private readonly IDiskProvider _diskProvider;
|
||||
private readonly IEnvironmentProvider _environmentProvider;
|
||||
private readonly Logger _logger;
|
||||
|
||||
public BackupAndRestore(IDiskProvider diskProvider, IEnvironmentProvider environmentProvider, Logger logger)
|
||||
{
|
||||
_diskProvider = diskProvider;
|
||||
_environmentProvider = environmentProvider;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public void BackUp(string source)
|
||||
{
|
||||
_logger.Info("Creating backup of existing installation");
|
||||
_diskProvider.CopyDirectory(source, _environmentProvider.GetUpdateBackUpFolder());
|
||||
}
|
||||
|
||||
public void Restore(string target)
|
||||
{
|
||||
//TODO:this should ignore single file failures.
|
||||
_logger.Info("Attempting to rollback upgrade");
|
||||
_diskProvider.CopyDirectory(_environmentProvider.GetUpdateBackUpFolder(), target);
|
||||
}
|
||||
}
|
||||
}
|
38
NzbDrone.Update/UpdateEngine/DetectApplicationType.cs
Normal file
38
NzbDrone.Update/UpdateEngine/DetectApplicationType.cs
Normal file
|
@ -0,0 +1,38 @@
|
|||
using System.Linq;
|
||||
using NzbDrone.Common;
|
||||
|
||||
namespace NzbDrone.Update.UpdateEngine
|
||||
{
|
||||
public interface IDetectApplicationType
|
||||
{
|
||||
AppType GetAppType();
|
||||
}
|
||||
|
||||
public class DetectApplicationType : IDetectApplicationType
|
||||
{
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private readonly IProcessProvider _processProvider;
|
||||
|
||||
public DetectApplicationType(IServiceProvider serviceProvider, IProcessProvider processProvider)
|
||||
{
|
||||
_serviceProvider = serviceProvider;
|
||||
_processProvider = processProvider;
|
||||
}
|
||||
|
||||
public AppType GetAppType()
|
||||
{
|
||||
if (_serviceProvider.ServiceExist(ServiceProvider.NZBDRONE_SERVICE_NAME)
|
||||
&& _serviceProvider.IsServiceRunning(ServiceProvider.NZBDRONE_SERVICE_NAME))
|
||||
{
|
||||
return AppType.Service;
|
||||
}
|
||||
|
||||
if (_processProvider.GetProcessByName(ProcessProvider.NzbDroneConsoleProcessName).Any())
|
||||
{
|
||||
return AppType.Console;
|
||||
}
|
||||
|
||||
return AppType.Normal;
|
||||
}
|
||||
}
|
||||
}
|
82
NzbDrone.Update/UpdateEngine/InstallUpdateService.cs
Normal file
82
NzbDrone.Update/UpdateEngine/InstallUpdateService.cs
Normal file
|
@ -0,0 +1,82 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using NLog;
|
||||
using NzbDrone.Common;
|
||||
|
||||
namespace NzbDrone.Update.UpdateEngine
|
||||
{
|
||||
public interface IInstallUpdateService
|
||||
{
|
||||
void Start(string installationFolder);
|
||||
}
|
||||
|
||||
public class InstallUpdateService : IInstallUpdateService
|
||||
{
|
||||
private readonly IDiskProvider _diskProvider;
|
||||
private readonly IDetectApplicationType _detectApplicationType;
|
||||
private readonly ITerminateNzbDrone _terminateNzbDrone;
|
||||
private readonly IEnvironmentProvider _environmentProvider;
|
||||
private readonly IBackupAndRestore _backupAndRestore;
|
||||
private readonly IStartNzbDrone _startNzbDrone;
|
||||
private readonly Logger _logger;
|
||||
|
||||
public InstallUpdateService(IDiskProvider diskProvider, IDetectApplicationType detectApplicationType, ITerminateNzbDrone terminateNzbDrone,
|
||||
IProcessProvider processProvider, IEnvironmentProvider environmentProvider, IBackupAndRestore backupAndRestore, IStartNzbDrone startNzbDrone, Logger logger)
|
||||
{
|
||||
_diskProvider = diskProvider;
|
||||
_detectApplicationType = detectApplicationType;
|
||||
_terminateNzbDrone = terminateNzbDrone;
|
||||
_environmentProvider = environmentProvider;
|
||||
_backupAndRestore = backupAndRestore;
|
||||
_startNzbDrone = startNzbDrone;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
private void Verify(string targetFolder)
|
||||
{
|
||||
_logger.Info("Verifying requirements before update...");
|
||||
|
||||
if (String.IsNullOrWhiteSpace(targetFolder))
|
||||
throw new ArgumentException("Target folder can not be null or empty");
|
||||
|
||||
if (!_diskProvider.FolderExists(targetFolder))
|
||||
throw new DirectoryNotFoundException("Target folder doesn't exist " + targetFolder);
|
||||
|
||||
_logger.Info("Verifying Update Folder");
|
||||
if (!_diskProvider.FolderExists(_environmentProvider.GetUpdatePackageFolder()))
|
||||
throw new DirectoryNotFoundException("Update folder doesn't exist " + _environmentProvider.GetUpdatePackageFolder());
|
||||
}
|
||||
|
||||
public void Start(string installationFolder)
|
||||
{
|
||||
Verify(installationFolder);
|
||||
|
||||
var appType = _detectApplicationType.GetAppType();
|
||||
|
||||
try
|
||||
{
|
||||
_terminateNzbDrone.Terminate();
|
||||
|
||||
_backupAndRestore.BackUp(installationFolder);
|
||||
|
||||
_logger.Info("Moving update package to target");
|
||||
|
||||
try
|
||||
{
|
||||
_diskProvider.CopyDirectory(_environmentProvider.GetUpdatePackageFolder(), installationFolder);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_backupAndRestore.Restore(installationFolder);
|
||||
_logger.FatalException("Failed to copy upgrade package to target folder.", e);
|
||||
}
|
||||
|
||||
}
|
||||
finally
|
||||
{
|
||||
_startNzbDrone.Start(appType, installationFolder);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
45
NzbDrone.Update/UpdateEngine/StartNzbDrone.cs
Normal file
45
NzbDrone.Update/UpdateEngine/StartNzbDrone.cs
Normal file
|
@ -0,0 +1,45 @@
|
|||
using System.IO;
|
||||
using NLog;
|
||||
using NzbDrone.Common;
|
||||
|
||||
namespace NzbDrone.Update.UpdateEngine
|
||||
{
|
||||
public interface IStartNzbDrone
|
||||
{
|
||||
void Start(AppType appType, string installationFolder);
|
||||
}
|
||||
|
||||
public class StartNzbDrone : IStartNzbDrone
|
||||
{
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private readonly IProcessProvider _processProvider;
|
||||
private readonly Logger _logger;
|
||||
|
||||
public StartNzbDrone(IServiceProvider serviceProvider, IProcessProvider processProvider, Logger logger)
|
||||
{
|
||||
_serviceProvider = serviceProvider;
|
||||
_processProvider = processProvider;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public void Start(AppType appType, string installationFolder)
|
||||
{
|
||||
_logger.Info("Starting NzbDrone");
|
||||
if (appType == AppType.Service)
|
||||
{
|
||||
_logger.Info("Starting NzbDrone service");
|
||||
_serviceProvider.Start(ServiceProvider.NZBDRONE_SERVICE_NAME);
|
||||
}
|
||||
else if (appType == AppType.Console)
|
||||
{
|
||||
_logger.Info("Starting NzbDrone with Console");
|
||||
_processProvider.Start(Path.Combine(installationFolder, "NzbDrone.Console.exe"));
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Info("Starting NzbDrone without Console");
|
||||
_processProvider.Start(Path.Combine(installationFolder, "NzbDrone.exe"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
57
NzbDrone.Update/UpdateEngine/TerminateNzbDrone.cs
Normal file
57
NzbDrone.Update/UpdateEngine/TerminateNzbDrone.cs
Normal file
|
@ -0,0 +1,57 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using NLog;
|
||||
using NzbDrone.Common;
|
||||
using IServiceProvider = NzbDrone.Common.IServiceProvider;
|
||||
|
||||
namespace NzbDrone.Update.UpdateEngine
|
||||
{
|
||||
public interface ITerminateNzbDrone
|
||||
{
|
||||
void Terminate();
|
||||
}
|
||||
|
||||
public class TerminateNzbDrone : ITerminateNzbDrone
|
||||
{
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private readonly IProcessProvider _processProvider;
|
||||
private readonly Logger _logger;
|
||||
|
||||
public TerminateNzbDrone(IServiceProvider serviceProvider, IProcessProvider processProvider, Logger logger)
|
||||
{
|
||||
_serviceProvider = serviceProvider;
|
||||
_processProvider = processProvider;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public void Terminate()
|
||||
{
|
||||
_logger.Info("Stopping all running services");
|
||||
|
||||
if (_serviceProvider.ServiceExist(ServiceProvider.NZBDRONE_SERVICE_NAME)
|
||||
&& _serviceProvider.IsServiceRunning(ServiceProvider.NZBDRONE_SERVICE_NAME))
|
||||
{
|
||||
try
|
||||
{
|
||||
_serviceProvider.Stop(ServiceProvider.NZBDRONE_SERVICE_NAME);
|
||||
|
||||
}
|
||||
catch (InvalidOperationException e)
|
||||
{
|
||||
_logger.WarnException("couldn't stop service", e);
|
||||
}
|
||||
}
|
||||
|
||||
//TODO:Should be able to restart service if anything beyond this point fails
|
||||
_logger.Info("Killing all running processes");
|
||||
|
||||
if (_processProvider.GetProcessByName(ProcessProvider.NzbDroneConsoleProcessName).Any())
|
||||
{
|
||||
_processProvider.KillAll(ProcessProvider.NzbDroneConsoleProcessName);
|
||||
}
|
||||
|
||||
_processProvider.KillAll(ProcessProvider.NzbDroneProcessName);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue