diff --git a/src/Tgstation.Server.Api/Models/DreamDaemon.cs b/src/Tgstation.Server.Api/Models/DreamDaemon.cs
index 4a332b36dd..3ca0f22d87 100644
--- a/src/Tgstation.Server.Api/Models/DreamDaemon.cs
+++ b/src/Tgstation.Server.Api/Models/DreamDaemon.cs
@@ -9,10 +9,16 @@ namespace Tgstation.Server.Api.Models
public sealed class DreamDaemon : DreamDaemonSettings
{
///
- /// When the live revision was compiled
+ /// The live revision
///
[Permissions(DenyWrite = true, ReadRight = DreamDaemonRights.ReadRevision)]
- public CompileJob CompileJob { get; set; }
+ public CompileJob ActiveCompileJob { get; set; }
+
+ ///
+ /// The next revision to go live
+ ///
+ [Permissions(DenyWrite = true, ReadRight = DreamDaemonRights.ReadRevision)]
+ public CompileJob StagedCompileJob { get; set; }
///
/// The current status of
@@ -31,5 +37,11 @@ namespace Tgstation.Server.Api.Models
///
[Permissions(DenyWrite = true, ReadRight = DreamDaemonRights.ReadMetadata)]
public ushort? CurrentPort { get; set; }
+
+ ///
+ /// The webclient status the running instance is set to
+ ///
+ [Permissions(DenyWrite = true, ReadRight = DreamDaemonRights.ReadMetadata)]
+ public bool? CurrentAllowWebclient { get; set; }
}
}
diff --git a/src/Tgstation.Server.Host/Components/DreamDaemon.cs b/src/Tgstation.Server.Host/Components/DreamDaemon.cs
deleted file mode 100644
index f699150079..0000000000
--- a/src/Tgstation.Server.Host/Components/DreamDaemon.cs
+++ /dev/null
@@ -1,216 +0,0 @@
-using System;
-using System.Threading;
-using System.Threading.Tasks;
-using Tgstation.Server.Api.Models;
-using Tgstation.Server.Api.Models.Internal;
-
-namespace Tgstation.Server.Host.Components
-{
- ///
- sealed class DreamDaemon : IDreamDaemon, ILaunchParametersFactory, IDisposable
- {
- ///
- public bool Running { get; private set; }
-
- ///
- public ushort? CurrentPort { get; private set; }
-
- ///
- public string AccessToken { get; private set; }
-
- ///
- public DreamDaemonSecurity? CurrentSecurity { get; private set; }
-
- ///
- public bool SoftRebooting { get; private set; }
-
- ///
- public bool SoftStopping { get; private set; }
-
- ///
- public DreamDaemonLaunchParameters LastLaunchParameters { get; private set; }
-
- ///
- public Host.Models.CompileJob LastCompileJob => watchdog.CurrentCompileJob;
-
- ///
- /// The for
- ///
- readonly IEventConsumer eventConsumer;
- ///
- /// The for
- ///
- readonly IInterop interop;
- ///
- /// The for
- ///
- readonly IWatchdog watchdog;
-
- ///
- /// Used for write control to class variables
- ///
- readonly SemaphoreSlim semaphore;
-
- ///
- /// If should start DD
- ///
- readonly bool autoStart;
-
- ///
- /// The current
- ///
- DreamDaemonLaunchParameters currentLaunchParameters;
-
- ///
- /// Construct
- ///
- /// The value of
- /// The value of
- /// The value of
- /// The initial value of and
- public DreamDaemon(IEventConsumer eventConsumer, IInterop interop, IWatchdog watchdog, DreamDaemonSettings initialSettings)
- {
- this.eventConsumer = eventConsumer ?? throw new ArgumentNullException(nameof(eventConsumer));
- this.interop = interop ?? throw new ArgumentNullException(nameof(interop));
- this.watchdog = watchdog ?? throw new ArgumentNullException(nameof(watchdog));
- currentLaunchParameters = initialSettings ?? throw new ArgumentNullException(nameof(initialSettings));
-
- autoStart = initialSettings.AutoStart.Value;
-
- semaphore = new SemaphoreSlim(1);
- }
-
- ///
- public void Dispose() => semaphore.Dispose();
-
- ///
- public async Task CancelGracefulActions(CancellationToken cancellationToken)
- {
- await semaphore.WaitAsync(cancellationToken).ConfigureAwait(false);
- try
- {
- SoftRebooting = false;
- SoftStopping = false;
- }
- finally
- {
- semaphore.Release();
- }
- }
-
- ///
- public async Task ChangeSettings(DreamDaemonLaunchParameters launchParameters, CancellationToken cancellationToken)
- {
- if (launchParameters == null)
- throw new ArgumentNullException(nameof(launchParameters));
- Task launchTask;
- await semaphore.WaitAsync(cancellationToken).ConfigureAwait(false);
- try
- {
- currentLaunchParameters = launchParameters;
- if (!Running)
- launchTask = Launch(launchParameters, cancellationToken);
- else
- launchTask = Restart(true, cancellationToken);
- }
- finally
- {
- semaphore.Release();
- }
- await launchTask.ConfigureAwait(false);
- }
-
- ///
- public async Task Launch(DreamDaemonLaunchParameters launchParameters, CancellationToken cancellationToken)
- {
- if (launchParameters == null)
- throw new ArgumentNullException(nameof(launchParameters));
- await semaphore.WaitAsync(cancellationToken).ConfigureAwait(false);
- Task watchdogStartup;
- try
- {
- if (Running)
- throw new InvalidOperationException("DreamDaemon already running!");
- Running = true;
- await eventConsumer.HandleEvent(EventType.DDLaunched, null, cancellationToken).ConfigureAwait(false);
- watchdogStartup = watchdog.Start(this, cancellationToken);
- }
- finally
- {
- semaphore.Release();
- }
- //important to leave the lock so the watchdog can enter it
- await watchdogStartup.ConfigureAwait(false);
- }
-
- ///
- public async Task Restart(bool graceful, CancellationToken cancellationToken)
- {
- await semaphore.WaitAsync(cancellationToken).ConfigureAwait(false);
- try
- {
- if (graceful)
- {
- if (!Running)
- throw new InvalidOperationException("DreamDaemon not running!");
- if (SoftStopping)
- throw new InvalidOperationException("DreamDaemon has a graceful stop queued!");
- SoftRebooting = true;
- return;
- }
- await eventConsumer.HandleEvent(EventType.DDRestart, null, cancellationToken).ConfigureAwait(false);
- if (Running)
- await watchdog.Stop().ConfigureAwait(false);
- await Launch(currentLaunchParameters, cancellationToken).ConfigureAwait(false);
- }
- finally
- {
- semaphore.Release();
- }
- }
-
- ///
- public Task StartAsync(CancellationToken cancellationToken) => autoStart ? Launch(currentLaunchParameters, cancellationToken) : Task.CompletedTask;
-
- ///
- public Task StopAsync(CancellationToken cancellationToken) => Terminate(false, cancellationToken);
-
- ///
- public async Task Terminate(bool graceful, CancellationToken cancellationToken)
- {
- await semaphore.WaitAsync(cancellationToken).ConfigureAwait(false);
- try
- {
- if (graceful)
- {
- if (!Running)
- throw new InvalidOperationException("DreamDaemon not running!");
- SoftRebooting = false;
- SoftStopping = true;
- return;
- }
- await eventConsumer.HandleEvent(EventType.DDTerminated, null, cancellationToken).ConfigureAwait(false);
- await watchdog.Stop().ConfigureAwait(false);
- }
- finally
- {
- semaphore.Release();
- }
- }
-
- ///
- public async Task GetLaunchParameters(CancellationToken cancellationToken)
- {
- await semaphore.WaitAsync(cancellationToken).ConfigureAwait(false);
- try
- {
- LastLaunchParameters = currentLaunchParameters;
- return currentLaunchParameters;
- }
- finally
- {
- semaphore.Release();
- }
- }
- }
-}
diff --git a/src/Tgstation.Server.Host/Components/IDreamDaemon.cs b/src/Tgstation.Server.Host/Components/IDreamDaemon.cs
deleted file mode 100644
index e435a3af69..0000000000
--- a/src/Tgstation.Server.Host/Components/IDreamDaemon.cs
+++ /dev/null
@@ -1,93 +0,0 @@
-using Microsoft.Extensions.Hosting;
-using System.Threading;
-using System.Threading.Tasks;
-using Tgstation.Server.Api.Models;
-using Tgstation.Server.Api.Models.Internal;
-
-namespace Tgstation.Server.Host.Components
-{
- ///
- /// For managing DreamDaemon
- ///
- public interface IDreamDaemon : IHostedService
- {
- ///
- /// If DreamDaemon is running
- ///
- bool Running { get; }
-
- ///
- /// If DreamDaemon is going to soft reboot
- ///
- bool SoftRebooting { get; }
-
- ///
- /// If DreamDaemon is going to soft stop
- ///
- bool SoftStopping { get; }
-
- ///
- /// The port DreamDaemon is currently running on
- ///
- ushort? CurrentPort { get; }
-
- ///
- /// The current of
- ///
- DreamDaemonSecurity? CurrentSecurity { get; }
-
- ///
- /// The access token used for communication with the DMAPI
- ///
- string AccessToken { get; }
-
- ///
- /// The most recently used
- ///
- DreamDaemonLaunchParameters LastLaunchParameters { get; }
-
- ///
- /// The most recently used
- ///
- Host.Models.CompileJob LastCompileJob { get; }
-
- ///
- /// Launch DreamDaemon
- ///
- /// The for the launch
- /// The for the operation
- /// A representing the running operation
- Task Launch(DreamDaemonLaunchParameters launchParameters, CancellationToken cancellationToken);
-
- ///
- /// Changes the if currently . Triggers a graceful restart
- ///
- /// The new
- /// The for the operation
- /// A representing the running operation
- Task ChangeSettings(DreamDaemonLaunchParameters launchParameters, CancellationToken cancellationToken);
-
- ///
- /// Restarts DreamDaemon
- ///
- /// If the restart will be delayed until a reboot is detected in the DMAPI and this function will retrun immediately. If the DMAPI isn't installed, this parameter is ignored
- /// The for the operation
- /// A representing the running operation
- Task Restart(bool graceful, CancellationToken cancellationToken);
-
- ///
- /// Terminates DreamDaemon
- ///
- /// If the termination will be delayed until a reboot is detected in the DMAPI and this function will return immediately. If the DMAPI isn't installed, this parameter is ignored
- /// The for the operation
- /// A representing the running operation
- Task Terminate(bool graceful, CancellationToken cancellationToken);
-
- ///
- /// Cancels any pending graceful reboots or terminations
- ///
- /// The for the operation
- /// A representing the running operation
- Task CancelGracefulActions(CancellationToken cancellationToken);
- }
-}
\ No newline at end of file
diff --git a/src/Tgstation.Server.Host/Components/IInstance.cs b/src/Tgstation.Server.Host/Components/IInstance.cs
index a06c30c3a3..faa3c99de7 100644
--- a/src/Tgstation.Server.Host/Components/IInstance.cs
+++ b/src/Tgstation.Server.Host/Components/IInstance.cs
@@ -1,5 +1,6 @@
using Microsoft.Extensions.Hosting;
using System.Threading.Tasks;
+using Tgstation.Server.Host.Components.Watchdog;
namespace Tgstation.Server.Host.Components
{
@@ -24,9 +25,9 @@ namespace Tgstation.Server.Host.Components
IDreamMaker DreamMaker { get; }
///
- /// The for the
+ /// The for the
///
- IDreamDaemon DreamDaemon { get; }
+ IWatchdog Watchdog { get; }
///
/// The for the
diff --git a/src/Tgstation.Server.Host/Components/ILaunchParametersFactory.cs b/src/Tgstation.Server.Host/Components/ILaunchParametersFactory.cs
deleted file mode 100644
index ee2a67ec21..0000000000
--- a/src/Tgstation.Server.Host/Components/ILaunchParametersFactory.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-using System.Threading;
-using System.Threading.Tasks;
-using Tgstation.Server.Api.Models.Internal;
-
-namespace Tgstation.Server.Host.Components
-{
- ///
- /// For retrieving current
- ///
- interface ILaunchParametersFactory
- {
- ///
- /// Get the latest
- ///
- /// The for the operation
- /// A resulting in the latest
- Task GetLaunchParameters(CancellationToken cancellationToken);
- }
-}
diff --git a/src/Tgstation.Server.Host/Components/Instance.cs b/src/Tgstation.Server.Host/Components/Instance.cs
index aea3891519..04554e81ec 100644
--- a/src/Tgstation.Server.Host/Components/Instance.cs
+++ b/src/Tgstation.Server.Host/Components/Instance.cs
@@ -3,6 +3,7 @@ using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
+using Tgstation.Server.Host.Components.Watchdog;
using Tgstation.Server.Host.Core;
namespace Tgstation.Server.Host.Components
@@ -20,7 +21,7 @@ namespace Tgstation.Server.Host.Components
public IDreamMaker DreamMaker { get; }
///
- public IDreamDaemon DreamDaemon { get; }
+ public IWatchdog Watchdog { get; }
///
public IChat Chat { get; }
@@ -52,13 +53,13 @@ namespace Tgstation.Server.Host.Components
///
CancellationTokenSource timerCts;
- public Instance(Api.Models.Instance metadata, IRepositoryManager repositoryManager, IByond byond, IDreamMaker dreamMaker, IDreamDaemon dreamDaemon, IChat chat, IConfiguration configuration, ICompileJobConsumer compileJobConsumer, IDatabaseContextFactory databaseContextFactory)
+ public Instance(Api.Models.Instance metadata, IRepositoryManager repositoryManager, IByond byond, IDreamMaker dreamMaker, IWatchdog watchdog, IChat chat, IConfiguration configuration, ICompileJobConsumer compileJobConsumer, IDatabaseContextFactory databaseContextFactory)
{
this.metadata = metadata ?? throw new ArgumentNullException(nameof(metadata));
RepositoryManager = repositoryManager ?? throw new ArgumentNullException(nameof(repositoryManager));
Byond = byond ?? throw new ArgumentNullException(nameof(byond));
DreamMaker = dreamMaker ?? throw new ArgumentNullException(nameof(dreamMaker));
- DreamDaemon = dreamDaemon ?? throw new ArgumentNullException(nameof(dreamDaemon));
+ watchdog = watchdog ?? throw new ArgumentNullException(nameof(watchdog));
Chat = chat ?? throw new ArgumentNullException(nameof(chat));
Configuration = configuration ?? throw new ArgumentNullException(nameof(configuration));
this.compileJobConsumer = compileJobConsumer ?? throw new ArgumentNullException(nameof(compileJobConsumer));
@@ -83,19 +84,22 @@ namespace Tgstation.Server.Host.Components
await Task.Delay(new TimeSpan(0, minutes, 0), cancellationToken).ConfigureAwait(false);
string accessToken = null, projectName = null;
+ int timeout = 0;
var dbTask = databaseContextFactory.UseContext(async (db) =>
{
var instanceQuery = db.Instances.Where(x => x.Id == metadata.Id);
+ var timeoutTask = instanceQuery.Select(x => x.DreamDaemonSettings.StartupTimeout).FirstAsync(cancellationToken);
var projectNameTask = instanceQuery.Select(x => x.DreamMakerSettings.ProjectName).FirstOrDefaultAsync(cancellationToken);
accessToken = await instanceQuery.Select(x => x.RepositorySettings.AccessToken).FirstOrDefaultAsync(cancellationToken).ConfigureAwait(false);
projectName = await projectNameTask.ConfigureAwait(false);
+ timeout = (await timeoutTask.ConfigureAwait(false)).Value;
});
using (var repo = await RepositoryManager.LoadRepository(cancellationToken).ConfigureAwait(false))
{
await dbTask.ConfigureAwait(false);
await repo.FetchOrigin(accessToken, cancellationToken).ConfigureAwait(false);
await repo.ResetToOrigin(cancellationToken).ConfigureAwait(false);
- await DreamMaker.Compile(projectName, repo, cancellationToken).ConfigureAwait(false);
+ await DreamMaker.Compile(projectName, timeout, repo, cancellationToken).ConfigureAwait(false);
}
}
}
@@ -114,10 +118,10 @@ namespace Tgstation.Server.Host.Components
}
///
- public Task StartAsync(CancellationToken cancellationToken) => Task.WhenAll(SetAutoUpdateInterval(metadata.AutoUpdateInterval), DreamDaemon.StartAsync(cancellationToken), Chat.StartAsync(cancellationToken), compileJobConsumer.StartAsync(cancellationToken));
+ public Task StartAsync(CancellationToken cancellationToken) => Task.WhenAll(SetAutoUpdateInterval(metadata.AutoUpdateInterval), Watchdog.StartAsync(cancellationToken), Chat.StartAsync(cancellationToken), compileJobConsumer.StartAsync(cancellationToken));
///
- public Task StopAsync(CancellationToken cancellationToken) => Task.WhenAll(SetAutoUpdateInterval(null), DreamDaemon.StopAsync(cancellationToken), Chat.StopAsync(cancellationToken), compileJobConsumer.StopAsync(cancellationToken));
+ public Task StopAsync(CancellationToken cancellationToken) => Task.WhenAll(SetAutoUpdateInterval(null), Watchdog.StopAsync(cancellationToken), Chat.StopAsync(cancellationToken), compileJobConsumer.StopAsync(cancellationToken));
///
public async Task SetAutoUpdateInterval(int? newInterval)
diff --git a/src/Tgstation.Server.Host/Components/Watchdog/IWatchdog.cs b/src/Tgstation.Server.Host/Components/Watchdog/IWatchdog.cs
index 18e6ef8dda..b7ee4ce2fd 100644
--- a/src/Tgstation.Server.Host/Components/Watchdog/IWatchdog.cs
+++ b/src/Tgstation.Server.Host/Components/Watchdog/IWatchdog.cs
@@ -1,14 +1,82 @@
-using System;
+using Microsoft.Extensions.Hosting;
+using System;
using System.Threading;
using System.Threading.Tasks;
using Tgstation.Server.Api.Models.Internal;
namespace Tgstation.Server.Host.Components.Watchdog
{
- interface IWatchdog : IDisposable
+ public interface IWatchdog : IHostedService, IDisposable
{
- DreamDaemonLaunchParameters LaunchParameters { get; set; }
+ ///
+ /// If the watchdog is running
+ ///
+ bool Running { get; }
+ ///
+ /// If the alpha server is the active server
+ ///
+ bool AlphaIsActive { get; }
+
+ ///
+ /// The latest of the twin servers
+ ///
+ LaunchResult LastLaunchResult { get; }
+
+ ///
+ /// The that is currently live
+ ///
+ Models.CompileJob LiveCompileJob { get; }
+
+ ///
+ /// The that is staged to go live
+ ///
+ Models.CompileJob StagedCompileJob { get; }
+
+ ///
+ /// The the active server is using
+ ///
+ DreamDaemonLaunchParameters ActiveLaunchParameters { get; }
+
+ ///
+ /// The to be applied
+ ///
+ DreamDaemonLaunchParameters LastLaunchParameters { get; }
+
+ ///
+ /// The of the active server
+ ///
+ RebootState? RebootState { get; }
+
+ ///
+ /// Start the
+ ///
+ /// The for the operation
+ /// A resulting in the or if it was already running
Task Launch(CancellationToken cancellationToken);
+
+ ///
+ /// Changes the . If currently triggers a graceful restart
+ ///
+ /// The new
+ /// The for the operation
+ /// A representing the running operation
+ Task ChangeSettings(DreamDaemonLaunchParameters launchParameters, CancellationToken cancellationToken);
+
+ ///
+ /// Restarts the watchdog
+ ///
+ /// If the restart will be delayed until a reboot is detected in the active server's DMAPI and this function will retrun immediately
+ /// The for the operation
+ /// A resulting in the or if it was already running or is and is
+ Task Restart(bool graceful, CancellationToken cancellationToken);
+
+ ///
+ /// Stops the watchdog
+ ///
+ /// If the termination will be delayed until a reboot is detected in the active server's DMAPI and this function will return immediately
+ /// The for the operation
+ /// A representing the running operation
+ Task Terminate(bool graceful, CancellationToken cancellationToken);
}
}
diff --git a/src/Tgstation.Server.Host/Components/Watchdog/LaunchResult.cs b/src/Tgstation.Server.Host/Components/Watchdog/LaunchResult.cs
index 8f8ae755ab..016d9f57d0 100644
--- a/src/Tgstation.Server.Host/Components/Watchdog/LaunchResult.cs
+++ b/src/Tgstation.Server.Host/Components/Watchdog/LaunchResult.cs
@@ -5,7 +5,7 @@ namespace Tgstation.Server.Host.Components.Watchdog
///
/// Represents the result of trying to start a DD process
///
- sealed class LaunchResult
+ public sealed class LaunchResult
{
///
/// The time it took for to return
diff --git a/src/Tgstation.Server.Host/Components/Watchdog/RebootState.cs b/src/Tgstation.Server.Host/Components/Watchdog/RebootState.cs
index b1fc80317a..6890df7bab 100644
--- a/src/Tgstation.Server.Host/Components/Watchdog/RebootState.cs
+++ b/src/Tgstation.Server.Host/Components/Watchdog/RebootState.cs
@@ -3,7 +3,7 @@
///
/// Represents the action to take when /world/Reboot() is called
///
- enum RebootState : int
+ public enum RebootState : int
{
///
/// Run DreamDaemon's normal reboot process
diff --git a/src/Tgstation.Server.Host/Components/Watchdog/Watchdog.cs b/src/Tgstation.Server.Host/Components/Watchdog/Watchdog.cs
index 4152b8bfb4..856aa8a941 100644
--- a/src/Tgstation.Server.Host/Components/Watchdog/Watchdog.cs
+++ b/src/Tgstation.Server.Host/Components/Watchdog/Watchdog.cs
@@ -77,8 +77,5 @@ namespace Tgstation.Server.Host.Components.Watchdog
disposed = true;
}
}
-
- ///
- public Task Launch(CancellationToken cancellationToken) => throw new NotImplementedException();
}
}
diff --git a/src/Tgstation.Server.Host/Components/Watchdog/WatchdogLaunchResult.cs b/src/Tgstation.Server.Host/Components/Watchdog/WatchdogLaunchResult.cs
index 3eb27b555a..0532326e78 100644
--- a/src/Tgstation.Server.Host/Components/Watchdog/WatchdogLaunchResult.cs
+++ b/src/Tgstation.Server.Host/Components/Watchdog/WatchdogLaunchResult.cs
@@ -5,27 +5,16 @@ namespace Tgstation.Server.Host.Components.Watchdog
///
/// Launch results for a
///
- sealed class WatchdogLaunchResult
+ public sealed class WatchdogLaunchResult
{
- ///
- /// If the watchdog is running
- ///
- bool Running {
- get {
- if (Alpha == null || Bravo == null)
- throw new InvalidOperationException("Alpha or Bravo is null!");
- return !Alpha.ExitCode.HasValue && !Bravo.ExitCode.HasValue;
- }
- }
-
///
/// The for the alpha process
///
- LaunchResult Alpha { get; set; }
+ public LaunchResult Alpha { get; set; }
///
/// The for the bravo process
///
- LaunchResult Bravo { get; set; }
+ public LaunchResult Bravo { get; set; }
}
}
diff --git a/src/Tgstation.Server.Host/Controllers/DreamDaemonController.cs b/src/Tgstation.Server.Host/Controllers/DreamDaemonController.cs
index a4570e2ff7..356e52fb9d 100644
--- a/src/Tgstation.Server.Host/Controllers/DreamDaemonController.cs
+++ b/src/Tgstation.Server.Host/Controllers/DreamDaemonController.cs
@@ -8,9 +8,9 @@ using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using Tgstation.Server.Api.Models;
-using Tgstation.Server.Api.Models.Internal;
using Tgstation.Server.Api.Rights;
using Tgstation.Server.Host.Components;
+using Tgstation.Server.Host.Components.Watchdog;
using Tgstation.Server.Host.Core;
using Tgstation.Server.Host.Models;
using Tgstation.Server.Host.Security;
@@ -51,17 +51,9 @@ namespace Tgstation.Server.Host.Controllers
{
var instance = instanceManager.GetInstance(Instance);
- if (instance.DreamDaemon.Running)
+ if (instance.Watchdog.Running)
return StatusCode(HttpStatusCode.Gone);
- var launchParams = await DatabaseContext.Instances.Where(x => x.Id == Instance.Id).Select(x => new DreamDaemonLaunchParameters
- {
- AllowWebClient = x.DreamDaemonSettings.AllowWebClient,
- PrimaryPort = x.DreamDaemonSettings.PrimaryPort,
- SecondaryPort = x.DreamDaemonSettings.SecondaryPort,
- SecurityLevel = x.DreamDaemonSettings.SecurityLevel
- }).FirstAsync(cancellationToken).ConfigureAwait(false);
-
await jobManager.RegisterOperation(new Models.Job
{
Description = "Launch DreamDaemon",
@@ -69,7 +61,16 @@ namespace Tgstation.Server.Host.Controllers
CancelRightsType = RightsType.DreamDaemon,
Instance = Instance,
StartedBy = AuthenticationContext.User
- }, (job, serviceProvider, innerCt) => instance.DreamDaemon.Launch(launchParams, innerCt), cancellationToken).ConfigureAwait(false);
+ },
+ async (job, serviceProvider, innerCt) =>
+ {
+ var result = await instance.Watchdog.Launch(innerCt).ConfigureAwait(false);
+ if (result == null)
+ throw new InvalidOperationException("Watchdog already running!");
+ if (!instance.Watchdog.Running)
+ throw new Exception("Failed to launch watchdog!");
+ },
+ cancellationToken).ConfigureAwait(false);
return Ok();
}
@@ -77,48 +78,55 @@ namespace Tgstation.Server.Host.Controllers
[TgsAuthorize(DreamDaemonRights.ReadMetadata | DreamDaemonRights.ReadRevision)]
public override async Task Read(CancellationToken cancellationToken)
{
- var dd = instanceManager.GetInstance(Instance).DreamDaemon;
+ var dd = instanceManager.GetInstance(Instance).Watchdog;
var metadata = (AuthenticationContext.GetRight(RightsType.DreamDaemon) & (int)DreamDaemonRights.ReadMetadata) != 0;
var revision = (AuthenticationContext.GetRight(RightsType.DreamDaemon) & (int)DreamDaemonRights.ReadRevision) != 0;
var settings = metadata ? await DatabaseContext.Instances.Where(x => x.Id == Instance.Id).Select(x => x.DreamDaemonSettings).FirstAsync(cancellationToken).ConfigureAwait(false) : null;
- Api.Models.DreamDaemon result = new Api.Models.DreamDaemon();
+ var result = new DreamDaemon();
if(metadata)
{
+ var alphaActive = dd.AlphaIsActive;
+ var llp = dd.LastLaunchParameters;
result.AutoStart = settings.AutoStart;
- result.CurrentPort = dd.CurrentPort;
- result.CurrentSecurity = dd.CurrentSecurity;
- result.PrimaryPort = dd.LastLaunchParameters.PrimaryPort;
- result.AllowWebClient = dd.LastLaunchParameters.AllowWebClient;
+ result.CurrentPort = alphaActive ? llp.PrimaryPort : llp.SecondaryPort;
+ result.CurrentSecurity = llp.SecurityLevel;
+ result.CurrentAllowWebclient = llp.AllowWebClient;
+ result.PrimaryPort = dd.ActiveLaunchParameters.PrimaryPort;
+ result.AllowWebClient = dd.ActiveLaunchParameters.AllowWebClient;
result.Running = dd.Running;
result.SecondaryPort = dd.LastLaunchParameters.SecondaryPort;
result.SecurityLevel = dd.LastLaunchParameters.SecurityLevel;
- result.SoftRestart = dd.SoftRebooting;
- result.SoftShutdown = dd.SoftStopping;
+ var rstate = dd.RebootState;
+ result.SoftRestart = rstate == RebootState.Restart;
+ result.SoftShutdown = rstate == RebootState.Shutdown;
};
if (revision)
- result.CompileJob = dd.LastCompileJob.ToApi();
+ {
+ result.ActiveCompileJob = dd.LiveCompileJob?.ToApi();
+ result.StagedCompileJob = dd.StagedCompileJob?.ToApi();
+ }
return Json(result);
}
///
[TgsAuthorize(DreamDaemonRights.Shutdown)]
- public override async Task Delete([FromBody] Api.Models.DreamDaemon model, CancellationToken cancellationToken)
+ public override async Task Delete([FromBody] DreamDaemon model, CancellationToken cancellationToken)
{
var instance = instanceManager.GetInstance(Instance);
- if (!instance.DreamDaemon.Running)
+ if (!instance.Watchdog.Running)
return StatusCode(HttpStatusCode.Gone);
- await instance.DreamDaemon.Terminate(false, cancellationToken).ConfigureAwait(false);
+ await instance.Watchdog.Terminate(false, cancellationToken).ConfigureAwait(false);
return Ok();
}
///
[TgsAuthorize(DreamDaemonRights.SetAutoStart | DreamDaemonRights.SetPorts | DreamDaemonRights.SetSecurity | DreamDaemonRights.SetWebClient | DreamDaemonRights.SoftRestart | DreamDaemonRights.SoftShutdown | DreamDaemonRights.Start)]
- public override async Task Update([FromBody] Api.Models.DreamDaemon model, CancellationToken cancellationToken)
+ public override async Task Update([FromBody] DreamDaemon model, CancellationToken cancellationToken)
{
var current = await DatabaseContext.Instances.Where(x => x.Id == Instance.Id).Select(x => x.DreamDaemonSettings).FirstAsync(cancellationToken).ConfigureAwait(false);
@@ -155,7 +163,7 @@ namespace Tgstation.Server.Host.Controllers
current.SoftShutdown = model.SoftShutdown;
}
- await instanceManager.GetInstance(Instance).DreamDaemon.ChangeSettings(current, cancellationToken).ConfigureAwait(false);
+ await instanceManager.GetInstance(Instance).Watchdog.ChangeSettings(current, cancellationToken).ConfigureAwait(false);
await DatabaseContext.Save(default).ConfigureAwait(false);
return Ok();