Version Swarm API separately from core version. Allow slight differences.

This commit is contained in:
Jordan Dominion
2024-09-12 18:39:46 -04:00
parent a3454149dd
commit 99baac333e
8 changed files with 48 additions and 14 deletions
+1
View File
@@ -12,6 +12,7 @@
<TgsDmapiVersion>7.3.0</TgsDmapiVersion>
<TgsInteropVersion>5.10.0</TgsInteropVersion>
<TgsHostWatchdogVersion>1.5.0</TgsHostWatchdogVersion>
<TgsSwarmProtocolVersion>7.0.0</TgsSwarmProtocolVersion>
<TgsContainerScriptVersion>1.2.1</TgsContainerScriptVersion>
<TgsMigratorVersion>2.0.0</TgsMigratorVersion>
<TgsNugetNetFramework>netstandard2.0</TgsNugetNetFramework>
@@ -14,8 +14,8 @@ using Serilog.Context;
using Tgstation.Server.Host.Configuration;
using Tgstation.Server.Host.Extensions;
using Tgstation.Server.Host.Properties;
using Tgstation.Server.Host.Swarm;
using Tgstation.Server.Host.System;
using Tgstation.Server.Host.Transfer;
using Tgstation.Server.Host.Utils;
@@ -44,11 +44,6 @@ namespace Tgstation.Server.Host.Controllers
/// </summary>
readonly IFileTransferStreamHandler transferService;
/// <summary>
/// The <see cref="IAssemblyInformationProvider"/> for the <see cref="SwarmController"/>.
/// </summary>
readonly IAssemblyInformationProvider assemblyInformationProvider;
/// <summary>
/// The <see cref="ILogger"/> for the <see cref="SwarmController"/>.
/// </summary>
@@ -63,19 +58,16 @@ namespace Tgstation.Server.Host.Controllers
/// Initializes a new instance of the <see cref="SwarmController"/> class.
/// </summary>
/// <param name="swarmOperations">The value of <see cref="swarmOperations"/>.</param>
/// <param name="assemblyInformationProvider">The value of <see cref="assemblyInformationProvider"/>.</param>
/// <param name="transferService">The value of <see cref="transferService"/>.</param>
/// <param name="swarmConfigurationOptions">The <see cref="IOptions{TOptions}"/> containing the value of <see cref="swarmConfiguration"/>.</param>
/// <param name="logger">The value of <see cref="logger"/>.</param>
public SwarmController(
ISwarmOperations swarmOperations,
IAssemblyInformationProvider assemblyInformationProvider,
IFileTransferStreamHandler transferService,
IOptions<SwarmConfiguration> swarmConfigurationOptions,
ILogger<SwarmController> logger)
{
this.swarmOperations = swarmOperations ?? throw new ArgumentNullException(nameof(swarmOperations));
this.assemblyInformationProvider = assemblyInformationProvider ?? throw new ArgumentNullException(nameof(assemblyInformationProvider));
this.transferService = transferService ?? throw new ArgumentNullException(nameof(transferService));
swarmConfiguration = swarmConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(swarmConfigurationOptions));
this.logger = logger;
@@ -92,12 +84,17 @@ namespace Tgstation.Server.Host.Controllers
{
ArgumentNullException.ThrowIfNull(registrationRequest);
if (registrationRequest.ServerVersion != assemblyInformationProvider.Version)
var swarmProtocolVersion = Version.Parse(MasterVersionsAttribute.Instance.RawSwarmProtocolVersion);
if (registrationRequest.ServerVersion?.Major != swarmProtocolVersion.Major)
return StatusCode((int)HttpStatusCode.UpgradeRequired);
var registrationResult = await swarmOperations.RegisterNode(registrationRequest, RequestRegistrationId, cancellationToken);
if (registrationResult == null)
return Conflict();
if (registrationRequest.ServerVersion != swarmProtocolVersion)
logger.LogWarning("Allowed node {identifier} to register despite having a slightly different swarm protocol version!", registrationRequest.Identifier);
return Json(registrationResult);
}
@@ -445,6 +445,7 @@ namespace Tgstation.Server.Host.Database
// HEY YOU
// IF YOU HAVE A TEST THAT'S CREATING ERRORS BECAUSE THESE VALUES AREN'T SET CORRECTLY THERE'S MORE TO FIXING IT THAN JUST UPDATING THEM
// IN THE FUNCTION BELOW YOU ALSO NEED TO CORRECTLY SET THE RIGHT MIGRATION TO DOWNGRADE TO FOR THE LAST TGS VERSION
// YOU ALSO NEED TO UPDATE THE SWARM PROTOCOL MAJOR VERSION
// IF THIS BREAKS AGAIN I WILL PERSONALLY HAUNT YOUR ASS WHEN I DIE
/// <summary>
@@ -480,6 +481,7 @@ namespace Tgstation.Server.Host.Database
string BadDatabaseType() => throw new ArgumentException($"Invalid DatabaseType: {currentDatabaseType}", nameof(currentDatabaseType));
// !!! DON'T FORGET TO UPDATE THE SWARM PROTOCOL MAJOR VERSION !!!
if (targetVersion < new Version(6, 7, 0))
targetMigration = currentDatabaseType switch
{
@@ -41,6 +41,11 @@ namespace Tgstation.Server.Host.Properties
/// </summary>
public string RawMariaDBRedistVersion { get; }
/// <summary>
/// The <see cref="Version"/> <see cref="string"/> of the MariaDB server bundled with TGS installs.
/// </summary>
public string RawSwarmProtocolVersion { get; }
/// <summary>
/// Initializes a new instance of the <see cref="MasterVersionsAttribute"/> class.
/// </summary>
@@ -49,18 +54,21 @@ namespace Tgstation.Server.Host.Properties
/// <param name="rawWebpanelVersion">The value of <see cref="RawWebpanelVersion"/>.</param>
/// <param name="rawHostWatchdogVersion">The value of <see cref="RawHostWatchdogVersion"/>.</param>
/// <param name="rawMariaDBRedistVersion">The value of <see cref="RawMariaDBRedistVersion"/>.</param>
/// <param name="rawSwarmProtocolVersion">The value of <see cref="RawSwarmProtocolVersion"/>.</param>
public MasterVersionsAttribute(
string rawConfigurationVersion,
string rawInteropVersion,
string rawWebpanelVersion,
string rawHostWatchdogVersion,
string rawMariaDBRedistVersion)
string rawMariaDBRedistVersion,
string rawSwarmProtocolVersion)
{
RawConfigurationVersion = rawConfigurationVersion ?? throw new ArgumentNullException(nameof(rawConfigurationVersion));
RawInteropVersion = rawInteropVersion ?? throw new ArgumentNullException(nameof(rawInteropVersion));
RawWebpanelVersion = rawWebpanelVersion ?? throw new ArgumentNullException(nameof(rawWebpanelVersion));
RawHostWatchdogVersion = rawHostWatchdogVersion ?? throw new ArgumentNullException(nameof(rawHostWatchdogVersion));
RawMariaDBRedistVersion = rawMariaDBRedistVersion ?? throw new ArgumentNullException(nameof(rawMariaDBRedistVersion));
RawSwarmProtocolVersion = rawSwarmProtocolVersion ?? throw new ArgumentNullException(nameof(rawSwarmProtocolVersion));
}
}
}
@@ -11,7 +11,7 @@ namespace Tgstation.Server.Host.Swarm
public sealed class SwarmRegistrationRequest : SwarmServer
{
/// <summary>
/// The TGS <see cref="Version"/> of the sending server.
/// The swarm protocol <see cref="Version"/> of the sending server. Named this way due to legacy reasons.
/// </summary>
[Required]
public Version ServerVersion { get; }
@@ -24,6 +24,7 @@ using Tgstation.Server.Host.Configuration;
using Tgstation.Server.Host.Core;
using Tgstation.Server.Host.Database;
using Tgstation.Server.Host.IO;
using Tgstation.Server.Host.Properties;
using Tgstation.Server.Host.Security;
using Tgstation.Server.Host.System;
using Tgstation.Server.Host.Transfer;
@@ -34,7 +35,9 @@ namespace Tgstation.Server.Host.Swarm
/// <summary>
/// Helps keep servers connected to the same database in sync by coordinating updates.
/// </summary>
#pragma warning disable CA1506 // TODO: Decomplexify
sealed class SwarmService : ISwarmService, ISwarmServiceController, ISwarmOperations, IDisposable
#pragma warning restore CA1506
{
/// <inheritdoc />
public bool ExpectedNumberOfNodesConnected
@@ -1282,7 +1285,7 @@ namespace Tgstation.Server.Host.Swarm
null,
HttpMethod.Post,
SwarmConstants.RegisterRoute,
new SwarmRegistrationRequest(assemblyInformationProvider.Version)
new SwarmRegistrationRequest(Version.Parse(MasterVersionsAttribute.Instance.RawSwarmProtocolVersion))
{
Identifier = swarmConfiguration.Identifier,
Address = swarmConfiguration.Address,
@@ -56,6 +56,7 @@
<_Parameter3>$(TgsWebpanelVersion)</_Parameter3>
<_Parameter4>$(TgsHostWatchdogVersion)</_Parameter4>
<_Parameter5>$(TgsMariaDBRedistVersion)</_Parameter5>
<_Parameter6>$(TgsSwarmProtocolVersion)</_Parameter6>
</MasterVersionAssemblyAttributes>
</ItemGroup>
<WriteCodeFragment AssemblyAttributes="@(MasterVersionAssemblyAttributes)" Language="C#" OutputDirectory="$(IntermediateOutputPath)" OutputFile="MasterVersionsAssemblyInfo.cs">
@@ -8,6 +8,7 @@ using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
@@ -20,6 +21,7 @@ using Tgstation.Server.Host.Controllers;
using Tgstation.Server.Host.Core;
using Tgstation.Server.Host.Database;
using Tgstation.Server.Host.IO;
using Tgstation.Server.Host.Models;
using Tgstation.Server.Host.Security;
using Tgstation.Server.Host.System;
using Tgstation.Server.Host.Transfer;
@@ -75,6 +77,24 @@ namespace Tgstation.Server.Host.Swarm.Tests
}
}
private class MockTokenFactory : ITokenFactory
{
public ReadOnlySpan<byte> SigningKey
{
get => [0, 1, 2, 3, 4];
set
{
}
}
public TokenValidationParameters ValidationParameters => throw new NotSupportedException();
public TokenResponse CreateToken(User user, bool oAuth)
{
throw new NotSupportedException();
}
}
public TestableSwarmNode(
ILoggerFactory loggerFactory,
SwarmConfiguration swarmConfiguration,
@@ -138,7 +158,6 @@ namespace Tgstation.Server.Host.Swarm.Tests
RpcMapper = new SwarmRpcMapper(
(targetService, targetTransfer) => new SwarmController(
targetService,
mockAssemblyInformationProvider.Object,
targetTransfer,
mockOptions.Object,
loggerFactory.CreateLogger<SwarmController>()),
@@ -154,6 +173,8 @@ namespace Tgstation.Server.Host.Swarm.Tests
logger = loggerFactory.CreateLogger($"TestableSwarmNode-{swarmConfiguration.Identifier}");
var mockTokenFactory = new MockTokenFactory();
var runCount = 0;
void RecreateControllerAndService()
{
@@ -180,6 +201,7 @@ namespace Tgstation.Server.Host.Swarm.Tests
mockAsyncDelayer.Object,
mockServerUpdater.Object,
TransferService,
mockTokenFactory,
mockOptions.Object,
serviceLogger);
}