mirror of
https://github.com/lidarr/lidarr.git
synced 2025-07-14 00:53:57 -07:00
New: Set Branch, Update Mech from PackageInfo
This commit is contained in:
parent
8eea5a0ac9
commit
5ef2ec18d3
10 changed files with 279 additions and 33 deletions
|
@ -101,6 +101,7 @@ class GeneralSettings extends Component {
|
||||||
isWindowsService,
|
isWindowsService,
|
||||||
isDocker,
|
isDocker,
|
||||||
mode,
|
mode,
|
||||||
|
packageUpdateMechanism,
|
||||||
onInputChange,
|
onInputChange,
|
||||||
onConfirmResetApiKey,
|
onConfirmResetApiKey,
|
||||||
...otherProps
|
...otherProps
|
||||||
|
@ -163,6 +164,7 @@ class GeneralSettings extends Component {
|
||||||
advancedSettings={advancedSettings}
|
advancedSettings={advancedSettings}
|
||||||
settings={settings}
|
settings={settings}
|
||||||
isWindows={isWindows}
|
isWindows={isWindows}
|
||||||
|
packageUpdateMechanism={packageUpdateMechanism}
|
||||||
isDocker={isDocker}
|
isDocker={isDocker}
|
||||||
onInputChange={onInputChange}
|
onInputChange={onInputChange}
|
||||||
/>
|
/>
|
||||||
|
@ -208,6 +210,7 @@ GeneralSettings.propTypes = {
|
||||||
isWindowsService: PropTypes.bool.isRequired,
|
isWindowsService: PropTypes.bool.isRequired,
|
||||||
isDocker: PropTypes.bool.isRequired,
|
isDocker: PropTypes.bool.isRequired,
|
||||||
mode: PropTypes.string.isRequired,
|
mode: PropTypes.string.isRequired,
|
||||||
|
packageUpdateMechanism: PropTypes.string.isRequired,
|
||||||
onInputChange: PropTypes.func.isRequired,
|
onInputChange: PropTypes.func.isRequired,
|
||||||
onConfirmResetApiKey: PropTypes.func.isRequired,
|
onConfirmResetApiKey: PropTypes.func.isRequired,
|
||||||
onConfirmRestart: PropTypes.func.isRequired
|
onConfirmRestart: PropTypes.func.isRequired
|
||||||
|
|
|
@ -28,6 +28,7 @@ function createMapStateToProps() {
|
||||||
isWindowsService: systemStatus.isWindows && systemStatus.mode === 'service',
|
isWindowsService: systemStatus.isWindows && systemStatus.mode === 'service',
|
||||||
isDocker: systemStatus.isDocker,
|
isDocker: systemStatus.isDocker,
|
||||||
mode: systemStatus.mode,
|
mode: systemStatus.mode,
|
||||||
|
packageUpdateMechanism: systemStatus.packageUpdateMechanism,
|
||||||
...sectionSettings
|
...sectionSettings
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,22 +1,19 @@
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import titleCase from 'Utilities/String/titleCase';
|
||||||
import { inputTypes, sizes } from 'Helpers/Props';
|
import { inputTypes, sizes } from 'Helpers/Props';
|
||||||
import FieldSet from 'Components/FieldSet';
|
import FieldSet from 'Components/FieldSet';
|
||||||
import FormGroup from 'Components/Form/FormGroup';
|
import FormGroup from 'Components/Form/FormGroup';
|
||||||
import FormLabel from 'Components/Form/FormLabel';
|
import FormLabel from 'Components/Form/FormLabel';
|
||||||
import FormInputGroup from 'Components/Form/FormInputGroup';
|
import FormInputGroup from 'Components/Form/FormInputGroup';
|
||||||
|
|
||||||
const branchValues = [
|
|
||||||
'develop',
|
|
||||||
'nightly'
|
|
||||||
];
|
|
||||||
|
|
||||||
function UpdateSettings(props) {
|
function UpdateSettings(props) {
|
||||||
const {
|
const {
|
||||||
advancedSettings,
|
advancedSettings,
|
||||||
settings,
|
settings,
|
||||||
isWindows,
|
isWindows,
|
||||||
isDocker,
|
isDocker,
|
||||||
|
packageUpdateMechanism,
|
||||||
onInputChange
|
onInputChange
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
|
@ -31,10 +28,20 @@ function UpdateSettings(props) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const updateOptions = [
|
const usingExternalUpdateMechanism = packageUpdateMechanism !== 'builtIn';
|
||||||
{ key: 'builtIn', value: 'Built-In' },
|
|
||||||
{ key: 'script', value: 'Script' }
|
const updateOptions = [];
|
||||||
];
|
|
||||||
|
if (usingExternalUpdateMechanism) {
|
||||||
|
updateOptions.push({
|
||||||
|
key: packageUpdateMechanism,
|
||||||
|
value: titleCase(packageUpdateMechanism)
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
updateOptions.push({ key: 'builtIn', value: 'Built-In' });
|
||||||
|
}
|
||||||
|
|
||||||
|
updateOptions.push({ key: 'script', value: 'Script' });
|
||||||
|
|
||||||
if (isDocker) {
|
if (isDocker) {
|
||||||
return (
|
return (
|
||||||
|
@ -53,13 +60,13 @@ function UpdateSettings(props) {
|
||||||
<FormLabel>Branch</FormLabel>
|
<FormLabel>Branch</FormLabel>
|
||||||
|
|
||||||
<FormInputGroup
|
<FormInputGroup
|
||||||
type={inputTypes.AUTO_COMPLETE}
|
type={inputTypes.TEXT}
|
||||||
name="branch"
|
name="branch"
|
||||||
helpText="Branch to use to update Lidarr"
|
helpText={usingExternalUpdateMechanism ? 'Branch used by external update mechanism' : 'Branch to use to update Lidarr'}
|
||||||
helpLink="https://github.com/Lidarr/Lidarr/wiki/Release-Branches"
|
helpLink="https://github.com/Lidarr/Lidarr/wiki/Release-Branches"
|
||||||
{...branch}
|
{...branch}
|
||||||
values={branchValues}
|
|
||||||
onChange={onInputChange}
|
onChange={onInputChange}
|
||||||
|
readOnly={usingExternalUpdateMechanism}
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
|
||||||
|
@ -127,6 +134,7 @@ UpdateSettings.propTypes = {
|
||||||
settings: PropTypes.object.isRequired,
|
settings: PropTypes.object.isRequired,
|
||||||
isWindows: PropTypes.bool.isRequired,
|
isWindows: PropTypes.bool.isRequired,
|
||||||
isDocker: PropTypes.bool.isRequired,
|
isDocker: PropTypes.bool.isRequired,
|
||||||
|
packageUpdateMechanism: PropTypes.string.isRequired,
|
||||||
onInputChange: PropTypes.func.isRequired
|
onInputChange: PropTypes.func.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,8 @@ class About extends Component {
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
version,
|
version,
|
||||||
|
packageVersion,
|
||||||
|
packageAuthor,
|
||||||
isNetCore,
|
isNetCore,
|
||||||
isMono,
|
isMono,
|
||||||
isDocker,
|
isDocker,
|
||||||
|
@ -36,6 +38,14 @@ class About extends Component {
|
||||||
data={version}
|
data={version}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
{
|
||||||
|
packageVersion &&
|
||||||
|
<DescriptionListItem
|
||||||
|
title="Package Version"
|
||||||
|
data={(packageAuthor ? `${packageVersion} by ${packageAuthor}` : packageVersion)}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
isMono &&
|
isMono &&
|
||||||
<DescriptionListItem
|
<DescriptionListItem
|
||||||
|
@ -99,6 +109,8 @@ class About extends Component {
|
||||||
|
|
||||||
About.propTypes = {
|
About.propTypes = {
|
||||||
version: PropTypes.string.isRequired,
|
version: PropTypes.string.isRequired,
|
||||||
|
packageVersion: PropTypes.string,
|
||||||
|
packageAuthor: PropTypes.string,
|
||||||
isNetCore: PropTypes.bool.isRequired,
|
isNetCore: PropTypes.bool.isRequired,
|
||||||
isMono: PropTypes.bool.isRequired,
|
isMono: PropTypes.bool.isRequired,
|
||||||
runtimeVersion: PropTypes.string.isRequired,
|
runtimeVersion: PropTypes.string.isRequired,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import React, { Component } from 'react';
|
import React, { Component, Fragment } from 'react';
|
||||||
import { icons, kinds } from 'Helpers/Props';
|
import { icons, kinds } from 'Helpers/Props';
|
||||||
import formatDate from 'Utilities/Date/formatDate';
|
import formatDate from 'Utilities/Date/formatDate';
|
||||||
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
|
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
|
||||||
|
@ -25,6 +25,7 @@ class Updates extends Component {
|
||||||
error,
|
error,
|
||||||
items,
|
items,
|
||||||
isInstallingUpdate,
|
isInstallingUpdate,
|
||||||
|
updateMechanism,
|
||||||
isDocker,
|
isDocker,
|
||||||
shortDateFormat,
|
shortDateFormat,
|
||||||
onInstallLatestPress
|
onInstallLatestPress
|
||||||
|
@ -35,6 +36,12 @@ class Updates extends Component {
|
||||||
const hasUpdateToInstall = hasUpdates && _.some(items, { installable: true, latest: true });
|
const hasUpdateToInstall = hasUpdates && _.some(items, { installable: true, latest: true });
|
||||||
const noUpdateToInstall = hasUpdates && !hasUpdateToInstall;
|
const noUpdateToInstall = hasUpdates && !hasUpdateToInstall;
|
||||||
|
|
||||||
|
const externalUpdaterMessages = {
|
||||||
|
external: 'Unable to update Lidarr directly, Lidarr is configured to use an external update mechanism',
|
||||||
|
apt: 'Unable to update Lidarr directly, use apt to install the update',
|
||||||
|
docker: 'Unable to update Lidarr directly, update the docker container to receive the update'
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageContent title="Updates">
|
<PageContent title="Updates">
|
||||||
<PageContentBodyConnector>
|
<PageContentBodyConnector>
|
||||||
|
@ -50,24 +57,29 @@ class Updates extends Component {
|
||||||
|
|
||||||
{
|
{
|
||||||
hasUpdateToInstall &&
|
hasUpdateToInstall &&
|
||||||
<div className={styles.updateAvailable}>
|
<div className={styles.messageContainer}>
|
||||||
{
|
{
|
||||||
!isDocker &&
|
(updateMechanism === 'builtIn' || updateMechanism === 'script') && !isDocker ?
|
||||||
<SpinnerButton
|
<SpinnerButton
|
||||||
className={styles.updateAvailable}
|
className={styles.updateAvailable}
|
||||||
kind={kinds.PRIMARY}
|
kind={kinds.PRIMARY}
|
||||||
isSpinning={isInstallingUpdate}
|
isSpinning={isInstallingUpdate}
|
||||||
onPress={onInstallLatestPress}
|
onPress={onInstallLatestPress}
|
||||||
>
|
>
|
||||||
Install Latest
|
Install Latest
|
||||||
</SpinnerButton>
|
</SpinnerButton> :
|
||||||
}
|
|
||||||
|
|
||||||
{
|
<Fragment>
|
||||||
isDocker &&
|
<Icon
|
||||||
<div className={styles.upToDateMessage}>
|
name={icons.WARNING}
|
||||||
An update is available. Please update your Docker image and re-create the container.
|
kind={kinds.WARNING}
|
||||||
</div>
|
size={30}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div className={styles.message}>
|
||||||
|
{externalUpdaterMessages[updateMechanism] || externalUpdaterMessages.external}
|
||||||
|
</div>
|
||||||
|
</Fragment>
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -188,6 +200,7 @@ Updates.propTypes = {
|
||||||
items: PropTypes.array.isRequired,
|
items: PropTypes.array.isRequired,
|
||||||
isInstallingUpdate: PropTypes.bool.isRequired,
|
isInstallingUpdate: PropTypes.bool.isRequired,
|
||||||
isDocker: PropTypes.bool.isRequired,
|
isDocker: PropTypes.bool.isRequired,
|
||||||
|
updateMechanism: PropTypes.string,
|
||||||
shortDateFormat: PropTypes.string.isRequired,
|
shortDateFormat: PropTypes.string.isRequired,
|
||||||
onInstallLatestPress: PropTypes.func.isRequired
|
onInstallLatestPress: PropTypes.func.isRequired
|
||||||
};
|
};
|
||||||
|
|
|
@ -18,6 +18,7 @@ namespace Lidarr.Api.V1.System
|
||||||
private readonly IConfigFileProvider _configFileProvider;
|
private readonly IConfigFileProvider _configFileProvider;
|
||||||
private readonly IMainDatabase _database;
|
private readonly IMainDatabase _database;
|
||||||
private readonly ILifecycleService _lifecycleService;
|
private readonly ILifecycleService _lifecycleService;
|
||||||
|
private readonly IDeploymentInfoProvider _deploymentInfoProvider;
|
||||||
|
|
||||||
public SystemModule(IAppFolderInfo appFolderInfo,
|
public SystemModule(IAppFolderInfo appFolderInfo,
|
||||||
IRuntimeInfo runtimeInfo,
|
IRuntimeInfo runtimeInfo,
|
||||||
|
@ -26,7 +27,8 @@ namespace Lidarr.Api.V1.System
|
||||||
IRouteCacheProvider routeCacheProvider,
|
IRouteCacheProvider routeCacheProvider,
|
||||||
IConfigFileProvider configFileProvider,
|
IConfigFileProvider configFileProvider,
|
||||||
IMainDatabase database,
|
IMainDatabase database,
|
||||||
ILifecycleService lifecycleService)
|
ILifecycleService lifecycleService,
|
||||||
|
IDeploymentInfoProvider deploymentInfoProvider)
|
||||||
: base("system")
|
: base("system")
|
||||||
{
|
{
|
||||||
_appFolderInfo = appFolderInfo;
|
_appFolderInfo = appFolderInfo;
|
||||||
|
@ -37,6 +39,7 @@ namespace Lidarr.Api.V1.System
|
||||||
_configFileProvider = configFileProvider;
|
_configFileProvider = configFileProvider;
|
||||||
_database = database;
|
_database = database;
|
||||||
_lifecycleService = lifecycleService;
|
_lifecycleService = lifecycleService;
|
||||||
|
_deploymentInfoProvider = deploymentInfoProvider;
|
||||||
Get("/status", x => GetStatus());
|
Get("/status", x => GetStatus());
|
||||||
Get("/routes", x => GetRoutes());
|
Get("/routes", x => GetRoutes());
|
||||||
Post("/shutdown", x => Shutdown());
|
Post("/shutdown", x => Shutdown());
|
||||||
|
@ -71,7 +74,10 @@ namespace Lidarr.Api.V1.System
|
||||||
UrlBase = _configFileProvider.UrlBase,
|
UrlBase = _configFileProvider.UrlBase,
|
||||||
RuntimeVersion = _platformInfo.Version,
|
RuntimeVersion = _platformInfo.Version,
|
||||||
RuntimeName = PlatformInfo.Platform,
|
RuntimeName = PlatformInfo.Platform,
|
||||||
StartTime = _runtimeInfo.StartTime
|
StartTime = _runtimeInfo.StartTime,
|
||||||
|
PackageVersion = _deploymentInfoProvider.PackageVersion,
|
||||||
|
PackageAuthor = _deploymentInfoProvider.PackageAuthor,
|
||||||
|
PackageUpdateMechanism = _deploymentInfoProvider.PackageUpdateMechanism
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
105
src/NzbDrone.Core/Configuration/DeploymentInfoProvider.cs
Normal file
105
src/NzbDrone.Core/Configuration/DeploymentInfoProvider.cs
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using NzbDrone.Common.Disk;
|
||||||
|
using NzbDrone.Common.EnvironmentInfo;
|
||||||
|
using NzbDrone.Common.Extensions;
|
||||||
|
using NzbDrone.Core.Update;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Configuration
|
||||||
|
{
|
||||||
|
public interface IDeploymentInfoProvider
|
||||||
|
{
|
||||||
|
string PackageVersion { get; }
|
||||||
|
string PackageAuthor { get; }
|
||||||
|
string PackageBranch { get; }
|
||||||
|
UpdateMechanism PackageUpdateMechanism { get; }
|
||||||
|
|
||||||
|
string ReleaseVersion { get; }
|
||||||
|
string ReleaseBranch { get; }
|
||||||
|
|
||||||
|
bool IsExternalUpdateMechanism { get; }
|
||||||
|
UpdateMechanism DefaultUpdateMechanism { get; }
|
||||||
|
string DefaultBranch { get; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class DeploymentInfoProvider : IDeploymentInfoProvider
|
||||||
|
{
|
||||||
|
public DeploymentInfoProvider(IAppFolderInfo appFolderInfo, IDiskProvider diskProvider)
|
||||||
|
{
|
||||||
|
var bin = appFolderInfo.StartUpFolder;
|
||||||
|
var packageInfoPath = Path.Combine(bin, "..", "package_info");
|
||||||
|
var releaseInfoPath = Path.Combine(bin, "release_info");
|
||||||
|
|
||||||
|
PackageUpdateMechanism = UpdateMechanism.BuiltIn;
|
||||||
|
DefaultBranch = "aphrodite";
|
||||||
|
|
||||||
|
if (Path.GetFileName(bin) == "bin" && diskProvider.FileExists(packageInfoPath))
|
||||||
|
{
|
||||||
|
var data = diskProvider.ReadAllText(packageInfoPath);
|
||||||
|
|
||||||
|
PackageVersion = ReadValue(data, "PackageVersion");
|
||||||
|
PackageAuthor = ReadValue(data, "PackageAuthor");
|
||||||
|
PackageUpdateMechanism = ReadEnumValue(data, "UpdateMethod", UpdateMechanism.BuiltIn);
|
||||||
|
PackageBranch = ReadValue(data, "Branch");
|
||||||
|
|
||||||
|
ReleaseVersion = ReadValue(data, "ReleaseVersion");
|
||||||
|
|
||||||
|
if (PackageBranch.IsNotNullOrWhiteSpace())
|
||||||
|
{
|
||||||
|
DefaultBranch = PackageBranch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (diskProvider.FileExists(releaseInfoPath))
|
||||||
|
{
|
||||||
|
var data = diskProvider.ReadAllText(releaseInfoPath);
|
||||||
|
|
||||||
|
ReleaseVersion = ReadValue(data, "ReleaseVersion", ReleaseVersion);
|
||||||
|
ReleaseBranch = ReadValue(data, "Branch");
|
||||||
|
|
||||||
|
if (ReleaseBranch.IsNotNullOrWhiteSpace())
|
||||||
|
{
|
||||||
|
DefaultBranch = ReleaseBranch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DefaultUpdateMechanism = PackageUpdateMechanism;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string ReadValue(string fileData, string key, string defaultValue = null)
|
||||||
|
{
|
||||||
|
var match = Regex.Match(fileData, "^" + key + "=(.*)$", RegexOptions.Multiline);
|
||||||
|
if (match.Success)
|
||||||
|
{
|
||||||
|
return match.Groups[1].Value.Trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static T ReadEnumValue<T>(string fileData, string key, T defaultValue)
|
||||||
|
where T : struct
|
||||||
|
{
|
||||||
|
var value = ReadValue(fileData, key);
|
||||||
|
if (value != null && Enum.TryParse<T>(value, true, out var result))
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string PackageVersion { get; private set; }
|
||||||
|
public string PackageAuthor { get; private set; }
|
||||||
|
public string PackageBranch { get; private set; }
|
||||||
|
public UpdateMechanism PackageUpdateMechanism { get; private set; }
|
||||||
|
|
||||||
|
public string ReleaseVersion { get; private set; }
|
||||||
|
public string ReleaseBranch { get; set; }
|
||||||
|
|
||||||
|
public bool IsExternalUpdateMechanism => PackageUpdateMechanism >= UpdateMechanism.External;
|
||||||
|
public UpdateMechanism DefaultUpdateMechanism { get; private set; }
|
||||||
|
public string DefaultBranch { get; private set; }
|
||||||
|
}
|
||||||
|
}
|
80
src/NzbDrone.Core/Update/ConfigureUpdateMechanism.cs
Normal file
80
src/NzbDrone.Core/Update/ConfigureUpdateMechanism.cs
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using NLog;
|
||||||
|
using NzbDrone.Common.Extensions;
|
||||||
|
using NzbDrone.Core.Configuration;
|
||||||
|
using NzbDrone.Core.Lifecycle;
|
||||||
|
using NzbDrone.Core.Messaging.Events;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Update
|
||||||
|
{
|
||||||
|
public interface IUpdaterConfigProvider
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public class UpdaterConfigProvider : IUpdaterConfigProvider, IHandle<ApplicationStartedEvent>
|
||||||
|
{
|
||||||
|
private readonly Logger _logger;
|
||||||
|
private readonly IConfigFileProvider _configFileProvider;
|
||||||
|
private readonly IDeploymentInfoProvider _deploymentInfoProvider;
|
||||||
|
|
||||||
|
public UpdaterConfigProvider(IDeploymentInfoProvider deploymentInfoProvider, IConfigFileProvider configFileProvider, Logger logger)
|
||||||
|
{
|
||||||
|
_deploymentInfoProvider = deploymentInfoProvider;
|
||||||
|
_configFileProvider = configFileProvider;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Handle(ApplicationStartedEvent message)
|
||||||
|
{
|
||||||
|
var updateMechanism = _configFileProvider.UpdateMechanism;
|
||||||
|
var packageUpdateMechanism = _deploymentInfoProvider.PackageUpdateMechanism;
|
||||||
|
|
||||||
|
var externalMechanisms = Enum.GetValues(typeof(UpdateMechanism))
|
||||||
|
.Cast<UpdateMechanism>()
|
||||||
|
.Where(v => v >= UpdateMechanism.External)
|
||||||
|
.ToArray();
|
||||||
|
|
||||||
|
foreach (var externalMechanism in externalMechanisms)
|
||||||
|
{
|
||||||
|
if ((packageUpdateMechanism != externalMechanism && updateMechanism == externalMechanism) ||
|
||||||
|
(packageUpdateMechanism == externalMechanism && updateMechanism == UpdateMechanism.BuiltIn))
|
||||||
|
{
|
||||||
|
_logger.Info("Update mechanism {0} not supported in the current configuration, changing to {1}.", updateMechanism, packageUpdateMechanism);
|
||||||
|
ChangeUpdateMechanism(packageUpdateMechanism);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_deploymentInfoProvider.IsExternalUpdateMechanism)
|
||||||
|
{
|
||||||
|
var currentBranch = _configFileProvider.Branch;
|
||||||
|
var packageBranch = _deploymentInfoProvider.PackageBranch;
|
||||||
|
if (packageBranch.IsNotNullOrWhiteSpace() && packageBranch != currentBranch)
|
||||||
|
{
|
||||||
|
_logger.Info("External updater uses branch {0} instead of the currently selected {1}, changing to {0}.", packageBranch, currentBranch);
|
||||||
|
ChangeBranch(packageBranch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ChangeUpdateMechanism(UpdateMechanism updateMechanism)
|
||||||
|
{
|
||||||
|
var config = new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
[nameof(_configFileProvider.UpdateMechanism)] = updateMechanism
|
||||||
|
};
|
||||||
|
_configFileProvider.SaveConfigDictionary(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ChangeBranch(string branch)
|
||||||
|
{
|
||||||
|
var config = new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
[nameof(_configFileProvider.Branch)] = branch
|
||||||
|
};
|
||||||
|
_configFileProvider.SaveConfigDictionary(config);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -29,6 +29,7 @@ namespace NzbDrone.Core.Update
|
||||||
private readonly IProcessProvider _processProvider;
|
private readonly IProcessProvider _processProvider;
|
||||||
private readonly IVerifyUpdates _updateVerifier;
|
private readonly IVerifyUpdates _updateVerifier;
|
||||||
private readonly IStartupContext _startupContext;
|
private readonly IStartupContext _startupContext;
|
||||||
|
private readonly IDeploymentInfoProvider _deploymentInfoProvider;
|
||||||
private readonly IConfigFileProvider _configFileProvider;
|
private readonly IConfigFileProvider _configFileProvider;
|
||||||
private readonly IRuntimeInfo _runtimeInfo;
|
private readonly IRuntimeInfo _runtimeInfo;
|
||||||
private readonly IBackupService _backupService;
|
private readonly IBackupService _backupService;
|
||||||
|
@ -43,6 +44,7 @@ namespace NzbDrone.Core.Update
|
||||||
IProcessProvider processProvider,
|
IProcessProvider processProvider,
|
||||||
IVerifyUpdates updateVerifier,
|
IVerifyUpdates updateVerifier,
|
||||||
IStartupContext startupContext,
|
IStartupContext startupContext,
|
||||||
|
IDeploymentInfoProvider deploymentInfoProvider,
|
||||||
IConfigFileProvider configFileProvider,
|
IConfigFileProvider configFileProvider,
|
||||||
IRuntimeInfo runtimeInfo,
|
IRuntimeInfo runtimeInfo,
|
||||||
IBackupService backupService,
|
IBackupService backupService,
|
||||||
|
@ -63,6 +65,7 @@ namespace NzbDrone.Core.Update
|
||||||
_processProvider = processProvider;
|
_processProvider = processProvider;
|
||||||
_updateVerifier = updateVerifier;
|
_updateVerifier = updateVerifier;
|
||||||
_startupContext = startupContext;
|
_startupContext = startupContext;
|
||||||
|
_deploymentInfoProvider = deploymentInfoProvider;
|
||||||
_configFileProvider = configFileProvider;
|
_configFileProvider = configFileProvider;
|
||||||
_runtimeInfo = runtimeInfo;
|
_runtimeInfo = runtimeInfo;
|
||||||
_backupService = backupService;
|
_backupService = backupService;
|
||||||
|
@ -237,6 +240,18 @@ namespace NzbDrone.Core.Update
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Safety net, ConfigureUpdateMechanism should take care of invalid settings
|
||||||
|
if (_configFileProvider.UpdateMechanism == UpdateMechanism.BuiltIn && _deploymentInfoProvider.IsExternalUpdateMechanism)
|
||||||
|
{
|
||||||
|
_logger.ProgressDebug("Built-In updater disabled, please use {0} to install", _deploymentInfoProvider.PackageUpdateMechanism);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (_configFileProvider.UpdateMechanism != UpdateMechanism.Script && _deploymentInfoProvider.IsExternalUpdateMechanism)
|
||||||
|
{
|
||||||
|
_logger.ProgressDebug("Update available, please use {0} to install", _deploymentInfoProvider.PackageUpdateMechanism);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
InstallUpdate(latestAvailable);
|
InstallUpdate(latestAvailable);
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
namespace NzbDrone.Core.Update
|
namespace NzbDrone.Core.Update
|
||||||
{
|
{
|
||||||
public enum UpdateMechanism
|
public enum UpdateMechanism
|
||||||
{
|
{
|
||||||
BuiltIn = 0,
|
BuiltIn = 0,
|
||||||
Script = 1
|
Script = 1,
|
||||||
|
External = 10,
|
||||||
|
Apt = 11,
|
||||||
|
Docker = 12
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue