mirror of
https://github.com/tgstation/tgstation-server.git
synced 2026-08-29 08:00:19 +01:00
+4
-4
@@ -5,15 +5,15 @@
|
||||
<PropertyGroup>
|
||||
<TgsCoreVersion>6.12.0</TgsCoreVersion>
|
||||
<TgsConfigVersion>5.4.0</TgsConfigVersion>
|
||||
<TgsRestVersion>10.11.0</TgsRestVersion>
|
||||
<TgsRestVersion>10.12.0</TgsRestVersion>
|
||||
<TgsGraphQLVersion>0.5.0</TgsGraphQLVersion>
|
||||
<TgsCommonLibraryVersion>7.0.0</TgsCommonLibraryVersion>
|
||||
<TgsApiLibraryVersion>16.2.0</TgsApiLibraryVersion>
|
||||
<TgsClientVersion>19.2.0</TgsClientVersion>
|
||||
<TgsApiLibraryVersion>16.3.0</TgsApiLibraryVersion>
|
||||
<TgsClientVersion>19.3.0</TgsClientVersion>
|
||||
<TgsDmapiVersion>7.3.0</TgsDmapiVersion>
|
||||
<TgsInteropVersion>5.10.0</TgsInteropVersion>
|
||||
<TgsHostWatchdogVersion>1.5.0</TgsHostWatchdogVersion>
|
||||
<TgsSwarmProtocolVersion>7.0.0</TgsSwarmProtocolVersion>
|
||||
<TgsSwarmProtocolVersion>8.0.0</TgsSwarmProtocolVersion>
|
||||
<TgsContainerScriptVersion>1.2.1</TgsContainerScriptVersion>
|
||||
<TgsMigratorVersion>2.0.0</TgsMigratorVersion>
|
||||
<TgsNugetNetFramework>netstandard2.0</TgsNugetNetFramework>
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace Tgstation.Server.Api.Models
|
||||
/// </summary>
|
||||
/// <remarks>Updates will not be triggered if the previous update is still running. Incompatible with <see cref="AutoUpdateInterval"/>.</remarks>
|
||||
[Required]
|
||||
[StringLength(Limits.MaximumStringLength)]
|
||||
[StringLength(Limits.CronStringLength)]
|
||||
public string? AutoUpdateCron { get; set; }
|
||||
|
||||
/// <summary>
|
||||
@@ -48,5 +48,21 @@ namespace Tgstation.Server.Api.Models
|
||||
/// </summary>
|
||||
[Required]
|
||||
public ushort? ChatBotLimit { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A cron expression indicating when the game server should start. Must be a valid 6 part cron schedule (SECONDS MINUTES HOURS DAY/MONTH MONTH DAY/WEEK). Empty <see cref="string"/> disables.
|
||||
/// </summary>
|
||||
/// <remarks>This will have no effect if the game server is already running when it fires.</remarks>
|
||||
[Required]
|
||||
[StringLength(Limits.CronStringLength)]
|
||||
public string? AutoStartCron { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A cron expression indicating when the game server should stop. Must be a valid 6 part cron schedule (SECONDS MINUTES HOURS DAY/MONTH MONTH DAY/WEEK). Empty <see cref="string"/> disables.
|
||||
/// </summary>
|
||||
/// <remarks>This will have no effect if the game server is not running when it fires.</remarks>
|
||||
[Required]
|
||||
[StringLength(Limits.CronStringLength)]
|
||||
public string? AutoStopCron { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,11 @@ namespace Tgstation.Server.Api.Models
|
||||
/// </summary>
|
||||
public const int MaximumStringLength = 10000;
|
||||
|
||||
/// <summary>
|
||||
/// Length limit for cron strings in fields.
|
||||
/// </summary>
|
||||
public const int CronStringLength = 1000;
|
||||
|
||||
/// <summary>
|
||||
/// Length limit for <see cref="NamedEntity.Name"/>s.
|
||||
/// </summary>
|
||||
|
||||
@@ -67,5 +67,15 @@ namespace Tgstation.Server.Api.Rights
|
||||
/// User can give themselves or their group full <see cref="InstancePermissionSetRights"/> on ALL instances.
|
||||
/// </summary>
|
||||
GrantPermissions = 1 << 10,
|
||||
|
||||
/// <summary>
|
||||
/// User can change <see cref="Models.Instance.AutoStartCron"/>.
|
||||
/// </summary>
|
||||
SetAutoStart = 1 << 11,
|
||||
|
||||
/// <summary>
|
||||
/// User can change <see cref="Models.Instance.AutoStopCron"/>.
|
||||
/// </summary>
|
||||
SetAutoStop = 1 << 12,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,5 +51,19 @@ namespace Tgstation.Server.Host.Components
|
||||
/// <param name="newCron">The new auto-update cron schedule.</param>
|
||||
/// <returns>A <see cref="ValueTask"/> representing the running operation.</returns>
|
||||
ValueTask ScheduleAutoUpdate(uint newInterval, string? newCron);
|
||||
|
||||
/// <summary>
|
||||
/// Change the server auto-start timing for the <see cref="IInstanceCore"/>.
|
||||
/// </summary>
|
||||
/// <param name="newCron">The new auto-start cron schedule.</param>
|
||||
/// <returns>A <see cref="ValueTask"/> representing the running operation.</returns>
|
||||
ValueTask ScheduleServerStart(string? newCron);
|
||||
|
||||
/// <summary>
|
||||
/// Change the server auto-stop timing for the <see cref="IInstanceCore"/>.
|
||||
/// </summary>
|
||||
/// <param name="newCron">The new auto-stop cron schedule.</param>
|
||||
/// <returns>A <see cref="ValueTask"/> representing the running operation.</returns>
|
||||
ValueTask ScheduleServerStop(string? newCron);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,19 +89,39 @@ namespace Tgstation.Server.Host.Components
|
||||
readonly Api.Models.Instance metadata;
|
||||
|
||||
/// <summary>
|
||||
/// <see langword="lock"/> <see cref="object"/> for <see cref="timerCts"/> and <see cref="timerTask"/>.
|
||||
/// <see langword="lock"/> <see cref="object"/> for <see cref="autoUpdateCts"/> and <see cref="autoUpdateTask"/>.
|
||||
/// </summary>
|
||||
readonly object timerLock;
|
||||
|
||||
/// <summary>
|
||||
/// The auto update <see cref="Task"/>.
|
||||
/// The auto-update <see cref="Task"/>.
|
||||
/// </summary>
|
||||
Task? timerTask;
|
||||
Task? autoUpdateTask;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="CancellationTokenSource"/> for <see cref="timerTask"/>.
|
||||
/// <see cref="CancellationTokenSource"/> for <see cref="autoUpdateTask"/>.
|
||||
/// </summary>
|
||||
CancellationTokenSource? timerCts;
|
||||
CancellationTokenSource? autoUpdateCts;
|
||||
|
||||
/// <summary>
|
||||
/// The auto-start <see cref="Task"/>.
|
||||
/// </summary>
|
||||
Task? autoStartTask;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="CancellationTokenSource"/> for <see cref="autoStartTask"/>.
|
||||
/// </summary>
|
||||
CancellationTokenSource? autoStartCts;
|
||||
|
||||
/// <summary>
|
||||
/// The auto-stop <see cref="Task"/>.
|
||||
/// </summary>
|
||||
Task? autoStopTask;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="CancellationTokenSource"/> for <see cref="autoStopTask"/>.
|
||||
/// </summary>
|
||||
CancellationTokenSource? autoStopCts;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Instance"/> class.
|
||||
@@ -159,7 +179,9 @@ namespace Tgstation.Server.Host.Components
|
||||
{
|
||||
var chatDispose = Chat.DisposeAsync();
|
||||
var watchdogDispose = Watchdog.DisposeAsync();
|
||||
timerCts?.Dispose();
|
||||
autoUpdateCts?.Dispose();
|
||||
autoStartCts?.Dispose();
|
||||
autoStopCts?.Dispose();
|
||||
Configuration.Dispose();
|
||||
dmbFactory.Dispose();
|
||||
RepositoryManager.Dispose();
|
||||
@@ -187,6 +209,8 @@ namespace Tgstation.Server.Host.Components
|
||||
{
|
||||
await Task.WhenAll(
|
||||
ScheduleAutoUpdate(metadata.Require(x => x.AutoUpdateInterval), metadata.AutoUpdateCron).AsTask(),
|
||||
ScheduleServerStart(null).AsTask(),
|
||||
ScheduleServerStop(null).AsTask(),
|
||||
Configuration.StartAsync(cancellationToken),
|
||||
EngineManager.StartAsync(cancellationToken),
|
||||
Chat.StartAsync(cancellationToken),
|
||||
@@ -223,14 +247,14 @@ namespace Tgstation.Server.Host.Components
|
||||
|
||||
Task toWait;
|
||||
lock (timerLock)
|
||||
if (timerTask != null)
|
||||
if (autoUpdateTask != null)
|
||||
{
|
||||
logger.LogTrace("Cancelling auto-update task");
|
||||
timerCts!.Cancel();
|
||||
timerCts.Dispose();
|
||||
toWait = timerTask;
|
||||
timerTask = null;
|
||||
timerCts = null;
|
||||
autoUpdateCts!.Cancel();
|
||||
autoUpdateCts.Dispose();
|
||||
toWait = autoUpdateTask;
|
||||
autoUpdateTask = null;
|
||||
autoUpdateCts = null;
|
||||
}
|
||||
else
|
||||
toWait = Task.CompletedTask;
|
||||
@@ -245,14 +269,95 @@ namespace Tgstation.Server.Host.Components
|
||||
lock (timerLock)
|
||||
{
|
||||
// race condition, just quit
|
||||
if (timerTask != null)
|
||||
if (autoUpdateTask != null)
|
||||
{
|
||||
logger.LogWarning("Aborting auto-update scheduling change due to race condition!");
|
||||
return;
|
||||
}
|
||||
|
||||
timerCts = new CancellationTokenSource();
|
||||
timerTask = TimerLoop(newInterval, newCron, timerCts.Token);
|
||||
autoUpdateCts = new CancellationTokenSource();
|
||||
autoUpdateTask = TimerLoop(AutoUpdateAction, "auto-update", newInterval, newCron, autoUpdateCts.Token);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async ValueTask ScheduleServerStart(string? newCron)
|
||||
{
|
||||
Task toWait;
|
||||
lock (timerLock)
|
||||
if (autoStartTask != null)
|
||||
{
|
||||
logger.LogTrace("Cancelling auto-start task");
|
||||
autoStartCts!.Cancel();
|
||||
autoStartCts.Dispose();
|
||||
toWait = autoStartTask;
|
||||
autoStartTask = null;
|
||||
autoStartCts = null;
|
||||
}
|
||||
else
|
||||
toWait = Task.CompletedTask;
|
||||
|
||||
await toWait;
|
||||
if (String.IsNullOrWhiteSpace(newCron))
|
||||
{
|
||||
logger.LogTrace("Auto-start disabled. Not starting task.");
|
||||
return;
|
||||
}
|
||||
|
||||
lock (timerLock)
|
||||
{
|
||||
// race condition, just quit
|
||||
if (autoStartTask != null)
|
||||
{
|
||||
logger.LogWarning("Aborting auto-start scheduling change due to race condition!");
|
||||
return;
|
||||
}
|
||||
|
||||
autoStartCts = new CancellationTokenSource();
|
||||
autoStartTask = TimerLoop(Watchdog.Launch, "auto-start", 0, newCron, autoStartCts.Token);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async ValueTask ScheduleServerStop(string? newCron)
|
||||
{
|
||||
Task toWait;
|
||||
lock (timerLock)
|
||||
if (autoStopTask != null)
|
||||
{
|
||||
logger.LogTrace("Cancelling auto-stop task");
|
||||
autoStopCts!.Cancel();
|
||||
autoStopCts.Dispose();
|
||||
toWait = autoStopTask;
|
||||
autoStopTask = null;
|
||||
autoStopCts = null;
|
||||
}
|
||||
else
|
||||
toWait = Task.CompletedTask;
|
||||
|
||||
await toWait;
|
||||
if (String.IsNullOrWhiteSpace(newCron))
|
||||
{
|
||||
logger.LogTrace("Auto-stop disabled. Not stoping task.");
|
||||
return;
|
||||
}
|
||||
|
||||
lock (timerLock)
|
||||
{
|
||||
// race condition, just quit
|
||||
if (autoStopTask != null)
|
||||
{
|
||||
logger.LogWarning("Aborting auto-stop scheduling change due to race condition!");
|
||||
return;
|
||||
}
|
||||
|
||||
autoStopCts = new CancellationTokenSource();
|
||||
autoStopTask = TimerLoop(
|
||||
async cancellationToken => await Watchdog.Terminate(true, cancellationToken),
|
||||
"auto-stop",
|
||||
0,
|
||||
newCron,
|
||||
autoStopCts.Token);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -485,14 +590,15 @@ namespace Tgstation.Server.Host.Components
|
||||
#pragma warning restore CA1502 // Cyclomatic complexity
|
||||
|
||||
/// <summary>
|
||||
/// Pull the repository and compile for every set of given <paramref name="minutes"/>.
|
||||
/// Runs a <paramref name="timerAction"/> every set of given <paramref name="minutes"/> or on a given <paramref name="cron"/> schedule.
|
||||
/// </summary>
|
||||
/// <param name="timerAction">The action to take when the timer elapses.</param>
|
||||
/// <param name="description">A description of the <paramref name="timerAction"/>.</param>
|
||||
/// <param name="minutes">How many minutes the operation should repeat. Does not include running time.</param>
|
||||
/// <param name="cron">Alternative cron schedule.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the running operation.</returns>
|
||||
#pragma warning disable CA1502 // TODO: Decomplexify
|
||||
async Task TimerLoop(uint minutes, string? cron, CancellationToken cancellationToken)
|
||||
async Task TimerLoop(Func<CancellationToken, ValueTask> timerAction, string description, uint minutes, string? cron, CancellationToken cancellationToken)
|
||||
{
|
||||
logger.LogDebug("Entering auto-update loop");
|
||||
while (true)
|
||||
@@ -519,76 +625,86 @@ namespace Tgstation.Server.Host.Components
|
||||
delay = TimeSpan.FromMinutes(minutes);
|
||||
}
|
||||
|
||||
logger.LogInformation("Next auto-update will occur at {time}", DateTimeOffset.UtcNow + delay);
|
||||
logger.LogInformation("Next {desc} will occur at {time}", description, DateTimeOffset.UtcNow + delay);
|
||||
|
||||
await asyncDelayer.Delay(delay, cancellationToken);
|
||||
logger.LogInformation("Beginning auto update...");
|
||||
await eventConsumer.HandleEvent(EventType.InstanceAutoUpdateStart, Enumerable.Empty<string>(), true, cancellationToken);
|
||||
|
||||
var repositoryUpdateJob = Job.Create(Api.Models.JobCode.RepositoryAutoUpdate, null, metadata, RepositoryRights.CancelPendingChanges);
|
||||
await jobManager.RegisterOperation(
|
||||
repositoryUpdateJob,
|
||||
RepositoryAutoUpdateJob,
|
||||
cancellationToken);
|
||||
|
||||
var repoUpdateJobResult = await jobManager.WaitForJobCompletion(repositoryUpdateJob, null, cancellationToken, cancellationToken);
|
||||
if (repoUpdateJobResult == false)
|
||||
{
|
||||
logger.LogWarning("Aborting auto-update due to repository update error!");
|
||||
continue;
|
||||
}
|
||||
|
||||
Job compileProcessJob;
|
||||
using (var repo = await RepositoryManager.LoadRepository(cancellationToken))
|
||||
{
|
||||
if (repo == null)
|
||||
throw new JobException(Api.Models.ErrorCode.RepoMissing);
|
||||
|
||||
var deploySha = repo.Head;
|
||||
if (deploySha == null)
|
||||
{
|
||||
logger.LogTrace("Aborting auto update, repository error!");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (deploySha == (await LatestCompileJob())?.RevisionInformation.CommitSha)
|
||||
{
|
||||
logger.LogTrace("Aborting auto update, same revision as latest CompileJob");
|
||||
continue;
|
||||
}
|
||||
|
||||
// finally set up the job
|
||||
compileProcessJob = Job.Create(Api.Models.JobCode.AutomaticDeployment, null, metadata, DreamMakerRights.CancelCompile);
|
||||
await jobManager.RegisterOperation(
|
||||
compileProcessJob,
|
||||
(core, databaseContextFactory, job, progressReporter, jobCancellationToken) =>
|
||||
{
|
||||
if (core != this)
|
||||
throw new InvalidOperationException(DifferentCoreExceptionMessage);
|
||||
return DreamMaker.DeploymentProcess(
|
||||
job,
|
||||
databaseContextFactory,
|
||||
progressReporter,
|
||||
jobCancellationToken);
|
||||
},
|
||||
cancellationToken);
|
||||
}
|
||||
|
||||
await jobManager.WaitForJobCompletion(compileProcessJob, null, default, cancellationToken);
|
||||
await timerAction(cancellationToken);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
logger.LogDebug("Cancelled auto update loop!");
|
||||
logger.LogDebug("Cancelled {desc} loop!", description);
|
||||
break;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
logger.LogError(e, "Error in auto update loop!");
|
||||
logger.LogError(e, "Error in {desc} loop!", description);
|
||||
continue;
|
||||
}
|
||||
|
||||
logger.LogTrace("Leaving auto update loop...");
|
||||
logger.LogTrace("Leaving {desc} loop...", description);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pulls the repository and compiles.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="ValueTask"/> representing the running operation.</returns>
|
||||
async ValueTask AutoUpdateAction(CancellationToken cancellationToken)
|
||||
{
|
||||
logger.LogInformation("Beginning auto update...");
|
||||
await eventConsumer.HandleEvent(EventType.InstanceAutoUpdateStart, Enumerable.Empty<string>(), true, cancellationToken);
|
||||
|
||||
var repositoryUpdateJob = Job.Create(Api.Models.JobCode.RepositoryAutoUpdate, null, metadata, RepositoryRights.CancelPendingChanges);
|
||||
await jobManager.RegisterOperation(
|
||||
repositoryUpdateJob,
|
||||
RepositoryAutoUpdateJob,
|
||||
cancellationToken);
|
||||
|
||||
var repoUpdateJobResult = await jobManager.WaitForJobCompletion(repositoryUpdateJob, null, cancellationToken, cancellationToken);
|
||||
if (repoUpdateJobResult == false)
|
||||
{
|
||||
logger.LogWarning("Aborting auto-update due to repository update error!");
|
||||
return;
|
||||
}
|
||||
|
||||
Job compileProcessJob;
|
||||
using (var repo = await RepositoryManager.LoadRepository(cancellationToken))
|
||||
{
|
||||
if (repo == null)
|
||||
throw new JobException(Api.Models.ErrorCode.RepoMissing);
|
||||
|
||||
var deploySha = repo.Head;
|
||||
if (deploySha == null)
|
||||
{
|
||||
logger.LogTrace("Aborting auto update, repository error!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (deploySha == (await LatestCompileJob())?.RevisionInformation.CommitSha)
|
||||
{
|
||||
logger.LogTrace("Aborting auto update, same revision as latest CompileJob");
|
||||
return;
|
||||
}
|
||||
|
||||
// finally set up the job
|
||||
compileProcessJob = Job.Create(Api.Models.JobCode.AutomaticDeployment, null, metadata, DreamMakerRights.CancelCompile);
|
||||
await jobManager.RegisterOperation(
|
||||
compileProcessJob,
|
||||
(core, databaseContextFactory, job, progressReporter, jobCancellationToken) =>
|
||||
{
|
||||
if (core != this)
|
||||
throw new InvalidOperationException(DifferentCoreExceptionMessage);
|
||||
return DreamMaker.DeploymentProcess(
|
||||
job,
|
||||
databaseContextFactory,
|
||||
progressReporter,
|
||||
jobCancellationToken);
|
||||
},
|
||||
cancellationToken);
|
||||
}
|
||||
|
||||
await jobManager.WaitForJobCompletion(compileProcessJob, null, default, cancellationToken);
|
||||
}
|
||||
#pragma warning restore CA1502
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,5 +59,11 @@ namespace Tgstation.Server.Host.Components
|
||||
|
||||
/// <inheritdoc />
|
||||
public ValueTask<CompileJob?> LatestCompileJob() => Instance.LatestCompileJob();
|
||||
|
||||
/// <inheritdoc />
|
||||
public ValueTask ScheduleServerStart(string? newCron) => Instance.ScheduleServerStart(newCron);
|
||||
|
||||
/// <inheritdoc />
|
||||
public ValueTask ScheduleServerStop(string? newCron) => Instance.ScheduleServerStop(newCron);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,7 +124,7 @@ namespace Tgstation.Server.Host.Controllers
|
||||
/// Attempt to perform a server upgrade.
|
||||
/// </summary>
|
||||
/// <param name="model">The <see cref="ServerUpdateRequest"/>.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <param name="cancellationToken">The <see cref="Cancellati6onToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="ValueTask{TResult}"/> resulting in the <see cref="IActionResult"/> for the operation.</returns>
|
||||
/// <response code="202">Update has been started successfully.</response>
|
||||
/// <response code="410">The requested release version could not be found in the target GitHub repository.</response>
|
||||
|
||||
@@ -20,6 +20,7 @@ using Tgstation.Server.Api.Models;
|
||||
using Tgstation.Server.Api.Models.Request;
|
||||
using Tgstation.Server.Api.Models.Response;
|
||||
using Tgstation.Server.Api.Rights;
|
||||
using Tgstation.Server.Common.Extensions;
|
||||
using Tgstation.Server.Host.Components;
|
||||
using Tgstation.Server.Host.Configuration;
|
||||
using Tgstation.Server.Host.Controllers.Results;
|
||||
@@ -341,7 +342,15 @@ namespace Tgstation.Server.Host.Controllers
|
||||
/// <response code="202">Instance updated successfully and relocation job created.</response>
|
||||
/// <response code="410">The database entity for the requested instance could not be retrieved. The instance was likely detached.</response>
|
||||
[HttpPost]
|
||||
[TgsAuthorize(InstanceManagerRights.Relocate | InstanceManagerRights.Rename | InstanceManagerRights.SetAutoUpdate | InstanceManagerRights.SetConfiguration | InstanceManagerRights.SetOnline | InstanceManagerRights.SetChatBotLimit)]
|
||||
[TgsAuthorize(
|
||||
InstanceManagerRights.Relocate
|
||||
| InstanceManagerRights.Rename
|
||||
| InstanceManagerRights.SetAutoUpdate
|
||||
| InstanceManagerRights.SetConfiguration
|
||||
| InstanceManagerRights.SetOnline
|
||||
| InstanceManagerRights.SetChatBotLimit
|
||||
| InstanceManagerRights.SetAutoStart
|
||||
| InstanceManagerRights.SetAutoStop)]
|
||||
[ProducesResponseType(typeof(InstanceResponse), 200)]
|
||||
[ProducesResponseType(typeof(InstanceResponse), 202)]
|
||||
[ProducesResponseType(typeof(ErrorMessageResponse), 410)]
|
||||
@@ -422,13 +431,18 @@ namespace Tgstation.Server.Host.Controllers
|
||||
|
||||
var oldAutoUpdateInterval = originalModel.AutoUpdateInterval!.Value;
|
||||
var oldAutoUpdateCron = originalModel.AutoUpdateCron;
|
||||
var oldAutoStartCron = originalModel.AutoStartCron;
|
||||
var oldAutoStopCron = originalModel.AutoStopCron;
|
||||
|
||||
var earlyOut = ValidateCronSetting(model);
|
||||
if (earlyOut != null)
|
||||
return earlyOut;
|
||||
|
||||
var changedAutoInterval = model.AutoUpdateInterval.HasValue && oldAutoUpdateInterval != model.AutoUpdateInterval;
|
||||
var changedAutoCron = model.AutoUpdateCron != null && oldAutoUpdateCron != model.AutoUpdateCron;
|
||||
var changedAutoUpdateInterval = model.AutoUpdateInterval.HasValue && oldAutoUpdateInterval != model.AutoUpdateInterval;
|
||||
var changedAutoUpdateCron = model.AutoUpdateCron != null && oldAutoUpdateCron != model.AutoUpdateCron;
|
||||
|
||||
var changedAutoStart = model.AutoStartCron != null && oldAutoStartCron != model.AutoStartCron;
|
||||
var changedAutoStop = model.AutoStopCron != null && oldAutoStopCron != model.AutoStopCron;
|
||||
|
||||
var renamed = model.Name != null && originalModel.Name != model.Name;
|
||||
|
||||
@@ -437,7 +451,9 @@ namespace Tgstation.Server.Host.Controllers
|
||||
|| CheckModified(x => x.ConfigurationType, InstanceManagerRights.SetConfiguration)
|
||||
|| CheckModified(x => x.Name, InstanceManagerRights.Rename)
|
||||
|| CheckModified(x => x.Online, InstanceManagerRights.SetOnline)
|
||||
|| CheckModified(x => x.ChatBotLimit, InstanceManagerRights.SetChatBotLimit))
|
||||
|| CheckModified(x => x.ChatBotLimit, InstanceManagerRights.SetChatBotLimit)
|
||||
|| CheckModified(x => x.AutoStartCron, InstanceManagerRights.SetAutoStart)
|
||||
|| CheckModified(x => x.AutoStopCron, InstanceManagerRights.SetAutoStop))
|
||||
return Forbid();
|
||||
|
||||
if (model.ChatBotLimit.HasValue)
|
||||
@@ -452,9 +468,9 @@ namespace Tgstation.Server.Host.Controllers
|
||||
return Conflict(new ErrorMessageResponse(ErrorCode.ChatBotMax));
|
||||
}
|
||||
|
||||
if (changedAutoCron)
|
||||
if (changedAutoUpdateCron)
|
||||
model.AutoUpdateInterval = 0;
|
||||
else if (changedAutoInterval)
|
||||
else if (changedAutoUpdateInterval)
|
||||
model.AutoUpdateCron = String.Empty;
|
||||
|
||||
await DatabaseContext.Save(cancellationToken);
|
||||
@@ -518,13 +534,27 @@ namespace Tgstation.Server.Host.Controllers
|
||||
api.MoveJob = job.ToApi();
|
||||
}
|
||||
|
||||
if (changedAutoInterval || changedAutoCron)
|
||||
var changedAutoUpdate = changedAutoUpdateInterval || changedAutoUpdateCron;
|
||||
if (changedAutoUpdate || changedAutoStart || changedAutoStop)
|
||||
{
|
||||
// ignoring retval because we don't care if it's offline
|
||||
await WithComponentInstanceNullable(
|
||||
async componentInstance =>
|
||||
{
|
||||
await componentInstance.ScheduleAutoUpdate(model.AutoUpdateInterval!.Value, model.AutoUpdateCron);
|
||||
var autoUpdateTask = changedAutoUpdate
|
||||
? componentInstance.ScheduleAutoUpdate(model.AutoUpdateInterval!.Value, model.AutoUpdateCron)
|
||||
: ValueTask.CompletedTask;
|
||||
|
||||
var autoStartTask = changedAutoStart
|
||||
? componentInstance.ScheduleServerStart(model.AutoStartCron)
|
||||
: ValueTask.CompletedTask;
|
||||
|
||||
var autoStopTask = changedAutoStop
|
||||
? componentInstance.ScheduleServerStop(model.AutoStopCron)
|
||||
: ValueTask.CompletedTask;
|
||||
|
||||
await ValueTaskExtensions.WhenAll(autoUpdateTask, autoStartTask, autoStopTask);
|
||||
|
||||
return null;
|
||||
},
|
||||
originalModel);
|
||||
@@ -769,6 +799,8 @@ namespace Tgstation.Server.Host.Controllers
|
||||
Path = initialSettings.Path,
|
||||
AutoUpdateInterval = initialSettings.AutoUpdateInterval ?? 0,
|
||||
AutoUpdateCron = initialSettings.AutoUpdateCron ?? String.Empty,
|
||||
AutoStartCron = initialSettings.AutoStartCron ?? String.Empty,
|
||||
AutoStopCron = initialSettings.AutoStopCron ?? String.Empty,
|
||||
ChatBotLimit = initialSettings.ChatBotLimit ?? Models.Instance.DefaultChatBotLimit,
|
||||
RepositorySettings = new Models.RepositorySettings
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
@@ -451,22 +451,22 @@ namespace Tgstation.Server.Host.Database
|
||||
/// <summary>
|
||||
/// Used by unit tests to remind us to setup the correct MSSQL migration downgrades.
|
||||
/// </summary>
|
||||
internal static readonly Type MSLatestMigration = typeof(MSAddDMApiValidationMode);
|
||||
internal static readonly Type MSLatestMigration = typeof(MSAddAutoStartAndStop);
|
||||
|
||||
/// <summary>
|
||||
/// Used by unit tests to remind us to setup the correct MYSQL migration downgrades.
|
||||
/// </summary>
|
||||
internal static readonly Type MYLatestMigration = typeof(MYAddDMApiValidationMode);
|
||||
internal static readonly Type MYLatestMigration = typeof(MYAddAutoStartAndStop);
|
||||
|
||||
/// <summary>
|
||||
/// Used by unit tests to remind us to setup the correct PostgresSQL migration downgrades.
|
||||
/// </summary>
|
||||
internal static readonly Type PGLatestMigration = typeof(PGAddDMApiValidationMode);
|
||||
internal static readonly Type PGLatestMigration = typeof(PGAddAutoStartAndStop);
|
||||
|
||||
/// <summary>
|
||||
/// Used by unit tests to remind us to setup the correct SQLite migration downgrades.
|
||||
/// </summary>
|
||||
internal static readonly Type SLLatestMigration = typeof(SLAddDMApiValidationMode);
|
||||
internal static readonly Type SLLatestMigration = typeof(SLAddAutoStartAndStop);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the migration to run for migrating down to a given <paramref name="targetVersion"/> for the <paramref name="currentDatabaseType"/>.
|
||||
@@ -482,6 +482,16 @@ namespace Tgstation.Server.Host.Database
|
||||
string BadDatabaseType() => throw new ArgumentException($"Invalid DatabaseType: {currentDatabaseType}", nameof(currentDatabaseType));
|
||||
|
||||
// !!! DON'T FORGET TO UPDATE THE SWARM PROTOCOL MAJOR VERSION !!!
|
||||
if (targetVersion < new Version(6, 12, 0))
|
||||
targetMigration = currentDatabaseType switch
|
||||
{
|
||||
DatabaseType.MySql => nameof(MYAddDMApiValidationMode),
|
||||
DatabaseType.PostgresSql => nameof(PGAddDMApiValidationMode),
|
||||
DatabaseType.SqlServer => nameof(MSAddDMApiValidationMode),
|
||||
DatabaseType.Sqlite => nameof(SLAddDMApiValidationMode),
|
||||
_ => BadDatabaseType(),
|
||||
};
|
||||
|
||||
if (targetVersion < new Version(6, 7, 0))
|
||||
targetMigration = currentDatabaseType switch
|
||||
{
|
||||
|
||||
Generated
+1102
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,84 @@
|
||||
using System;
|
||||
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
namespace Tgstation.Server.Host.Database
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class MSAddAutoStartAndStop : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(migrationBuilder);
|
||||
|
||||
migrationBuilder.AlterColumn<long>(
|
||||
name: "UserId",
|
||||
table: "OAuthConnections",
|
||||
type: "bigint",
|
||||
nullable: false,
|
||||
defaultValue: 0L,
|
||||
oldClrType: typeof(long),
|
||||
oldType: "bigint",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "AutoUpdateCron",
|
||||
table: "Instances",
|
||||
type: "nvarchar(1000)",
|
||||
maxLength: 1000,
|
||||
nullable: false,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "nvarchar(max)",
|
||||
oldMaxLength: 10000);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "AutoStartCron",
|
||||
table: "Instances",
|
||||
type: "nvarchar(1000)",
|
||||
maxLength: 1000,
|
||||
nullable: false,
|
||||
defaultValue: String.Empty);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "AutoStopCron",
|
||||
table: "Instances",
|
||||
type: "nvarchar(1000)",
|
||||
maxLength: 1000,
|
||||
nullable: false,
|
||||
defaultValue: String.Empty);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(migrationBuilder);
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "AutoStartCron",
|
||||
table: "Instances");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "AutoStopCron",
|
||||
table: "Instances");
|
||||
|
||||
migrationBuilder.AlterColumn<long>(
|
||||
name: "UserId",
|
||||
table: "OAuthConnections",
|
||||
type: "bigint",
|
||||
nullable: true,
|
||||
oldClrType: typeof(long),
|
||||
oldType: "bigint");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "AutoUpdateCron",
|
||||
table: "Instances",
|
||||
type: "nvarchar(max)",
|
||||
maxLength: 10000,
|
||||
nullable: false,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "nvarchar(1000)",
|
||||
oldMaxLength: 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
Generated
+1173
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,90 @@
|
||||
using System;
|
||||
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
namespace Tgstation.Server.Host.Database
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class MYAddAutoStartAndStop : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(migrationBuilder);
|
||||
|
||||
migrationBuilder.AlterColumn<long>(
|
||||
name: "UserId",
|
||||
table: "OAuthConnections",
|
||||
type: "bigint",
|
||||
nullable: false,
|
||||
defaultValue: 0L,
|
||||
oldClrType: typeof(long),
|
||||
oldType: "bigint",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "AutoUpdateCron",
|
||||
table: "Instances",
|
||||
type: "varchar(1000)",
|
||||
maxLength: 1000,
|
||||
nullable: false,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "varchar(10000)",
|
||||
oldMaxLength: 10000)
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "AutoStartCron",
|
||||
table: "Instances",
|
||||
type: "varchar(1000)",
|
||||
maxLength: 1000,
|
||||
nullable: false,
|
||||
defaultValue: String.Empty)
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "AutoStopCron",
|
||||
table: "Instances",
|
||||
type: "varchar(1000)",
|
||||
maxLength: 1000,
|
||||
nullable: false,
|
||||
defaultValue: String.Empty)
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(migrationBuilder);
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "AutoStartCron",
|
||||
table: "Instances");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "AutoStopCron",
|
||||
table: "Instances");
|
||||
|
||||
migrationBuilder.AlterColumn<long>(
|
||||
name: "UserId",
|
||||
table: "OAuthConnections",
|
||||
type: "bigint",
|
||||
nullable: true,
|
||||
oldClrType: typeof(long),
|
||||
oldType: "bigint");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "AutoUpdateCron",
|
||||
table: "Instances",
|
||||
type: "varchar(10000)",
|
||||
maxLength: 10000,
|
||||
nullable: false,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "varchar(1000)",
|
||||
oldMaxLength: 1000)
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
.OldAnnotation("MySql:CharSet", "utf8mb4");
|
||||
}
|
||||
}
|
||||
}
|
||||
Generated
+1096
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,84 @@
|
||||
using System;
|
||||
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
namespace Tgstation.Server.Host.Database
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class PGAddAutoStartAndStop : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(migrationBuilder);
|
||||
|
||||
migrationBuilder.AlterColumn<long>(
|
||||
name: "UserId",
|
||||
table: "OAuthConnections",
|
||||
type: "bigint",
|
||||
nullable: false,
|
||||
defaultValue: 0L,
|
||||
oldClrType: typeof(long),
|
||||
oldType: "bigint",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "AutoUpdateCron",
|
||||
table: "Instances",
|
||||
type: "character varying(1000)",
|
||||
maxLength: 1000,
|
||||
nullable: false,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "character varying(10000)",
|
||||
oldMaxLength: 10000);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "AutoStartCron",
|
||||
table: "Instances",
|
||||
type: "character varying(1000)",
|
||||
maxLength: 1000,
|
||||
nullable: false,
|
||||
defaultValue: String.Empty);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "AutoStopCron",
|
||||
table: "Instances",
|
||||
type: "character varying(1000)",
|
||||
maxLength: 1000,
|
||||
nullable: false,
|
||||
defaultValue: String.Empty);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(migrationBuilder);
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "AutoStartCron",
|
||||
table: "Instances");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "AutoStopCron",
|
||||
table: "Instances");
|
||||
|
||||
migrationBuilder.AlterColumn<long>(
|
||||
name: "UserId",
|
||||
table: "OAuthConnections",
|
||||
type: "bigint",
|
||||
nullable: true,
|
||||
oldClrType: typeof(long),
|
||||
oldType: "bigint");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "AutoUpdateCron",
|
||||
table: "Instances",
|
||||
type: "character varying(10000)",
|
||||
maxLength: 10000,
|
||||
nullable: false,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "character varying(1000)",
|
||||
oldMaxLength: 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
Generated
+1069
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,64 @@
|
||||
using System;
|
||||
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
namespace Tgstation.Server.Host.Database
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class SLAddAutoStartAndStop : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(migrationBuilder);
|
||||
|
||||
migrationBuilder.AlterColumn<long>(
|
||||
name: "UserId",
|
||||
table: "OAuthConnections",
|
||||
type: "INTEGER",
|
||||
nullable: false,
|
||||
defaultValue: 0L,
|
||||
oldClrType: typeof(long),
|
||||
oldType: "INTEGER",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "AutoStartCron",
|
||||
table: "Instances",
|
||||
type: "TEXT",
|
||||
maxLength: 1000,
|
||||
nullable: false,
|
||||
defaultValue: String.Empty);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "AutoStopCron",
|
||||
table: "Instances",
|
||||
type: "TEXT",
|
||||
maxLength: 1000,
|
||||
nullable: false,
|
||||
defaultValue: String.Empty);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(migrationBuilder);
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "AutoStartCron",
|
||||
table: "Instances");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "AutoStopCron",
|
||||
table: "Instances");
|
||||
|
||||
migrationBuilder.AlterColumn<long>(
|
||||
name: "UserId",
|
||||
table: "OAuthConnections",
|
||||
type: "INTEGER",
|
||||
nullable: true,
|
||||
oldClrType: typeof(long),
|
||||
oldType: "INTEGER");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@ using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
|
||||
namespace Tgstation.Server.Host.Database.Migrations
|
||||
namespace Tgstation.Server.Host.Database
|
||||
{
|
||||
[DbContext(typeof(MySqlDatabaseContext))]
|
||||
partial class MySqlDatabaseContextModelSnapshot : ModelSnapshot
|
||||
@@ -13,7 +13,7 @@ namespace Tgstation.Server.Host.Database.Migrations
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "8.0.8")
|
||||
.HasAnnotation("ProductVersion", "8.0.10")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 64);
|
||||
|
||||
MySqlModelBuilderExtensions.AutoIncrementColumns(modelBuilder);
|
||||
@@ -318,10 +318,20 @@ namespace Tgstation.Server.Host.Database.Migrations
|
||||
|
||||
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<long?>("Id"));
|
||||
|
||||
b.Property<string>("AutoStartCron")
|
||||
.IsRequired()
|
||||
.HasMaxLength(1000)
|
||||
.HasColumnType("varchar(1000)");
|
||||
|
||||
b.Property<string>("AutoStopCron")
|
||||
.IsRequired()
|
||||
.HasMaxLength(1000)
|
||||
.HasColumnType("varchar(1000)");
|
||||
|
||||
b.Property<string>("AutoUpdateCron")
|
||||
.IsRequired()
|
||||
.HasMaxLength(10000)
|
||||
.HasColumnType("varchar(10000)");
|
||||
.HasMaxLength(1000)
|
||||
.HasColumnType("varchar(1000)");
|
||||
|
||||
b.Property<uint?>("AutoUpdateInterval")
|
||||
.IsRequired()
|
||||
@@ -489,7 +499,7 @@ namespace Tgstation.Server.Host.Database.Migrations
|
||||
b.Property<int>("Provider")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<long?>("UserId")
|
||||
b.Property<long>("UserId")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.HasKey("Id");
|
||||
@@ -980,7 +990,8 @@ namespace Tgstation.Server.Host.Database.Migrations
|
||||
b.HasOne("Tgstation.Server.Host.Models.User", "User")
|
||||
.WithMany("OAuthConnections")
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
+17
-6
@@ -4,7 +4,7 @@ using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
|
||||
namespace Tgstation.Server.Host.Database.Migrations
|
||||
namespace Tgstation.Server.Host.Database
|
||||
{
|
||||
[DbContext(typeof(PostgresSqlDatabaseContext))]
|
||||
partial class PostgresSqlDatabaseContextModelSnapshot : ModelSnapshot
|
||||
@@ -13,7 +13,7 @@ namespace Tgstation.Server.Host.Database.Migrations
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "8.0.8")
|
||||
.HasAnnotation("ProductVersion", "8.0.10")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||
|
||||
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||
@@ -291,10 +291,20 @@ namespace Tgstation.Server.Host.Database.Migrations
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long?>("Id"));
|
||||
|
||||
b.Property<string>("AutoStartCron")
|
||||
.IsRequired()
|
||||
.HasMaxLength(1000)
|
||||
.HasColumnType("character varying(1000)");
|
||||
|
||||
b.Property<string>("AutoStopCron")
|
||||
.IsRequired()
|
||||
.HasMaxLength(1000)
|
||||
.HasColumnType("character varying(1000)");
|
||||
|
||||
b.Property<string>("AutoUpdateCron")
|
||||
.IsRequired()
|
||||
.HasMaxLength(10000)
|
||||
.HasColumnType("character varying(10000)");
|
||||
.HasMaxLength(1000)
|
||||
.HasColumnType("character varying(1000)");
|
||||
|
||||
b.Property<long>("AutoUpdateInterval")
|
||||
.HasColumnType("bigint");
|
||||
@@ -448,7 +458,7 @@ namespace Tgstation.Server.Host.Database.Migrations
|
||||
b.Property<int>("Provider")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<long?>("UserId")
|
||||
b.Property<long>("UserId")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.HasKey("Id");
|
||||
@@ -903,7 +913,8 @@ namespace Tgstation.Server.Host.Database.Migrations
|
||||
b.HasOne("Tgstation.Server.Host.Models.User", "User")
|
||||
.WithMany("OAuthConnections")
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
+17
-6
@@ -4,7 +4,7 @@ using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
|
||||
namespace Tgstation.Server.Host.Database.Migrations
|
||||
namespace Tgstation.Server.Host.Database
|
||||
{
|
||||
[DbContext(typeof(SqlServerDatabaseContext))]
|
||||
partial class SqlServerDatabaseContextModelSnapshot : ModelSnapshot
|
||||
@@ -13,7 +13,7 @@ namespace Tgstation.Server.Host.Database.Migrations
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "8.0.8")
|
||||
.HasAnnotation("ProductVersion", "8.0.10")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
||||
|
||||
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
||||
@@ -293,10 +293,20 @@ namespace Tgstation.Server.Host.Database.Migrations
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long?>("Id"));
|
||||
|
||||
b.Property<string>("AutoStartCron")
|
||||
.IsRequired()
|
||||
.HasMaxLength(1000)
|
||||
.HasColumnType("nvarchar(1000)");
|
||||
|
||||
b.Property<string>("AutoStopCron")
|
||||
.IsRequired()
|
||||
.HasMaxLength(1000)
|
||||
.HasColumnType("nvarchar(1000)");
|
||||
|
||||
b.Property<string>("AutoUpdateCron")
|
||||
.IsRequired()
|
||||
.HasMaxLength(10000)
|
||||
.HasColumnType("nvarchar(max)");
|
||||
.HasMaxLength(1000)
|
||||
.HasColumnType("nvarchar(1000)");
|
||||
|
||||
b.Property<long>("AutoUpdateInterval")
|
||||
.HasColumnType("bigint");
|
||||
@@ -451,7 +461,7 @@ namespace Tgstation.Server.Host.Database.Migrations
|
||||
b.Property<int>("Provider")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<long?>("UserId")
|
||||
b.Property<long>("UserId")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.HasKey("Id");
|
||||
@@ -909,7 +919,8 @@ namespace Tgstation.Server.Host.Database.Migrations
|
||||
b.HasOne("Tgstation.Server.Host.Models.User", "User")
|
||||
.WithMany("OAuthConnections")
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
+16
-5
@@ -4,7 +4,7 @@ using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
|
||||
namespace Tgstation.Server.Host.Database.Migrations
|
||||
namespace Tgstation.Server.Host.Database
|
||||
{
|
||||
[DbContext(typeof(SqliteDatabaseContext))]
|
||||
partial class SqliteDatabaseContextModelSnapshot : ModelSnapshot
|
||||
@@ -12,7 +12,7 @@ namespace Tgstation.Server.Host.Database.Migrations
|
||||
protected override void BuildModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder.HasAnnotation("ProductVersion", "8.0.8");
|
||||
modelBuilder.HasAnnotation("ProductVersion", "8.0.10");
|
||||
|
||||
modelBuilder.Entity("Tgstation.Server.Host.Models.ChatBot", b =>
|
||||
{
|
||||
@@ -284,9 +284,19 @@ namespace Tgstation.Server.Host.Database.Migrations
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("AutoStartCron")
|
||||
.IsRequired()
|
||||
.HasMaxLength(1000)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("AutoStopCron")
|
||||
.IsRequired()
|
||||
.HasMaxLength(1000)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("AutoUpdateCron")
|
||||
.IsRequired()
|
||||
.HasMaxLength(10000)
|
||||
.HasMaxLength(1000)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<uint?>("AutoUpdateInterval")
|
||||
@@ -437,7 +447,7 @@ namespace Tgstation.Server.Host.Database.Migrations
|
||||
b.Property<int>("Provider")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<long?>("UserId")
|
||||
b.Property<long>("UserId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Id");
|
||||
@@ -876,7 +886,8 @@ namespace Tgstation.Server.Host.Database.Migrations
|
||||
b.HasOne("Tgstation.Server.Host.Models.User", "User")
|
||||
.WithMany("OAuthConnections")
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
@@ -76,6 +76,8 @@ namespace Tgstation.Server.Host.Models
|
||||
Path = Path,
|
||||
Online = Online,
|
||||
ChatBotLimit = ChatBotLimit,
|
||||
AutoStartCron = AutoStartCron,
|
||||
AutoStopCron = AutoStopCron,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,6 +109,8 @@ namespace Tgstation.Server.Tests
|
||||
ChatBotLimit = 1,
|
||||
ChatSettings = new List<Host.Models.ChatBot>(),
|
||||
ConfigurationType = ConfigurationType.HostWrite,
|
||||
AutoStartCron = String.Empty,
|
||||
AutoStopCron = String.Empty,
|
||||
DreamDaemonSettings = new Host.Models.DreamDaemonSettings
|
||||
{
|
||||
AllowWebClient = false,
|
||||
|
||||
Reference in New Issue
Block a user