Added error code for swarm integrity check failures

This commit is contained in:
Dominion
2023-04-22 11:40:01 -04:00
parent e823ca7c4c
commit c1f68d9243
11 changed files with 52 additions and 20 deletions
+3 -3
View File
@@ -5,9 +5,9 @@
<PropertyGroup>
<TgsCoreVersion>5.11.0</TgsCoreVersion>
<TgsConfigVersion>4.6.0</TgsConfigVersion>
<TgsApiVersion>9.9.0</TgsApiVersion>
<TgsApiLibraryVersion>10.3.0</TgsApiLibraryVersion>
<TgsClientVersion>11.3.1</TgsClientVersion>
<TgsApiVersion>9.10.0</TgsApiVersion>
<TgsApiLibraryVersion>10.4.0</TgsApiLibraryVersion>
<TgsClientVersion>11.4.0</TgsClientVersion>
<TgsDmapiVersion>6.4.2</TgsDmapiVersion>
<TgsInteropVersion>5.6.0</TgsInteropVersion>
<TgsHostWatchdogVersion>1.2.2</TgsHostWatchdogVersion>
+1 -1
View File
@@ -70,7 +70,7 @@ TGS will only every return the response codes listed here
- 409: Conflict. Documented in the requests that use them
- 410: Gone. Attempted to access/modify a resource that ideally should have been ready, but isn't or no longer is
- 422: Unprocessable Entity: Used specifically when an operation that requires a server restart is unable to be performed due to the @ref Tgstation.Server.Host.Watchdog not being present in the deployment. Should not happen with a proper server configuration. Response body contains an @ref Tgstation.Server.Api.Models.ErrorMessage
- 424: Failed Dependency: When a request that depends on the GitHub API fails for a reason other than rate limiting. Check server logs, usually this indicates a bad access token.
- 424: Failed Dependency: When a request that depends on an external API fails for a reason other than rate limiting. The response body will contain an @ref Tgstation.Server.Api.Models.ErrorMessage model detailing the error.
- 426: Upgrade required: Used when the client's API version is not compatible with the server's. Response body contains an @ref Tgstation.Server.Api.Models.ErrorMessage
- 429: Rate limited. Used with operations that rely on GitHub.com. If a rate limit is hit for an operation this will be returned. Response will contain a Retry-After header
- 500: Server error. Please report the request and response body to the code repository
@@ -629,5 +629,11 @@ namespace Tgstation.Server.Api.Models
/// </summary>
[Description("The deployment took longer than the configured timeout!")]
DeploymentTimeout,
/// <summary>
/// The server swarm has less than the expected amount of nodes.
/// </summary>
[Description("The server swarm has less than the expected amount of nodes!")]
SwarmIntegrityCheckFailed,
}
}
@@ -16,7 +16,7 @@
<RepositoryUrl>https://github.com/tgstation/tgstation-server</RepositoryUrl>
<Copyright>2018-2023</Copyright>
<PackageTags>json web api tgstation-server tgstation ss13 byond</PackageTags>
<PackageReleaseNotes>Added ChannelData field to ChatChannels model.</PackageReleaseNotes>
<PackageReleaseNotes>Added ErrorCode.SwarmIntegrityCheckFailed.</PackageReleaseNotes>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<CodeAnalysisRuleSet>../../build/analyzers.ruleset</CodeAnalysisRuleSet>
@@ -16,7 +16,7 @@
<RepositoryUrl>https://github.com/tgstation/tgstation-server</RepositoryUrl>
<Copyright>2018-2023</Copyright>
<PackageTags>json web api tgstation-server tgstation ss13 byond client</PackageTags>
<PackageReleaseNotes>Fix login refreshing not working.</PackageReleaseNotes>
<PackageReleaseNotes>Updated definitions for API version 9.10.0.</PackageReleaseNotes>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<CodeAnalysisRuleSet>../../build/analyzers.ruleset</CodeAnalysisRuleSet>
@@ -35,7 +35,7 @@ namespace Tgstation.Server.Host.Configuration
public string PrivateKey { get; set; }
/// <summary>
/// The number of nodes required to be connected before performing an update. Must be set on controller. Does not include controller.
/// The number of nodes in addition to the controller required to be connected a server swarm before performing an update.
/// </summary>
public uint UpdateRequiredNodeCount { get; set; }
}
@@ -233,16 +233,17 @@ namespace Tgstation.Server.Host.Controllers
try
{
var updateResult = await serverUpdateInitiator.InitiateUpdate(model.NewVersion, cancellationToken);
if (updateResult == ServerUpdateResult.ReleaseMissing)
return Gone();
if (updateResult == ServerUpdateResult.UpdateInProgress)
return BadRequest(new ErrorMessageResponse(ErrorCode.ServerUpdateInProgress));
return Accepted(new ServerUpdateResponse
return updateResult switch
{
NewVersion = model.NewVersion,
});
ServerUpdateResult.Started => Accepted(new ServerUpdateResponse
{
NewVersion = model.NewVersion,
}),
ServerUpdateResult.ReleaseMissing => Gone(),
ServerUpdateResult.UpdateInProgress => BadRequest(new ErrorMessageResponse(ErrorCode.ServerUpdateInProgress)),
ServerUpdateResult.SwarmIntegrityCheckFailed => StatusCode(HttpStatusCode.FailedDependency, new ErrorMessageResponse(ErrorCode.SwarmIntegrityCheckFailed)),
_ => throw new InvalidOperationException($"Unexpected ServerUpdateResult: {updateResult}"),
};
}
catch (RateLimitExceededException e)
{
@@ -19,5 +19,10 @@
/// Another update is already in progress.
/// </summary>
UpdateInProgress,
/// <summary>
/// The server swarm does not contain the expected amount of nodes.
/// </summary>
SwarmIntegrityCheckFailed,
}
}
@@ -89,6 +89,9 @@ namespace Tgstation.Server.Host.Core
if (newVersion == null)
throw new ArgumentNullException(nameof(newVersion));
if (!swarmService.ExpectedNumberOfNodesConnected)
return ServerUpdateResult.SwarmIntegrityCheckFailed;
logger.LogDebug("Looking for GitHub releases version {version}...", newVersion);
IEnumerable<Release> releases;
var gitHubClient = gitHubClientFactory.CreateClient();
@@ -12,6 +12,11 @@ namespace Tgstation.Server.Host.Swarm
/// </summary>
public interface ISwarmService
{
/// <summary>
/// Gets a value indicating if the expected amount of nodes are connected to the swarm.
/// </summary>
bool ExpectedNumberOfNodesConnected { get; }
/// <summary>
/// Signal to the swarm that an update is requested.
/// </summary>
@@ -67,6 +67,16 @@ namespace Tgstation.Server.Host.Swarm
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
};
/// <inheritdoc />
public bool ExpectedNumberOfNodesConnected
{
get
{
lock (swarmServers)
return swarmServers.Count - 1 > swarmConfiguration.UpdateRequiredNodeCount;
}
}
/// <summary>
/// If the swarm system is enabled.
/// </summary>
@@ -1087,10 +1097,14 @@ namespace Tgstation.Server.Host.Swarm
/// <returns>A <see cref="Task"/> representing the running operation.</returns>
async Task SendUpdatedServerListToNodes(CancellationToken cancellationToken)
{
logger.LogDebug("Sending updated server list to all nodes...");
List<SwarmServerResponse> currentSwarmServers;
lock (swarmServers)
{
serversDirty = false;
currentSwarmServers = swarmServers.ToList();
}
logger.LogDebug("Sending updated server list to all {nodeCount} nodes...", currentSwarmServers.Count);
using var httpClient = httpClientFactory.CreateClient();
async Task UpdateRequestForServer(SwarmServerResponse swarmServer)
@@ -1124,9 +1138,7 @@ namespace Tgstation.Server.Host.Swarm
await Task.WhenAll(
currentSwarmServers
.Where(x => !x.Controller)
.Select(UpdateRequestForServer))
;
serversDirty = false;
.Select(UpdateRequestForServer));
}
/// <summary>