Merge pull request #1062 from tgstation/1059-ConfigVersion

Add config versioning
This commit is contained in:
Jordan Brown
2020-06-27 14:07:38 -04:00
committed by GitHub
9 changed files with 61 additions and 2 deletions
+2
View File
@@ -86,6 +86,8 @@ This wizard will, generally, run whenever the server is launched without detecti
Create an `appsettings.Production.json` file next to `appsettings.json`. This will override the default settings in appsettings.json with your production settings. There are a few keys meant to be changed by hosts. Modifying any config files while the server is running will trigger a safe restart (Keeps DreamDaemon's running). Note these are all case-sensitive:
- `General:ConfigVersion`: Suppresses warnings about out of date config versions. You should change this after updating TGS to one with a new config version. The current version can be found on the releases page for your server version (This field did not exist before v4.4.0).
- `General:MinimumPasswordLength`: Minimum password length requirement for database users
- `General:ValidInstancePaths`: Array meant to limit the directories in which instances may be created.
+1
View File
@@ -3,6 +3,7 @@
<!-- This is the authorative version list -->
<!-- Integration tests will ensure they match across the board -->
<TgsCoreVersion>4.4.0</TgsCoreVersion>
<TgsConfigVersion>2.0.0</TgsConfigVersion>
<TgsApiVersion>7.0.0</TgsApiVersion>
<TgsClientVersion>7.3.0</TgsClientVersion>
<TgsDmapiVersion>5.2.2</TgsDmapiVersion>
@@ -280,6 +280,8 @@ namespace Tgstation.Server.Host.Components
try
{
generalConfiguration.CheckCompatibility(logger);
CheckSystemCompatibility();
var factoryStartup = instanceFactory.StartAsync(cancellationToken);
await databaseSeeder.Initialize(databaseContext, cancellationToken).ConfigureAwait(false);
@@ -1,5 +1,7 @@
using Newtonsoft.Json;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System;
using Tgstation.Server.Api.Models.Internal;
namespace Tgstation.Server.Host.Configuration
@@ -19,6 +21,11 @@ namespace Tgstation.Server.Host.Configuration
/// </summary>
public const ushort DefaultApiPort = 5000;
/// <summary>
/// The current <see cref="ConfigVersion"/>.
/// </summary>
public static readonly Version CurrentConfigVersion = new Version(2, 0, 0);
/// <summary>
/// The default value for <see cref="ServerInformation.MinimumPasswordLength"/>.
/// </summary>
@@ -44,6 +51,11 @@ namespace Tgstation.Server.Host.Configuration
/// </summary>
const uint DefaultRestartTimeout = 60000;
/// <summary>
/// The <see cref="Version"/> the file says it is.
/// </summary>
public Version ConfigVersion { get; set; }
/// <summary>
/// The port the TGS API listens on.
/// </summary>
@@ -89,5 +101,27 @@ namespace Tgstation.Server.Host.Configuration
InstanceLimit = DefaultInstanceLimit;
UserLimit = DefaultUserLimit;
}
/// <summary>
/// Validates the current <see cref="ConfigVersion"/>'s compatibility and provides migration instructions.
/// </summary>
/// <param name="logger">The <see cref="ILogger"/> to use.</param>
public void CheckCompatibility(ILogger logger)
{
if (logger == null)
throw new ArgumentNullException(nameof(logger));
if (ConfigVersion == null)
logger.LogCritical(
"No `ConfigVersion` specified, your configuration may be out of date! The current version is \"{0}\"",
CurrentConfigVersion);
else if (ConfigVersion != CurrentConfigVersion)
if (ConfigVersion.Major != CurrentConfigVersion.Major)
logger.LogCritical(
"Your `ConfigVersion` is majorly out-of-date and may potentially cause issues running the server. Please follow migration instructions from the TGS release notes.",
CurrentConfigVersion);
else
logger.LogWarning("Your `ConfigVersion` is out-of-date. Please follow migration instructions from the TGS release notes.");
}
}
}
@@ -0,0 +1,5 @@
# Configuration Classes
These types map directly to the settings used in the [appsettings.json](../appsettings.json) file and its derivatives. See the [Microsoft Docs on the ASP .NET Core configuration system](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-3.1) for details.
When making changes here, it's important to also update the config version in [build/Version.props](../../../build/Version.props) according to semver semantics. You'll also need to update the constant in [GeneralConfiguration.cs](./GeneralConfigration.cs).
@@ -409,6 +409,8 @@ namespace Tgstation.Server.Host.Core
else
logger.LogDebug("Web control panel disabled!");
logger.LogDebug("Starting hosting...");
// authenticate JWT tokens using our security pipeline if present, returns 401 if bad
applicationBuilder.UseAuthentication();
@@ -745,6 +745,7 @@ namespace Tgstation.Server.Host.Setup
await console.WriteAsync(String.Format(CultureInfo.InvariantCulture, "Configuration complete! Saving to {0}", userConfigFileName), true, cancellationToken).ConfigureAwait(false);
newGeneralConfiguration.ApiPort = hostingPort ?? GeneralConfiguration.DefaultApiPort;
newGeneralConfiguration.ConfigVersion = GeneralConfiguration.CurrentConfigVersion;
var map = new Dictionary<string, object>()
{
{ DatabaseConfiguration.Section, databaseConfiguration },
@@ -9,6 +9,7 @@ using Tgstation.Server.Client;
using Tgstation.Server.Host;
using Tgstation.Server.Host.Components.Interop;
using Tgstation.Server.Host.Components.Watchdog;
using Tgstation.Server.Host.Configuration;
namespace Tgstation.Server.Tests
{
@@ -40,6 +41,16 @@ namespace Tgstation.Server.Tests
Assert.AreEqual(expected, actual);
}
[TestMethod]
public void TestConfigVersion()
{
var versionString = versionsPropertyGroup.Element(xmlNamespace + "TgsConfigVersion").Value;
Assert.IsNotNull(versionString);
Assert.IsTrue(Version.TryParse(versionString, out var expected));
var actual = GeneralConfiguration.CurrentConfigVersion;
Assert.AreEqual(expected, actual);
}
[TestMethod]
public void TestApiVersion()
{
+2 -1
View File
@@ -250,6 +250,7 @@ namespace ReleaseNotes
}
var apiVersion = Version.Parse(versionsPropertyGroup.Element(xmlNamespace + "TgsApiVersion").Value);
var configVersion = Version.Parse(versionsPropertyGroup.Element(xmlNamespace + "TgsConfigVersion").Value);
var dmApiVersion = Version.Parse(versionsPropertyGroup.Element(xmlNamespace + "TgsDmapiVersion").Value);
var webControlVersion = Version.Parse(versionsPropertyGroup.Element(xmlNamespace + "TgsControlPanelVersion").Value);
var hostWatchdogVersion = Version.Parse(versionsPropertyGroup.Element(xmlNamespace + "TgsHostWatchdogVersion").Value);
@@ -257,7 +258,7 @@ namespace ReleaseNotes
if (webControlVersion.Major == 0)
postControlPanelMessage = true;
prefix = $"Please refer to the [README](https://github.com/tgstation/tgstation-server#setup) for setup instructions.{Environment.NewLine}{Environment.NewLine}#### Component Versions\nCore: {coreVersion}\nHTTP API: {apiVersion}\nDreamMaker API: {dmApiVersion}\n[Web Control Panel](https://github.com/tgstation/tgstation-server-control-panel): {webControlVersion}\nHost Watchdog: {hostWatchdogVersion}";
prefix = $"Please refer to the [README](https://github.com/tgstation/tgstation-server#setup) for setup instructions.{Environment.NewLine}{Environment.NewLine}#### Component Versions\nCore: {coreVersion}\nConfiguration: {configVersion}\nHTTP API: {apiVersion}\nDreamMaker API: {dmApiVersion}\n[Web Control Panel](https://github.com/tgstation/tgstation-server-control-panel): {webControlVersion}\nHost Watchdog: {hostWatchdogVersion}";
break;
case 3:
prefix = "The /tg/station server suite";