Post package upgrade fixes

This commit is contained in:
Jordan Brown
2019-12-30 20:58:29 -05:00
parent 3a32181975
commit ab55d1f75d
21 changed files with 93 additions and 99 deletions
+5 -2
View File
@@ -24,13 +24,16 @@ namespace Tgstation.Server.Host.Console
/// <returns>A <see cref="Task"/> representing the running operation</returns>
internal static async Task Main(string[] args)
{
using (var loggerFactory = LoggerFactory.Create(
builder => builder.AddConsole()))
using (var loggerFactory = new LoggerFactory())
{
var arguments = new List<string>(args);
var trace = arguments.Remove("--trace-host-watchdog");
var debug = arguments.Remove("--debug-host-watchdog");
#pragma warning disable CS0618 // Type or member is obsolete
loggerFactory.AddConsole(trace ? LogLevel.Trace : debug ? LogLevel.Debug : LogLevel.Information, true);
#pragma warning restore CS0618 // Type or member is obsolete
if (trace && debug)
{
loggerFactory.CreateLogger(nameof(Program)).LogCritical("Please specify only 1 of --trace-host-watchdog or --debug-host-watchdog!");
@@ -27,7 +27,7 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>compile; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="3.1.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.2.0" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
+3 -13
View File
@@ -108,18 +108,7 @@ namespace Tgstation.Server.Host.Service
}
}
bool serviceWillRun = !Configure && !Install && !Uninstall;
ServerService service = null;
ILoggerFactory loggerFactory = null;
using (loggerFactory = LoggerFactory.Create(builder =>
{
if (serviceWillRun)
{
LogLevel logLevel = Trace ? LogLevel.Trace : Debug ? LogLevel.Debug : LogLevel.Information;
service = new ServerService(WatchdogFactory, builder, () => loggerFactory, logLevel);
}
}))
using(service)
using (var loggerFactory = new LoggerFactory())
{
if (Configure)
await WatchdogFactory.CreateWatchdog(loggerFactory).RunAsync(true, Array.Empty<string>(), default).ConfigureAwait(false);
@@ -153,7 +142,8 @@ namespace Tgstation.Server.Host.Service
installer.ServiceName = ServerService.Name;
installer.Uninstall(null);
}
else if (serviceWillRun)
else if (!Configure)
using (var service = new ServerService(WatchdogFactory, loggerFactory, Trace ? LogLevel.Trace : Debug ? LogLevel.Debug : LogLevel.Information))
ServiceBase.Run(service);
}
}
@@ -21,17 +21,12 @@ namespace Tgstation.Server.Host.Service
public const string Name = "tgstation-server-4";
/// <summary>
/// The <see cref="IWatchdogFactory"/> for the <see cref="ServerService"/>
/// The <see cref="IWatchdog"/> for the <see cref="ServerService"/>
/// </summary>
readonly IWatchdogFactory watchdogFactory;
readonly IWatchdog watchdog;
/// <summary>
/// The <see cref="Func{TResult}"/> used to retrieve a configured <see cref="ILoggerFactory"/>.
/// </summary>
readonly Func<ILoggerFactory> getLoggerFactory;
/// <summary>
/// The <see cref="Task"/> recieved from <see cref="IWatchdog.RunAsync(bool, string[], CancellationToken)"/>.
/// The <see cref="Task"/> recieved from <see cref="IWatchdog.RunAsync(bool, string[], CancellationToken)"/> of <see cref="watchdog"/>
/// </summary>
Task watchdogTask;
@@ -43,39 +38,39 @@ namespace Tgstation.Server.Host.Service
/// <summary>
/// Construct a <see cref="ServerService"/>
/// </summary>
/// <param name="watchdogFactory">The value of <see cref="watchdogFactory"/>.</param>
/// <param name="loggingBuilder">The <see cref="ILoggingBuilder"/> to configure.</param>
/// <param name="getLoggerFactory">The <see cref="Func{TResult}"/> used to retrieve a <see cref="ILoggerFactory"/> based on the <paramref name="loggingBuilder"/> configuration.</param>
/// <param name="watchdogFactory">The <see cref="IWatchdogFactory"/> to create <see cref="watchdog"/> with</param>
/// <param name="loggerFactory">The <see cref="ILoggerFactory"/> for <paramref name="watchdogFactory"/></param>
/// <param name="minumumLogLevel">The minimum <see cref="Microsoft.Extensions.Logging.LogLevel"/> to record in the event log</param>
public ServerService(IWatchdogFactory watchdogFactory, ILoggingBuilder loggingBuilder, Func<ILoggerFactory> getLoggerFactory, LogLevel minumumLogLevel)
public ServerService(IWatchdogFactory watchdogFactory, ILoggerFactory loggerFactory, LogLevel minumumLogLevel)
{
this.watchdogFactory = watchdogFactory ?? throw new ArgumentNullException(nameof(watchdogFactory));
if (loggingBuilder == null)
throw new ArgumentNullException(nameof(loggingBuilder));
this.getLoggerFactory = getLoggerFactory ?? throw new ArgumentNullException(nameof(getLoggerFactory));
if (watchdogFactory == null)
throw new ArgumentNullException(nameof(watchdogFactory));
if (loggerFactory == null)
throw new ArgumentNullException(nameof(loggerFactory));
ServiceName = Name;
loggingBuilder.AddEventLog(new EventLogSettings
#pragma warning disable CS0618 // Type or member is obsolete
loggerFactory.AddEventLog(new EventLogSettings
{
LogName = EventLog.Log,
MachineName = EventLog.MachineName,
SourceName = EventLog.Source,
Filter = (message, logLevel) => logLevel >= minumumLogLevel
});
#pragma warning restore CS0618 // Type or member is obsolete
ServiceName = Name;
watchdog = watchdogFactory.CreateWatchdog(loggerFactory);
}
/// <summary>
/// Creates and executes the watchdog stopping the service if it exits
/// Executes the <see cref="watchdog"/>, stopping the service if it exits
/// </summary>
/// <param name="args">The arguments for the watchdog.</param>
/// <param name="args">The arguments for the <see cref="watchdog"/></param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation</param>
/// <returns>A <see cref="Task"/> representing the running operation</returns>
async Task RunWatchdog(string[] args, CancellationToken cancellationToken)
{
var watchdog = watchdogFactory.CreateWatchdog(getLoggerFactory());
await watchdog.RunAsync(false, args, cancellationToken).ConfigureAwait(false);
await watchdog.RunAsync(false, args, cancellationTokenSource.Token).ConfigureAwait(false);
void StopServiceAsync()
{
@@ -28,7 +28,7 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Logging.EventLog" Version="3.1.0" />
<PackageReference Include="Microsoft.Extensions.Logging.EventLog" Version="2.2.0" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
@@ -27,7 +27,7 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>compile; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Logging" Version="3.1.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.2.0" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
@@ -18,7 +18,6 @@ namespace Tgstation.Server.Host.Controllers
/// A <see cref="Controller"/> for API functions
/// </summary>
[Produces(ApiHeaders.ApplicationJson)]
[Consumes(ApiHeaders.ApplicationJson)]
public abstract class ApiController : Controller
{
/// <summary>
+11 -8
View File
@@ -104,6 +104,9 @@ namespace Tgstation.Server.Host.Core
// enable options which give us config reloading
services.AddOptions();
// this is needful for the setup wizard
services.AddLogging();
// other stuff needed for for setup wizard and configuration
services.AddSingleton<IIOManager, DefaultIOManager>();
services.AddSingleton<IConsole, IO.Console>();
@@ -231,9 +234,8 @@ namespace Tgstation.Server.Host.Core
// enable browser detection
services.AddDetectionCore().AddBrowser();
// enable CORS if necessary
if (controlPanelConfiguration.AllowAnyOrigin || controlPanelConfiguration.AllowedOrigins?.Count > 0)
services.AddCors();
// CORS conditionally enabled later
services.AddCors();
void AddTypedContext<TContext>() where TContext : DatabaseContext<TContext>
{
@@ -369,12 +371,13 @@ namespace Tgstation.Server.Host.Core
corsBuilder = builder => builder.WithOrigins(controlPanelConfiguration.AllowedOrigins.ToArray());
}
if (corsBuilder != null)
var originalBuilder = corsBuilder;
corsBuilder = builder =>
{
var originalBuilder = corsBuilder;
corsBuilder = builder => originalBuilder(builder.AllowAnyHeader().AllowAnyMethod());
applicationBuilder.UseCors(corsBuilder);
}
builder.AllowAnyHeader().AllowAnyMethod();
originalBuilder?.Invoke(builder);
};
applicationBuilder.UseCors(corsBuilder);
// Do not service requests until Ready is called, this will return 503 until that point
applicationBuilder.UseAsyncInitialization(async cancellationToken =>
@@ -274,8 +274,10 @@ namespace Tgstation.Server.Host.Core
await console.WriteAsync("Testing create DB permission...", true, cancellationToken).ConfigureAwait(false);
using (var command = testConnection.CreateCommand())
{
command.CommandText = "CREATE DATABASE ?";
command.Parameters.Add(databaseName);
// I really don't care about user sanitization here, they want to fuck their own DB? so be it
#pragma warning disable CA2100 // Review SQL queries for security vulnerabilities
command.CommandText = $"CREATE DATABASE {databaseName}";
#pragma warning restore CA2100 // Review SQL queries for security vulnerabilities
await command.ExecuteNonQueryAsync(cancellationToken).ConfigureAwait(false);
}
@@ -283,8 +285,9 @@ namespace Tgstation.Server.Host.Core
await console.WriteAsync("Dropping test database...", true, cancellationToken).ConfigureAwait(false);
using (var command = testConnection.CreateCommand())
{
command.CommandText = "DROP DATABASE ?";
command.Parameters.Add(databaseName);
#pragma warning disable CA2100 // Review SQL queries for security vulnerabilities
command.CommandText = $"DROP DATABASE {databaseName}";
#pragma warning restore CA2100 // Review SQL queries for security vulnerabilities
try
{
await command.ExecuteNonQueryAsync(cancellationToken).ConfigureAwait(false);
@@ -12,7 +12,7 @@ namespace Tgstation.Server.Host.Models.Migrations
/// <inheritdoc />
public MySqlDatabaseContext CreateDbContext(string[] args)
{
using (var loggerFactory = LoggerFactory.Create(builder => { }))
using (var loggerFactory = new LoggerFactory())
{
return new MySqlDatabaseContext(new DbContextOptions<MySqlDatabaseContext>(), DesignTimeDbContextFactoryHelpers.GetDbContextOptions(), new DatabaseSeeder(new CryptographySuite(new PasswordHasher<User>())), loggerFactory.CreateLogger<MySqlDatabaseContext>());
}
@@ -12,7 +12,7 @@ namespace Tgstation.Server.Host.Models.Migrations
/// <inheritdoc />
public SqlServerDatabaseContext CreateDbContext(string[] args)
{
using (var loggerFactory = LoggerFactory.Create(builder => { }))
using (var loggerFactory = new LoggerFactory())
{
return new SqlServerDatabaseContext(new DbContextOptions<SqlServerDatabaseContext>(), DesignTimeDbContextFactoryHelpers.GetDbContextOptions(), new DatabaseSeeder(new CryptographySuite(new PasswordHasher<User>())), loggerFactory.CreateLogger<SqlServerDatabaseContext>());
}
@@ -56,7 +56,7 @@
<PackageReference Include="Discord.Net.WebSocket" Version="2.1.1" />
<PackageReference Include="LibGit2Sharp" Version="0.26.2" />
<PackageReference Include="Microsoft.AspNetCore" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="2.1.2" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Identity" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.2.0" />
@@ -64,16 +64,16 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.1.0" PrivateAssets="All" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.0">
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="2.2.6" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.2.6" PrivateAssets="All" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="2.2.6" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="2.2.6">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="Mono.Posix.NETStandard" Version="1.0.0" />
<PackageReference Include="Octokit" Version="0.36.0" />
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="3.1.0" />
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="2.2.6" />
<PackageReference Include="Serilog.Extensions.Logging" Version="3.0.1" />
<PackageReference Include="Serilog.Sinks.Async" Version="1.4.0" />
<PackageReference Include="Serilog.Sinks.RollingFile" Version="3.3.0" />
@@ -85,7 +85,7 @@
<PackageReference Include="System.DirectoryServices.AccountManagement" Version="4.7.0" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="5.6.0" />
<PackageReference Include="Wangkanai.Detection.Browser" Version="2.0.0" />
<PackageReference Include="Z.EntityFramework.Plus.EFCore" Version="3.0.32" />
<PackageReference Include="Z.EntityFramework.Plus.EFCore" Version="2.0.32" />
</ItemGroup>
<ItemGroup>
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>
@@ -10,7 +10,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.2.2" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
<PackageReference Include="MSTest.TestAdapter" Version="2.0.0" />
<PackageReference Include="MSTest.TestFramework" Version="2.0.0" />
</ItemGroup>
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>
@@ -9,7 +9,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
<PackageReference Include="Moq" Version="4.13.1" />
<PackageReference Include="MSTest.TestAdapter" Version="2.0.0" />
<PackageReference Include="MSTest.TestFramework" Version="2.0.0" />
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>
@@ -9,7 +9,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
<PackageReference Include="Moq" Version="4.13.1" />
<PackageReference Include="MSTest.TestAdapter" Version="2.0.0" />
<PackageReference Include="MSTest.TestFramework" Version="2.0.0" />
@@ -18,11 +18,11 @@ namespace Tgstation.Server.Host.Service.Tests
[TestMethod]
public void TestConstructionAndDisposal()
{
Assert.ThrowsException<ArgumentNullException>(() => new ServerService(null, null, null, default));
Assert.ThrowsException<ArgumentNullException>(() => new ServerService(null, null, default));
var mockWatchdogFactory = new Mock<IWatchdogFactory>();
Assert.ThrowsException<ArgumentNullException>(() => new ServerService(mockWatchdogFactory.Object, null, null, default));
LoggerFactory.Create(builder => Assert.ThrowsException<ArgumentNullException>(() => new ServerService(mockWatchdogFactory.Object, builder, null, default)));
LoggerFactory.Create(builder => { new ServerService(mockWatchdogFactory.Object, builder, () => null, default).Dispose(); });
Assert.ThrowsException<ArgumentNullException>(() => new ServerService(mockWatchdogFactory.Object, null, default));
var mockLoggerFactory = new LoggerFactory();
new ServerService(mockWatchdogFactory.Object, mockLoggerFactory, default).Dispose();
}
[TestMethod]
@@ -34,32 +34,23 @@ namespace Tgstation.Server.Host.Service.Tests
var mockWatchdog = new Mock<IWatchdog>();
var args = Array.Empty<string>();
CancellationToken cancellationToken, originalToken;
using(var cts = new CancellationTokenSource())
{
originalToken = cts.Token;
cancellationToken = originalToken;
}
var cancelled = false;
mockWatchdog.Setup(x => x.RunAsync(false, args, It.IsAny<CancellationToken>())).Callback((bool x, string[] _, CancellationToken token) => token.Register(() => cancelled = true)).Returns(Task.CompletedTask).Verifiable();
CancellationToken cancellationToken;
mockWatchdog.Setup(x => x.RunAsync(false, args, It.IsAny<CancellationToken>())).Callback((bool x, string[] _, CancellationToken token) => cancellationToken = token).Returns(Task.CompletedTask).Verifiable();
var mockWatchdogFactory = new Mock<IWatchdogFactory>();
var mockLoggerFactory = new LoggerFactory();
mockWatchdogFactory.Setup(x => x.CreateWatchdog(mockLoggerFactory)).Returns(mockWatchdog.Object).Verifiable();
ServerService service = null;
ILoggerFactory loggerFactory = null;
using (loggerFactory = LoggerFactory.Create(builder => service = new ServerService(mockWatchdogFactory.Object, builder, () => loggerFactory, default)))
using (service)
using (var service = new ServerService(mockWatchdogFactory.Object, mockLoggerFactory, default))
{
mockWatchdogFactory.Setup(x => x.CreateWatchdog(loggerFactory)).Returns(mockWatchdog.Object).Verifiable();
Assert.IsFalse(cancelled);
onStart.Invoke(service, new object[] { args });
mockWatchdog.VerifyAll();
Assert.AreNotSame(cancellationToken, originalToken);
Assert.IsFalse(cancellationToken.IsCancellationRequested);
onStop.Invoke(service, Array.Empty<object>());
Assert.IsTrue(cancelled);
Assert.IsTrue(cancellationToken.IsCancellationRequested);
mockWatchdog.VerifyAll();
}
mockWatchdogFactory.VerifyAll();
}
}
@@ -202,15 +202,25 @@ namespace Tgstation.Server.Host.Core.Tests
mockApplication.SetupGet(x => x.VersionPrefix).Returns("sumfuk").Verifiable();
// This list is here for ease of debugging.
var consolePlayback = new List<string>();
mockConsole.Setup(x => x.PressAnyKeyAsync(It.IsAny<CancellationToken>())).Returns(Task.CompletedTask).Verifiable();
mockConsole.Setup(x => x.ReadLineAsync(It.IsAny<bool>(), It.IsAny<CancellationToken>())).Returns(() =>
{
if (inputPos == finalInputSequence.Count)
Assert.Fail("Exhausted input sequence!");
var res = finalInputSequence[inputPos++];
consolePlayback.Add($"Input: {res}");
return Task.FromResult(res);
}).Verifiable();
mockConsole.Setup(x => x.WriteAsync(It.IsAny<string>(), It.IsAny<bool>(), It.IsAny<CancellationToken>())).Returns(Task.CompletedTask).Verifiable();
mockConsole
.Setup(x => x.WriteAsync(It.IsAny<string>(), It.IsAny<bool>(), It.IsAny<CancellationToken>()))
.Callback<string, bool, CancellationToken>((message, error, token) => consolePlayback.Add($"Output: {message}"))
.Returns(Task.CompletedTask)
.Verifiable();
Assert.IsFalse(await wizard.CheckRunWizard(default).ConfigureAwait(false));
//first real run
@@ -9,7 +9,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
<PackageReference Include="Moq" Version="4.13.1" />
<PackageReference Include="MSTest.TestAdapter" Version="2.0.0" />
<PackageReference Include="MSTest.TestFramework" Version="2.0.0" />
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>
@@ -15,7 +15,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
<PackageReference Include="Moq" Version="4.13.1" />
<PackageReference Include="MSTest.TestAdapter" Version="2.0.0" />
<PackageReference Include="MSTest.TestFramework" Version="2.0.0" />
@@ -117,7 +117,7 @@ namespace Tgstation.Server.Tests
}
catch (ServiceUnavailableException)
{
//migrating, to be expected
// migrating, to be expected
if (DateTimeOffset.Now > giveUpAt)
throw;
await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken);
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>
@@ -9,7 +9,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
<PackageReference Include="MSTest.TestAdapter" Version="2.0.0" />
<PackageReference Include="MSTest.TestFramework" Version="2.0.0" />
</ItemGroup>