@ -1,5 +1,7 @@
using System ;
using System ;
using System.Collections.Generic ;
using System.IO ;
using System.IO ;
using System.Linq ;
using NLog ;
using NLog ;
using NzbDrone.Common ;
using NzbDrone.Common ;
using NzbDrone.Common.Disk ;
using NzbDrone.Common.Disk ;
@ -10,13 +12,11 @@ using NzbDrone.Common.Instrumentation.Extensions;
using NzbDrone.Common.Processes ;
using NzbDrone.Common.Processes ;
using NzbDrone.Core.Backup ;
using NzbDrone.Core.Backup ;
using NzbDrone.Core.Configuration ;
using NzbDrone.Core.Configuration ;
using NzbDrone.Core.Exceptions ;
using NzbDrone.Core.Messaging.Commands ;
using NzbDrone.Core.Messaging.Commands ;
using NzbDrone.Core.Update.Commands ;
using NzbDrone.Core.Update.Commands ;
namespace NzbDrone.Core.Update
namespace NzbDrone.Core.Update
{
{
public class InstallUpdateService : IExecute < ApplicationUpdateCommand > , IExecute < InstallUpdateCommand >
public class InstallUpdateService : IExecute < ApplicationUpdateCommand > , IExecute < InstallUpdateCommand >
{
{
private readonly ICheckUpdateService _checkUpdateService ;
private readonly ICheckUpdateService _checkUpdateService ;
@ -62,9 +62,7 @@ namespace NzbDrone.Core.Update
_logger = logger ;
_logger = logger ;
}
}
private bool InstallUpdate ( UpdatePackage updatePackage )
private void InstallUpdate ( UpdatePackage updatePackage )
{
try
{
{
EnsureAppDataSafety ( ) ;
EnsureAppDataSafety ( ) ;
@ -72,7 +70,7 @@ namespace NzbDrone.Core.Update
{
{
if ( ! _diskProvider . FolderWritable ( _appFolderInfo . StartUpFolder ) )
if ( ! _diskProvider . FolderWritable ( _appFolderInfo . StartUpFolder ) )
{
{
throw new ApplicationException ( string . Format ( "Cannot install update because startup folder '{0}' is not writable by the user '{1}'." , _appFolderInfo . StartUpFolder , Environment . UserName ) ) ;
throw new UpdateFolderNotWritableException ( "Cannot install update because startup folder '{0}' is not writable by the user '{1}'." , _appFolderInfo . StartUpFolder , Environment . UserName ) ;
}
}
}
}
@ -109,7 +107,7 @@ namespace NzbDrone.Core.Update
if ( OsInfo . IsNotWindows & & _configFileProvider . UpdateMechanism = = UpdateMechanism . Script )
if ( OsInfo . IsNotWindows & & _configFileProvider . UpdateMechanism = = UpdateMechanism . Script )
{
{
InstallUpdateWithScript ( updateSandboxFolder ) ;
InstallUpdateWithScript ( updateSandboxFolder ) ;
return true ;
return ;
}
}
_logger . Info ( "Preparing client" ) ;
_logger . Info ( "Preparing client" ) ;
@ -117,17 +115,9 @@ namespace NzbDrone.Core.Update
updateSandboxFolder ) ;
updateSandboxFolder ) ;
_logger . Info ( "Starting update client {0}" , _appFolderInfo . GetUpdateClientExePath ( ) ) ;
_logger . Info ( "Starting update client {0}" , _appFolderInfo . GetUpdateClientExePath ( ) ) ;
_logger . ProgressInfo ( " NzbDrone will restart shortly.") ;
_logger . ProgressInfo ( " Sonarr will restart shortly.") ;
_processProvider . Start ( _appFolderInfo . GetUpdateClientExePath ( ) , GetUpdaterArgs ( updateSandboxFolder ) ) ;
_processProvider . Start ( _appFolderInfo . GetUpdateClientExePath ( ) , GetUpdaterArgs ( updateSandboxFolder ) ) ;
return true ;
}
catch ( Exception ex )
{
_logger . ErrorException ( "Update process failed" , ex ) ;
return false ;
}
}
}
private void InstallUpdateWithScript ( String updateSandboxFolder )
private void InstallUpdateWithScript ( String updateSandboxFolder )
@ -165,7 +155,32 @@ namespace NzbDrone.Core.Update
if ( _appFolderInfo . StartUpFolder . IsParentPath ( _appFolderInfo . AppDataFolder ) | |
if ( _appFolderInfo . StartUpFolder . IsParentPath ( _appFolderInfo . AppDataFolder ) | |
_appFolderInfo . StartUpFolder . PathEquals ( _appFolderInfo . AppDataFolder ) )
_appFolderInfo . StartUpFolder . PathEquals ( _appFolderInfo . AppDataFolder ) )
{
{
throw new NotSupportedException ( "Update will cause AppData to be deleted, correct you configuration before proceeding" ) ;
throw new UpdateFailedException ( "You Sonarr configuration ('{0}') is being stored in application folder ('{1}') which will cause data lost during the upgrade. Please remove any symlinks or redirects before trying again." , _appFolderInfo . AppDataFolder , _appFolderInfo . StartUpFolder ) ;
}
}
private void ExecuteInstallUpdate ( Command message , UpdatePackage package )
{
try
{
InstallUpdate ( package ) ;
message . Completed ( "Restarting Sonarr to apply updates" ) ;
}
catch ( UpdateFolderNotWritableException ex )
{
_logger . ErrorException ( "Update process failed" , ex ) ;
message . Failed ( ex , string . Format ( "Startup folder not writable by user '{0}'" , Environment . UserName ) ) ;
}
catch ( UpdateVerificationFailedException ex )
{
_logger . ErrorException ( "Update process failed" , ex ) ;
message . Failed ( ex , "Downloaded update package is corrupt" ) ;
}
catch ( UpdateFailedException ex )
{
_logger . ErrorException ( "Update process failed" , ex ) ;
message . Failed ( ex ) ;
}
}
}
}
@ -176,18 +191,20 @@ namespace NzbDrone.Core.Update
if ( latestAvailable ! = null )
if ( latestAvailable ! = null )
{
{
InstallUpdate( latestAvailable ) ;
Execute InstallUpdate( message , latestAvailable ) ;
}
}
}
}
public void Execute ( InstallUpdateCommand message )
public void Execute ( InstallUpdateCommand message )
{
{
var success = InstallUpdate ( message . UpdatePackage ) ;
var latestAvailable = _checkUpdateService . AvailableUpdate ( ) ;
if ( ! success )
if ( latestAvailable = = null | | latestAvailable . Hash ! = message . UpdatePackage . Hash )
{
{
throw new NzbDroneClientException( System . Net . HttpStatusCode . Conflict , "Failed to install update ") ;
throw new ApplicationException( "Unknown or invalid update specified ") ;
}
}
ExecuteInstallUpdate ( message , latestAvailable ) ;
}
}
}
}
}
}