mirror of
https://github.com/tgstation/tgstation-server.git
synced 2026-07-15 01:52:54 +01:00
Fix a ton of shit
This commit is contained in:
@@ -33,7 +33,8 @@ namespace Tgstation.Server.Api.Models.Internal
|
||||
/// When the <see cref="Job"/> was started
|
||||
/// </summary>
|
||||
[Permissions(DenyWrite = true)]
|
||||
public DateTimeOffset StartedAt { get; set; }
|
||||
[Required]
|
||||
public DateTimeOffset? StartedAt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// When the <see cref="Job"/> stopped
|
||||
@@ -45,7 +46,8 @@ namespace Tgstation.Server.Api.Models.Internal
|
||||
/// If the <see cref="Job"/> was cancelled
|
||||
/// </summary>
|
||||
[Permissions(DenyWrite = true)]
|
||||
public bool Cancelled { get; set; }
|
||||
[Required]
|
||||
public bool? Cancelled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="RightsType"/> of <see cref="CancelRight"/> if it can be cancelled
|
||||
|
||||
@@ -5,6 +5,7 @@ using System.Globalization;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Tgstation.Server.Host.Core;
|
||||
using Tgstation.Server.Host.IO;
|
||||
|
||||
namespace Tgstation.Server.Host.Components.Byond
|
||||
@@ -12,7 +13,7 @@ namespace Tgstation.Server.Host.Components.Byond
|
||||
/// <summary>
|
||||
/// <see cref="IByondInstaller"/> for windows systems
|
||||
/// </summary>
|
||||
sealed class WindowsByondInstaller : IByondInstaller
|
||||
sealed class WindowsByondInstaller : IByondInstaller, IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// The URL format string for getting BYOND windows version {0}.{1} zipfile
|
||||
@@ -51,6 +52,11 @@ namespace Tgstation.Server.Host.Components.Byond
|
||||
/// </summary>
|
||||
readonly ILogger<WindowsByondInstaller> logger;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="SemaphoreSlim"/> for the <see cref="WindowsByondInstaller"/>
|
||||
/// </summary>
|
||||
readonly SemaphoreSlim semaphore;
|
||||
|
||||
/// <summary>
|
||||
/// If DirectX was installed
|
||||
/// </summary>
|
||||
@@ -66,9 +72,13 @@ namespace Tgstation.Server.Host.Components.Byond
|
||||
this.ioManager = ioManager ?? throw new ArgumentNullException(nameof(ioManager));
|
||||
this.logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
|
||||
semaphore = new SemaphoreSlim(1);
|
||||
installedDirectX = false;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Dispose() => semaphore.Dispose();
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task CleanCache(CancellationToken cancellationToken)
|
||||
{
|
||||
@@ -103,8 +113,8 @@ namespace Tgstation.Server.Host.Components.Byond
|
||||
var setNoPromptTrustedModeTask = SetNoPromptTrusted();
|
||||
|
||||
//after this version lummox made DD depend of directx lol
|
||||
if (version.Major >= 512 && version.Minor >= 1427 && Monitor.TryEnter(this))
|
||||
try
|
||||
if (version.Major >= 512 && version.Minor >= 1427 && !installedDirectX)
|
||||
using (await SemaphoreSlimContext.Lock(semaphore, cancellationToken).ConfigureAwait(false))
|
||||
{
|
||||
if (!installedDirectX)
|
||||
//always install it, it's pretty fast and will do better redundancy checking than us
|
||||
@@ -143,10 +153,6 @@ namespace Tgstation.Server.Host.Components.Byond
|
||||
installedDirectX = true;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
Monitor.Exit(this);
|
||||
}
|
||||
|
||||
await setNoPromptTrustedModeTask.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ namespace Tgstation.Server.Host.Components.Compiler
|
||||
{
|
||||
if (job == null)
|
||||
throw new ArgumentNullException(nameof(job));
|
||||
if (job.DMApiValidated != true || job.Job.Cancelled || job.Job.ExceptionDetails != null || job.Job.StoppedAt == null)
|
||||
if (job.DMApiValidated != true || job.Job.Cancelled.Value || job.Job.ExceptionDetails != null || job.Job.StoppedAt == null)
|
||||
throw new InvalidOperationException("Cannot load incomplete compile job!");
|
||||
if (setAsStagedInDb)
|
||||
await databaseContextFactory.UseContext(async db =>
|
||||
|
||||
@@ -3,7 +3,6 @@ using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Tgstation.Server.Api.Rights;
|
||||
@@ -73,25 +72,6 @@ namespace Tgstation.Server.Host.Controllers
|
||||
return Json(job);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
[TgsAuthorize(DreamMakerRights.CancelCompile)]
|
||||
public override async Task<IActionResult> Delete(long id, CancellationToken cancellationToken)
|
||||
{
|
||||
//alias for cancelling the latest job
|
||||
var job = await DatabaseContext.CompileJobs.OrderByDescending(x => x.Job.StartedAt).Select(x => new Job { Id = x.Job.Id, StoppedAt = x.Job.StoppedAt }).FirstAsync(cancellationToken).ConfigureAwait(false);
|
||||
if (job.StoppedAt != null)
|
||||
return StatusCode((int)HttpStatusCode.Gone);
|
||||
try
|
||||
{
|
||||
await jobManager.CancelJob(job, AuthenticationContext.User, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
catch (InvalidOperationException) //job already stopped
|
||||
{
|
||||
return StatusCode((int)HttpStatusCode.Gone);
|
||||
}
|
||||
return Ok();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
[TgsAuthorize(DreamMakerRights.SetDme)]
|
||||
public override async Task<IActionResult> Update([FromBody] Api.Models.DreamMaker model, CancellationToken cancellationToken)
|
||||
|
||||
@@ -68,7 +68,7 @@ namespace Tgstation.Server.Host.Controllers
|
||||
/// <param name="id">The ID of the model to delete</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation</param>
|
||||
/// <returns>A <see cref="Task{TResult}"/> resulting in the <see cref="IActionResult"/> of the operation</returns>
|
||||
[HttpDelete]
|
||||
[HttpDelete("{id}")]
|
||||
public virtual Task<IActionResult> Delete(long id, CancellationToken cancellationToken) => Task.FromResult((IActionResult)NotFound());
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -10,7 +10,7 @@ using Tgstation.Server.Host.Models;
|
||||
namespace Tgstation.Server.Host.Core
|
||||
{
|
||||
/// <inheritdoc />
|
||||
sealed class JobManager : IHostedService, IJobManager
|
||||
sealed class JobManager : IHostedService, IJobManager, IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// The <see cref="IServiceProvider"/> for the <see cref="JobManager"/>
|
||||
@@ -31,6 +31,13 @@ namespace Tgstation.Server.Host.Core
|
||||
jobs = new Dictionary<long, JobHandler>();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Dispose()
|
||||
{
|
||||
foreach (var job in jobs)
|
||||
job.Value.Dispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="JobHandler"/> for a given <paramref name="job"/> if it exists
|
||||
/// </summary>
|
||||
@@ -104,6 +111,7 @@ namespace Tgstation.Server.Host.Core
|
||||
{
|
||||
var databaseContext = scope.ServiceProvider.GetRequiredService<IDatabaseContext>();
|
||||
job.StartedAt = DateTimeOffset.Now;
|
||||
job.Cancelled = false;
|
||||
job.Instance = new Instance
|
||||
{
|
||||
Id = job.Instance.Id
|
||||
@@ -134,7 +142,7 @@ namespace Tgstation.Server.Host.Core
|
||||
await databaseContext.Initialize(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
//mark all jobs as cancelled
|
||||
var enumerator = await databaseContext.Jobs.Where(y => !y.Cancelled && y.StoppedAt == null).Select(y => y.Id).ToAsyncEnumerable().ToList(cancellationToken).ConfigureAwait(false);
|
||||
var enumerator = await databaseContext.Jobs.Where(y => !y.Cancelled.Value && !y.StoppedAt.HasValue).Select(y => y.Id).ToAsyncEnumerable().ToList(cancellationToken).ConfigureAwait(false);
|
||||
foreach(var I in enumerator)
|
||||
{
|
||||
var job = new Job { Id = I };
|
||||
@@ -154,9 +162,6 @@ namespace Tgstation.Server.Host.Core
|
||||
return x.Value.Wait(cancellationToken);
|
||||
});
|
||||
await Task.WhenAll(joinTasks).ConfigureAwait(false);
|
||||
foreach (var job in jobs)
|
||||
job.Value.Dispose();
|
||||
jobs.Clear();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -175,6 +180,7 @@ namespace Tgstation.Server.Host.Core
|
||||
user = new User { Id = user.Id };
|
||||
databaseContext.Users.Attach(user);
|
||||
job.CancelledBy = user;
|
||||
//let either startup or cancellation set job.cancelled
|
||||
await databaseContext.Save(cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -265,9 +265,27 @@ namespace Tgstation.Server.Host.IO
|
||||
/// <inheritdoc />
|
||||
public async Task<byte[]> DownloadFile(Uri url, CancellationToken cancellationToken)
|
||||
{
|
||||
//DownloadDataTaskAsync can't be cancelled and is shittily written, don't use it
|
||||
using (var wc = new WebClient())
|
||||
using (cancellationToken.Register(() => wc.CancelAsync()))
|
||||
return await wc.DownloadDataTaskAsync(url).ConfigureAwait(false);
|
||||
{
|
||||
var tcs = new TaskCompletionSource<byte[]>();
|
||||
wc.DownloadDataCompleted += (a, b) =>
|
||||
{
|
||||
if (b.Error != null)
|
||||
tcs.TrySetException(b.Error);
|
||||
else if (b.Cancelled)
|
||||
tcs.TrySetCanceled();
|
||||
else
|
||||
tcs.TrySetResult(b.Result);
|
||||
};
|
||||
wc.DownloadDataAsync(url);
|
||||
using (cancellationToken.Register(() =>
|
||||
{
|
||||
wc.CancelAsync(); //cancelasync alone doesnt do it either! who wrote this!!
|
||||
tcs.SetCanceled();
|
||||
}))
|
||||
return await tcs.Task.ConfigureAwait(false);
|
||||
} //ITS STILL FUCKING DOWNLOADING!!!
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -842,6 +842,49 @@
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "Set ID 1 to only #botbus",
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"header": [
|
||||
{
|
||||
"key": "Accept",
|
||||
"value": "application/json"
|
||||
},
|
||||
{
|
||||
"key": "User-Agent",
|
||||
"value": "Postman/1.0"
|
||||
},
|
||||
{
|
||||
"key": "User-Agent",
|
||||
"value": "Tgstation.Server.Api/4.0.0.0"
|
||||
},
|
||||
{
|
||||
"key": "Content-Type",
|
||||
"value": "application/json"
|
||||
},
|
||||
{
|
||||
"key": "InstanceId",
|
||||
"value": "1"
|
||||
}
|
||||
],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "{\n\t\"id\": 1,\n\t\"channels\": [\n\t\t{\n\t\t\t\"ircChannel\": \"#botbus\",\n\t\t\t\"isAdminChannel\": true,\n\t\t\t\"isWatchdogChannel\": true\n\t\t}\n\t\t]\n}"
|
||||
},
|
||||
"url": {
|
||||
"raw": "localhost:5000/Chat",
|
||||
"host": [
|
||||
"localhost"
|
||||
],
|
||||
"port": "5000",
|
||||
"path": [
|
||||
"Chat"
|
||||
]
|
||||
}
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "Create r4407 on Disord",
|
||||
"request": {
|
||||
@@ -1199,6 +1242,167 @@
|
||||
],
|
||||
"_postman_isSubFolder": true
|
||||
},
|
||||
{
|
||||
"name": "Jobs",
|
||||
"description": "",
|
||||
"item": [
|
||||
{
|
||||
"name": "List Ids",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": [
|
||||
{
|
||||
"key": "Accept",
|
||||
"value": "application/json"
|
||||
},
|
||||
{
|
||||
"key": "User-Agent",
|
||||
"value": "Postman/1.0"
|
||||
},
|
||||
{
|
||||
"key": "User-Agent",
|
||||
"value": "Tgstation.Server.Api/4.0.0.0"
|
||||
},
|
||||
{
|
||||
"key": "Content-Type",
|
||||
"value": "application/json"
|
||||
},
|
||||
{
|
||||
"key": "InstanceId",
|
||||
"value": "1"
|
||||
}
|
||||
],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "{\n\t\"userId\": 1,\n\t\"byondRights\": -1,\n\t\"dreamDaemonRights\": -1,\n\t\"dreamMakerRights\": -1,\n\t\"repositoryRights\": -1,\n\t\"chatSettingsRights\": -1,\n\t\"configurationRights\": -1\n}"
|
||||
},
|
||||
"url": {
|
||||
"raw": "localhost:5000/Job/List",
|
||||
"host": [
|
||||
"localhost"
|
||||
],
|
||||
"port": "5000",
|
||||
"path": [
|
||||
"Job",
|
||||
"List"
|
||||
]
|
||||
}
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "Get ID",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": [
|
||||
{
|
||||
"key": "Accept",
|
||||
"value": "application/json"
|
||||
},
|
||||
{
|
||||
"key": "User-Agent",
|
||||
"value": "Postman/1.0"
|
||||
},
|
||||
{
|
||||
"key": "User-Agent",
|
||||
"value": "Tgstation.Server.Api/4.0.0.0"
|
||||
},
|
||||
{
|
||||
"key": "Content-Type",
|
||||
"value": "application/json"
|
||||
},
|
||||
{
|
||||
"key": "InstanceId",
|
||||
"value": "1"
|
||||
}
|
||||
],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "{\n\t\"userId\": 1,\n\t\"byondRights\": -1,\n\t\"dreamDaemonRights\": -1,\n\t\"dreamMakerRights\": -1,\n\t\"repositoryRights\": -1,\n\t\"chatSettingsRights\": -1,\n\t\"configurationRights\": -1\n}"
|
||||
},
|
||||
"url": {
|
||||
"raw": "localhost:5000/Job/10",
|
||||
"host": [
|
||||
"localhost"
|
||||
],
|
||||
"port": "5000",
|
||||
"path": [
|
||||
"Job",
|
||||
"10"
|
||||
]
|
||||
}
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "Cancel ID",
|
||||
"request": {
|
||||
"method": "DELETE",
|
||||
"header": [
|
||||
{
|
||||
"key": "Accept",
|
||||
"value": "application/json"
|
||||
},
|
||||
{
|
||||
"key": "User-Agent",
|
||||
"value": "Postman/1.0"
|
||||
},
|
||||
{
|
||||
"key": "User-Agent",
|
||||
"value": "Tgstation.Server.Api/4.0.0.0"
|
||||
},
|
||||
{
|
||||
"key": "Content-Type",
|
||||
"value": "application/json"
|
||||
},
|
||||
{
|
||||
"key": "InstanceId",
|
||||
"value": "1"
|
||||
}
|
||||
],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": ""
|
||||
},
|
||||
"url": {
|
||||
"raw": "localhost:5000/Job/11",
|
||||
"host": [
|
||||
"localhost"
|
||||
],
|
||||
"port": "5000",
|
||||
"path": [
|
||||
"Job",
|
||||
"11"
|
||||
]
|
||||
}
|
||||
},
|
||||
"response": []
|
||||
}
|
||||
],
|
||||
"event": [
|
||||
{
|
||||
"listen": "prerequest",
|
||||
"script": {
|
||||
"id": "a3f3a2f7-5700-48a9-88bf-d18ac2a1855c",
|
||||
"type": "text/javascript",
|
||||
"exec": [
|
||||
""
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"listen": "test",
|
||||
"script": {
|
||||
"id": "787a5a17-ad9c-4772-9052-85d81e87d4a9",
|
||||
"type": "text/javascript",
|
||||
"exec": [
|
||||
""
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"_postman_isSubFolder": true
|
||||
},
|
||||
{
|
||||
"name": "Online Instance ID 1",
|
||||
"request": {
|
||||
@@ -1397,6 +1601,185 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Byond",
|
||||
"description": "",
|
||||
"item": [
|
||||
{
|
||||
"name": "List installed versions",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": [
|
||||
{
|
||||
"key": "Accept",
|
||||
"value": "application/json"
|
||||
},
|
||||
{
|
||||
"key": "User-Agent",
|
||||
"value": "Postman/1.0"
|
||||
},
|
||||
{
|
||||
"key": "User-Agent",
|
||||
"value": "Tgstation.Server.Api/4.0.0.0"
|
||||
},
|
||||
{
|
||||
"key": "Content-Type",
|
||||
"value": "application/json"
|
||||
},
|
||||
{
|
||||
"key": "InstanceId",
|
||||
"value": "1"
|
||||
}
|
||||
],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "{\n \"id\": 1,\n \"online\": false\n}"
|
||||
},
|
||||
"url": {
|
||||
"raw": "localhost:5000/Byond/List",
|
||||
"host": [
|
||||
"localhost"
|
||||
],
|
||||
"port": "5000",
|
||||
"path": [
|
||||
"Byond",
|
||||
"List"
|
||||
]
|
||||
}
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "Read active version",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": [
|
||||
{
|
||||
"key": "Accept",
|
||||
"value": "application/json"
|
||||
},
|
||||
{
|
||||
"key": "User-Agent",
|
||||
"value": "Postman/1.0"
|
||||
},
|
||||
{
|
||||
"key": "User-Agent",
|
||||
"value": "Tgstation.Server.Api/4.0.0.0"
|
||||
},
|
||||
{
|
||||
"key": "Content-Type",
|
||||
"value": "application/json"
|
||||
},
|
||||
{
|
||||
"key": "InstanceId",
|
||||
"value": "1"
|
||||
}
|
||||
],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "{\n \"id\": 1,\n \"online\": false\n}"
|
||||
},
|
||||
"url": {
|
||||
"raw": "localhost:5000/Byond",
|
||||
"host": [
|
||||
"localhost"
|
||||
],
|
||||
"port": "5000",
|
||||
"path": [
|
||||
"Byond"
|
||||
]
|
||||
}
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "Set 511.1385 active",
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"header": [
|
||||
{
|
||||
"key": "Accept",
|
||||
"value": "application/json"
|
||||
},
|
||||
{
|
||||
"key": "User-Agent",
|
||||
"value": "Postman/1.0"
|
||||
},
|
||||
{
|
||||
"key": "User-Agent",
|
||||
"value": "Tgstation.Server.Api/4.0.0.0"
|
||||
},
|
||||
{
|
||||
"key": "Content-Type",
|
||||
"value": "application/json"
|
||||
},
|
||||
{
|
||||
"key": "InstanceId",
|
||||
"value": "1"
|
||||
}
|
||||
],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "{\n \"version\": {\n \t\"major\": 511,\n \t\"minor\": 1385\n }\n}"
|
||||
},
|
||||
"url": {
|
||||
"raw": "localhost:5000/Byond",
|
||||
"host": [
|
||||
"localhost"
|
||||
],
|
||||
"port": "5000",
|
||||
"path": [
|
||||
"Byond"
|
||||
]
|
||||
}
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "Set 512.1441 active",
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"header": [
|
||||
{
|
||||
"key": "Accept",
|
||||
"value": "application/json"
|
||||
},
|
||||
{
|
||||
"key": "User-Agent",
|
||||
"value": "Postman/1.0"
|
||||
},
|
||||
{
|
||||
"key": "User-Agent",
|
||||
"value": "Tgstation.Server.Api/4.0.0.0"
|
||||
},
|
||||
{
|
||||
"key": "Content-Type",
|
||||
"value": "application/json"
|
||||
},
|
||||
{
|
||||
"key": "InstanceId",
|
||||
"value": "1"
|
||||
}
|
||||
],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "{\n \"version\": {\n \t\"major\": 512,\n \t\"minor\": 1441\n }\n}"
|
||||
},
|
||||
"url": {
|
||||
"raw": "localhost:5000/Byond",
|
||||
"host": [
|
||||
"localhost"
|
||||
],
|
||||
"port": "5000",
|
||||
"path": [
|
||||
"Byond"
|
||||
]
|
||||
}
|
||||
},
|
||||
"response": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Login Admin Default",
|
||||
"request": {
|
||||
|
||||
Reference in New Issue
Block a user