From 253acf08b41a69a65e9d27f6bfe8f3e44efd3006 Mon Sep 17 00:00:00 2001
From: AffectedArc07 <25063394+AffectedArc07@users.noreply.github.com>
Date: Sat, 9 Jan 2021 22:26:14 +0000
Subject: [PATCH 01/42] DNM - Initial Commit
---
.../Components/Events/EventType.cs | 8 +++++++-
.../Components/InstanceFactory.cs | 3 ++-
.../Components/Session/SessionController.cs | 13 +++++++++++--
.../Components/Watchdog/README.md | 2 +-
4 files changed, 21 insertions(+), 5 deletions(-)
diff --git a/src/Tgstation.Server.Host/Components/Events/EventType.cs b/src/Tgstation.Server.Host/Components/Events/EventType.cs
index 9085c6e215..93fe022964 100644
--- a/src/Tgstation.Server.Host/Components/Events/EventType.cs
+++ b/src/Tgstation.Server.Host/Components/Events/EventType.cs
@@ -111,6 +111,12 @@ namespace Tgstation.Server.Host.Components.Events
/// Before the watchdog launches. No parameters.
///
[EventScript("WatchdogLaunch")]
- WatchdogLaunch
+ WatchdogLaunch,
+
+ ///
+ /// Inbetween DD restarts if the process has been force-ended by the DMAPI
+ ///
+ [EventScript("DDEndProcess")]
+ DDEndProcess
}
}
diff --git a/src/Tgstation.Server.Host/Components/InstanceFactory.cs b/src/Tgstation.Server.Host/Components/InstanceFactory.cs
index cd04474fb4..8296da7f35 100644
--- a/src/Tgstation.Server.Host/Components/InstanceFactory.cs
+++ b/src/Tgstation.Server.Host/Components/InstanceFactory.cs
@@ -273,7 +273,8 @@ namespace Tgstation.Server.Host.Components
serverPortProvider,
loggerFactory,
loggerFactory.CreateLogger(),
- metadata.CloneMetadata());
+ metadata.CloneMetadata(),
+ eventConsumer);
var dmbFactory = new DmbFactory(
databaseContextFactory,
diff --git a/src/Tgstation.Server.Host/Components/Session/SessionController.cs b/src/Tgstation.Server.Host/Components/Session/SessionController.cs
index 1462b6cd50..47317b6474 100644
--- a/src/Tgstation.Server.Host/Components/Session/SessionController.cs
+++ b/src/Tgstation.Server.Host/Components/Session/SessionController.cs
@@ -14,6 +14,7 @@ using Tgstation.Server.Api.Models;
using Tgstation.Server.Host.Components.Byond;
using Tgstation.Server.Host.Components.Chat;
using Tgstation.Server.Host.Components.Deployment;
+using Tgstation.Server.Host.Components.Events;
using Tgstation.Server.Host.Components.Interop;
using Tgstation.Server.Host.Components.Interop.Bridge;
using Tgstation.Server.Host.Components.Interop.Topic;
@@ -168,6 +169,11 @@ namespace Tgstation.Server.Host.Components.Session
///
bool released;
+ ///
+ /// The
+ ///
+ readonly IEventConsumer eventConsumer;
+
///
/// Construct a
///
@@ -185,6 +191,7 @@ namespace Tgstation.Server.Host.Components.Session
/// The optional time to wait before failing the
/// If this is a reattached session.
/// If this is a DMAPI validation session.
+ /// The value of .
public SessionController(
ReattachInformation reattachInformation,
Api.Models.Instance metadata,
@@ -199,7 +206,8 @@ namespace Tgstation.Server.Host.Components.Session
Func postLifetimeCallback,
uint? startupTimeout,
bool reattached,
- bool apiValidate)
+ bool apiValidate,
+ IEventConsumer eventConsumer)
{
this.reattachInformation = reattachInformation ?? throw new ArgumentNullException(nameof(reattachInformation));
this.metadata = metadata ?? throw new ArgumentNullException(nameof(metadata));
@@ -211,7 +219,7 @@ namespace Tgstation.Server.Host.Components.Session
throw new ArgumentNullException(nameof(bridgeRegistrar));
this.chat = chat ?? throw new ArgumentNullException(nameof(chat));
this.logger = logger ?? throw new ArgumentNullException(nameof(logger));
-
+ this.eventConsumer = eventConsumer ?? throw new ArgumentNullException(nameof(eventConsumer));
portClosedForReboot = false;
disposed = false;
apiValidationStatus = ApiValidationStatus.NeverValidated;
@@ -393,6 +401,7 @@ namespace Tgstation.Server.Host.Components.Session
logger.LogInformation("Bridge requested process termination!");
TerminationWasRequested = true;
process.Terminate();
+ eventConsumer.HandleEvent(EventType.DDEndProcess, Enumerable.Empty(), cancellationToken);
break;
case BridgeCommandType.PortUpdate:
lock (synchronizationLock)
diff --git a/src/Tgstation.Server.Host/Components/Watchdog/README.md b/src/Tgstation.Server.Host/Components/Watchdog/README.md
index f9846a0db7..229dc45032 100644
--- a/src/Tgstation.Server.Host/Components/Watchdog/README.md
+++ b/src/Tgstation.Server.Host/Components/Watchdog/README.md
@@ -29,7 +29,7 @@ From the perspective of `WatchdogBase`
Watchdog monitoring takes place in the `MonitorLifetimes()` functiona and is entirely event based. It responds to a set of [MonitorActivationReason](./MonitorActivationReason.cs)s and takes the apporprate action. This includes:
- When a server crashes.
-- When a server calls `/world/prod/Reboot()`.
+- When a server calls `/world/proc/Reboot()`.
- When a new .dmb is deployed.
- When DreamDaemon settings are changed via the API.
- When it is time to make a heartbeat.
From 129d1e7b631b051e9034ac458e3e23d3016f0c5b Mon Sep 17 00:00:00 2001
From: AffectedArc07 <25063394+AffectedArc07@users.noreply.github.com>
Date: Sun, 10 Jan 2021 13:19:58 +0000
Subject: [PATCH 02/42] Revert "DNM - Initial Commit"
This reverts commit 253acf08b41a69a65e9d27f6bfe8f3e44efd3006.
---
.../Components/Events/EventType.cs | 8 +-------
.../Components/InstanceFactory.cs | 3 +--
.../Components/Session/SessionController.cs | 13 ++-----------
.../Components/Watchdog/README.md | 2 +-
4 files changed, 5 insertions(+), 21 deletions(-)
diff --git a/src/Tgstation.Server.Host/Components/Events/EventType.cs b/src/Tgstation.Server.Host/Components/Events/EventType.cs
index 93fe022964..9085c6e215 100644
--- a/src/Tgstation.Server.Host/Components/Events/EventType.cs
+++ b/src/Tgstation.Server.Host/Components/Events/EventType.cs
@@ -111,12 +111,6 @@ namespace Tgstation.Server.Host.Components.Events
/// Before the watchdog launches. No parameters.
///
[EventScript("WatchdogLaunch")]
- WatchdogLaunch,
-
- ///
- /// Inbetween DD restarts if the process has been force-ended by the DMAPI
- ///
- [EventScript("DDEndProcess")]
- DDEndProcess
+ WatchdogLaunch
}
}
diff --git a/src/Tgstation.Server.Host/Components/InstanceFactory.cs b/src/Tgstation.Server.Host/Components/InstanceFactory.cs
index 8296da7f35..cd04474fb4 100644
--- a/src/Tgstation.Server.Host/Components/InstanceFactory.cs
+++ b/src/Tgstation.Server.Host/Components/InstanceFactory.cs
@@ -273,8 +273,7 @@ namespace Tgstation.Server.Host.Components
serverPortProvider,
loggerFactory,
loggerFactory.CreateLogger(),
- metadata.CloneMetadata(),
- eventConsumer);
+ metadata.CloneMetadata());
var dmbFactory = new DmbFactory(
databaseContextFactory,
diff --git a/src/Tgstation.Server.Host/Components/Session/SessionController.cs b/src/Tgstation.Server.Host/Components/Session/SessionController.cs
index 47317b6474..1462b6cd50 100644
--- a/src/Tgstation.Server.Host/Components/Session/SessionController.cs
+++ b/src/Tgstation.Server.Host/Components/Session/SessionController.cs
@@ -14,7 +14,6 @@ using Tgstation.Server.Api.Models;
using Tgstation.Server.Host.Components.Byond;
using Tgstation.Server.Host.Components.Chat;
using Tgstation.Server.Host.Components.Deployment;
-using Tgstation.Server.Host.Components.Events;
using Tgstation.Server.Host.Components.Interop;
using Tgstation.Server.Host.Components.Interop.Bridge;
using Tgstation.Server.Host.Components.Interop.Topic;
@@ -169,11 +168,6 @@ namespace Tgstation.Server.Host.Components.Session
///
bool released;
- ///
- /// The
- ///
- readonly IEventConsumer eventConsumer;
-
///
/// Construct a
///
@@ -191,7 +185,6 @@ namespace Tgstation.Server.Host.Components.Session
/// The optional time to wait before failing the
/// If this is a reattached session.
/// If this is a DMAPI validation session.
- /// The value of .
public SessionController(
ReattachInformation reattachInformation,
Api.Models.Instance metadata,
@@ -206,8 +199,7 @@ namespace Tgstation.Server.Host.Components.Session
Func postLifetimeCallback,
uint? startupTimeout,
bool reattached,
- bool apiValidate,
- IEventConsumer eventConsumer)
+ bool apiValidate)
{
this.reattachInformation = reattachInformation ?? throw new ArgumentNullException(nameof(reattachInformation));
this.metadata = metadata ?? throw new ArgumentNullException(nameof(metadata));
@@ -219,7 +211,7 @@ namespace Tgstation.Server.Host.Components.Session
throw new ArgumentNullException(nameof(bridgeRegistrar));
this.chat = chat ?? throw new ArgumentNullException(nameof(chat));
this.logger = logger ?? throw new ArgumentNullException(nameof(logger));
- this.eventConsumer = eventConsumer ?? throw new ArgumentNullException(nameof(eventConsumer));
+
portClosedForReboot = false;
disposed = false;
apiValidationStatus = ApiValidationStatus.NeverValidated;
@@ -401,7 +393,6 @@ namespace Tgstation.Server.Host.Components.Session
logger.LogInformation("Bridge requested process termination!");
TerminationWasRequested = true;
process.Terminate();
- eventConsumer.HandleEvent(EventType.DDEndProcess, Enumerable.Empty(), cancellationToken);
break;
case BridgeCommandType.PortUpdate:
lock (synchronizationLock)
diff --git a/src/Tgstation.Server.Host/Components/Watchdog/README.md b/src/Tgstation.Server.Host/Components/Watchdog/README.md
index 229dc45032..f9846a0db7 100644
--- a/src/Tgstation.Server.Host/Components/Watchdog/README.md
+++ b/src/Tgstation.Server.Host/Components/Watchdog/README.md
@@ -29,7 +29,7 @@ From the perspective of `WatchdogBase`
Watchdog monitoring takes place in the `MonitorLifetimes()` functiona and is entirely event based. It responds to a set of [MonitorActivationReason](./MonitorActivationReason.cs)s and takes the apporprate action. This includes:
- When a server crashes.
-- When a server calls `/world/proc/Reboot()`.
+- When a server calls `/world/prod/Reboot()`.
- When a new .dmb is deployed.
- When DreamDaemon settings are changed via the API.
- When it is time to make a heartbeat.
From a447dd323dcf07b57c7b79b590ccefc7f485712d Mon Sep 17 00:00:00 2001
From: AffectedArc07 <25063394+AffectedArc07@users.noreply.github.com>
Date: Sun, 10 Jan 2021 14:06:02 +0000
Subject: [PATCH 03/42] V2
---
src/Tgstation.Server.Host/Components/Events/EventType.cs | 8 +++++++-
.../Components/Watchdog/BasicWatchdog.cs | 4 ++++
.../Components/Watchdog/WatchdogBase.cs | 2 +-
3 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/src/Tgstation.Server.Host/Components/Events/EventType.cs b/src/Tgstation.Server.Host/Components/Events/EventType.cs
index 9085c6e215..4e20113171 100644
--- a/src/Tgstation.Server.Host/Components/Events/EventType.cs
+++ b/src/Tgstation.Server.Host/Components/Events/EventType.cs
@@ -111,6 +111,12 @@ namespace Tgstation.Server.Host.Components.Events
/// Before the watchdog launches. No parameters.
///
[EventScript("WatchdogLaunch")]
- WatchdogLaunch
+ WatchdogLaunch,
+
+ ///
+ /// Inbetween DD restarts if the process has been force-ended by the DMAPI (TgsEndProcess())
+ ///
+ [EventScript("WorldEndProcess")]
+ WorldEndProcess,
}
}
diff --git a/src/Tgstation.Server.Host/Components/Watchdog/BasicWatchdog.cs b/src/Tgstation.Server.Host/Components/Watchdog/BasicWatchdog.cs
index c364a8cf65..4a83eab388 100644
--- a/src/Tgstation.Server.Host/Components/Watchdog/BasicWatchdog.cs
+++ b/src/Tgstation.Server.Host/Components/Watchdog/BasicWatchdog.cs
@@ -1,6 +1,7 @@
using Microsoft.Extensions.Logging;
using System;
using System.Globalization;
+using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Tgstation.Server.Api.Models.Internal;
@@ -91,6 +92,9 @@ namespace Tgstation.Server.Host.Components.Watchdog
switch (reason)
{
case MonitorActivationReason.ActiveServerCrashed:
+ if (Server.TerminationWasRequested)
+ await eventConsumer.HandleEvent(EventType.WorldEndProcess, Enumerable.Empty(), cancellationToken).ConfigureAwait(false);
+
string exitWord = Server.TerminationWasRequested ? "exited" : "crashed";
if (Server.RebootState == Session.RebootState.Shutdown)
{
diff --git a/src/Tgstation.Server.Host/Components/Watchdog/WatchdogBase.cs b/src/Tgstation.Server.Host/Components/Watchdog/WatchdogBase.cs
index 5a24b01076..e1c8336752 100644
--- a/src/Tgstation.Server.Host/Components/Watchdog/WatchdogBase.cs
+++ b/src/Tgstation.Server.Host/Components/Watchdog/WatchdogBase.cs
@@ -121,7 +121,7 @@ namespace Tgstation.Server.Host.Components.Watchdog
///
/// The that is not the
///
- readonly IEventConsumer eventConsumer;
+ public IEventConsumer eventConsumer;
///
/// The for the .
From f678d6c0d6476591f076f2ce9b17b9386423e341 Mon Sep 17 00:00:00 2001
From: AffectedArc07 <25063394+AffectedArc07@users.noreply.github.com>
Date: Sun, 10 Jan 2021 18:52:15 +0000
Subject: [PATCH 04/42] Cybertweaks
---
build/Version.props | 2 +-
src/DMAPI/tgs.dm | 4 +++-
.../Components/Events/EventType.cs | 2 +-
.../Components/Watchdog/BasicWatchdog.cs | 2 +-
.../Components/Watchdog/WatchdogBase.cs | 18 +++++++--------
.../PublishProfiles/FolderProfile.pubxml | 22 +++++++++++++++++++
6 files changed, 37 insertions(+), 13 deletions(-)
create mode 100644 src/Tgstation.Server.Host/Properties/PublishProfiles/FolderProfile.pubxml
diff --git a/build/Version.props b/build/Version.props
index 44647f7611..7214e884f4 100644
--- a/build/Version.props
+++ b/build/Version.props
@@ -7,7 +7,7 @@
2.2.0
8.2.0
9.1.1
- 5.2.10
+ 5.2.11
1.1.0
1.2.0
diff --git a/src/DMAPI/tgs.dm b/src/DMAPI/tgs.dm
index 3225f14d8c..e1eac9f291 100644
--- a/src/DMAPI/tgs.dm
+++ b/src/DMAPI/tgs.dm
@@ -1,6 +1,6 @@
// tgstation-server DMAPI
-#define TGS_DMAPI_VERSION "5.2.10"
+#define TGS_DMAPI_VERSION "5.2.11"
// All functions and datums outside this document are subject to change with any version and should not be relied on.
@@ -97,6 +97,8 @@
#define TGS_EVENT_WATCHDOG_DETACH 16
// We don't actually implement this value as the DMAPI can never receive it
// #define TGS_EVENT_WATCHDOG_LAUNCH 17
+// Same here. We don't actually implement this value as the DMAPI can never receive it
+// #define TGS_EVENT_WORLD_END_PROCESS 18
// OTHER ENUMS
diff --git a/src/Tgstation.Server.Host/Components/Events/EventType.cs b/src/Tgstation.Server.Host/Components/Events/EventType.cs
index 4e20113171..f22c1db8e0 100644
--- a/src/Tgstation.Server.Host/Components/Events/EventType.cs
+++ b/src/Tgstation.Server.Host/Components/Events/EventType.cs
@@ -114,7 +114,7 @@ namespace Tgstation.Server.Host.Components.Events
WatchdogLaunch,
///
- /// Inbetween DD restarts if the process has been force-ended by the DMAPI (TgsEndProcess())
+ /// In between DD restarts if the process has been force-ended by the DMAPI (TgsEndProcess())
///
[EventScript("WorldEndProcess")]
WorldEndProcess,
diff --git a/src/Tgstation.Server.Host/Components/Watchdog/BasicWatchdog.cs b/src/Tgstation.Server.Host/Components/Watchdog/BasicWatchdog.cs
index 4a83eab388..433680a941 100644
--- a/src/Tgstation.Server.Host/Components/Watchdog/BasicWatchdog.cs
+++ b/src/Tgstation.Server.Host/Components/Watchdog/BasicWatchdog.cs
@@ -93,7 +93,7 @@ namespace Tgstation.Server.Host.Components.Watchdog
{
case MonitorActivationReason.ActiveServerCrashed:
if (Server.TerminationWasRequested)
- await eventConsumer.HandleEvent(EventType.WorldEndProcess, Enumerable.Empty(), cancellationToken).ConfigureAwait(false);
+ await EventConsumer.HandleEvent(EventType.WorldEndProcess, Enumerable.Empty(), cancellationToken).ConfigureAwait(false);
string exitWord = Server.TerminationWasRequested ? "exited" : "crashed";
if (Server.RebootState == Session.RebootState.Shutdown)
diff --git a/src/Tgstation.Server.Host/Components/Watchdog/WatchdogBase.cs b/src/Tgstation.Server.Host/Components/Watchdog/WatchdogBase.cs
index e1c8336752..f6a7ed6160 100644
--- a/src/Tgstation.Server.Host/Components/Watchdog/WatchdogBase.cs
+++ b/src/Tgstation.Server.Host/Components/Watchdog/WatchdogBase.cs
@@ -83,6 +83,11 @@ namespace Tgstation.Server.Host.Components.Watchdog
///
protected IAsyncDelayer AsyncDelayer { get; }
+ ///
+ /// The that is not the
+ ///
+ protected IEventConsumer EventConsumer { get; }
+
///
/// The for the .
///
@@ -118,11 +123,6 @@ namespace Tgstation.Server.Host.Components.Watchdog
///
readonly IIOManager diagnosticsIOManager;
- ///
- /// The that is not the
- ///
- public IEventConsumer eventConsumer;
-
///
/// The for the .
///
@@ -179,7 +179,7 @@ namespace Tgstation.Server.Host.Components.Watchdog
/// The to populate with
/// The value of .
/// The value of .
- /// The value of .
+ /// The value of .
/// The value of .
/// The value of
/// The initial value of . May be modified
@@ -208,7 +208,7 @@ namespace Tgstation.Server.Host.Components.Watchdog
this.jobManager = jobManager ?? throw new ArgumentNullException(nameof(jobManager));
AsyncDelayer = asyncDelayer ?? throw new ArgumentNullException(nameof(asyncDelayer));
this.diagnosticsIOManager = diagnosticsIOManager ?? throw new ArgumentNullException(nameof(diagnosticsIOManager));
- this.eventConsumer = eventConsumer ?? throw new ArgumentNullException(nameof(eventConsumer));
+ EventConsumer = eventConsumer ?? throw new ArgumentNullException(nameof(eventConsumer));
this.remoteDeploymentManagerFactory = remoteDeploymentManagerFactory ?? throw new ArgumentNullException(nameof(remoteDeploymentManagerFactory));
Logger = logger ?? throw new ArgumentNullException(nameof(logger));
ActiveLaunchParameters = initialLaunchParameters ?? throw new ArgumentNullException(nameof(initialLaunchParameters));
@@ -267,7 +267,7 @@ namespace Tgstation.Server.Host.Components.Watchdog
return;
if (!graceful)
{
- var eventTask = eventConsumer.HandleEvent(releaseServers ? EventType.WatchdogDetach : EventType.WatchdogShutdown, null, cancellationToken);
+ var eventTask = EventConsumer.HandleEvent(releaseServers ? EventType.WatchdogDetach : EventType.WatchdogShutdown, null, cancellationToken);
var chatTask = announce ? Chat.QueueWatchdogMessage("Shutting down...", cancellationToken) : Task.CompletedTask;
@@ -378,7 +378,7 @@ namespace Tgstation.Server.Host.Components.Watchdog
cancellationToken); // simple announce
if (reattachInfo == null)
announceTask = Task.WhenAll(
- eventConsumer.HandleEvent(EventType.WatchdogLaunch, Enumerable.Empty(), cancellationToken),
+ EventConsumer.HandleEvent(EventType.WatchdogLaunch, Enumerable.Empty(), cancellationToken),
announceTask);
}
else
diff --git a/src/Tgstation.Server.Host/Properties/PublishProfiles/FolderProfile.pubxml b/src/Tgstation.Server.Host/Properties/PublishProfiles/FolderProfile.pubxml
new file mode 100644
index 0000000000..a23e825bed
--- /dev/null
+++ b/src/Tgstation.Server.Host/Properties/PublishProfiles/FolderProfile.pubxml
@@ -0,0 +1,22 @@
+
+
+
+
+ FileSystem
+ FileSystem
+ Release
+ Any CPU
+
+ True
+ False
+ netcoreapp3.1
+ linux-x64
+ 2b69ad6d-2b5a-4023-8ead-0bd1b18e028a
+ false
+ bin\Release\netcoreapp3.1\publish\
+ False
+
+
\ No newline at end of file
From 95906f3bbbbb28a87ed1a345f52e3d5b41ee62dd Mon Sep 17 00:00:00 2001
From: AffectedArc07 <25063394+AffectedArc07@users.noreply.github.com>
Date: Sun, 10 Jan 2021 19:25:14 +0000
Subject: [PATCH 05/42] VS Why
---
.../PublishProfiles/FolderProfile.pubxml | 22 -------------------
1 file changed, 22 deletions(-)
delete mode 100644 src/Tgstation.Server.Host/Properties/PublishProfiles/FolderProfile.pubxml
diff --git a/src/Tgstation.Server.Host/Properties/PublishProfiles/FolderProfile.pubxml b/src/Tgstation.Server.Host/Properties/PublishProfiles/FolderProfile.pubxml
deleted file mode 100644
index a23e825bed..0000000000
--- a/src/Tgstation.Server.Host/Properties/PublishProfiles/FolderProfile.pubxml
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
-
- FileSystem
- FileSystem
- Release
- Any CPU
-
- True
- False
- netcoreapp3.1
- linux-x64
- 2b69ad6d-2b5a-4023-8ead-0bd1b18e028a
- false
- bin\Release\netcoreapp3.1\publish\
- False
-
-
\ No newline at end of file
From 9ef486c083b0b46b0579e3416be94b52f2165d5a Mon Sep 17 00:00:00 2001
From: Jordan Brown
Date: Sun, 10 Jan 2021 15:06:31 -0500
Subject: [PATCH 06/42] Release notes now credit authors
---
tools/ReleaseNotes/Program.cs | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/tools/ReleaseNotes/Program.cs b/tools/ReleaseNotes/Program.cs
index 65760f4b8d..7477895cdf 100644
--- a/tools/ReleaseNotes/Program.cs
+++ b/tools/ReleaseNotes/Program.cs
@@ -72,7 +72,7 @@ namespace ReleaseNotes
Task milestoneTask = null;
var milestoneTaskLock = new object();
- var releaseDictionary = new Dictionary>>(StringComparer.OrdinalIgnoreCase);
+ var releaseDictionary = new Dictionary>>(StringComparer.OrdinalIgnoreCase);
var authorizedUsers = new Dictionary>();
bool postControlPanelMessage = false;
@@ -136,7 +136,7 @@ namespace ReleaseNotes
foreach (var I in notes)
Console.WriteLine(component + " #" + fullPR.Number + " - " + I + " (@" + user.Login + ")");
- var tupleSelector = notes.Select(note => Tuple.Create(note, fullPR.Number));
+ var tupleSelector = notes.Select(note => Tuple.Create(note, fullPR.Number, user.Login));
if (releaseDictionary.TryGetValue(component, out var currentValues))
currentValues.AddRange(tupleSelector);
else
@@ -169,6 +169,7 @@ namespace ReleaseNotes
}
if (trimmedLine.Length == 0)
continue;
+
notes.Add(trimmedLine);
}
}
@@ -325,6 +326,8 @@ namespace ReleaseNotes
newNotes.Append(noteTuple.Item1);
newNotes.Append(" (#");
newNotes.Append(noteTuple.Item2);
+ newNotes.Append(" @");
+ newNotes.Append(noteTuple.Item3);
newNotes.Append(')');
}
From 2236a5614953879a507379e0872059963dd8735d Mon Sep 17 00:00:00 2001
From: Jordan Brown
Date: Mon, 11 Jan 2021 21:50:05 -0500
Subject: [PATCH 07/42] Infinitely cache .js files served from /app
---
.../Controllers/ControlPanelController.cs | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/src/Tgstation.Server.Host/Controllers/ControlPanelController.cs b/src/Tgstation.Server.Host/Controllers/ControlPanelController.cs
index 275acbe91a..28f68d21d7 100644
--- a/src/Tgstation.Server.Host/Controllers/ControlPanelController.cs
+++ b/src/Tgstation.Server.Host/Controllers/ControlPanelController.cs
@@ -1,6 +1,8 @@
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.StaticFiles;
+using Microsoft.Extensions.Primitives;
+using Microsoft.Net.Http.Headers;
using System;
using System.Net.Mime;
using Tgstation.Server.Host.Core;
@@ -42,6 +44,10 @@ namespace Tgstation.Server.Host.Controllers
var contentTypeProvider = new FileExtensionContentTypeProvider();
if (!contentTypeProvider.TryGetContentType(fileInfo.Name, out var contentType))
contentType = MediaTypeNames.Application.Octet;
+ else if (contentType == MediaTypeNames.Application.Json)
+ Response.Headers.Add(
+ HeaderNames.CacheControl,
+ new StringValues(new[] { "public", "max-age=31536000", "immutable" }));
return File(appRoute, contentType);
}
From c3f66394631c89db4b6ab8437c2ebb5c8a55bd6b Mon Sep 17 00:00:00 2001
From: Jordan Brown
Date: Tue, 12 Jan 2021 12:53:28 -0500
Subject: [PATCH 08/42] Adds Timestamp to RevisionInformation
---
build/Version.props | 4 +-
src/DMAPI/tgs.dm | 4 +-
src/DMAPI/tgs/v5/_defines.dm | 1 +
src/DMAPI/tgs/v5/api.dm | 2 +
src/DMAPI/tgs/v5/undefs.dm | 1 +
.../Models/Internal/RevisionInformation.cs | 10 +-
.../Components/Deployment/DreamMaker.cs | 3 +-
.../Components/Instance.cs | 1 +
.../Interop/Bridge/RuntimeInformation.cs | 1 +
.../Components/Repository/IRepository.cs | 8 +
.../Components/Repository/Repository.cs | 13 +
.../Controllers/RepositoryController.cs | 1 +
.../Database/DatabaseContext.cs | 17 +-
...12154040_MSAddRevInfoTimestamp.Designer.cs | 902 ++++++++++++++++++
.../20210112154040_MSAddRevInfoTimestamp.cs | 35 +
...12154123_MYAddRevInfoTimestamp.Designer.cs | 886 +++++++++++++++++
.../20210112154123_MYAddRevInfoTimestamp.cs | 35 +
...12154203_PGAddRevInfoTimestamp.Designer.cs | 896 +++++++++++++++++
.../20210112154203_PGAddRevInfoTimestamp.cs | 35 +
...12154243_SLAddRevInfoTimestamp.Designer.cs | 885 +++++++++++++++++
.../20210112154243_SLAddRevInfoTimestamp.cs | 69 ++
.../MySqlDatabaseContextModelSnapshot.cs | 3 +
...PostgresSqlDatabaseContextModelSnapshot.cs | 3 +
.../SqlServerDatabaseContextModelSnapshot.cs | 3 +
.../SqliteDatabaseContextModelSnapshot.cs | 3 +
.../Models/RevisionInformation.cs | 1 +
.../Instance/RepositoryTest.cs | 1 +
27 files changed, 3812 insertions(+), 11 deletions(-)
create mode 100644 src/Tgstation.Server.Host/Database/Migrations/20210112154040_MSAddRevInfoTimestamp.Designer.cs
create mode 100644 src/Tgstation.Server.Host/Database/Migrations/20210112154040_MSAddRevInfoTimestamp.cs
create mode 100644 src/Tgstation.Server.Host/Database/Migrations/20210112154123_MYAddRevInfoTimestamp.Designer.cs
create mode 100644 src/Tgstation.Server.Host/Database/Migrations/20210112154123_MYAddRevInfoTimestamp.cs
create mode 100644 src/Tgstation.Server.Host/Database/Migrations/20210112154203_PGAddRevInfoTimestamp.Designer.cs
create mode 100644 src/Tgstation.Server.Host/Database/Migrations/20210112154203_PGAddRevInfoTimestamp.cs
create mode 100644 src/Tgstation.Server.Host/Database/Migrations/20210112154243_SLAddRevInfoTimestamp.Designer.cs
create mode 100644 src/Tgstation.Server.Host/Database/Migrations/20210112154243_SLAddRevInfoTimestamp.cs
diff --git a/build/Version.props b/build/Version.props
index 2ff2ac18e2..8d1bf5b98a 100644
--- a/build/Version.props
+++ b/build/Version.props
@@ -5,9 +5,9 @@
4.7.3
2.2.0
- 8.2.0
+ 8.3.0
9.1.2
- 5.2.11
+ 5.3.0
1.1.0
1.2.0
diff --git a/src/DMAPI/tgs.dm b/src/DMAPI/tgs.dm
index e1eac9f291..fb6261a9bc 100644
--- a/src/DMAPI/tgs.dm
+++ b/src/DMAPI/tgs.dm
@@ -1,6 +1,6 @@
// tgstation-server DMAPI
-#define TGS_DMAPI_VERSION "5.2.11"
+#define TGS_DMAPI_VERSION "5.3.0"
// All functions and datums outside this document are subject to change with any version and should not be relied on.
@@ -154,6 +154,8 @@
/datum/tgs_revision_information
/// Full SHA of the commit.
var/commit
+ /// ISO8601 timestamp of the commit
+ var/timestamp
/// Full sha of last known remote commit. This may be null if the TGS repository is not currently tracking a remote branch.
var/origin_commit
diff --git a/src/DMAPI/tgs/v5/_defines.dm b/src/DMAPI/tgs/v5/_defines.dm
index 8fd84e19fa..10bc4cbe40 100644
--- a/src/DMAPI/tgs/v5/_defines.dm
+++ b/src/DMAPI/tgs/v5/_defines.dm
@@ -79,6 +79,7 @@
#define DMAPI5_TOPIC_RESPONSE_CHAT_RESPONSES "chatResponses"
#define DMAPI5_REVISION_INFORMATION_COMMIT_SHA "commitSha"
+#define DMAPI5_REVISION_INFORMATION_TIMESTAMP "timestamp"
#define DMAPI5_REVISION_INFORMATION_ORIGIN_COMMIT_SHA "originCommitSha"
#define DMAPI5_CHAT_USER_ID "id"
diff --git a/src/DMAPI/tgs/v5/api.dm b/src/DMAPI/tgs/v5/api.dm
index 7a2ff694e0..c5b5257fb5 100644
--- a/src/DMAPI/tgs/v5/api.dm
+++ b/src/DMAPI/tgs/v5/api.dm
@@ -48,6 +48,7 @@
if(istype(revisionData))
revision = new
revision.commit = revisionData[DMAPI5_REVISION_INFORMATION_COMMIT_SHA]
+ revision.timestamp = revisionData[DMAPI5_REVISION_INFORMATION_TIMESTAMP]
revision.origin_commit = revisionData[DMAPI5_REVISION_INFORMATION_ORIGIN_COMMIT_SHA]
else
TGS_ERROR_LOG("Failed to decode [DMAPI5_RUNTIME_INFORMATION_REVISION] from runtime information!")
@@ -62,6 +63,7 @@
var/list/revInfo = entry[DMAPI5_TEST_MERGE_REVISION]
if(revInfo)
tm.commit = revisionData[DMAPI5_REVISION_INFORMATION_COMMIT_SHA]
+ tm.timestamp = revisionData[DMAPI5_REVISION_INFORMATION_TIMESTAMP]
tm.origin_commit = revisionData[DMAPI5_REVISION_INFORMATION_ORIGIN_COMMIT_SHA]
else
TGS_WARNING_LOG("Failed to decode [DMAPI5_TEST_MERGE_REVISION] from test merge #[tm.number]!")
diff --git a/src/DMAPI/tgs/v5/undefs.dm b/src/DMAPI/tgs/v5/undefs.dm
index 34fc481d36..5885a60e75 100644
--- a/src/DMAPI/tgs/v5/undefs.dm
+++ b/src/DMAPI/tgs/v5/undefs.dm
@@ -79,6 +79,7 @@
#undef DMAPI5_TOPIC_RESPONSE_CHAT_RESPONSES
#undef DMAPI5_REVISION_INFORMATION_COMMIT_SHA
+#undef DMAPI5_REVISION_INFORMATION_TIMESTAMP
#undef DMAPI5_REVISION_INFORMATION_ORIGIN_COMMIT_SHA
#undef DMAPI5_CHAT_USER_ID
diff --git a/src/Tgstation.Server.Api/Models/Internal/RevisionInformation.cs b/src/Tgstation.Server.Api/Models/Internal/RevisionInformation.cs
index 6d45f3e42a..18acf71ae9 100644
--- a/src/Tgstation.Server.Api/Models/Internal/RevisionInformation.cs
+++ b/src/Tgstation.Server.Api/Models/Internal/RevisionInformation.cs
@@ -1,3 +1,4 @@
+using System;
using System.ComponentModel.DataAnnotations;
namespace Tgstation.Server.Api.Models.Internal
@@ -8,14 +9,19 @@ namespace Tgstation.Server.Api.Models.Internal
public class RevisionInformation
{
///
- /// The revision sha
+ /// The revision SHA.
///
[Required]
[StringLength(Limits.MaximumCommitShaLength)]
public string? CommitSha { get; set; }
///
- /// The sha of the most recent remote commit
+ /// The timestamp of the revision.
+ ///
+ public DateTimeOffset Timestamp { get; set; }
+
+ ///
+ /// The SHA of the most recent remote commit.
///
[Required]
[StringLength(Limits.MaximumCommitShaLength)]
diff --git a/src/Tgstation.Server.Host/Components/Deployment/DreamMaker.cs b/src/Tgstation.Server.Host/Components/Deployment/DreamMaker.cs
index 7b2d5f1b07..04b80d802c 100644
--- a/src/Tgstation.Server.Host/Components/Deployment/DreamMaker.cs
+++ b/src/Tgstation.Server.Host/Components/Deployment/DreamMaker.cs
@@ -525,10 +525,8 @@ namespace Tgstation.Server.Host.Components.Deployment
Action progressReporter,
CancellationToken cancellationToken)
{
-#pragma warning disable IDE0016 // Use 'throw' expression
if (job == null)
throw new ArgumentNullException(nameof(job));
-#pragma warning restore IDE0016 // Use 'throw' expression
if (databaseContextFactory == null)
throw new ArgumentNullException(nameof(databaseContextFactory));
if (progressReporter == null)
@@ -625,6 +623,7 @@ namespace Tgstation.Server.Host.Components.Deployment
revInfo = new Models.RevisionInformation
{
CommitSha = repoSha,
+ Timestamp = await repo.TimestampCommit(repoSha, cancellationToken).ConfigureAwait(false),
OriginCommitSha = repoSha,
Instance = new Models.Instance
{
diff --git a/src/Tgstation.Server.Host/Components/Instance.cs b/src/Tgstation.Server.Host/Components/Instance.cs
index 3c4b3f437f..1bbc2d6975 100644
--- a/src/Tgstation.Server.Host/Components/Instance.cs
+++ b/src/Tgstation.Server.Host/Components/Instance.cs
@@ -248,6 +248,7 @@ namespace Tgstation.Server.Host.Components
currentRevInfo = new RevisionInformation
{
CommitSha = currentHead,
+ Timestamp = await repo.TimestampCommit(currentHead, cancellationToken).ConfigureAwait(false),
OriginCommitSha = onOrigin
? currentHead
: await repo.GetOriginSha(cancellationToken).ConfigureAwait(false),
diff --git a/src/Tgstation.Server.Host/Components/Interop/Bridge/RuntimeInformation.cs b/src/Tgstation.Server.Host/Components/Interop/Bridge/RuntimeInformation.cs
index 77fb040e37..a54398a512 100644
--- a/src/Tgstation.Server.Host/Components/Interop/Bridge/RuntimeInformation.cs
+++ b/src/Tgstation.Server.Host/Components/Interop/Bridge/RuntimeInformation.cs
@@ -76,6 +76,7 @@ namespace Tgstation.Server.Host.Components.Interop.Bridge
Revision = new Api.Models.Internal.RevisionInformation
{
CommitSha = dmbProvider.CompileJob.RevisionInformation.CommitSha,
+ Timestamp = dmbProvider.CompileJob.RevisionInformation.Timestamp,
OriginCommitSha = dmbProvider.CompileJob.RevisionInformation.OriginCommitSha
};
diff --git a/src/Tgstation.Server.Host/Components/Repository/IRepository.cs b/src/Tgstation.Server.Host/Components/Repository/IRepository.cs
index e2caa16611..e1c0bd0af1 100644
--- a/src/Tgstation.Server.Host/Components/Repository/IRepository.cs
+++ b/src/Tgstation.Server.Host/Components/Repository/IRepository.cs
@@ -133,5 +133,13 @@ namespace Tgstation.Server.Host.Components.Repository
/// The for the operation.
/// A resulting in the tracked origin reference's SHA.
Task GetOriginSha(CancellationToken cancellationToken);
+
+ ///
+ /// Gets the a given was created on.
+ ///
+ /// The SHA to timestamp.
+ /// The for the operation.
+ /// A resulting in the that was created on.
+ Task TimestampCommit(string sha, CancellationToken cancellationToken);
}
}
diff --git a/src/Tgstation.Server.Host/Components/Repository/Repository.cs b/src/Tgstation.Server.Host/Components/Repository/Repository.cs
index 3ab698c381..89c958eb70 100644
--- a/src/Tgstation.Server.Host/Components/Repository/Repository.cs
+++ b/src/Tgstation.Server.Host/Components/Repository/Repository.cs
@@ -777,5 +777,18 @@ namespace Tgstation.Server.Host.Components.Repository
parameters,
repositorySettings,
cancellationToken);
+
+ ///
+ public Task TimestampCommit(string sha, CancellationToken cancellationToken) => Task.Factory.StartNew(() =>
+ {
+ if (sha == null)
+ throw new ArgumentNullException(nameof(sha));
+
+ var commit = libGitRepo.Lookup(sha);
+ if (commit == null)
+ throw new JobException($"Commit {sha} does not exist in the repository!");
+
+ return commit.Committer.When;
+ }, cancellationToken, DefaultIOManager.BlockingTaskCreationOptions, TaskScheduler.Current);
}
}
diff --git a/src/Tgstation.Server.Host/Controllers/RepositoryController.cs b/src/Tgstation.Server.Host/Controllers/RepositoryController.cs
index c76b40682b..1114813a45 100644
--- a/src/Tgstation.Server.Host/Controllers/RepositoryController.cs
+++ b/src/Tgstation.Server.Host/Controllers/RepositoryController.cs
@@ -91,6 +91,7 @@ namespace Tgstation.Server.Host.Controllers
{
Instance = instance,
CommitSha = repoSha,
+ Timestamp = await repository.TimestampCommit(repoSha, cancellationToken).ConfigureAwait(false),
CompileJobs = new List(),
ActiveTestMerges = new List() // non null vals for api returns
};
diff --git a/src/Tgstation.Server.Host/Database/DatabaseContext.cs b/src/Tgstation.Server.Host/Database/DatabaseContext.cs
index 9de0ffa3f2..7992a475cc 100644
--- a/src/Tgstation.Server.Host/Database/DatabaseContext.cs
+++ b/src/Tgstation.Server.Host/Database/DatabaseContext.cs
@@ -377,22 +377,22 @@ namespace Tgstation.Server.Host.Database
///
/// Used by unit tests to remind us to setup the correct MSSQL migration downgrades.
///
- internal static readonly Type MSLatestMigration = typeof(MSAddSwarmIdentifer);
+ internal static readonly Type MSLatestMigration = typeof(MSAddRevInfoTimestamp);
///
/// Used by unit tests to remind us to setup the correct MYSQL migration downgrades.
///
- internal static readonly Type MYLatestMigration = typeof(MYAddSwarmIdentifer);
+ internal static readonly Type MYLatestMigration = typeof(MYAddRevInfoTimestamp);
///
/// Used by unit tests to remind us to setup the correct PostgresSQL migration downgrades.
///
- internal static readonly Type PGLatestMigration = typeof(PGAddSwarmIdentifer);
+ internal static readonly Type PGLatestMigration = typeof(PGAddRevInfoTimestamp);
///
/// Used by unit tests to remind us to setup the correct SQLite migration downgrades.
///
- internal static readonly Type SLLatestMigration = typeof(SLAddSwarmIdentifer);
+ internal static readonly Type SLLatestMigration = typeof(SLAddRevInfoTimestamp);
///
#pragma warning disable CA1502 // Cyclomatic complexity
@@ -420,6 +420,15 @@ namespace Tgstation.Server.Host.Database
// Update this with new migrations as they are made
string targetMigration = null;
+ if (targetVersion < new Version(4, 8, 0))
+ targetMigration = currentDatabaseType switch
+ {
+ DatabaseType.MySql => nameof(MYAddSwarmIdentifer),
+ DatabaseType.PostgresSql => nameof(PGAddSwarmIdentifer),
+ DatabaseType.SqlServer => nameof(MSAddSwarmIdentifer),
+ DatabaseType.Sqlite => nameof(SLAddSwarmIdentifer),
+ _ => throw new ArgumentException($"Invalid DatabaseType: {currentDatabaseType}", nameof(currentDatabaseType)),
+ };
if (targetVersion < new Version(4, 7, 0))
targetMigration = currentDatabaseType switch
{
diff --git a/src/Tgstation.Server.Host/Database/Migrations/20210112154040_MSAddRevInfoTimestamp.Designer.cs b/src/Tgstation.Server.Host/Database/Migrations/20210112154040_MSAddRevInfoTimestamp.Designer.cs
new file mode 100644
index 0000000000..3691118827
--- /dev/null
+++ b/src/Tgstation.Server.Host/Database/Migrations/20210112154040_MSAddRevInfoTimestamp.Designer.cs
@@ -0,0 +1,902 @@
+//
+using System;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Migrations;
+
+namespace Tgstation.Server.Host.Database.Migrations
+{
+ [DbContext(typeof(SqlServerDatabaseContext))]
+ [Migration("20210112154040_MSAddRevInfoTimestamp")]
+ partial class MSAddRevInfoTimestamp
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "3.1.10")
+ .HasAnnotation("Relational:MaxIdentifierLength", 128)
+ .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.ChatBot", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint")
+ .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
+
+ b.Property("ChannelLimit")
+ .HasColumnType("int");
+
+ b.Property("ConnectionString")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)")
+ .HasMaxLength(10000);
+
+ b.Property("Enabled")
+ .HasColumnType("bit");
+
+ b.Property("InstanceId")
+ .HasColumnType("bigint");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("nvarchar(100)")
+ .HasMaxLength(100);
+
+ b.Property("Provider")
+ .HasColumnType("int");
+
+ b.Property("ReconnectionInterval")
+ .HasColumnType("bigint");
+
+ b.HasKey("Id");
+
+ b.HasIndex("InstanceId", "Name")
+ .IsUnique();
+
+ b.ToTable("ChatBots");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.ChatChannel", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint")
+ .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
+
+ b.Property("ChatSettingsId")
+ .HasColumnType("bigint");
+
+ b.Property("DiscordChannelId")
+ .HasColumnType("decimal(20,0)");
+
+ b.Property("IrcChannel")
+ .HasColumnType("nvarchar(100)")
+ .HasMaxLength(100);
+
+ b.Property("IsAdminChannel")
+ .IsRequired()
+ .HasColumnType("bit");
+
+ b.Property("IsUpdatesChannel")
+ .IsRequired()
+ .HasColumnType("bit");
+
+ b.Property("IsWatchdogChannel")
+ .IsRequired()
+ .HasColumnType("bit");
+
+ b.Property("Tag")
+ .HasColumnType("nvarchar(max)")
+ .HasMaxLength(10000);
+
+ b.HasKey("Id");
+
+ b.HasIndex("ChatSettingsId", "DiscordChannelId")
+ .IsUnique()
+ .HasFilter("[DiscordChannelId] IS NOT NULL");
+
+ b.HasIndex("ChatSettingsId", "IrcChannel")
+ .IsUnique()
+ .HasFilter("[IrcChannel] IS NOT NULL");
+
+ b.ToTable("ChatChannels");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.CompileJob", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint")
+ .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
+
+ b.Property("ByondVersion")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("DMApiMajorVersion")
+ .HasColumnType("int");
+
+ b.Property("DMApiMinorVersion")
+ .HasColumnType("int");
+
+ b.Property("DMApiPatchVersion")
+ .HasColumnType("int");
+
+ b.Property("DirectoryName")
+ .IsRequired()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("DmeName")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("GitHubDeploymentId")
+ .HasColumnType("int");
+
+ b.Property("GitHubRepoId")
+ .HasColumnType("bigint");
+
+ b.Property("JobId")
+ .HasColumnType("bigint");
+
+ b.Property("MinimumSecurityLevel")
+ .HasColumnType("int");
+
+ b.Property("Output")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("RepositoryOrigin")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("RevisionInformationId")
+ .HasColumnType("bigint");
+
+ b.HasKey("Id");
+
+ b.HasIndex("DirectoryName");
+
+ b.HasIndex("JobId")
+ .IsUnique();
+
+ b.HasIndex("RevisionInformationId");
+
+ b.ToTable("CompileJobs");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.DreamDaemonSettings", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint")
+ .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
+
+ b.Property("AdditionalParameters")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)")
+ .HasMaxLength(10000);
+
+ b.Property("AllowWebClient")
+ .IsRequired()
+ .HasColumnType("bit");
+
+ b.Property("AutoStart")
+ .IsRequired()
+ .HasColumnType("bit");
+
+ b.Property("HeartbeatSeconds")
+ .HasColumnType("bigint");
+
+ b.Property("InstanceId")
+ .HasColumnType("bigint");
+
+ b.Property("Port")
+ .HasColumnType("int");
+
+ b.Property("SecurityLevel")
+ .HasColumnType("int");
+
+ b.Property("StartupTimeout")
+ .HasColumnType("bigint");
+
+ b.Property("TopicRequestTimeout")
+ .HasColumnType("bigint");
+
+ b.HasKey("Id");
+
+ b.HasIndex("InstanceId")
+ .IsUnique();
+
+ b.ToTable("DreamDaemonSettings");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.DreamMakerSettings", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint")
+ .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
+
+ b.Property("ApiValidationPort")
+ .HasColumnType("int");
+
+ b.Property("ApiValidationSecurityLevel")
+ .HasColumnType("int");
+
+ b.Property("InstanceId")
+ .HasColumnType("bigint");
+
+ b.Property("ProjectName")
+ .HasColumnType("nvarchar(max)")
+ .HasMaxLength(10000);
+
+ b.Property("RequireDMApiValidation")
+ .IsRequired()
+ .HasColumnType("bit");
+
+ b.HasKey("Id");
+
+ b.HasIndex("InstanceId")
+ .IsUnique();
+
+ b.ToTable("DreamMakerSettings");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.Instance", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint")
+ .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
+
+ b.Property("AutoUpdateInterval")
+ .HasColumnType("bigint");
+
+ b.Property("ChatBotLimit")
+ .HasColumnType("int");
+
+ b.Property("ConfigurationType")
+ .HasColumnType("int");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)")
+ .HasMaxLength(10000);
+
+ b.Property("Online")
+ .IsRequired()
+ .HasColumnType("bit");
+
+ b.Property("Path")
+ .IsRequired()
+ .HasColumnType("nvarchar(450)");
+
+ b.Property("SwarmIdentifer")
+ .HasColumnType("nvarchar(450)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Path", "SwarmIdentifer")
+ .IsUnique()
+ .HasFilter("[SwarmIdentifer] IS NOT NULL");
+
+ b.ToTable("Instances");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.InstancePermissionSet", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint")
+ .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
+
+ b.Property("ByondRights")
+ .HasColumnType("decimal(20,0)");
+
+ b.Property("ChatBotRights")
+ .HasColumnType("decimal(20,0)");
+
+ b.Property("ConfigurationRights")
+ .HasColumnType("decimal(20,0)");
+
+ b.Property("DreamDaemonRights")
+ .HasColumnType("decimal(20,0)");
+
+ b.Property("DreamMakerRights")
+ .HasColumnType("decimal(20,0)");
+
+ b.Property("InstanceId")
+ .HasColumnType("bigint");
+
+ b.Property("InstancePermissionSetRights")
+ .HasColumnType("decimal(20,0)");
+
+ b.Property("PermissionSetId")
+ .HasColumnType("bigint");
+
+ b.Property("RepositoryRights")
+ .HasColumnType("decimal(20,0)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("InstanceId");
+
+ b.HasIndex("PermissionSetId", "InstanceId")
+ .IsUnique();
+
+ b.ToTable("InstancePermissionSets");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.Job", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint")
+ .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
+
+ b.Property("CancelRight")
+ .HasColumnType("decimal(20,0)");
+
+ b.Property("CancelRightsType")
+ .HasColumnType("decimal(20,0)");
+
+ b.Property("Cancelled")
+ .IsRequired()
+ .HasColumnType("bit");
+
+ b.Property("CancelledById")
+ .HasColumnType("bigint");
+
+ b.Property("Description")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("ErrorCode")
+ .HasColumnType("bigint");
+
+ b.Property("ExceptionDetails")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("InstanceId")
+ .HasColumnType("bigint");
+
+ b.Property("StartedAt")
+ .IsRequired()
+ .HasColumnType("datetimeoffset");
+
+ b.Property("StartedById")
+ .HasColumnType("bigint");
+
+ b.Property("StoppedAt")
+ .HasColumnType("datetimeoffset");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CancelledById");
+
+ b.HasIndex("InstanceId");
+
+ b.HasIndex("StartedById");
+
+ b.ToTable("Jobs");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.OAuthConnection", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint")
+ .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
+
+ b.Property("ExternalUserId")
+ .IsRequired()
+ .HasColumnType("nvarchar(100)")
+ .HasMaxLength(100);
+
+ b.Property("Provider")
+ .HasColumnType("int");
+
+ b.Property("UserId")
+ .HasColumnType("bigint");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId");
+
+ b.HasIndex("Provider", "ExternalUserId")
+ .IsUnique();
+
+ b.ToTable("OAuthConnections");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.PermissionSet", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint")
+ .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
+
+ b.Property("AdministrationRights")
+ .HasColumnType("decimal(20,0)");
+
+ b.Property("GroupId")
+ .HasColumnType("bigint");
+
+ b.Property("InstanceManagerRights")
+ .HasColumnType("decimal(20,0)");
+
+ b.Property("UserId")
+ .HasColumnType("bigint");
+
+ b.HasKey("Id");
+
+ b.HasIndex("GroupId")
+ .IsUnique()
+ .HasFilter("[GroupId] IS NOT NULL");
+
+ b.HasIndex("UserId")
+ .IsUnique()
+ .HasFilter("[UserId] IS NOT NULL");
+
+ b.ToTable("PermissionSets");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.ReattachInformation", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint")
+ .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
+
+ b.Property("AccessIdentifier")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("CompileJobId")
+ .HasColumnType("bigint");
+
+ b.Property("LaunchSecurityLevel")
+ .HasColumnType("int");
+
+ b.Property("Port")
+ .HasColumnType("int");
+
+ b.Property("ProcessId")
+ .HasColumnType("int");
+
+ b.Property("RebootState")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CompileJobId");
+
+ b.ToTable("ReattachInformations");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.RepositorySettings", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint")
+ .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
+
+ b.Property("AccessToken")
+ .HasColumnType("nvarchar(max)")
+ .HasMaxLength(10000);
+
+ b.Property("AccessUser")
+ .HasColumnType("nvarchar(max)")
+ .HasMaxLength(10000);
+
+ b.Property("AutoUpdatesKeepTestMerges")
+ .IsRequired()
+ .HasColumnType("bit");
+
+ b.Property("AutoUpdatesSynchronize")
+ .IsRequired()
+ .HasColumnType("bit");
+
+ b.Property("CommitterEmail")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)")
+ .HasMaxLength(10000);
+
+ b.Property("CommitterName")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)")
+ .HasMaxLength(10000);
+
+ b.Property("CreateGitHubDeployments")
+ .IsRequired()
+ .HasColumnType("bit");
+
+ b.Property("InstanceId")
+ .HasColumnType("bigint");
+
+ b.Property("PostTestMergeComment")
+ .IsRequired()
+ .HasColumnType("bit");
+
+ b.Property("PushTestMergeCommits")
+ .IsRequired()
+ .HasColumnType("bit");
+
+ b.Property("ShowTestMergeCommitters")
+ .IsRequired()
+ .HasColumnType("bit");
+
+ b.HasKey("Id");
+
+ b.HasIndex("InstanceId")
+ .IsUnique();
+
+ b.ToTable("RepositorySettings");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.RevInfoTestMerge", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint")
+ .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
+
+ b.Property("RevisionInformationId")
+ .HasColumnType("bigint");
+
+ b.Property("TestMergeId")
+ .HasColumnType("bigint");
+
+ b.HasKey("Id");
+
+ b.HasIndex("RevisionInformationId");
+
+ b.HasIndex("TestMergeId");
+
+ b.ToTable("RevInfoTestMerges");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.RevisionInformation", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint")
+ .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
+
+ b.Property("CommitSha")
+ .IsRequired()
+ .HasColumnType("nvarchar(40)")
+ .HasMaxLength(40);
+
+ b.Property("InstanceId")
+ .HasColumnType("bigint");
+
+ b.Property("OriginCommitSha")
+ .IsRequired()
+ .HasColumnType("nvarchar(40)")
+ .HasMaxLength(40);
+
+ b.Property("Timestamp")
+ .HasColumnType("datetimeoffset");
+
+ b.HasKey("Id");
+
+ b.HasIndex("InstanceId", "CommitSha")
+ .IsUnique();
+
+ b.ToTable("RevisionInformations");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.TestMerge", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint")
+ .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
+
+ b.Property("Author")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("BodyAtMerge")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Comment")
+ .HasColumnType("nvarchar(max)")
+ .HasMaxLength(10000);
+
+ b.Property("MergedAt")
+ .HasColumnType("datetimeoffset");
+
+ b.Property("MergedById")
+ .HasColumnType("bigint");
+
+ b.Property("Number")
+ .HasColumnType("int");
+
+ b.Property("PrimaryRevisionInformationId")
+ .IsRequired()
+ .HasColumnType("bigint");
+
+ b.Property("TargetCommitSha")
+ .IsRequired()
+ .HasColumnType("nvarchar(40)")
+ .HasMaxLength(40);
+
+ b.Property("TitleAtMerge")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Url")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("MergedById");
+
+ b.HasIndex("PrimaryRevisionInformationId")
+ .IsUnique();
+
+ b.ToTable("TestMerges");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.User", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint")
+ .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
+
+ b.Property("CanonicalName")
+ .IsRequired()
+ .HasColumnType("nvarchar(100)")
+ .HasMaxLength(100);
+
+ b.Property("CreatedAt")
+ .IsRequired()
+ .HasColumnType("datetimeoffset");
+
+ b.Property("CreatedById")
+ .HasColumnType("bigint");
+
+ b.Property("Enabled")
+ .IsRequired()
+ .HasColumnType("bit");
+
+ b.Property("GroupId")
+ .HasColumnType("bigint");
+
+ b.Property("LastPasswordUpdate")
+ .HasColumnType("datetimeoffset");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("nvarchar(100)")
+ .HasMaxLength(100);
+
+ b.Property("PasswordHash")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("SystemIdentifier")
+ .HasColumnType("nvarchar(100)")
+ .HasMaxLength(100);
+
+ b.HasKey("Id");
+
+ b.HasIndex("CanonicalName")
+ .IsUnique();
+
+ b.HasIndex("CreatedById");
+
+ b.HasIndex("GroupId");
+
+ b.HasIndex("SystemIdentifier")
+ .IsUnique()
+ .HasFilter("[SystemIdentifier] IS NOT NULL");
+
+ b.ToTable("Users");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.UserGroup", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint")
+ .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("nvarchar(100)")
+ .HasMaxLength(100);
+
+ b.HasKey("Id");
+
+ b.HasIndex("Name")
+ .IsUnique();
+
+ b.ToTable("Groups");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.ChatBot", b =>
+ {
+ b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
+ .WithMany("ChatSettings")
+ .HasForeignKey("InstanceId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.ChatChannel", b =>
+ {
+ b.HasOne("Tgstation.Server.Host.Models.ChatBot", "ChatSettings")
+ .WithMany("Channels")
+ .HasForeignKey("ChatSettingsId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.CompileJob", b =>
+ {
+ b.HasOne("Tgstation.Server.Host.Models.Job", "Job")
+ .WithOne()
+ .HasForeignKey("Tgstation.Server.Host.Models.CompileJob", "JobId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Tgstation.Server.Host.Models.RevisionInformation", "RevisionInformation")
+ .WithMany("CompileJobs")
+ .HasForeignKey("RevisionInformationId")
+ .OnDelete(DeleteBehavior.ClientNoAction)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.DreamDaemonSettings", b =>
+ {
+ b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
+ .WithOne("DreamDaemonSettings")
+ .HasForeignKey("Tgstation.Server.Host.Models.DreamDaemonSettings", "InstanceId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.DreamMakerSettings", b =>
+ {
+ b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
+ .WithOne("DreamMakerSettings")
+ .HasForeignKey("Tgstation.Server.Host.Models.DreamMakerSettings", "InstanceId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.InstancePermissionSet", b =>
+ {
+ b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
+ .WithMany("InstancePermissionSets")
+ .HasForeignKey("InstanceId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Tgstation.Server.Host.Models.PermissionSet", "PermissionSet")
+ .WithMany("InstancePermissionSets")
+ .HasForeignKey("PermissionSetId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.Job", b =>
+ {
+ b.HasOne("Tgstation.Server.Host.Models.User", "CancelledBy")
+ .WithMany()
+ .HasForeignKey("CancelledById");
+
+ b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
+ .WithMany("Jobs")
+ .HasForeignKey("InstanceId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Tgstation.Server.Host.Models.User", "StartedBy")
+ .WithMany()
+ .HasForeignKey("StartedById")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.OAuthConnection", b =>
+ {
+ b.HasOne("Tgstation.Server.Host.Models.User", "User")
+ .WithMany("OAuthConnections")
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade);
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.PermissionSet", b =>
+ {
+ b.HasOne("Tgstation.Server.Host.Models.UserGroup", "Group")
+ .WithOne("PermissionSet")
+ .HasForeignKey("Tgstation.Server.Host.Models.PermissionSet", "GroupId")
+ .OnDelete(DeleteBehavior.Cascade);
+
+ b.HasOne("Tgstation.Server.Host.Models.User", "User")
+ .WithOne("PermissionSet")
+ .HasForeignKey("Tgstation.Server.Host.Models.PermissionSet", "UserId")
+ .OnDelete(DeleteBehavior.Cascade);
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.ReattachInformation", b =>
+ {
+ b.HasOne("Tgstation.Server.Host.Models.CompileJob", "CompileJob")
+ .WithMany()
+ .HasForeignKey("CompileJobId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.RepositorySettings", b =>
+ {
+ b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
+ .WithOne("RepositorySettings")
+ .HasForeignKey("Tgstation.Server.Host.Models.RepositorySettings", "InstanceId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.RevInfoTestMerge", b =>
+ {
+ b.HasOne("Tgstation.Server.Host.Models.RevisionInformation", "RevisionInformation")
+ .WithMany("ActiveTestMerges")
+ .HasForeignKey("RevisionInformationId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Tgstation.Server.Host.Models.TestMerge", "TestMerge")
+ .WithMany("RevisonInformations")
+ .HasForeignKey("TestMergeId")
+ .OnDelete(DeleteBehavior.ClientNoAction)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.RevisionInformation", b =>
+ {
+ b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance")
+ .WithMany("RevisionInformations")
+ .HasForeignKey("InstanceId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.TestMerge", b =>
+ {
+ b.HasOne("Tgstation.Server.Host.Models.User", "MergedBy")
+ .WithMany("TestMerges")
+ .HasForeignKey("MergedById")
+ .OnDelete(DeleteBehavior.Restrict)
+ .IsRequired();
+
+ b.HasOne("Tgstation.Server.Host.Models.RevisionInformation", "PrimaryRevisionInformation")
+ .WithOne("PrimaryTestMerge")
+ .HasForeignKey("Tgstation.Server.Host.Models.TestMerge", "PrimaryRevisionInformationId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.User", b =>
+ {
+ b.HasOne("Tgstation.Server.Host.Models.User", "CreatedBy")
+ .WithMany("CreatedUsers")
+ .HasForeignKey("CreatedById");
+
+ b.HasOne("Tgstation.Server.Host.Models.UserGroup", "Group")
+ .WithMany("Users")
+ .HasForeignKey("GroupId");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/src/Tgstation.Server.Host/Database/Migrations/20210112154040_MSAddRevInfoTimestamp.cs b/src/Tgstation.Server.Host/Database/Migrations/20210112154040_MSAddRevInfoTimestamp.cs
new file mode 100644
index 0000000000..73f94d358b
--- /dev/null
+++ b/src/Tgstation.Server.Host/Database/Migrations/20210112154040_MSAddRevInfoTimestamp.cs
@@ -0,0 +1,35 @@
+using System;
+using Microsoft.EntityFrameworkCore.Migrations;
+
+namespace Tgstation.Server.Host.Database.Migrations
+{
+ ///
+ /// Add the Timestamp column to RevisionInformations for MSSQL.
+ ///
+ public partial class MSAddRevInfoTimestamp : Migration
+ {
+ ///
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ if (migrationBuilder == null)
+ throw new ArgumentNullException(nameof(migrationBuilder));
+
+ migrationBuilder.AddColumn(
+ name: "Timestamp",
+ table: "RevisionInformations",
+ nullable: false,
+ defaultValue: new DateTimeOffset(new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified), new TimeSpan(0, 0, 0, 0, 0)));
+ }
+
+ ///
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ if (migrationBuilder == null)
+ throw new ArgumentNullException(nameof(migrationBuilder));
+
+ migrationBuilder.DropColumn(
+ name: "Timestamp",
+ table: "RevisionInformations");
+ }
+ }
+}
diff --git a/src/Tgstation.Server.Host/Database/Migrations/20210112154123_MYAddRevInfoTimestamp.Designer.cs b/src/Tgstation.Server.Host/Database/Migrations/20210112154123_MYAddRevInfoTimestamp.Designer.cs
new file mode 100644
index 0000000000..35e54bb9e7
--- /dev/null
+++ b/src/Tgstation.Server.Host/Database/Migrations/20210112154123_MYAddRevInfoTimestamp.Designer.cs
@@ -0,0 +1,886 @@
+//
+using System;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+
+namespace Tgstation.Server.Host.Database.Migrations
+{
+ [DbContext(typeof(MySqlDatabaseContext))]
+ [Migration("20210112154123_MYAddRevInfoTimestamp")]
+ partial class MYAddRevInfoTimestamp
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "3.1.10")
+ .HasAnnotation("Relational:MaxIdentifierLength", 64);
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.ChatBot", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ b.Property("ChannelLimit")
+ .IsRequired()
+ .HasColumnType("smallint unsigned");
+
+ b.Property("ConnectionString")
+ .IsRequired()
+ .HasColumnType("longtext CHARACTER SET utf8mb4")
+ .HasMaxLength(10000);
+
+ b.Property("Enabled")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("InstanceId")
+ .HasColumnType("bigint");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("varchar(100) CHARACTER SET utf8mb4")
+ .HasMaxLength(100);
+
+ b.Property("Provider")
+ .HasColumnType("int");
+
+ b.Property("ReconnectionInterval")
+ .IsRequired()
+ .HasColumnType("int unsigned");
+
+ b.HasKey("Id");
+
+ b.HasIndex("InstanceId", "Name")
+ .IsUnique();
+
+ b.ToTable("ChatBots");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.ChatChannel", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ b.Property("ChatSettingsId")
+ .HasColumnType("bigint");
+
+ b.Property("DiscordChannelId")
+ .HasColumnType("bigint unsigned");
+
+ b.Property("IrcChannel")
+ .HasColumnType("varchar(100) CHARACTER SET utf8mb4")
+ .HasMaxLength(100);
+
+ b.Property("IsAdminChannel")
+ .IsRequired()
+ .HasColumnType("tinyint(1)");
+
+ b.Property("IsUpdatesChannel")
+ .IsRequired()
+ .HasColumnType("tinyint(1)");
+
+ b.Property("IsWatchdogChannel")
+ .IsRequired()
+ .HasColumnType("tinyint(1)");
+
+ b.Property("Tag")
+ .HasColumnType("longtext CHARACTER SET utf8mb4")
+ .HasMaxLength(10000);
+
+ b.HasKey("Id");
+
+ b.HasIndex("ChatSettingsId", "DiscordChannelId")
+ .IsUnique();
+
+ b.HasIndex("ChatSettingsId", "IrcChannel")
+ .IsUnique();
+
+ b.ToTable("ChatChannels");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.CompileJob", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ b.Property("ByondVersion")
+ .IsRequired()
+ .HasColumnType("longtext CHARACTER SET utf8mb4");
+
+ b.Property("DMApiMajorVersion")
+ .HasColumnType("int");
+
+ b.Property("DMApiMinorVersion")
+ .HasColumnType("int");
+
+ b.Property("DMApiPatchVersion")
+ .HasColumnType("int");
+
+ b.Property("DirectoryName")
+ .IsRequired()
+ .HasColumnType("char(36)");
+
+ b.Property("DmeName")
+ .IsRequired()
+ .HasColumnType("longtext CHARACTER SET utf8mb4");
+
+ b.Property("GitHubDeploymentId")
+ .HasColumnType("int");
+
+ b.Property("GitHubRepoId")
+ .HasColumnType("bigint");
+
+ b.Property("JobId")
+ .HasColumnType("bigint");
+
+ b.Property("MinimumSecurityLevel")
+ .HasColumnType("int");
+
+ b.Property("Output")
+ .IsRequired()
+ .HasColumnType("longtext CHARACTER SET utf8mb4");
+
+ b.Property("RepositoryOrigin")
+ .HasColumnType("longtext CHARACTER SET utf8mb4");
+
+ b.Property("RevisionInformationId")
+ .HasColumnType("bigint");
+
+ b.HasKey("Id");
+
+ b.HasIndex("DirectoryName");
+
+ b.HasIndex("JobId")
+ .IsUnique();
+
+ b.HasIndex("RevisionInformationId");
+
+ b.ToTable("CompileJobs");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.DreamDaemonSettings", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ b.Property("AdditionalParameters")
+ .IsRequired()
+ .HasColumnType("longtext CHARACTER SET utf8mb4")
+ .HasMaxLength(10000);
+
+ b.Property("AllowWebClient")
+ .IsRequired()
+ .HasColumnType("tinyint(1)");
+
+ b.Property("AutoStart")
+ .IsRequired()
+ .HasColumnType("tinyint(1)");
+
+ b.Property("HeartbeatSeconds")
+ .IsRequired()
+ .HasColumnType("int unsigned");
+
+ b.Property("InstanceId")
+ .HasColumnType("bigint");
+
+ b.Property("Port")
+ .IsRequired()
+ .HasColumnType("smallint unsigned");
+
+ b.Property("SecurityLevel")
+ .HasColumnType("int");
+
+ b.Property("StartupTimeout")
+ .IsRequired()
+ .HasColumnType("int unsigned");
+
+ b.Property("TopicRequestTimeout")
+ .IsRequired()
+ .HasColumnType("int unsigned");
+
+ b.HasKey("Id");
+
+ b.HasIndex("InstanceId")
+ .IsUnique();
+
+ b.ToTable("DreamDaemonSettings");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.DreamMakerSettings", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ b.Property("ApiValidationPort")
+ .IsRequired()
+ .HasColumnType("smallint unsigned");
+
+ b.Property("ApiValidationSecurityLevel")
+ .HasColumnType("int");
+
+ b.Property("InstanceId")
+ .HasColumnType("bigint");
+
+ b.Property("ProjectName")
+ .HasColumnType("longtext CHARACTER SET utf8mb4")
+ .HasMaxLength(10000);
+
+ b.Property("RequireDMApiValidation")
+ .IsRequired()
+ .HasColumnType("tinyint(1)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("InstanceId")
+ .IsUnique();
+
+ b.ToTable("DreamMakerSettings");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.Instance", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ b.Property("AutoUpdateInterval")
+ .IsRequired()
+ .HasColumnType("int unsigned");
+
+ b.Property("ChatBotLimit")
+ .IsRequired()
+ .HasColumnType("smallint unsigned");
+
+ b.Property("ConfigurationType")
+ .HasColumnType("int");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("longtext CHARACTER SET utf8mb4")
+ .HasMaxLength(10000);
+
+ b.Property("Online")
+ .IsRequired()
+ .HasColumnType("tinyint(1)");
+
+ b.Property("Path")
+ .IsRequired()
+ .HasColumnType("varchar(255) CHARACTER SET utf8mb4");
+
+ b.Property("SwarmIdentifer")
+ .HasColumnType("varchar(255) CHARACTER SET utf8mb4");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Path", "SwarmIdentifer")
+ .IsUnique();
+
+ b.ToTable("Instances");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.InstancePermissionSet", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ b.Property("ByondRights")
+ .HasColumnType("bigint unsigned");
+
+ b.Property("ChatBotRights")
+ .HasColumnType("bigint unsigned");
+
+ b.Property("ConfigurationRights")
+ .HasColumnType("bigint unsigned");
+
+ b.Property("DreamDaemonRights")
+ .HasColumnType("bigint unsigned");
+
+ b.Property("DreamMakerRights")
+ .HasColumnType("bigint unsigned");
+
+ b.Property("InstanceId")
+ .HasColumnType("bigint");
+
+ b.Property("InstancePermissionSetRights")
+ .HasColumnType("bigint unsigned");
+
+ b.Property("PermissionSetId")
+ .HasColumnType("bigint");
+
+ b.Property("RepositoryRights")
+ .HasColumnType("bigint unsigned");
+
+ b.HasKey("Id");
+
+ b.HasIndex("InstanceId");
+
+ b.HasIndex("PermissionSetId", "InstanceId")
+ .IsUnique();
+
+ b.ToTable("InstancePermissionSets");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.Job", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ b.Property("CancelRight")
+ .HasColumnType("bigint unsigned");
+
+ b.Property("CancelRightsType")
+ .HasColumnType("bigint unsigned");
+
+ b.Property("Cancelled")
+ .IsRequired()
+ .HasColumnType("tinyint(1)");
+
+ b.Property("CancelledById")
+ .HasColumnType("bigint");
+
+ b.Property("Description")
+ .IsRequired()
+ .HasColumnType("longtext CHARACTER SET utf8mb4");
+
+ b.Property("ErrorCode")
+ .HasColumnType("int unsigned");
+
+ b.Property("ExceptionDetails")
+ .HasColumnType("longtext CHARACTER SET utf8mb4");
+
+ b.Property("InstanceId")
+ .HasColumnType("bigint");
+
+ b.Property("StartedAt")
+ .IsRequired()
+ .HasColumnType("datetime(6)");
+
+ b.Property("StartedById")
+ .HasColumnType("bigint");
+
+ b.Property("StoppedAt")
+ .HasColumnType("datetime(6)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CancelledById");
+
+ b.HasIndex("InstanceId");
+
+ b.HasIndex("StartedById");
+
+ b.ToTable("Jobs");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.OAuthConnection", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ b.Property("ExternalUserId")
+ .IsRequired()
+ .HasColumnType("varchar(100) CHARACTER SET utf8mb4")
+ .HasMaxLength(100);
+
+ b.Property("Provider")
+ .HasColumnType("int");
+
+ b.Property("UserId")
+ .HasColumnType("bigint");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId");
+
+ b.HasIndex("Provider", "ExternalUserId")
+ .IsUnique();
+
+ b.ToTable("OAuthConnections");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.PermissionSet", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ b.Property("AdministrationRights")
+ .HasColumnType("bigint unsigned");
+
+ b.Property("GroupId")
+ .HasColumnType("bigint");
+
+ b.Property("InstanceManagerRights")
+ .HasColumnType("bigint unsigned");
+
+ b.Property("UserId")
+ .HasColumnType("bigint");
+
+ b.HasKey("Id");
+
+ b.HasIndex("GroupId")
+ .IsUnique();
+
+ b.HasIndex("UserId")
+ .IsUnique();
+
+ b.ToTable("PermissionSets");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.ReattachInformation", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ b.Property("AccessIdentifier")
+ .IsRequired()
+ .HasColumnType("longtext CHARACTER SET utf8mb4");
+
+ b.Property("CompileJobId")
+ .HasColumnType("bigint");
+
+ b.Property("LaunchSecurityLevel")
+ .HasColumnType("int");
+
+ b.Property("Port")
+ .HasColumnType("smallint unsigned");
+
+ b.Property("ProcessId")
+ .HasColumnType("int");
+
+ b.Property("RebootState")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CompileJobId");
+
+ b.ToTable("ReattachInformations");
+ });
+
+ modelBuilder.Entity("Tgstation.Server.Host.Models.RepositorySettings", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ b.Property("AccessToken")
+ .HasColumnType("longtext CHARACTER SET utf8mb4")
+ .HasMaxLength(10000);
+
+ b.Property("AccessUser")
+ .HasColumnType("longtext CHARACTER SET utf8mb4")
+ .HasMaxLength(10000);
+
+ b.Property