Merge branch 'dev' of https://github.com/tgstation/tgstation-server into 1089-DeploymentsButGitHubThisTime

This commit is contained in:
Cyberboss
2020-08-13 12:30:29 -04:00
10 changed files with 146 additions and 76 deletions
+1 -1
View File
@@ -4,7 +4,7 @@
<!-- Integration tests will ensure they match across the board -->
<TgsCoreVersion>4.5.0</TgsCoreVersion>
<TgsConfigVersion>2.0.0</TgsConfigVersion>
<TgsApiVersion>7.2.0</TgsApiVersion>
<TgsApiVersion>7.3.0</TgsApiVersion>
<TgsClientVersion>8.2.0</TgsClientVersion>
<TgsDmapiVersion>5.2.3</TgsDmapiVersion>
<TgsControlPanelVersion>0.4.0</TgsControlPanelVersion>
+7 -1
View File
@@ -563,6 +563,12 @@ namespace Tgstation.Server.Api.Models
/// An attempt to connect a chat bot failed.
/// </summary>
[Description("Failed to connect chat bot!")]
ChatCannotConnectProvider
ChatCannotConnectProvider,
/// <summary>
/// Attempt to add DreamDaemon to the list of firewall exempt processes failed.
/// </summary>
[Description("Failed to allow DreamDaemon through the Windows firewall!")]
ByondDreamDaemonFirewallFail,
}
}
+2 -2
View File
@@ -1,4 +1,4 @@
using System;
using System;
using Tgstation.Server.Api.Models.Internal;
namespace Tgstation.Server.Api.Models
@@ -11,7 +11,7 @@ namespace Tgstation.Server.Api.Models
/// <summary>
/// The name of the log file.
/// </summary>
public string? Name { get; set; }
public string Name { get; set; } = String.Empty;
/// <summary>
/// The <see cref="DateTimeOffset"/> of when the log file was modified.
@@ -3,10 +3,10 @@
"isRoot": true,
"tools": {
"dotnet-ef": {
"version": "3.1.6",
"version": "3.1.7",
"commands": [
"dotnet-ef"
]
}
}
}
}
@@ -1,4 +1,4 @@
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging;
using System;
using System.Text;
using System.Threading;
@@ -84,65 +84,99 @@ namespace Tgstation.Server.Host.Components.Byond
public void Dispose() => semaphore.Dispose();
/// <inheritdoc />
public override async Task InstallByond(string path, Version version, CancellationToken cancellationToken)
{
async Task SetNoPromptTrusted()
{
var configPath = IOManager.ConcatPath(path, ByondConfigDir);
await IOManager.CreateDirectory(configPath, cancellationToken).ConfigureAwait(false);
public override Task InstallByond(string path, Version version, CancellationToken cancellationToken)
=> Task.WhenAll(
SetNoPromptTrusted(path, cancellationToken),
InstallDirectX(path, cancellationToken),
AddDreamDaemonToFirewall(path, cancellationToken));
var configFilePath = IOManager.ConcatPath(configPath, ByondDDConfig);
Logger.LogTrace("Disabling trusted prompts in {0}...", configFilePath);
await IOManager.WriteAllBytes(
configFilePath,
Encoding.UTF8.GetBytes(ByondNoPromptTrustedMode),
cancellationToken)
.ConfigureAwait(false);
async Task SetNoPromptTrusted(string path, CancellationToken cancellationToken)
{
var configPath = IOManager.ConcatPath(path, ByondConfigDir);
await IOManager.CreateDirectory(configPath, cancellationToken).ConfigureAwait(false);
var configFilePath = IOManager.ConcatPath(configPath, ByondDDConfig);
Logger.LogTrace("Disabling trusted prompts in {0}...", configFilePath);
await IOManager.WriteAllBytes(
configFilePath,
Encoding.UTF8.GetBytes(ByondNoPromptTrustedMode),
cancellationToken)
.ConfigureAwait(false);
}
async Task InstallDirectX(string path, CancellationToken cancellationToken)
{
using var lockContext = await SemaphoreSlimContext.Lock(semaphore, cancellationToken).ConfigureAwait(false);
if (installedDirectX)
{
Logger.LogTrace("DirectX already installed.");
return;
}
var setNoPromptTrustedModeTask = SetNoPromptTrusted();
Logger.LogTrace("Installing DirectX redistributable...");
// after this version lummox made DD depend of directx lol
// but then he became amazing and not only fixed it but also gave us 30s compiles \[T]/
// then he readded it again so -_-
if (!installedDirectX)
using (await SemaphoreSlimContext.Lock(semaphore, cancellationToken).ConfigureAwait(false))
if (!installedDirectX)
{
// ^check again because race conditions
Logger.LogTrace("Installing DirectX redistributable...");
// always install it, it's pretty fast and will do better redundancy checking than us
var rbdx = IOManager.ConcatPath(path, ByondDXDir);
// always install it, it's pretty fast and will do better redundancy checking than us
var rbdx = IOManager.ConcatPath(path, ByondDXDir);
try
{
// noShellExecute because we aren't doing runas shennanigans
using var directXInstaller = processExecutor.LaunchProcess(
IOManager.ConcatPath(rbdx, "DXSETUP.exe"),
rbdx,
"/silent",
noShellExecute: true);
// noShellExecute because we aren't doing runas shennanigans
IProcess directXInstaller;
try
{
directXInstaller = processExecutor.LaunchProcess(
IOManager.ConcatPath(rbdx, "DXSETUP.exe"),
rbdx, "/silent",
noShellExecute: true);
}
catch (Exception e)
{
throw new JobException(ErrorCode.ByondDirectXInstallFail, e);
}
int exitCode;
using (cancellationToken.Register(() => directXInstaller.Terminate()))
exitCode = await directXInstaller.Lifetime.ConfigureAwait(false);
cancellationToken.ThrowIfCancellationRequested();
using (directXInstaller)
{
int exitCode;
using (cancellationToken.Register(() => directXInstaller.Terminate()))
exitCode = await directXInstaller.Lifetime.ConfigureAwait(false);
cancellationToken.ThrowIfCancellationRequested();
if (exitCode != 0)
throw new JobException(ErrorCode.ByondDirectXInstallFail, new JobException($"Invalid exit code: {exitCode}"));
installedDirectX = true;
}
catch (Exception e)
{
throw new JobException(ErrorCode.ByondDirectXInstallFail, e);
}
}
if (exitCode != 0)
throw new JobException(ErrorCode.ByondDirectXInstallFail, new JobException($"Invalid exit code: {exitCode}"));
installedDirectX = true;
}
}
async Task AddDreamDaemonToFirewall(string path, CancellationToken cancellationToken)
{
var dreamDaemonPath = IOManager.ResolvePath(
IOManager.ConcatPath(
path,
ByondManager.BinPath,
DreamDaemonName));
await setNoPromptTrustedModeTask.ConfigureAwait(false);
try
{
using var netshProcess = processExecutor.LaunchProcess(
"netsh.exe",
IOManager.ResolvePath(),
$"advfirewall firewall add rule name=\"TGS DreamDaemon\" program=\"{dreamDaemonPath}\" protocol=tcp dir=in enable=yes action=allow",
true,
true,
true);
int exitCode;
using (cancellationToken.Register(() => netshProcess.Terminate()))
exitCode = await netshProcess.Lifetime.ConfigureAwait(false);
cancellationToken.ThrowIfCancellationRequested();
Logger.LogDebug(
"netsh.exe output:{0}{1}",
Environment.NewLine,
await netshProcess.GetCombinedOutput(cancellationToken).ConfigureAwait(false));
if (exitCode != 0)
throw new JobException(ErrorCode.ByondDreamDaemonFirewallFail, new JobException($"Invalid exit code: {exitCode}"));
}
catch (Exception ex)
{
throw new JobException(ErrorCode.ByondDreamDaemonFirewallFail, ex);
}
}
}
}
@@ -57,7 +57,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
/// </summary>
/// <param name="fromDiscord">The mention <see cref="string"/> provided by the Discord library</param>
/// <returns>The normalized mention <see cref="string"/></returns>
static string NormalizeMentions(string fromDiscord) => fromDiscord.Replace("<!@", "<@", StringComparison.Ordinal);
static string NormalizeMentions(string fromDiscord) => fromDiscord.Replace("<@!", "<@", StringComparison.Ordinal);
/// <summary>
/// Construct a <see cref="DiscordProvider"/>
@@ -96,6 +96,16 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
if (e.Author.Id == client.CurrentUser.Id)
return;
if (e.Content.Equals("Based on what?", StringComparison.OrdinalIgnoreCase))
{
// DCT: None available
await SendMessage(
e.Channel.Id,
"https://youtu.be/LrNu-SuFF_o",
default)
.ConfigureAwait(false);
}
var pm = e.Channel is IPrivateChannel;
if (!pm && !mappedChannels.Contains(e.Channel.Id))
@@ -374,7 +374,7 @@ namespace Tgstation.Server.Host.Controllers
/// <response code="409">An IO error occurred while downloading.</response>
[HttpGet(Routes.Logs + "/{*path}")]
[TgsAuthorize(AdministrationRights.DownloadLogs)]
[ProducesResponseType(typeof(List<LogFile>), 200)]
[ProducesResponseType(typeof(LogFile), 200)]
[ProducesResponseType(typeof(ErrorMessage), 409)]
public async Task<IActionResult> GetLog(string path, CancellationToken cancellationToken)
{
@@ -1,4 +1,4 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
@@ -291,6 +291,9 @@ namespace Tgstation.Server.Host.Controllers
if (directory == null)
throw new ArgumentNullException(nameof(directory));
if (directory.Path == null)
return BadRequest(new ErrorMessage(ErrorCode.ModelValidationFailure));
if (ForbidDueToModeConflicts(directory.Path, out var systemIdentity))
return Forbid();
@@ -128,7 +128,18 @@ namespace Tgstation.Server.Host.Core
new OpenApiInfo
{
Title = "TGS API",
Version = ApiHeaders.Version.Semver().ToString()
Version = ApiHeaders.Version.Semver().ToString(),
License = new OpenApiLicense
{
Name = "AGPL-3.0",
Url = new Uri("https://github.com/tgstation/tgstation-server/blob/dev/LICENSE")
},
Contact = new OpenApiContact
{
Name = "/tg/station 13",
Url = new Uri("https://github.com/tgstation")
},
Description = "A production scale tool for BYOND server management"
});
// Important to do this before applying our own filters
@@ -136,6 +147,9 @@ namespace Tgstation.Server.Host.Core
swaggerGenOptions.IncludeXmlComments(assemblyDocumentationPath);
swaggerGenOptions.IncludeXmlComments(apiDocumentationPath);
// nullable stuff
swaggerGenOptions.UseAllOfToExtendReferenceSchemas();
swaggerGenOptions.OperationFilter<SwaggerConfiguration>();
swaggerGenOptions.DocumentFilter<SwaggerConfiguration>();
swaggerGenOptions.SchemaFilter<SwaggerConfiguration>();
@@ -337,15 +351,18 @@ namespace Tgstation.Server.Host.Core
// Nothing is required
schema.Required.Clear();
if (!schema.Enum?.Any() ?? false)
return;
// Could be nullable type, make sure to get the right one
Type enumType = context.Type.IsConstructedGenericType
Type nonNullableType = context.Type.IsConstructedGenericType
? context.Type.GenericTypeArguments.First()
: context.Type;
OpenApiEnumVarNamesExtension.Apply(schema, enumType);
if (nonNullableType != context.Type)
schema.Nullable = true;
if (!schema.Enum?.Any() ?? false)
return;
OpenApiEnumVarNamesExtension.Apply(schema, nonNullableType);
}
}
}
@@ -48,20 +48,20 @@
<PackageReference Include="Cyberboss.SmartIrc4net.Standard" Version="0.4.6" />
<PackageReference Include="Discord.Net.WebSocket" Version="2.2.0" />
<PackageReference Include="LibGit2Sharp" Version="0.27.0-preview-0034" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="3.1.6" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.1.6" />
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="3.3.0-beta1.final">
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="3.1.7" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.1.7" />
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="3.3.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.6" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.1.6">
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.7" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.1.7">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="3.1.6" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.6" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.6">
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="3.1.7" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.7" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.7">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
@@ -81,12 +81,12 @@
</PackageReference>
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.5.1" />
<PackageReference Include="Swashbuckle.AspNetCore.Newtonsoft" Version="5.5.1" />
<PackageReference Include="System.Data.SqlClient" Version="4.8.1" />
<PackageReference Include="System.Data.SqlClient" Version="4.8.2" />
<PackageReference Include="System.DirectoryServices.AccountManagement" Version="4.7.0" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.7.1" />
<PackageReference Include="System.Management" Version="4.7.0" />
<PackageReference Include="Wangkanai.Detection.Browser" Version="2.0.0" />
<PackageReference Include="Z.EntityFramework.Plus.EFCore" Version="3.0.55" />
<PackageReference Include="Z.EntityFramework.Plus.EFCore" Version="3.0.57" />
</ItemGroup>
<ItemGroup>