Merge branch 'master' into URLChangeDoc

This commit is contained in:
Jordan Brown
2018-09-10 10:12:21 -04:00
committed by GitHub
9 changed files with 70 additions and 71 deletions
@@ -21,7 +21,7 @@ namespace Tgstation.Server.Host.Components.Byond
/// <summary>
/// Directory to byond installation configuration
/// </summary>
const string ByondConfigDir = "byond/config";
const string ByondConfigDir = "byond/cfg";
/// <summary>
/// BYOND's DreamDaemon config file
/// </summary>
@@ -84,6 +84,11 @@ namespace Tgstation.Server.Host.Components
/// </summary>
readonly IPostWriteHandler postWriteHandler;
/// <summary>
/// The <see cref="IWatchdogFactory"/> for the <see cref="InstanceFactory"/>
/// </summary>
readonly IWatchdogFactory watchdogFactory;
/// <summary>
/// Construct an <see cref="InstanceFactory"/>
/// </summary>
@@ -100,7 +105,8 @@ namespace Tgstation.Server.Host.Components
/// <param name="providerFactory">The value of <see cref="providerFactory"/></param>
/// <param name="processExecutor">The value of <see cref="processExecutor"/></param>
/// <param name="postWriteHandler">The value of <see cref="postWriteHandler"/></param>
public InstanceFactory(IIOManager ioManager, IDatabaseContextFactory databaseContextFactory, IApplication application, ILoggerFactory loggerFactory, IByondTopicSender byondTopicSender, IServerControl serverUpdater, ICryptographySuite cryptographySuite, ISynchronousIOManager synchronousIOManager, ISymlinkFactory symlinkFactory, IByondInstaller byondInstaller, IProviderFactory providerFactory, IProcessExecutor processExecutor, IPostWriteHandler postWriteHandler)
/// <param name="watchdogFactory">The value of <see cref="watchdogFactory"/></param>
public InstanceFactory(IIOManager ioManager, IDatabaseContextFactory databaseContextFactory, IApplication application, ILoggerFactory loggerFactory, IByondTopicSender byondTopicSender, IServerControl serverUpdater, ICryptographySuite cryptographySuite, ISynchronousIOManager synchronousIOManager, ISymlinkFactory symlinkFactory, IByondInstaller byondInstaller, IProviderFactory providerFactory, IProcessExecutor processExecutor, IPostWriteHandler postWriteHandler, IWatchdogFactory watchdogFactory)
{
this.ioManager = ioManager ?? throw new ArgumentNullException(nameof(ioManager));
this.databaseContextFactory = databaseContextFactory ?? throw new ArgumentNullException(nameof(databaseContextFactory));
@@ -115,6 +121,7 @@ namespace Tgstation.Server.Host.Components
this.providerFactory = providerFactory ?? throw new ArgumentNullException(nameof(providerFactory));
this.processExecutor = processExecutor ?? throw new ArgumentNullException(nameof(processExecutor));
this.postWriteHandler = postWriteHandler ?? throw new ArgumentNullException(nameof(postWriteHandler));
this.watchdogFactory = watchdogFactory ?? throw new ArgumentNullException(nameof(watchdogFactory));
}
/// <inheritdoc />
@@ -148,8 +155,7 @@ namespace Tgstation.Server.Host.Components
{
var sessionControllerFactory = new SessionControllerFactory(processExecutor, byond, byondTopicSender, cryptographySuite, application, gameIoManager, chat, loggerFactory, metadata.CloneMetadata());
var reattachInfoHandler = new ReattachInfoHandler(databaseContextFactory, dmbFactory, loggerFactory.CreateLogger<ReattachInfoHandler>(), metadata.CloneMetadata());
var watchdogFactory = new WatchdogFactory(chat, sessionControllerFactory, serverUpdater, loggerFactory, reattachInfoHandler, databaseContextFactory, byondTopicSender, eventConsumer, metadata.CloneMetadata());
var watchdog = watchdogFactory.CreateWatchdog(dmbFactory, metadata.DreamDaemonSettings);
var watchdog = watchdogFactory.CreateWatchdog(chat, dmbFactory, reattachInfoHandler, configuration, sessionControllerFactory, metadata.CloneMetadata(), metadata.DreamDaemonSettings);
eventConsumer.SetWatchdog(watchdog);
commandFactory.SetWatchdog(watchdog);
try
@@ -1,4 +1,5 @@
using Tgstation.Server.Api.Models.Internal;
using Tgstation.Server.Host.Components.Chat;
using Tgstation.Server.Host.Components.Compiler;
namespace Tgstation.Server.Host.Components.Watchdog
@@ -11,9 +12,14 @@ namespace Tgstation.Server.Host.Components.Watchdog
/// <summary>
/// Creates a <see cref="IWatchdog"/>
/// </summary>
/// <param name="chat">The <see cref="IChat"/> for the <see cref="IWatchdog"/></param>
/// <param name="dmbFactory">The <see cref="IDmbFactory"/> for the <see cref="IWatchdog"/> with</param>
/// <param name="reattachInfoHandler">The <see cref="IReattachInfoHandler"/> for the <see cref="IWatchdog"/></param>
/// <param name="eventConsumer">The <see cref="IEventConsumer"/> for the <see cref="IWatchdog"/></param>
/// <param name="sessionControllerFactory">The <see cref="ISessionControllerFactory"/> for the <see cref="IWatchdog"/></param>
/// <param name="instance">The <see cref="Instance"/> for the <see cref="IWatchdog"/></param>
/// <param name="settings">The initial <see cref="DreamDaemonSettings"/> for the <see cref="IWatchdog"/></param>
/// <returns>A new <see cref="IWatchdog"/></returns>
IWatchdog CreateWatchdog(IDmbFactory dmbFactory, DreamDaemonSettings settings);
IWatchdog CreateWatchdog(IChat chat, IDmbFactory dmbFactory, IReattachInfoHandler reattachInfoHandler, IEventConsumer eventConsumer, ISessionControllerFactory sessionControllerFactory, Api.Models.Instance instance, DreamDaemonSettings settings);
}
}
@@ -10,6 +10,7 @@ using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Tgstation.Server.Api.Models.Internal;
using Tgstation.Server.Api.Rights;
using Tgstation.Server.Host.Components.Chat;
using Tgstation.Server.Host.Components.Compiler;
using Tgstation.Server.Host.Components.Interop;
@@ -86,6 +87,11 @@ namespace Tgstation.Server.Host.Components.Watchdog
/// </summary>
readonly IEventConsumer eventConsumer;
/// <summary>
/// The <see cref="IJobManager"/> for the <see cref="Watchdog"/>
/// </summary>
readonly IJobManager jobManager;
/// <summary>
/// The <see cref="SemaphoreSlim"/> for the <see cref="Watchdog"/>
/// </summary>
@@ -141,11 +147,12 @@ namespace Tgstation.Server.Host.Components.Watchdog
/// <param name="reattachInfoHandler">The value of <see cref="reattachInfoHandler"/></param>
/// <param name="databaseContextFactory">The value of <see cref="databaseContextFactory"/></param>
/// <param name="byondTopicSender">The value of <see cref="byondTopicSender"/></param>
/// <param name="eventConsumer">The value of <see cref="eventConsumer"/></param>
/// <param name="jobManager">The value of <see cref="jobManager"/></param>
/// <param name="initialLaunchParameters">The initial value of <see cref="ActiveLaunchParameters"/></param>
/// <param name="instance">The value of <see cref="instance"/></param>
/// <param name="autoStart">The value of <see cref="autoStart"/></param>
/// <param name="eventConsumer">The value of <see cref="eventConsumer"/></param>
public Watchdog(IChat chat, ISessionControllerFactory sessionControllerFactory, IDmbFactory dmbFactory, IServerControl serverUpdater, ILogger<Watchdog> logger, IReattachInfoHandler reattachInfoHandler, IDatabaseContextFactory databaseContextFactory, IByondTopicSender byondTopicSender, IEventConsumer eventConsumer, DreamDaemonLaunchParameters initialLaunchParameters, Api.Models.Instance instance, bool autoStart)
public Watchdog(IChat chat, ISessionControllerFactory sessionControllerFactory, IDmbFactory dmbFactory, IServerControl serverUpdater, ILogger<Watchdog> logger, IReattachInfoHandler reattachInfoHandler, IDatabaseContextFactory databaseContextFactory, IByondTopicSender byondTopicSender, IEventConsumer eventConsumer, IJobManager jobManager, DreamDaemonLaunchParameters initialLaunchParameters, Api.Models.Instance instance, bool autoStart)
{
this.chat = chat ?? throw new ArgumentNullException(nameof(chat));
this.sessionControllerFactory = sessionControllerFactory ?? throw new ArgumentNullException(nameof(sessionControllerFactory));
@@ -155,6 +162,7 @@ namespace Tgstation.Server.Host.Components.Watchdog
this.databaseContextFactory = databaseContextFactory ?? throw new ArgumentNullException(nameof(databaseContextFactory));
this.byondTopicSender = byondTopicSender ?? throw new ArgumentNullException(nameof(byondTopicSender));
this.eventConsumer = eventConsumer ?? throw new ArgumentNullException(nameof(eventConsumer));
this.jobManager = jobManager ?? throw new ArgumentNullException(nameof(jobManager));
this.instance = instance ?? throw new ArgumentNullException(nameof(instance));
this.autoStart = autoStart;
@@ -642,7 +650,7 @@ namespace Tgstation.Server.Host.Components.Watchdog
throw new InvalidOperationException("Entered LaunchNoLock with one or more of the servers not being null!");
var reattachInfo = doReattach ? await reattachInfoHandler.Load(cancellationToken).ConfigureAwait(false) : null;
var doesntNeedNewDmb = doReattach && reattachInfo.Alpha != null && reattachInfo.Bravo != null;
var doesntNeedNewDmb = doReattach && reattachInfo?.Alpha != null && reattachInfo?.Bravo != null;
var dmbToUse = doesntNeedNewDmb ? null : dmbFactory.LockNextDmb(2);
try
@@ -697,7 +705,7 @@ namespace Tgstation.Server.Host.Components.Watchdog
cancellationToken.ThrowIfCancellationRequested();
//both servers are now running, alpha is the active server, huzzah
AlphaIsActive = doReattach ? reattachInfo.AlphaIsActive : true;
AlphaIsActive = doReattach ? reattachInfo?.AlphaIsActive ?? true : true;
LastLaunchResult = alphaLrt.Result;
logger.LogInformation("Launched servers successfully");
Running = true;
@@ -789,8 +797,24 @@ namespace Tgstation.Server.Host.Components.Watchdog
/// <inheritdoc />
public async Task StartAsync(CancellationToken cancellationToken)
{
if (autoStart)
await LaunchNoLock(true, true, true, cancellationToken).ConfigureAwait(false);
if (!autoStart)
return;
var job = new Models.Job
{
StartedBy = new Models.User
{
Id = 1 //just use admin for this cause whatever
},
Instance = new Models.Instance
{
Id = instance.Id
},
Description = "Instance startup watchdog launch",
CancelRight = (ulong)DreamDaemonRights.Shutdown,
CancelRightsType = RightsType.DreamDaemon
};
await jobManager.RegisterOperation(job, (j, serviceProvider, progressFunction, ct) => Launch(ct), cancellationToken).ConfigureAwait(false);
}
/// <inheritdoc />
@@ -11,16 +11,6 @@ namespace Tgstation.Server.Host.Components.Watchdog
/// <inheritdoc />
sealed class WatchdogFactory : IWatchdogFactory
{
/// <summary>
/// The <see cref="IChat"/> for the <see cref="WatchdogFactory"/>
/// </summary>
readonly IChat chat;
/// <summary>
/// The <see cref="ISessionControllerFactory"/> for the <see cref="WatchdogFactory"/>
/// </summary>
readonly ISessionControllerFactory sessionControllerFactory;
/// <summary>
/// The <see cref="IServerControl"/> for the <see cref="WatchdogFactory"/>
/// </summary>
@@ -31,11 +21,6 @@ namespace Tgstation.Server.Host.Components.Watchdog
/// </summary>
readonly ILoggerFactory loggerFactory;
/// <summary>
/// The <see cref="IReattachInfoHandler"/> for the <see cref="WatchdogFactory"/>
/// </summary>
readonly IReattachInfoHandler reattachInfoHandler;
/// <summary>
/// The <see cref="IDatabaseContextFactory"/> for the <see cref="WatchdogFactory"/>
/// </summary>
@@ -47,42 +32,28 @@ namespace Tgstation.Server.Host.Components.Watchdog
readonly IByondTopicSender byondTopicSender;
/// <summary>
/// The <see cref="IEventConsumer"/> for the <see cref="WatchdogFactory"/>
/// The <see cref="IJobManager"/> for the <see cref="WatchdogFactory"/>
/// </summary>
readonly IEventConsumer eventConsumer;
/// <summary>
/// The <see cref="Api.Models.Instance"/> for the <see cref="WatchdogFactory"/>
/// </summary>
readonly Api.Models.Instance instance;
readonly IJobManager jobManager;
/// <summary>
/// Construct a <see cref="WatchdogFactory"/>
/// </summary>
/// <param name="chat">The value of <see cref="chat"/></param>
/// <param name="sessionControllerFactory">The value of <see cref="sessionControllerFactory"/></param>
/// <param name="serverUpdater">The value of <see cref="serverUpdater"/></param>
/// <param name="loggerFactory">The value of <see cref="loggerFactory"/></param>
/// <param name="reattachInfoHandler">The value of <see cref="reattachInfoHandler"/></param>
/// <param name="databaseContextFactory">The value of <see cref="databaseContextFactory"/></param>
/// <param name="byondTopicSender">The value of <see cref="byondTopicSender"/></param>
/// <param name="eventConsumer">The value of <see cref="eventConsumer"/></param>
/// <param name="instance">The value of <see cref="instance"/></param>
public WatchdogFactory(IChat chat, ISessionControllerFactory sessionControllerFactory, IServerControl serverUpdater, ILoggerFactory loggerFactory, IReattachInfoHandler reattachInfoHandler, IDatabaseContextFactory databaseContextFactory, IByondTopicSender byondTopicSender, IEventConsumer eventConsumer, Api.Models.Instance instance)
/// <param name="jobManager">The value of <see cref="jobManager"/></param>
public WatchdogFactory(IServerControl serverUpdater, ILoggerFactory loggerFactory, IDatabaseContextFactory databaseContextFactory, IByondTopicSender byondTopicSender, IJobManager jobManager)
{
this.chat = chat ?? throw new ArgumentNullException(nameof(chat));
this.sessionControllerFactory = sessionControllerFactory ?? throw new ArgumentNullException(nameof(sessionControllerFactory));
this.serverUpdater = serverUpdater ?? throw new ArgumentNullException(nameof(serverUpdater));
this.loggerFactory = loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory));
this.reattachInfoHandler = reattachInfoHandler ?? throw new ArgumentNullException(nameof(reattachInfoHandler));
this.databaseContextFactory = databaseContextFactory ?? throw new ArgumentNullException(nameof(databaseContextFactory));
this.byondTopicSender = byondTopicSender ?? throw new ArgumentNullException(nameof(byondTopicSender));
this.eventConsumer = eventConsumer ?? throw new ArgumentNullException(nameof(eventConsumer));
this.instance = instance ?? throw new ArgumentNullException(nameof(instance));
this.jobManager = jobManager ?? throw new ArgumentNullException(nameof(jobManager));
}
/// <inheritdoc />
public IWatchdog CreateWatchdog(IDmbFactory dmbFactory, DreamDaemonSettings settings) => new Watchdog(chat, sessionControllerFactory, dmbFactory, serverUpdater, loggerFactory.CreateLogger<Watchdog>(), reattachInfoHandler, databaseContextFactory, byondTopicSender, eventConsumer, settings, instance, settings.AutoStart.Value);
public IWatchdog CreateWatchdog(IChat chat, IDmbFactory dmbFactory, IReattachInfoHandler reattachInfoHandler, IEventConsumer eventConsumer, ISessionControllerFactory sessionControllerFactory, Api.Models.Instance instance, DreamDaemonSettings settings) => new Watchdog(chat, sessionControllerFactory, dmbFactory, serverUpdater, loggerFactory.CreateLogger<Watchdog>(), reattachInfoHandler, databaseContextFactory, byondTopicSender, eventConsumer, jobManager, settings, instance, settings.AutoStart.Value);
}
}
@@ -71,7 +71,7 @@ namespace Tgstation.Server.Host.Controllers
{
var result = await instance.Watchdog.Launch(innerCt).ConfigureAwait(false);
if (result == null)
throw new InvalidOperationException("Watchdog already running!");
throw new JobException("Watchdog already running!");
},
cancellationToken).ConfigureAwait(false);
return Accepted(job.ToApi());
@@ -287,6 +287,12 @@ namespace Tgstation.Server.Host.Controllers
if (model.NewTestMerges?.Any(x => model.NewTestMerges.Any(y => x != y && x.Number == y.Number)) == true)
return BadRequest(new ErrorMessage { Message = "Cannot test merge the same PR twice in one job!" });
if (model.CommitterName?.Length == 0)
return BadRequest(new ErrorMessage { Message = "Cannot set empty committer name!" });
if (model.CommitterEmail?.Length == 0)
return BadRequest(new ErrorMessage { Message = "Cannot set empty committer e=mail!" });
var newTestMerges = model.NewTestMerges != null && model.NewTestMerges.Count > 0;
var userRights = (RepositoryRights)AuthenticationContext.GetRight(RightsType.Repository);
if (newTestMerges && !userRights.HasFlag(RepositoryRights.MergePullRequest))
+10 -4
View File
@@ -3,13 +3,13 @@ using Cyberboss.AspNetCore.AsyncInitializer;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Hosting.Server.Features;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Primitives;
using Microsoft.IdentityModel.Tokens;
using Newtonsoft.Json;
using System;
@@ -22,6 +22,7 @@ using Tgstation.Server.Host.Components;
using Tgstation.Server.Host.Components.Byond;
using Tgstation.Server.Host.Components.Chat;
using Tgstation.Server.Host.Components.StaticFiles;
using Tgstation.Server.Host.Components.Watchdog;
using Tgstation.Server.Host.Configuration;
using Tgstation.Server.Host.Controllers;
using Tgstation.Server.Host.IO;
@@ -200,8 +201,9 @@ namespace Tgstation.Server.Host.Core
SendTimeout = 5000
});
services.AddSingleton<InstanceFactory>();
services.AddSingleton<IInstanceFactory>(x => x.GetRequiredService<InstanceFactory>());
services.AddSingleton<IWatchdogFactory, WatchdogFactory>();
services.AddSingleton<IInstanceFactory, InstanceFactory>();
services.AddSingleton<InstanceManager>();
services.AddSingleton<IInstanceManager>(x => x.GetRequiredService<InstanceManager>());
services.AddSingleton<IHostedService>(x => x.GetRequiredService<InstanceManager>());
@@ -221,7 +223,8 @@ namespace Tgstation.Server.Host.Core
/// </summary>
/// <param name="applicationBuilder">The <see cref="IApplicationBuilder"/> to configure</param>
/// <param name="logger">The <see cref="ILogger"/> for the <see cref="Application"/></param>
public void Configure(IApplicationBuilder applicationBuilder, ILogger<Application> logger)
/// <param name="serverControl">The <see cref="IServerControl"/> for the application</param>
public void Configure(IApplicationBuilder applicationBuilder, ILogger<Application> logger, IServerControl serverControl)
{
if (applicationBuilder == null)
throw new ArgumentNullException(nameof(applicationBuilder));
@@ -229,6 +232,9 @@ namespace Tgstation.Server.Host.Core
throw new ArgumentNullException(nameof(logger));
logger.LogInformation(VersionString);
//attempt to restart the server if the configuration changes
ChangeToken.OnChange(configuration.GetReloadToken, () => serverControl.Restart());
applicationBuilder.UseDeveloperExceptionPage(); //it is not worth it to limit this, you should only ever get it if you're an authorized user
@@ -1,20 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
<IsPackable>false</IsPackable>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.7.0" />
<PackageReference Include="MSTest.TestAdapter" Version="1.2.0" />
<PackageReference Include="MSTest.TestFramework" Version="1.2.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Tgstation.Server.CommandLine\Tgstation.Server.CommandLine.csproj" />
</ItemGroup>
</Project>