Merge branch 'master' into dev

This commit is contained in:
Dominion
2023-06-08 08:30:22 -04:00
39 changed files with 272 additions and 340 deletions
+2 -40
View File
@@ -57,44 +57,6 @@ jobs:
- name: GitHub Requires at Least One Step for a Job
run: exit 0
analyze:
name: Code Scanning
needs: start-ci-run-gate
if: "!(cancelled() || failure()) && needs.start-ci-run-gate.result == 'success'"
runs-on: ubuntu-latest
steps:
- name: Install Node 12.X
uses: actions/setup-node@v3
with:
node-version: 12.x
- name: Upgrade NPM
run: npm install -g npm
- name: Checkout (Branch)
uses: actions/checkout@v3
if: github.event_name == 'push' || github.event_name == 'schedule'
with:
fetch-depth: 2
- name: Checkout (PR Merge)
uses: actions/checkout@v3
if: github.event_name != 'push' && github.event_name != 'schedule'
with:
fetch-depth: 2
ref: "refs/pull/${{ github.event.number }}/merge"
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: csharp
- name: Autobuild
uses: github/codeql-action/autobuild@v2
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
dmapi-build:
name: Build DMAPI
needs: start-ci-run-gate
@@ -114,7 +76,7 @@ jobs:
uses: actions/cache@v3
id: cache-byond
with:
path: $HOME/BYOND-${{ env.BYOND_MAJOR }}.${{ env.BYOND_MINOR }}
path: ~/BYOND-${{ env.BYOND_MAJOR }}.${{ env.BYOND_MINOR }}
key: ${{ env.BYOND_MAJOR }}-${{ env.BYOND_MINOR }}-dmapibyond
- name: Install BYOND
@@ -338,7 +300,7 @@ jobs:
uses: actions/cache@v3
id: cache-byond
with:
path: $HOME/BYOND-${{ env.BYOND_MAJOR }}.${{ env.BYOND_MINOR }}
path: ~/BYOND-${{ env.BYOND_MAJOR }}.${{ env.BYOND_MINOR }}
key: ${{ env.BYOND_MAJOR }}-${{ env.BYOND_MINOR }}-livebyond
- name: Download BYOND
+44
View File
@@ -0,0 +1,44 @@
name: 'Code Scanning'
on:
schedule:
- cron: 0 23 * * *
push:
branches:
- dev
- master
pull_request:
branches:
- dev
- master
concurrency:
group: "code-scanning-${{ github.head_ref || github.run_id }}-${{ github.event_name }}"
cancel-in-progress: true
jobs:
analyze:
name: Code Scanning
runs-on: ubuntu-latest
steps:
- name: Install Node 12.X
uses: actions/setup-node@v3
with:
node-version: 12.x
- name: Upgrade NPM
run: npm install -g npm
- name: Checkout
uses: actions/checkout@v3
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: csharp
- name: Autobuild
uses: github/codeql-action/autobuild@v2
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
@@ -70,8 +70,7 @@ namespace Tgstation.Server.Host.Components.Byond
IOManager.ConcatPath(
PathToUserByondFolder,
CacheDirectoryName),
cancellationToken)
;
cancellationToken);
}
catch (OperationCanceledException)
{
@@ -383,8 +383,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
cancellationToken,
DefaultIOManager.BlockingTaskCreationOptions,
TaskScheduler.Current)
.WithToken(cancellationToken)
;
.WithToken(cancellationToken);
cancellationToken.ThrowIfCancellationRequested();
@@ -480,8 +479,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
},
cancellationToken,
DefaultIOManager.BlockingTaskCreationOptions,
TaskScheduler.Current)
;
TaskScheduler.Current);
await HardDisconnect(cancellationToken);
}
catch (OperationCanceledException)
@@ -145,8 +145,7 @@ namespace Tgstation.Server.Host.Components.Deployment
job);
await remoteDeploymentManager.StageDeployment(
newProvider.CompileJob,
cancellationToken)
;
cancellationToken);
}
lock (jobLockCounts)
@@ -188,10 +187,8 @@ namespace Tgstation.Server.Host.Components.Deployment
.AsQueryable()
.Where(x => x.Job.Instance.Id == metadata.Id)
.OrderByDescending(x => x.Job.StoppedAt)
.FirstOrDefaultAsync(cancellationToken)
;
})
;
.FirstOrDefaultAsync(cancellationToken);
});
if (cj == default(CompileJob))
return;
@@ -267,8 +264,7 @@ namespace Tgstation.Server.Host.Components.Deployment
ioManager.ConcatPath(
newProvider.Directory,
newProvider.DmbName),
cancellationToken)
;
cancellationToken);
if (!dmbExistsAtRoot)
{
@@ -241,8 +241,7 @@ namespace Tgstation.Server.Host.Components.Deployment
StartupTimeout = x.StartupTimeout,
LogOutput = x.LogOutput,
})
.FirstOrDefaultAsync(cancellationToken)
;
.FirstOrDefaultAsync(cancellationToken);
if (ddSettings == default)
throw new JobException(ErrorCode.InstanceMissingDreamDaemonSettings);
@@ -250,8 +249,7 @@ namespace Tgstation.Server.Host.Components.Deployment
.DreamMakerSettings
.AsQueryable()
.Where(x => x.InstanceId == metadata.Id)
.FirstAsync(cancellationToken)
;
.FirstAsync(cancellationToken);
if (dreamMakerSettings == default)
throw new JobException(ErrorCode.InstanceMissingDreamMakerSettings);
@@ -267,8 +265,7 @@ namespace Tgstation.Server.Host.Components.Deployment
PushTestMergeCommits = x.PushTestMergeCommits,
PostTestMergeComment = x.PostTestMergeComment,
})
.FirstOrDefaultAsync(cancellationToken)
;
.FirstOrDefaultAsync(cancellationToken);
if (repositorySettings == default)
throw new JobException(ErrorCode.InstanceMissingRepositorySettings);
@@ -291,8 +288,7 @@ namespace Tgstation.Server.Host.Components.Deployment
.Include(x => x.ActiveTestMerges)
.ThenInclude(x => x.TestMerge)
.ThenInclude(x => x.MergedBy)
.FirstOrDefaultAsync(cancellationToken)
;
.FirstOrDefaultAsync(cancellationToken);
if (revInfo == default)
{
@@ -319,8 +315,7 @@ namespace Tgstation.Server.Host.Components.Deployment
repo?.Dispose();
throw;
}
})
;
});
var likelyPushedTestMergeCommit =
repositorySettings.PushTestMergeCommits.Value
@@ -336,8 +331,7 @@ namespace Tgstation.Server.Host.Components.Deployment
progressReporter,
averageSpan,
likelyPushedTestMergeCommit,
cancellationToken)
;
cancellationToken);
var activeCompileJob = compileJobConsumer.LatestCompileJob();
try
@@ -379,8 +373,7 @@ namespace Tgstation.Server.Host.Components.Deployment
compileJob.Job = fullJob;
compileJob.RevisionInformation = fullRevInfo;
})
;
});
}
catch (Exception ex)
{
@@ -447,8 +440,7 @@ namespace Tgstation.Server.Host.Components.Deployment
StoppedAt = x.Job.StoppedAt,
StartedAt = x.Job.StartedAt,
})
.ToListAsync(cancellationToken)
;
.ToListAsync(cancellationToken);
TimeSpan? averageSpan = null;
if (previousCompileJobs.Count != 0)
@@ -605,8 +597,7 @@ namespace Tgstation.Server.Host.Components.Deployment
repoOrigin.ToString(),
$"{byondLock.Version.Major}.{byondLock.Version.Minor}",
},
cancellationToken)
;
cancellationToken);
// determine the dme
progressReporter.StageName = "Determining .dme";
@@ -978,8 +969,7 @@ namespace Tgstation.Server.Host.Components.Deployment
remoteDeploymentManager.FailDeployment(
job,
FormatExceptionForUsers(exception),
default))
;
default));
}
}
}
@@ -73,8 +73,7 @@ namespace Tgstation.Server.Host.Components.Deployment
await symlinkFactory.CreateSymbolicLink(
ioManager.ResolvePath(baseProvider.Directory),
ioManager.ResolvePath(LiveGameDirectory),
cancellationToken)
;
cancellationToken);
}
}
}
@@ -185,8 +185,7 @@ namespace Tgstation.Server.Host.Components
Configuration.StartAsync(cancellationToken),
ByondManager.StartAsync(cancellationToken),
Chat.StartAsync(cancellationToken),
dmbFactory.StartAsync(cancellationToken))
;
dmbFactory.StartAsync(cancellationToken));
// dependent on so many things, its just safer this way
await Watchdog.StartAsync(cancellationToken);
@@ -310,8 +309,7 @@ namespace Tgstation.Server.Host.Components
repositorySettings.AccessUser,
repositorySettings.AccessToken,
NextProgressReporter("Fetch Origin"),
cancellationToken)
;
cancellationToken);
var hasDbChanges = false;
RevisionInformation currentRevInfo = null;
@@ -385,8 +383,7 @@ namespace Tgstation.Server.Host.Components
repositorySettings.CommitterName,
repositorySettings.CommitterEmail,
NextProgressReporter("Merge Origin"),
cancellationToken)
;
cancellationToken);
var preserveTestMerges = repositorySettings.AutoUpdatesKeepTestMerges.Value;
var remoteDeploymentManager = remoteDeploymentManagerFactory.CreateRemoteDeploymentManager(
@@ -435,16 +432,14 @@ namespace Tgstation.Server.Host.Components
repositorySettings.AccessToken,
repositorySettings.UpdateSubmodules.Value,
NextProgressReporter(StageName),
cancellationToken)
;
cancellationToken);
var currentHead = repo.Head;
currentRevInfo = await databaseContext.RevisionInformations
.AsQueryable()
.Where(x => x.CommitSha == currentHead && x.Instance.Id == metadata.Id)
.FirstOrDefaultAsync(cancellationToken)
;
.FirstOrDefaultAsync(cancellationToken);
if (currentHead != startSha && currentRevInfo == default)
await UpdateRevInfo(currentHead, true, null);
@@ -555,8 +550,7 @@ namespace Tgstation.Server.Host.Components
progressReporter,
jobCancellationToken);
},
cancellationToken)
;
cancellationToken);
}
await jobManager.WaitForJobCompletion(compileProcessJob, null, default, cancellationToken);
@@ -284,8 +284,7 @@ namespace Tgstation.Server.Host.Components
await ioManager.WriteAllBytes(
ioManager.ConcatPath(oldPath, InstanceController.InstanceAttachFileName),
Array.Empty<byte>(),
default)
;
default);
}
catch (Exception tripleEx)
{
@@ -66,8 +66,7 @@ namespace Tgstation.Server.Host.Components.Repository
var mr = await client
.MergeRequests
.GetAsync($"{RemoteRepositoryOwner}/{RemoteRepositoryName}", parameters.Number)
.WithToken(cancellationToken)
;
.WithToken(cancellationToken);
var revisionToUse = parameters.TargetCommitSha == null
|| mr.Sha.StartsWith(parameters.TargetCommitSha, StringComparison.OrdinalIgnoreCase)
@@ -356,8 +356,7 @@ namespace Tgstation.Server.Host.Components.Repository
}),
cancellationToken,
DefaultIOManager.BlockingTaskCreationOptions,
TaskScheduler.Current)
;
TaskScheduler.Current);
if (updateSubmodules)
{
@@ -412,8 +411,7 @@ namespace Tgstation.Server.Host.Components.Repository
},
cancellationToken,
DefaultIOManager.BlockingTaskCreationOptions,
TaskScheduler.Current)
;
TaskScheduler.Current);
if (updateSubmodules)
await UpdateSubmodules(
@@ -463,8 +461,7 @@ namespace Tgstation.Server.Host.Components.Repository
},
cancellationToken,
DefaultIOManager.BlockingTaskCreationOptions,
TaskScheduler.Current)
;
TaskScheduler.Current);
}
/// <inheritdoc />
@@ -485,8 +482,7 @@ namespace Tgstation.Server.Host.Components.Repository
await ResetToSha(
trackedBranch.Tip.Sha,
progressReporter.CreateSection(null, updateSubmodules ? 2.0 / 3 : 1.0),
cancellationToken)
;
cancellationToken);
if (updateSubmodules)
await UpdateSubmodules(
@@ -619,8 +615,7 @@ namespace Tgstation.Server.Host.Components.Repository
},
cancellationToken,
DefaultIOManager.BlockingTaskCreationOptions,
TaskScheduler.Current)
;
TaskScheduler.Current);
if (result.Status == MergeStatus.Conflicts)
{
@@ -684,8 +679,7 @@ namespace Tgstation.Server.Host.Components.Repository
{
ioMananger.ResolvePath(),
},
cancellationToken)
;
cancellationToken);
}
finally
{
@@ -702,8 +696,7 @@ namespace Tgstation.Server.Host.Components.Repository
},
cancellationToken,
DefaultIOManager.BlockingTaskCreationOptions,
TaskScheduler.Current)
;
TaskScheduler.Current);
}
var remainingProgressFactor = 0.9;
@@ -759,8 +752,7 @@ namespace Tgstation.Server.Host.Components.Repository
},
cancellationToken,
DefaultIOManager.BlockingTaskCreationOptions,
TaskScheduler.Current)
;
TaskScheduler.Current);
}
/// <inheritdoc />
@@ -1040,8 +1032,7 @@ namespace Tgstation.Server.Host.Components.Repository
await Task.WhenAll(
ioMananger.DeleteDirectory($".git/modules/{submodule.Path}", cancellationToken),
ioMananger.DeleteDirectory(submodule.Path, cancellationToken))
;
ioMananger.DeleteDirectory(submodule.Path, cancellationToken));
logger.LogTrace("Second update attempt for submodule {submoduleName}...", submodule.Name);
try
@@ -270,8 +270,7 @@ namespace Tgstation.Server.Host.Components.Repository
currentModel.CommitterEmail,
NextProgressReporter("Sychronize"),
true,
cancellationToken)
;
cancellationToken);
postUpdateSha = repo.Head;
}
else
@@ -305,8 +304,7 @@ namespace Tgstation.Server.Host.Components.Repository
currentModel.AccessToken,
updateSubmodules,
NextProgressReporter("Checkout"),
cancellationToken)
;
cancellationToken);
await CallLoadRevInfo(); // we've either seen origin before or what we're checking out is on origin
}
else
@@ -321,8 +319,7 @@ namespace Tgstation.Server.Host.Components.Repository
currentModel.AccessToken,
updateSubmodules,
NextProgressReporter("Reset to Origin"),
cancellationToken)
;
cancellationToken);
await repo.Sychronize(
currentModel.AccessUser,
currentModel.AccessToken,
@@ -330,8 +327,7 @@ namespace Tgstation.Server.Host.Components.Repository
currentModel.CommitterEmail,
NextProgressReporter("Synchronize"),
true,
cancellationToken)
;
cancellationToken);
await CallLoadRevInfo();
// repo head is on origin so force this
@@ -545,8 +541,7 @@ namespace Tgstation.Server.Host.Components.Repository
currentModel.CommitterEmail,
NextProgressReporter("Synchronize"),
false,
cancellationToken)
;
cancellationToken);
await UpdateRevInfo();
}
@@ -444,8 +444,7 @@ namespace Tgstation.Server.Host.Components.Session
{
var commandResult = await SendCommand(
new TopicParameters(port),
cancellationToken)
;
cancellationToken);
if (commandResult?.ErrorMessage != null)
return false;
@@ -478,8 +477,7 @@ namespace Tgstation.Server.Host.Components.Session
ReattachInformation.RebootState = newRebootState;
var result = await SendCommand(
new TopicParameters(newRebootState),
cancellationToken)
;
cancellationToken);
return result?.ErrorMessage == null;
}
@@ -140,8 +140,7 @@ namespace Tgstation.Server.Host.Components.Session
.AsQueryable()
.Where(x => x.Id == metadata.Id)
.Select(x => x.DreamDaemonSettings.TopicRequestTimeout)
.FirstOrDefaultAsync(cancellationToken)
;
.FirstOrDefaultAsync(cancellationToken);
if (timeoutMilliseconds == default)
{
@@ -238,8 +237,7 @@ namespace Tgstation.Server.Host.Components.Session
if (instant)
await baseQuery
.DeleteAsync(cancellationToken)
;
.DeleteAsync(cancellationToken);
else
{
var results = await baseQuery.ToListAsync(cancellationToken);
@@ -652,8 +652,7 @@ namespace Tgstation.Server.Host.Components.StaticFiles
await Task.WhenAll(
ioManager.CreateDirectory(CodeModificationsSubdirectory, cancellationToken),
ioManager.CreateDirectory(EventScriptsSubdirectory, cancellationToken),
ValidateStaticFolder())
;
ValidateStaticFolder());
}
/// <summary>
@@ -102,8 +102,7 @@ namespace Tgstation.Server.Host.Components.Watchdog
await GameIOManager.MoveDirectory(
ActiveSwappable.CompileJob.DirectoryName.ToString(),
ActiveSwappable.Directory,
cancellationToken)
;
cancellationToken);
hardLinkedDmb = ActiveSwappable;
}
@@ -131,8 +130,7 @@ namespace Tgstation.Server.Host.Components.Watchdog
await GameIOManager.MoveDirectory(
hardLink,
originalPosition,
default)
;
default);
}
catch (Exception ex)
{
@@ -465,8 +465,7 @@ namespace Tgstation.Server.Host.Components.Watchdog
var notification = new EventNotification(eventType, parameters);
var result = await activeServer.SendCommand(
new TopicParameters(notification),
cancellationToken)
;
cancellationToken);
HandleChatResponses(result);
}
@@ -122,8 +122,7 @@ namespace Tgstation.Server.Host.Controllers
await StatusCode(
HttpStatusCode.UpgradeRequired,
new ErrorMessageResponse(ErrorCode.ApiMismatch))
.ExecuteResultAsync(context)
;
.ExecuteResultAsync(context);
return;
}
@@ -139,8 +138,7 @@ namespace Tgstation.Server.Host.Controllers
if (requireHeaders)
{
await HeadersIssue(false)
.ExecuteResultAsync(context)
;
.ExecuteResultAsync(context);
return;
}
}
@@ -221,8 +219,13 @@ namespace Tgstation.Server.Host.Controllers
/// <summary>
/// Generic 501 response.
/// </summary>
/// <param name="ex">The <see cref="NotImplementedException"/> that was thrown.</param>
/// <returns>An <see cref="ObjectResult"/> with <see cref="HttpStatusCode.NotImplemented"/>.</returns>
protected ObjectResult RequiresPosixSystemIdentity() => StatusCode(HttpStatusCode.NotImplemented, new ErrorMessageResponse(ErrorCode.RequiresPosixSystemIdentity));
protected ObjectResult RequiresPosixSystemIdentity(NotImplementedException ex)
{
Logger.LogTrace(ex, "System identities not implemented!");
return StatusCode(HttpStatusCode.NotImplemented, new ErrorMessageResponse(ErrorCode.RequiresPosixSystemIdentity));
}
/// <summary>
/// Strongly type calls to <see cref="ControllerBase.StatusCode(int)"/>.
@@ -395,8 +398,7 @@ namespace Tgstation.Server.Host.Controllers
{
totalResults = await paginationResult.Results.CountAsync(cancellationToken);
pagedResults = await queriedResults
.ToListAsync(cancellationToken)
;
.ToListAsync(cancellationToken);
}
else
{
@@ -188,8 +188,7 @@ namespace Tgstation.Server.Host.Controllers
.ChatBots
.AsQueryable()
.Where(x => x.Id == id)
.DeleteAsync(cancellationToken))
;
.DeleteAsync(cancellationToken));
return null;
})
@@ -364,8 +363,7 @@ namespace Tgstation.Server.Host.Controllers
await chat.ChangeChannels(current.Id.Value, current.Channels, cancellationToken);
return null;
})
;
});
if (earlyOut != null)
return earlyOut;
@@ -84,12 +84,10 @@ namespace Tgstation.Server.Host.Controllers
model.Path,
systemIdentity,
model.LastReadHash,
cancellationToken)
;
cancellationToken);
return model.LastReadHash == null ? Accepted(newFile) : Json(newFile);
})
;
});
}
catch (IOException e)
{
@@ -99,9 +97,9 @@ namespace Tgstation.Server.Host.Controllers
AdditionalData = e.Message,
});
}
catch (NotImplementedException)
catch (NotImplementedException ex)
{
return RequiresPosixSystemIdentity();
return RequiresPosixSystemIdentity(ex);
}
}
@@ -129,14 +127,12 @@ namespace Tgstation.Server.Host.Controllers
{
var result = await instance
.Configuration
.Read(filePath, systemIdentity, cancellationToken)
;
.Read(filePath, systemIdentity, cancellationToken);
if (result == null)
return Gone();
return Json(result);
})
;
});
}
catch (IOException e)
{
@@ -146,9 +142,9 @@ namespace Tgstation.Server.Host.Controllers
AdditionalData = e.Message,
});
}
catch (NotImplementedException)
catch (NotImplementedException ex)
{
return RequiresPosixSystemIdentity();
return RequiresPosixSystemIdentity(ex);
}
}
@@ -183,8 +179,7 @@ namespace Tgstation.Server.Host.Controllers
{
var result = await instance
.Configuration
.ListDirectory(directoryPath, systemIdentity, cancellationToken)
;
.ListDirectory(directoryPath, systemIdentity, cancellationToken);
if (result == null)
return new PaginatableResult<ConfigurationFileResponse>(Gone());
@@ -193,10 +188,10 @@ namespace Tgstation.Server.Host.Controllers
.AsQueryable()
.OrderBy(x => x.Path));
}
catch (NotImplementedException)
catch (NotImplementedException ex)
{
return new PaginatableResult<ConfigurationFileResponse>(
RequiresPosixSystemIdentity());
RequiresPosixSystemIdentity(ex));
}
catch (UnauthorizedAccessException)
{
@@ -257,8 +252,7 @@ namespace Tgstation.Server.Host.Controllers
.Configuration
.CreateDirectory(model.Path, systemIdentity, cancellationToken)
? Json(resultModel)
: Created(resultModel))
;
: Created(resultModel));
}
catch (IOException e)
{
@@ -268,9 +262,9 @@ namespace Tgstation.Server.Host.Controllers
Message = e.Message,
});
}
catch (NotImplementedException)
catch (NotImplementedException ex)
{
return RequiresPosixSystemIdentity();
return RequiresPosixSystemIdentity(ex);
}
catch (UnauthorizedAccessException)
{
@@ -308,9 +302,9 @@ namespace Tgstation.Server.Host.Controllers
? NoContent()
: Conflict(new ErrorMessageResponse(ErrorCode.ConfigurationDirectoryNotEmpty)));
}
catch (NotImplementedException)
catch (NotImplementedException ex)
{
return RequiresPosixSystemIdentity();
return RequiresPosixSystemIdentity(ex);
}
catch (UnauthorizedAccessException)
{
@@ -94,8 +94,7 @@ namespace Tgstation.Server.Host.Controllers
await jobManager.RegisterOperation(
job,
(core, databaseContextFactory, paramJob, progressHandler, innerCt) => core.Watchdog.Launch(innerCt),
cancellationToken)
;
cancellationToken);
return Accepted(job.ToApi());
});
@@ -241,8 +240,7 @@ namespace Tgstation.Server.Host.Controllers
await watchdog.ResetRebootState(cancellationToken);
return await ReadImpl(current, cancellationToken);
})
;
});
}
#pragma warning restore CA1506
#pragma warning restore CA1502
@@ -276,8 +274,7 @@ namespace Tgstation.Server.Host.Controllers
await jobManager.RegisterOperation(
job,
(core, paramJob, databaseContextFactory, progressReporter, ct) => core.Watchdog.Restart(false, ct),
cancellationToken)
;
cancellationToken);
return Accepted(job.ToApi());
});
@@ -310,8 +307,7 @@ namespace Tgstation.Server.Host.Controllers
await jobManager.RegisterOperation(
job,
(core, databaseContextFactory, paramJob, progressReporter, ct) => core.Watchdog.CreateDump(ct),
cancellationToken)
;
cancellationToken);
return Accepted(job.ToApi());
});
@@ -336,8 +332,7 @@ namespace Tgstation.Server.Host.Controllers
.AsQueryable()
.Where(x => x.Id == Instance.Id)
.Select(x => x.DreamDaemonSettings)
.FirstOrDefaultAsync(cancellationToken)
;
.FirstOrDefaultAsync(cancellationToken);
if (settings == default)
return Gone();
}
@@ -79,8 +79,7 @@ namespace Tgstation.Server.Host.Controllers
.DreamMakerSettings
.AsQueryable()
.Where(x => x.InstanceId == Instance.Id)
.FirstOrDefaultAsync(cancellationToken)
;
.FirstOrDefaultAsync(cancellationToken);
return Json(dreamMakerSettings.ToApi());
}
@@ -152,8 +151,7 @@ namespace Tgstation.Server.Host.Controllers
job,
(core, databaseContextFactory, paramJob, progressReporter, jobCancellationToken)
=> core.DreamMaker.DeploymentProcess(paramJob, databaseContextFactory, progressReporter, jobCancellationToken),
cancellationToken)
;
cancellationToken);
return Accepted(job.ToApi());
}
@@ -188,8 +186,7 @@ namespace Tgstation.Server.Host.Controllers
.DreamMakerSettings
.AsQueryable()
.Where(x => x.InstanceId == Instance.Id)
.FirstOrDefaultAsync(cancellationToken)
;
.FirstOrDefaultAsync(cancellationToken);
if (hostModel == null)
return Gone();
@@ -214,8 +211,7 @@ namespace Tgstation.Server.Host.Controllers
.GetAvailablePort(
model.ApiValidationPort.Value,
true,
cancellationToken)
;
cancellationToken);
if (verifiedPort != model.ApiValidationPort)
return Conflict(new ErrorMessageResponse(ErrorCode.PortNotAvailable));
@@ -241,7 +241,7 @@ namespace Tgstation.Server.Host.Controllers
}
catch (NotImplementedException ex)
{
Logger.LogTrace(ex, "System identities not implemented!");
RequiresPosixSystemIdentity(ex);
}
using (systemIdentity)
@@ -297,6 +297,7 @@ namespace Tgstation.Server.Host.Controllers
PasswordHash = x.PasswordHash,
Enabled = x.Enabled,
Name = x.Name,
SystemIdentifier = x.SystemIdentifier,
})
.ToListAsync(cancellationToken);
@@ -315,13 +316,13 @@ namespace Tgstation.Server.Host.Controllers
// FALLBACK TO THE DB USER HERE, DO NOT REVEAL A SYSTEM LOGIN!!!
// This of course, allows system users to discover TGS users in this (HIGHLY IMPROBABLE) case but that is not our fault
var originalHash = user.PasswordHash;
var isDbUser = originalHash != null;
bool usingSystemIdentity = systemIdentity != null && !isDbUser;
var isLikelyDbUser = originalHash != null;
bool usingSystemIdentity = systemIdentity != null && !isLikelyDbUser;
if (!oAuthLogin)
if (!usingSystemIdentity)
{
// DB User password check and update
if (originalHash == null || !cryptographySuite.CheckUserPassword(user, ApiHeaders.Password))
if (!isLikelyDbUser || !cryptographySuite.CheckUserPassword(user, ApiHeaders.Password))
return Unauthorized();
if (user.PasswordHash != originalHash)
{
@@ -335,14 +336,30 @@ namespace Tgstation.Server.Host.Controllers
await DatabaseContext.Save(cancellationToken);
}
}
else if (systemIdentity.Username != user.Name)
else
{
// System identity username change update
Logger.LogDebug("User ID {userId}'s system identity needs a refresh, updating database.", user.Id);
DatabaseContext.Users.Attach(user);
user.Name = systemIdentity.Username;
user.CanonicalName = Models.User.CanonicalizeName(user.Name);
await DatabaseContext.Save(cancellationToken);
var usernameMismatch = systemIdentity.Username != user.Name;
if (isLikelyDbUser || usernameMismatch)
{
DatabaseContext.Users.Attach(user);
if (isLikelyDbUser)
{
// cleanup from https://github.com/tgstation/tgstation-server/issues/1528
Logger.LogDebug("System user ID {userId}'s PasswordHash is polluted, updating database.", user.Id);
user.PasswordHash = null;
user.LastPasswordUpdate = DateTimeOffset.UtcNow;
}
if (usernameMismatch)
{
// System identity username change update
Logger.LogDebug("User ID {userId}'s system identity needs a refresh, updating database.", user.Id);
user.Name = systemIdentity.Username;
user.CanonicalName = Models.User.CanonicalizeName(user.Name);
}
await DatabaseContext.Save(cancellationToken);
}
}
// Now that the bookeeping is done, tell them to fuck off if necessary
@@ -182,8 +182,7 @@ namespace Tgstation.Server.Host.Controllers
if (earlyOut != null && !newCancellationToken.IsCancellationRequested)
cts.Cancel();
},
newCancellationToken)
;
newCancellationToken);
}
catch (OperationCanceledException)
{
@@ -419,8 +418,7 @@ namespace Tgstation.Server.Host.Controllers
.ChatBots
.AsQueryable()
.Where(x => x.InstanceId == originalModel.Id)
.CountAsync(cancellationToken)
;
.CountAsync(cancellationToken);
if (countOfExistingChatBots > model.ChatBotLimit.Value)
return Conflict(new ErrorMessageResponse(ErrorCode.ChatBotMax));
@@ -486,8 +484,7 @@ namespace Tgstation.Server.Host.Controllers
job,
(core, databaseContextFactory, paramJob, progressHandler, ct) // core will be null here since the instance is offline
=> InstanceOperations.MoveInstance(originalModel, originalModelPath, ct),
cancellationToken)
;
cancellationToken);
api.MoveJob = job.ToApi();
}
@@ -548,8 +545,7 @@ namespace Tgstation.Server.Host.Controllers
.Where(x => !x.StoppedAt.HasValue && x.Description.StartsWith(MoveInstanceJobPrefix))
.Include(x => x.StartedBy).ThenInclude(x => x.CreatedBy)
.Include(x => x.Instance)
.ToListAsync(cancellationToken)
;
.ToListAsync(cancellationToken);
var needsUpdate = false;
var result = await Paginated<Models.Instance, InstanceResponse>(
@@ -565,8 +561,7 @@ namespace Tgstation.Server.Host.Controllers
},
page,
pageSize,
cancellationToken)
;
cancellationToken);
if (needsUpdate)
await DatabaseContext.Save(cancellationToken);
@@ -625,8 +620,7 @@ namespace Tgstation.Server.Host.Controllers
.SelectMany(x => x.Jobs)
.Where(x => !x.StoppedAt.HasValue && x.Description.StartsWith(MoveInstanceJobPrefix))
.Include(x => x.StartedBy).ThenInclude(x => x.CreatedBy)
.FirstOrDefaultAsync(cancellationToken)
;
.FirstOrDefaultAsync(cancellationToken);
api.MoveJob = moveJob?.ToApi();
await CheckAccessible(api, cancellationToken);
return Json(api);
@@ -654,14 +648,12 @@ namespace Tgstation.Server.Host.Controllers
var usersInstancePermissionSet = await BaseQuery()
.SelectMany(x => x.InstancePermissionSets)
.Where(x => x.PermissionSetId == AuthenticationContext.PermissionSet.Id.Value)
.FirstOrDefaultAsync(cancellationToken)
;
.FirstOrDefaultAsync(cancellationToken);
if (usersInstancePermissionSet == default)
{
// does the instance actually exist?
var instanceExists = await BaseQuery()
.AnyAsync(cancellationToken)
;
.AnyAsync(cancellationToken);
if (!instanceExists)
return Gone();
@@ -700,8 +692,7 @@ namespace Tgstation.Server.Host.Controllers
.GetAvailablePort(
Math.Min((ushort)(ddPort.Value + 1), DefaultApiValidationPort),
false,
cancellationToken)
;
cancellationToken);
if (!dmPort.HasValue)
return null;
@@ -73,8 +73,7 @@ namespace Tgstation.Server.Host.Controllers
{
UserId = x.UserId,
})
.FirstOrDefaultAsync(cancellationToken)
;
.FirstOrDefaultAsync(cancellationToken);
if (existingPermissionSet == default)
return Gone();
@@ -86,8 +85,7 @@ namespace Tgstation.Server.Host.Controllers
.AsQueryable()
.Where(x => x.Id == existingPermissionSet.UserId.Value)
.Select(x => x.CanonicalName)
.FirstAsync(cancellationToken)
;
.FirstAsync(cancellationToken);
if (userCanonicalName == Models.User.CanonicalizeName(Models.User.TgsSystemUserName))
return Forbid();
@@ -137,8 +135,7 @@ namespace Tgstation.Server.Host.Controllers
.Where(x => x.Id == Instance.Id)
.SelectMany(x => x.InstancePermissionSets)
.Where(x => x.PermissionSetId == model.PermissionSetId)
.FirstOrDefaultAsync(cancellationToken)
;
.FirstOrDefaultAsync(cancellationToken);
if (originalPermissionSet == null)
return Gone();
@@ -219,8 +216,7 @@ namespace Tgstation.Server.Host.Controllers
.Where(x => x.Id == Instance.Id)
.SelectMany(x => x.InstancePermissionSets)
.Where(x => x.PermissionSetId == id)
.FirstOrDefaultAsync(cancellationToken)
;
.FirstOrDefaultAsync(cancellationToken);
if (permissionSet == default)
return Gone();
return Json(permissionSet.ToApi());
@@ -246,8 +242,7 @@ namespace Tgstation.Server.Host.Controllers
.Where(x => x.Id == Instance.Id)
.SelectMany(x => x.InstancePermissionSets)
.Where(x => x.PermissionSetId == id)
.DeleteAsync(cancellationToken)
;
.DeleteAsync(cancellationToken);
return numDeleted > 0 ? NoContent() : Gone();
}
}
@@ -127,8 +127,7 @@ namespace Tgstation.Server.Host.Controllers
.AsQueryable()
.Include(x => x.StartedBy)
.Where(x => x.Id == id && x.Instance.Id == Instance.Id)
.FirstOrDefaultAsync(cancellationToken)
;
.FirstOrDefaultAsync(cancellationToken);
if (job == default)
return NotFound();
@@ -162,8 +161,7 @@ namespace Tgstation.Server.Host.Controllers
.Where(x => x.Id == id && x.Instance.Id == Instance.Id)
.Include(x => x.StartedBy)
.Include(x => x.CancelledBy)
.FirstOrDefaultAsync(cancellationToken)
;
.FirstOrDefaultAsync(cancellationToken);
if (job == default)
return NotFound();
var api = job.ToApi();
@@ -50,8 +50,7 @@ namespace Tgstation.Server.Host.Controllers
outputStream,
contentLength,
BufferSize,
cancellationToken)
;
cancellationToken);
}
else
{
@@ -61,8 +60,7 @@ namespace Tgstation.Server.Host.Controllers
outputStream,
rangeLength,
BufferSize,
cancellationToken)
;
cancellationToken);
}
}
catch (OperationCanceledException)
@@ -103,8 +103,7 @@ namespace Tgstation.Server.Host.Controllers
.RepositorySettings
.AsQueryable()
.Where(x => x.InstanceId == Instance.Id)
.FirstOrDefaultAsync(cancellationToken)
;
.FirstOrDefaultAsync(cancellationToken);
if (currentModel == default)
return Gone();
@@ -178,19 +177,16 @@ namespace Tgstation.Server.Host.Controllers
databaseContext.Instances.Attach(instance);
if (await PopulateApi(api, repos, databaseContext, instance, ct))
await databaseContext.Save(ct);
})
;
});
},
cancellationToken)
;
cancellationToken);
api.Origin = model.Origin;
api.Reference = model.Reference;
api.ActiveJob = job.ToApi();
return Created(api);
})
;
});
}
/// <summary>
@@ -210,8 +206,7 @@ namespace Tgstation.Server.Host.Controllers
.RepositorySettings
.AsQueryable()
.Where(x => x.InstanceId == Instance.Id)
.FirstOrDefaultAsync(cancellationToken)
;
.FirstOrDefaultAsync(cancellationToken);
if (currentModel == default)
return Gone();
@@ -233,8 +228,7 @@ namespace Tgstation.Server.Host.Controllers
await jobManager.RegisterOperation(
job,
(core, databaseContextFactory, paramJob, progressReporter, ct) => core.RepositoryManager.DeleteRepository(ct),
cancellationToken)
;
cancellationToken);
api.ActiveJob = job.ToApi();
return Accepted(api);
}
@@ -258,8 +252,7 @@ namespace Tgstation.Server.Host.Controllers
.RepositorySettings
.AsQueryable()
.Where(x => x.InstanceId == Instance.Id)
.FirstOrDefaultAsync(cancellationToken)
;
.FirstOrDefaultAsync(cancellationToken);
if (currentModel == default)
return Gone();
@@ -286,8 +279,7 @@ namespace Tgstation.Server.Host.Controllers
}
return Json(api);
})
;
});
}
/// <summary>
@@ -347,8 +339,7 @@ namespace Tgstation.Server.Host.Controllers
.RepositorySettings
.AsQueryable()
.Where(x => x.InstanceId == Instance.Id)
.FirstOrDefaultAsync(cancellationToken)
;
.FirstOrDefaultAsync(cancellationToken);
if (currentModel == default)
return Gone();
@@ -412,8 +403,7 @@ namespace Tgstation.Server.Host.Controllers
await PopulateApi(api, repo, DatabaseContext, Instance, cancellationToken);
return null;
})
;
});
if (earlyOut != null)
return earlyOut;
@@ -127,9 +127,9 @@ namespace Tgstation.Server.Host.Controllers
dbUser.Name = sysIdentity.Username;
dbUser.SystemIdentifier = sysIdentity.Uid;
}
catch (NotImplementedException)
catch (NotImplementedException ex)
{
return RequiresPosixSystemIdentity();
return RequiresPosixSystemIdentity(ex);
}
else if (!(model.Password?.Length == 0 && model.OAuthConnections?.Any() == true))
{
@@ -144,7 +144,7 @@ namespace Tgstation.Server.Host.Controllers
await DatabaseContext.Save(cancellationToken);
Logger.LogInformation("Created new user {0} ({1})", dbUser.Name, dbUser.Id);
Logger.LogInformation("Created new user {name} ({id})", dbUser.Name, dbUser.Id);
return Created(dbUser.ToApi());
}
@@ -195,8 +195,7 @@ namespace Tgstation.Server.Host.Controllers
.Include(x => x.Group)
.ThenInclude(x => x.PermissionSet)
.Include(x => x.PermissionSet)
.FirstOrDefaultAsync(cancellationToken)
;
.FirstOrDefaultAsync(cancellationToken);
if (originalUser == default)
return NotFound();
@@ -215,12 +214,21 @@ namespace Tgstation.Server.Host.Controllers
|| (!oAuthEdit && model.OAuthConnections != null))
return Forbid();
var originalUserHasSid = originalUser.SystemIdentifier != null;
if (originalUserHasSid && originalUser.PasswordHash != null)
{
// cleanup from https://github.com/tgstation/tgstation-server/issues/1528
Logger.LogDebug("System user ID {userId}'s PasswordHash is polluted, updating database.", originalUser.Id);
originalUser.PasswordHash = null;
originalUser.LastPasswordUpdate = DateTimeOffset.UtcNow;
}
if (model.SystemIdentifier != null && model.SystemIdentifier != originalUser.SystemIdentifier)
return BadRequest(new ErrorMessageResponse(ErrorCode.UserSidChange));
if (model.Password != null)
{
if (model.SystemIdentifier != null)
if (originalUserHasSid)
return BadRequest(new ErrorMessageResponse(ErrorCode.UserMismatchPasswordSid));
var result = TrySetPassword(originalUser, model.Password, false);
@@ -265,8 +273,7 @@ namespace Tgstation.Server.Host.Controllers
.AsQueryable()
.Where(x => x.Id == model.Group.Id)
.Include(x => x.PermissionSet)
.FirstOrDefaultAsync(cancellationToken)
;
.FirstOrDefaultAsync(cancellationToken);
if (originalUser.Group == default)
return Gone();
@@ -408,8 +415,7 @@ namespace Tgstation.Server.Host.Controllers
.AsQueryable()
.Where(x => x.Id == model.Group.Id)
.Include(x => x.PermissionSet)
.FirstOrDefaultAsync(cancellationToken)
;
.FirstOrDefaultAsync(cancellationToken);
else
permissionSet = new Models.PermissionSet
{
@@ -75,8 +75,7 @@ namespace Tgstation.Server.Host.Controllers
var totalGroups = await DatabaseContext
.Groups
.AsQueryable()
.CountAsync(cancellationToken)
;
.CountAsync(cancellationToken);
if (totalGroups >= generalConfiguration.UserGroupLimit)
return Conflict(new ErrorMessageResponse(ErrorCode.UserGroupLimitReached));
@@ -121,8 +120,7 @@ namespace Tgstation.Server.Host.Controllers
.Where(x => x.Id == model.Id)
.Include(x => x.PermissionSet)
.Include(x => x.Users)
.FirstOrDefaultAsync(cancellationToken)
;
.FirstOrDefaultAsync(cancellationToken);
if (currentGroup == default)
return Gone();
@@ -167,8 +165,7 @@ namespace Tgstation.Server.Host.Controllers
.Where(x => x.Id == id)
.Include(x => x.Users)
.Include(x => x.PermissionSet)
.FirstOrDefaultAsync(cancellationToken)
;
.FirstOrDefaultAsync(cancellationToken);
if (group == default)
return Gone();
return Json(group.ToApi(true));
@@ -220,8 +217,7 @@ namespace Tgstation.Server.Host.Controllers
.Groups
.AsQueryable()
.Where(x => x.Id == id && x.Users.Count == 0)
.DeleteAsync(cancellationToken)
;
.DeleteAsync(cancellationToken);
if (numDeleted > 0)
return NoContent();
@@ -231,8 +227,7 @@ namespace Tgstation.Server.Host.Controllers
.Groups
.AsQueryable()
.Where(x => x.Id == id)
.AnyAsync(cancellationToken)
;
.AnyAsync(cancellationToken);
return groupExists
? Conflict(new ErrorMessageResponse(ErrorCode.UserGroupNotEmpty))
@@ -215,8 +215,7 @@ namespace Tgstation.Server.Host.Database
.Users
.AsQueryable()
.Where(x => x.CanonicalName == User.CanonicalizeName(User.TgsSystemUserName))
.FirstOrDefaultAsync(cancellationToken)
;
.FirstOrDefaultAsync(cancellationToken);
if (tgsUser != null)
logger.LogError(
@@ -233,8 +232,7 @@ namespace Tgstation.Server.Host.Database
var allInstances = await databaseContext
.Instances
.AsQueryable()
.ToListAsync(cancellationToken)
;
.ToListAsync(cancellationToken);
foreach (var instance in allInstances)
instance.Path = instance.Path.Replace('\\', '/');
}
@@ -246,8 +244,7 @@ namespace Tgstation.Server.Host.Database
.AsQueryable()
.Where(x => x.TopicRequestTimeout == 0)
.Select(x => x.Id)
.ToListAsync(cancellationToken)
;
.ToListAsync(cancellationToken);
var rowsUpdated = ids.Count;
foreach (var id in ids)
@@ -318,8 +315,7 @@ namespace Tgstation.Server.Host.Database
.Include(x => x.CreatedBy)
.Include(x => x.PermissionSet)
.Include(x => x.Group)
.FirstOrDefaultAsync(cancellationToken)
;
.FirstOrDefaultAsync(cancellationToken);
if (admin == default)
SeedAdminUser(databaseContext);
+1 -2
View File
@@ -108,8 +108,7 @@ namespace Tgstation.Server.Host.Jobs
if (job.StartedBy == null)
job.StartedBy = await databaseContext
.Users
.GetTgsUser(cancellationToken)
;
.GetTgsUser(cancellationToken);
else
job.StartedBy = new User
{
@@ -76,8 +76,7 @@ namespace Tgstation.Server.Host.Security
.Include(x => x.Group)
.ThenInclude(x => x.PermissionSet)
.Include(x => x.OAuthConnections)
.FirstOrDefaultAsync(cancellationToken)
;
.FirstOrDefaultAsync(cancellationToken);
if (user == default)
{
logger.LogWarning("Unable to find user with ID {0}!", userId);
@@ -110,8 +109,7 @@ namespace Tgstation.Server.Host.Security
.AsQueryable()
.Where(x => x.PermissionSetId == userPermissionSet.Id && x.InstanceId == instanceId && x.Instance.SwarmIdentifer == swarmConfiguration.Identifier)
.Include(x => x.Instance)
.FirstOrDefaultAsync(cancellationToken)
;
.FirstOrDefaultAsync(cancellationToken);
if (instancePermissionSet == null)
logger.LogDebug("User {0} does not have permissions on instance {1}!", userId, instanceId.Value);
@@ -68,8 +68,7 @@ namespace Tgstation.Server.Host.Security
userId,
apiHeaders.InstanceId,
tokenValidatedContext.SecurityToken.ValidFrom,
cancellationToken)
;
cancellationToken);
var authenticationContext = authenticationContextFactory.CurrentAuthenticationContext;
@@ -63,11 +63,15 @@ namespace Tgstation.Server.Host.Security
PrincipalContext pc = null;
UserPrincipal principal = null;
GetUserAndDomainName(user.SystemIdentifier, out _, out var domainName);
bool TryGetPrincipalFromContextType(ContextType contextType)
{
try
{
pc = new PrincipalContext(contextType);
pc = domainName != null
? new PrincipalContext(contextType, domainName)
: new PrincipalContext(contextType);
cancellationToken.ThrowIfCancellationRequested();
principal = UserPrincipal.FindByIdentity(pc, user.SystemIdentifier);
}
@@ -75,9 +79,13 @@ namespace Tgstation.Server.Host.Security
{
throw;
}
catch (Exception e)
catch (Exception ex)
{
logger.LogWarning(e, "Error loading user for context type {0}!", contextType);
logger.LogDebug(
ex,
"Error loading user for context type {contextType} and principal \"{domainName}\"!",
contextType,
domainName);
}
finally
{
+8 -16
View File
@@ -176,8 +176,7 @@ namespace Tgstation.Server.Host.Setup
await console.WriteAsync(
$"API Port (leave blank for default of {GeneralConfiguration.DefaultApiPort}): ",
false,
cancellationToken)
;
cancellationToken);
var portString = await console.ReadLineAsync(false, cancellationToken);
if (String.IsNullOrWhiteSpace(portString))
return null;
@@ -319,8 +318,7 @@ namespace Tgstation.Server.Host.Setup
await console.WriteAsync(resolvedPath, true, cancellationToken);
bool writeResolved = await PromptYesNo(
"Would you like to save the relative path in the configuration? If not, the full path will be saved. (y/n): ",
cancellationToken)
;
cancellationToken);
if (writeResolved)
databaseName = resolvedPath;
@@ -344,23 +342,19 @@ namespace Tgstation.Server.Host.Setup
await console.WriteAsync(
"NOTE: It is HIGHLY reccommended that TGS runs on a complete relational database, specfically *NOT* Sqlite.",
true,
cancellationToken)
;
cancellationToken);
await console.WriteAsync(
"Sqlite, by nature cannot perform several DDL operations. Because of this future compatiblility cannot be guaranteed.",
true,
cancellationToken)
;
cancellationToken);
await console.WriteAsync(
"This means that you may not be able to update to the next minor version of TGS without a clean re-installation!",
true,
cancellationToken)
;
cancellationToken);
await console.WriteAsync(
"Please consider taking the time to set up a relational database if this is meant to be a long-standing server.",
true,
cancellationToken)
;
cancellationToken);
await console.WriteAsync(String.Empty, true, cancellationToken);
await asyncDelayer.Delay(TimeSpan.FromSeconds(3), cancellationToken);
@@ -379,8 +373,7 @@ namespace Tgstation.Server.Host.Setup
DatabaseType.SqlServer,
DatabaseType.Sqlite),
false,
cancellationToken)
;
cancellationToken);
var databaseTypeString = await console.ReadLineAsync(false, cancellationToken);
if (Enum.TryParse<DatabaseType>(databaseTypeString, out var databaseType))
return databaseType;
@@ -1007,8 +1000,7 @@ namespace Tgstation.Server.Host.Setup
elasticSearchConfiguration,
controlPanelConfiguration,
swarmConfiguration,
cancellationToken)
;
cancellationToken);
}
/// <summary>
@@ -965,8 +965,7 @@ namespace Tgstation.Server.Host.Swarm
await Task.WhenAll(
currentSwarmServers
.Where(x => !x.Controller)
.Select(HealthRequestForServer))
;
.Select(HealthRequestForServer));
lock (swarmServers)
if (swarmServers.Count != currentSwarmServers.Count)
@@ -67,16 +67,14 @@ namespace Tgstation.Server.Host.Utils
.AsQueryable()
.Where(x => x.Instance.SwarmIdentifer == swarmConfiguration.Identifier)
.Select(x => x.Port)
.ToListAsync(cancellationToken)
;
.ToListAsync(cancellationToken);
var dmPorts = await databaseContext
.DreamMakerSettings
.AsQueryable()
.Where(x => x.Instance.SwarmIdentifer == swarmConfiguration.Identifier)
.Select(x => x.ApiValidationPort)
.ToListAsync(cancellationToken)
;
.ToListAsync(cancellationToken);
var exceptions = new List<Exception>();
ushort port = 0;
@@ -224,35 +224,45 @@ namespace Tgstation.Server.Tests.Live.Instance
Assert.AreEqual(1, dumpFiles.Length);
File.Delete(dumpFiles.Single());
KillDD(true);
var jobTcs = new TaskCompletionSource();
var killTaskStarted = new TaskCompletionSource();
var killTask = Task.Run(() =>
{
killTaskStarted.SetResult();
while (!jobTcs.Task.IsCompleted)
KillDD(false);
}, cancellationToken);
JobResponse job;
try
while (true)
{
await killTaskStarted.Task;
var dumpTask = instanceClient.DreamDaemon.CreateDump(cancellationToken);
job = await WaitForJob(await dumpTask, 20, true, null, cancellationToken);
}
finally
{
jobTcs.SetResult();
await killTask;
KillDD(true);
var jobTcs = new TaskCompletionSource();
var killTaskStarted = new TaskCompletionSource();
var killTask = Task.Run(() =>
{
killTaskStarted.SetResult();
while (!jobTcs.Task.IsCompleted)
KillDD(false);
}, cancellationToken);
try
{
await killTaskStarted.Task;
var dumpTask = instanceClient.DreamDaemon.CreateDump(cancellationToken);
job = await WaitForJob(await dumpTask, 20, true, null, cancellationToken);
}
finally
{
jobTcs.SetResult();
await killTask;
}
// these can also happen
if (!(new PlatformIdentifier().IsWindows
&& (job.ExceptionDetails.Contains("BetterWin32Errors.Win32Exception: E_ACCESSDENIED: Access is denied.")
|| job.ExceptionDetails.Contains("BetterWin32Errors.Win32Exception: E_HANDLE: The handle is invalid.")
|| job.ExceptionDetails.Contains("BetterWin32Errors.Win32Exception: 3489660936: Unknown error (0xd0000008)")
|| job.ExceptionDetails.Contains("System.InvalidOperationException: No process is associated with this object."))))
break;
var restartJob = await instanceClient.DreamDaemon.Restart(cancellationToken);
await WaitForJob(restartJob, 20, false, null, cancellationToken);
}
// these can also happen
if (!(new PlatformIdentifier().IsWindows
&& (job.ExceptionDetails.Contains("BetterWin32Errors.Win32Exception: E_ACCESSDENIED: Access is denied.")
|| job.ExceptionDetails.Contains("BetterWin32Errors.Win32Exception: E_HANDLE: The handle is invalid.")
|| job.ExceptionDetails.Contains("BetterWin32Errors.Win32Exception: 3489660936: Unknown error (0xd0000008)")))) // kek
Assert.IsTrue(job.ErrorCode == ErrorCode.DreamDaemonOffline || job.ErrorCode == ErrorCode.GCoreFailure, $"{job.ErrorCode}: {job.ExceptionDetails}");
Assert.IsTrue(job.ErrorCode == ErrorCode.DreamDaemonOffline || job.ErrorCode == ErrorCode.GCoreFailure, $"{job.ErrorCode}: {job.ExceptionDetails}");
await Task.Delay(TimeSpan.FromSeconds(20), cancellationToken);