diff --git a/.github/workflows/check-pr-has-milestone.yml b/.github/workflows/check-pr-has-milestone.yml index ebf3832622..056ddc7b82 100644 --- a/.github/workflows/check-pr-has-milestone.yml +++ b/.github/workflows/check-pr-has-milestone.yml @@ -14,6 +14,7 @@ concurrency: jobs: fail-on-bad-milestone: + if: github.event.pull_request.draft != true name: Fail if Pull Request has no Associated Version Milestone runs-on: ubuntu-latest steps: diff --git a/.github/workflows/ci-security.yml b/.github/workflows/ci-security.yml index eb7806f7d1..279b8bc2b4 100644 --- a/.github/workflows/ci-security.yml +++ b/.github/workflows/ci-security.yml @@ -24,7 +24,7 @@ concurrency: jobs: security-checkpoint: name: Check CI Clearance - if: github.event_name == 'pull_request_target' && (github.event.pull_request.head.repo.id != github.event.pull_request.base.repo.id || github.event.pull_request.user.id == 49699333) && github.event.pull_request.state == 'open' + if: github.event_name == 'pull_request_target' && (github.event.pull_request.head.repo.id != github.event.pull_request.base.repo.id || github.event.pull_request.user.id == 49699333) && github.event.pull_request.state == 'open' && github.event.pull_request.draft != true runs-on: ubuntu-latest steps: - name: Generate App Token @@ -62,7 +62,7 @@ jobs: ci-pipline-workflow-call: name: CI Pipeline needs: security-checkpoint - if: (!(cancelled() || failure()) && (needs.security-checkpoint.result == 'success' || (github.event_name != 'pull_request_target' && github.event.pull_request.head.repo.id == github.event.pull_request.base.repo.id && github.event.pull_request.user.id != 49699333))) + if: (!(cancelled() || failure()) && (needs.security-checkpoint.result == 'success' || (github.event_name != 'pull_request_target' && github.event.pull_request.head.repo.id == github.event.pull_request.base.repo.id && github.event.pull_request.user.id != 49699333)) && github.event.pull_request.draft != true) uses: ./.github/workflows/ci-pipeline.yml secrets: inherit with: diff --git a/src/Tgstation.Server.Client.GraphQL/Tgstation.Server.Client.GraphQL.csproj b/src/Tgstation.Server.Client.GraphQL/Tgstation.Server.Client.GraphQL.csproj index 67e9d74754..dc312601f6 100644 --- a/src/Tgstation.Server.Client.GraphQL/Tgstation.Server.Client.GraphQL.csproj +++ b/src/Tgstation.Server.Client.GraphQL/Tgstation.Server.Client.GraphQL.csproj @@ -14,23 +14,19 @@ + - - - - - - + - + $(IntermediateOutputPath)berry/GraphQLClient.Client.cs $(IntermediateOutputPath)berry/GraphQLClient.Client.cs diff --git a/src/Tgstation.Server.Host/Authority/LoginAuthority.cs b/src/Tgstation.Server.Host/Authority/LoginAuthority.cs index 363744fbf1..f0286767e4 100644 --- a/src/Tgstation.Server.Host/Authority/LoginAuthority.cs +++ b/src/Tgstation.Server.Host/Authority/LoginAuthority.cs @@ -62,9 +62,9 @@ namespace Tgstation.Server.Host.Authority readonly ISessionInvalidationTracker sessionInvalidationTracker; /// - /// The for the . + /// The containing the for the . /// - readonly SecurityConfiguration securityConfiguration; + readonly IOptionsSnapshot securityConfigurationOptions; /// /// Generate an for a given . @@ -113,7 +113,7 @@ namespace Tgstation.Server.Host.Authority /// The value of . /// The value of . /// The value of . - /// The containing the value of . + /// The value of . public LoginAuthority( IDatabaseContext databaseContext, ILogger logger, @@ -124,7 +124,7 @@ namespace Tgstation.Server.Host.Authority ICryptographySuite cryptographySuite, IIdentityCache identityCache, ISessionInvalidationTracker sessionInvalidationTracker, - IOptions securityConfigurationOptions) + IOptionsSnapshot securityConfigurationOptions) : base( databaseContext, logger) @@ -136,7 +136,7 @@ namespace Tgstation.Server.Host.Authority this.cryptographySuite = cryptographySuite ?? throw new ArgumentNullException(nameof(cryptographySuite)); this.identityCache = identityCache ?? throw new ArgumentNullException(nameof(identityCache)); this.sessionInvalidationTracker = sessionInvalidationTracker ?? throw new ArgumentNullException(nameof(sessionInvalidationTracker)); - securityConfiguration = securityConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(securityConfigurationOptions)); + this.securityConfigurationOptions = securityConfigurationOptions ?? throw new ArgumentNullException(nameof(securityConfigurationOptions)); } /// @@ -181,7 +181,7 @@ namespace Tgstation.Server.Host.Authority private async ValueTask> AttemptLoginImpl(CancellationToken cancellationToken) { // password and oauth logins disabled - if (securityConfiguration.OidcStrictMode) + if (securityConfigurationOptions.Value.OidcStrictMode) return Unauthorized(); var headers = apiHeadersProvider.ApiHeaders; @@ -208,7 +208,7 @@ namespace Tgstation.Server.Host.Authority using (systemIdentity) { // Get the user from the database - IQueryable query = DatabaseContext.Users.AsQueryable(); + IQueryable query = DatabaseContext.Users; if (oAuthLogin) { var oAuthProvider = headers.OAuthProvider!.Value; diff --git a/src/Tgstation.Server.Host/Authority/PermissionSetAuthority.cs b/src/Tgstation.Server.Host/Authority/PermissionSetAuthority.cs index bd50714aee..22fdea4114 100644 --- a/src/Tgstation.Server.Host/Authority/PermissionSetAuthority.cs +++ b/src/Tgstation.Server.Host/Authority/PermissionSetAuthority.cs @@ -118,13 +118,11 @@ namespace Tgstation.Server.Host.Authority var groupIdQuery = DatabaseContext .Users - .AsQueryable() .Where(user => user.Id == userId) .Select(user => user.GroupId); var permissionSetId = await DatabaseContext .PermissionSets - .AsQueryable() .Where(permissionSet => permissionSet.UserId == userId || groupIdQuery.Contains(permissionSet.GroupId)) .Select(permissionSet => permissionSet.Id!.Value) diff --git a/src/Tgstation.Server.Host/Authority/UserAuthority.cs b/src/Tgstation.Server.Host/Authority/UserAuthority.cs index 416df9ff7c..1022e79e28 100644 --- a/src/Tgstation.Server.Host/Authority/UserAuthority.cs +++ b/src/Tgstation.Server.Host/Authority/UserAuthority.cs @@ -85,9 +85,9 @@ namespace Tgstation.Server.Host.Authority readonly IOptionsSnapshot generalConfigurationOptions; /// - /// The of for the . + /// The of for the . /// - readonly IOptions securityConfigurationOptions; + readonly IOptionsSnapshot securityConfigurationOptions; /// /// Implements the . @@ -107,7 +107,6 @@ namespace Tgstation.Server.Host.Authority return databaseContext .Users - .AsQueryable() .Where(x => ids.Contains(x.Id!.Value)) .ToDictionaryAsync(user => user.Id!.Value, cancellationToken); } @@ -130,7 +129,6 @@ namespace Tgstation.Server.Host.Authority var list = await databaseContext .OAuthConnections - .AsQueryable() .Where(x => userIds.Contains(x.User!.Id!.Value)) .ToListAsync(cancellationToken); @@ -161,7 +159,6 @@ namespace Tgstation.Server.Host.Authority var list = await databaseContext .OidcConnections - .AsQueryable() .Where(x => userIds.Contains(x.User!.Id!.Value)) .ToListAsync(cancellationToken); @@ -221,7 +218,7 @@ namespace Tgstation.Server.Host.Authority ITopicEventSender topicEventSender, IClaimsPrincipalAccessor claimsPrincipalAccessor, IOptionsSnapshot generalConfigurationOptions, - IOptions securityConfigurationOptions) + IOptionsSnapshot securityConfigurationOptions) : base( databaseContext, logger) @@ -371,7 +368,6 @@ namespace Tgstation.Server.Host.Authority var totalUsers = await DatabaseContext .Users - .AsQueryable() .CountAsync(cancellationToken); if (totalUsers >= generalConfigurationOptions.Value.UserLimit) return Conflict(ErrorCode.UserLimitReached); @@ -473,7 +469,6 @@ namespace Tgstation.Server.Host.Authority var userQuery = DatabaseContext .Users - .AsQueryable() .Where(x => x.Id == model.Id) .Include(x => x.CreatedBy) .Include(x => x.OAuthConnections) @@ -574,7 +569,6 @@ namespace Tgstation.Server.Host.Authority originalUser.Group = await DatabaseContext .Groups - .AsQueryable() .Where(x => x.Id == model.Group.Id) .Include(x => x.PermissionSet) .FirstOrDefaultAsync(cancellationToken); @@ -759,9 +753,8 @@ namespace Tgstation.Server.Host.Authority IQueryable Queryable(bool includeJoins, bool allowSystemUser) { var tgsUserCanonicalName = User.CanonicalizeName(User.TgsSystemUserName); - var queryable = DatabaseContext - .Users - .AsQueryable(); + IQueryable queryable = DatabaseContext + .Users; if (!allowSystemUser) queryable = queryable @@ -792,7 +785,6 @@ namespace Tgstation.Server.Host.Authority if (model.Group != null) group = await DatabaseContext .Groups - .AsQueryable() .Where(x => x.Id == model.Group.Id) .Include(x => x.PermissionSet) .FirstOrDefaultAsync(cancellationToken); diff --git a/src/Tgstation.Server.Host/Authority/UserGroupAuthority.cs b/src/Tgstation.Server.Host/Authority/UserGroupAuthority.cs index a429b1bab4..47ca690d5e 100644 --- a/src/Tgstation.Server.Host/Authority/UserGroupAuthority.cs +++ b/src/Tgstation.Server.Host/Authority/UserGroupAuthority.cs @@ -121,7 +121,6 @@ namespace Tgstation.Server.Host.Authority var userId = claimsPrincipalAccessor.User.GetTgsUserId(); var group = await DatabaseContext .Users - .AsQueryable() .Where(user => user.Id == userId) .Select(user => user.Group) .FirstOrDefaultAsync(cancellationToken); @@ -148,7 +147,6 @@ namespace Tgstation.Server.Host.Authority { var totalGroups = await DatabaseContext .Groups - .AsQueryable() .CountAsync(cancellationToken); if (totalGroups >= generalConfigurationOptions.Value.UserGroupLimit) return Conflict(ErrorCode.UserGroupLimitReached); @@ -183,7 +181,6 @@ namespace Tgstation.Server.Host.Authority { var currentGroup = await DatabaseContext .Groups - .AsQueryable() .Where(x => x.Id == id) .Include(x => x.PermissionSet) .FirstOrDefaultAsync(cancellationToken); @@ -212,7 +209,6 @@ namespace Tgstation.Server.Host.Authority { var numDeleted = await DatabaseContext .Groups - .AsQueryable() .Where(x => x.Id == id && x.Users!.Count == 0) .ExecuteDeleteAsync(cancellationToken); @@ -222,7 +218,6 @@ namespace Tgstation.Server.Host.Authority // find out how we failed var groupExists = await DatabaseContext .Groups - .AsQueryable() .Where(x => x.Id == id) .AnyAsync(cancellationToken); @@ -242,9 +237,8 @@ namespace Tgstation.Server.Host.Authority /// An of s. IQueryable QueryableImpl(bool includeJoins) { - var queryable = DatabaseContext - .Groups - .AsQueryable(); + IQueryable queryable = DatabaseContext + .Groups; if (includeJoins) queryable = queryable diff --git a/src/Tgstation.Server.Host/Components/Chat/Commands/PullRequestsCommand.cs b/src/Tgstation.Server.Host/Components/Chat/Commands/PullRequestsCommand.cs index 5cc52d2b83..573473c2f6 100644 --- a/src/Tgstation.Server.Host/Components/Chat/Commands/PullRequestsCommand.cs +++ b/src/Tgstation.Server.Host/Components/Chat/Commands/PullRequestsCommand.cs @@ -116,7 +116,6 @@ namespace Tgstation.Server.Host.Components.Chat.Commands await databaseContextFactory.UseContext( async db => results = await db .RevisionInformations - .AsQueryable() .Where(x => x.Instance!.Id == instance.Id && x.CommitSha == head) .SelectMany(x => x.ActiveTestMerges!) .Select(x => x.TestMerge) diff --git a/src/Tgstation.Server.Host/Components/Chat/Providers/DiscordProvider.cs b/src/Tgstation.Server.Host/Components/Chat/Providers/DiscordProvider.cs index f76ee34517..63f8c166f5 100644 --- a/src/Tgstation.Server.Host/Components/Chat/Providers/DiscordProvider.cs +++ b/src/Tgstation.Server.Host/Components/Chat/Providers/DiscordProvider.cs @@ -9,6 +9,7 @@ using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; using Remora.Discord.API.Abstractions.Gateway.Commands; using Remora.Discord.API.Abstractions.Gateway.Events; @@ -72,9 +73,9 @@ namespace Tgstation.Server.Host.Components.Chat.Providers readonly IAssemblyInformationProvider assemblyInformationProvider; /// - /// The for the . + /// The for the . /// - readonly GeneralConfiguration generalConfiguration; + readonly IOptionsMonitor generalConfigurationOptions; /// /// The containing Discord services. @@ -141,18 +142,18 @@ namespace Tgstation.Server.Host.Components.Chat.Providers /// The for the . /// The value of . /// The for the . - /// The value of . + /// The value of . public DiscordProvider( IJobManager jobManager, IAsyncDelayer asyncDelayer, ILogger logger, IAssemblyInformationProvider assemblyInformationProvider, - ChatBot chatBot, - GeneralConfiguration generalConfiguration) + IOptionsMonitor generalConfigurationOptions, + ChatBot chatBot) : base(jobManager, asyncDelayer, logger, chatBot) { this.assemblyInformationProvider = assemblyInformationProvider ?? throw new ArgumentNullException(nameof(assemblyInformationProvider)); - this.generalConfiguration = generalConfiguration ?? throw new ArgumentNullException(nameof(generalConfiguration)); + this.generalConfigurationOptions = generalConfigurationOptions ?? throw new ArgumentNullException(nameof(generalConfigurationOptions)); mappedChannels = new List(); connectDisconnectLock = new object(); @@ -924,7 +925,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers true), EngineType.OpenDream => new EmbedField( "OpenDream Version", - $"[{engineVersion.SourceSHA![..7]}]({generalConfiguration.OpenDreamGitUrl}/commit/{engineVersion.SourceSHA})", + $"[{engineVersion.SourceSHA![..7]}]({generalConfigurationOptions.CurrentValue.OpenDreamGitUrl}/commit/{engineVersion.SourceSHA})", true), _ => throw new InvalidOperationException($"Invaild EngineType: {engineVersion.Engine.Value}"), }; diff --git a/src/Tgstation.Server.Host/Components/Chat/Providers/IrcProvider.cs b/src/Tgstation.Server.Host/Components/Chat/Providers/IrcProvider.cs index 560390201d..0a947c85e2 100644 --- a/src/Tgstation.Server.Host/Components/Chat/Providers/IrcProvider.cs +++ b/src/Tgstation.Server.Host/Components/Chat/Providers/IrcProvider.cs @@ -8,6 +8,7 @@ using System.Threading.Tasks; using Meebey.SmartIrc4net; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; using Newtonsoft.Json; @@ -92,7 +93,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers /// /// The for the . /// - readonly FileLoggingConfiguration loggingConfiguration; + readonly IOptionsMonitor loggingConfigurationOptions; /// /// The client. @@ -117,18 +118,18 @@ namespace Tgstation.Server.Host.Components.Chat.Providers /// The for the . /// The to get the from. /// The for the . - /// The for the . + /// The value of . public IrcProvider( IJobManager jobManager, IAsyncDelayer asyncDelayer, ILogger logger, - IAssemblyInformationProvider assemblyInformationProvider, Models.ChatBot chatBot, - FileLoggingConfiguration loggingConfiguration) + IAssemblyInformationProvider assemblyInformationProvider, + IOptionsMonitor loggingConfigurationOptions) : base(jobManager, asyncDelayer, logger, chatBot) { ArgumentNullException.ThrowIfNull(assemblyInformationProvider); - ArgumentNullException.ThrowIfNull(loggingConfiguration); + ArgumentNullException.ThrowIfNull(loggingConfigurationOptions); var builder = chatBot.CreateConnectionStringBuilder(); if (builder == null || !builder.Valid || builder is not IrcConnectionStringBuilder ircBuilder) @@ -143,7 +144,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers passwordType = ircBuilder.PasswordType; assemblyInfo = assemblyInformationProvider ?? throw new ArgumentNullException(nameof(assemblyInformationProvider)); - this.loggingConfiguration = loggingConfiguration ?? throw new ArgumentNullException(nameof(loggingConfiguration)); + this.loggingConfigurationOptions = loggingConfigurationOptions ?? throw new ArgumentNullException(nameof(loggingConfigurationOptions)); client = InstantiateClient(); @@ -758,7 +759,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers newClient.OnChannelMessage += Client_OnChannelMessage; newClient.OnQueryMessage += Client_OnQueryMessage; - if (loggingConfiguration.ProviderNetworkDebug) + if (loggingConfigurationOptions.CurrentValue.ProviderNetworkDebug) { newClient.OnReadLine += (sender, e) => Logger.LogTrace("READ: {line}", e.Line); newClient.OnWriteLine += (sender, e) => Logger.LogTrace("WRITE: {line}", e.Line); diff --git a/src/Tgstation.Server.Host/Components/Chat/Providers/ProviderFactory.cs b/src/Tgstation.Server.Host/Components/Chat/Providers/ProviderFactory.cs index 41113d196f..f8b3be51d0 100644 --- a/src/Tgstation.Server.Host/Components/Chat/Providers/ProviderFactory.cs +++ b/src/Tgstation.Server.Host/Components/Chat/Providers/ProviderFactory.cs @@ -36,14 +36,14 @@ namespace Tgstation.Server.Host.Components.Chat.Providers readonly ILoggerFactory loggerFactory; /// - /// The for the . + /// The for the . /// - readonly GeneralConfiguration generalConfiguration; + readonly IOptionsMonitor generalConfigurationOptions; /// - /// The for the . + /// The for the . /// - readonly FileLoggingConfiguration loggingConfiguration; + readonly IOptionsMonitor loggingConfigurationOptions; /// /// Initializes a new instance of the class. @@ -52,22 +52,22 @@ namespace Tgstation.Server.Host.Components.Chat.Providers /// The value of . /// The value of . /// The value of . - /// The containing the value of . - /// The containing the value of . + /// The value of . + /// The value of . public ProviderFactory( IJobManager jobManager, IAssemblyInformationProvider assemblyInformationProvider, IAsyncDelayer asyncDelayer, ILoggerFactory loggerFactory, - IOptions generalConfigurationOptions, - IOptions loggingConfigurationOptions) + IOptionsMonitor generalConfigurationOptions, + IOptionsMonitor loggingConfigurationOptions) { this.jobManager = jobManager ?? throw new ArgumentNullException(nameof(jobManager)); this.loggerFactory = loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory)); this.asyncDelayer = asyncDelayer ?? throw new ArgumentNullException(nameof(asyncDelayer)); this.assemblyInformationProvider = assemblyInformationProvider ?? throw new ArgumentNullException(nameof(assemblyInformationProvider)); - generalConfiguration = generalConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(generalConfigurationOptions)); - loggingConfiguration = loggingConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(loggingConfigurationOptions)); + this.generalConfigurationOptions = generalConfigurationOptions ?? throw new ArgumentNullException(nameof(generalConfigurationOptions)); + this.loggingConfigurationOptions = loggingConfigurationOptions ?? throw new ArgumentNullException(nameof(loggingConfigurationOptions)); } /// @@ -80,16 +80,16 @@ namespace Tgstation.Server.Host.Components.Chat.Providers jobManager, asyncDelayer, loggerFactory.CreateLogger(), - assemblyInformationProvider, settings, - loggingConfiguration), + assemblyInformationProvider, + loggingConfigurationOptions), ChatProvider.Discord => new DiscordProvider( jobManager, asyncDelayer, loggerFactory.CreateLogger(), assemblyInformationProvider, - settings, - generalConfiguration), + generalConfigurationOptions, + settings), _ => throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, "Invalid ChatProvider: {0}", settings.Provider)), }; } diff --git a/src/Tgstation.Server.Host/Components/Deployment/DmbFactory.cs b/src/Tgstation.Server.Host/Components/Deployment/DmbFactory.cs index c6ff9808a3..8c920d0cbb 100644 --- a/src/Tgstation.Server.Host/Components/Deployment/DmbFactory.cs +++ b/src/Tgstation.Server.Host/Components/Deployment/DmbFactory.cs @@ -207,7 +207,6 @@ namespace Tgstation.Server.Host.Components.Deployment async (db) => cj = await db .CompileJobs - .AsQueryable() .Where(x => x.Job.Instance!.Id == metadata.Id) .OrderByDescending(x => x.Job.StoppedAt) .FirstOrDefaultAsync(cancellationToken)); @@ -277,7 +276,6 @@ namespace Tgstation.Server.Host.Components.Deployment { jobUidsToNotErase = (await db .CompileJobs - .AsQueryable() .Where( x => x.Job.Instance!.Id == metadata.Id && jobIdsToSkip.Contains(x.Id!.Value)) @@ -364,7 +362,6 @@ namespace Tgstation.Server.Host.Components.Deployment await databaseContextFactory.UseContext( async db => compileJob = await db .CompileJobs - .AsQueryable() .Where(x => x!.Id == compileJobId) .Include(x => x.Job!) .ThenInclude(x => x.StartedBy) diff --git a/src/Tgstation.Server.Host/Components/Deployment/DreamMaker.cs b/src/Tgstation.Server.Host/Components/Deployment/DreamMaker.cs index 6f8b05c9d2..c702b1fa8a 100644 --- a/src/Tgstation.Server.Host/Components/Deployment/DreamMaker.cs +++ b/src/Tgstation.Server.Host/Components/Deployment/DreamMaker.cs @@ -7,6 +7,7 @@ using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; using Prometheus; @@ -30,7 +31,9 @@ using Tgstation.Server.Host.Utils; namespace Tgstation.Server.Host.Components.Deployment { /// +#pragma warning disable CA1506 // TODO: Decomplexify sealed class DreamMaker : IDreamMaker +#pragma warning restore CA1506 { /// /// Extension for .dmes. @@ -92,16 +95,16 @@ namespace Tgstation.Server.Host.Components.Deployment /// readonly IAsyncDelayer asyncDelayer; + /// + /// The of for . + /// + readonly IOptionsMonitor sessionConfigurationOptions; + /// /// The for . /// readonly ILogger logger; - /// - /// The for . - /// - readonly SessionConfiguration sessionConfiguration; - /// /// The belongs to. /// @@ -167,8 +170,8 @@ namespace Tgstation.Server.Host.Components.Deployment /// The value of . /// The value of . /// The to use. + /// The value of . /// The value of . - /// The value of . /// The value of . public DreamMaker( IEngineManager engineManager, @@ -183,8 +186,8 @@ namespace Tgstation.Server.Host.Components.Deployment IRemoteDeploymentManagerFactory remoteDeploymentManagerFactory, IAsyncDelayer asyncDelayer, IMetricFactory metricFactory, + IOptionsMonitor sessionConfigurationOptions, ILogger logger, - SessionConfiguration sessionConfiguration, Api.Models.Instance metadata) { this.engineManager = engineManager ?? throw new ArgumentNullException(nameof(engineManager)); @@ -199,8 +202,8 @@ namespace Tgstation.Server.Host.Components.Deployment this.remoteDeploymentManagerFactory = remoteDeploymentManagerFactory ?? throw new ArgumentNullException(nameof(remoteDeploymentManagerFactory)); this.asyncDelayer = asyncDelayer ?? throw new ArgumentNullException(nameof(asyncDelayer)); ArgumentNullException.ThrowIfNull(metricFactory); + this.sessionConfigurationOptions = sessionConfigurationOptions ?? throw new ArgumentNullException(nameof(sessionConfigurationOptions)); this.logger = logger ?? throw new ArgumentNullException(nameof(logger)); - this.sessionConfiguration = sessionConfiguration ?? throw new ArgumentNullException(nameof(sessionConfiguration)); this.metadata = metadata ?? throw new ArgumentNullException(nameof(metadata)); successfulDeployments = metricFactory.CreateCounter("tgs_successful_deployments", "The number of deployments that have completed successfully"); @@ -253,7 +256,6 @@ namespace Tgstation.Server.Host.Components.Deployment ddSettings = await databaseContext .DreamDaemonSettings - .AsQueryable() .Where(x => x.InstanceId == metadata.Id) .Select(x => new Models.DreamDaemonSettings { @@ -266,7 +268,6 @@ namespace Tgstation.Server.Host.Components.Deployment dreamMakerSettings = await databaseContext .DreamMakerSettings - .AsQueryable() .Where(x => x.InstanceId == metadata.Id) .FirstAsync(cancellationToken); if (dreamMakerSettings == default) @@ -274,7 +275,6 @@ namespace Tgstation.Server.Host.Components.Deployment repositorySettings = await databaseContext .RepositorySettings - .AsQueryable() .Where(x => x.InstanceId == metadata.Id) .Select(x => new Models.RepositorySettings { @@ -302,7 +302,6 @@ namespace Tgstation.Server.Host.Components.Deployment repoName = repo.RemoteRepositoryName; revInfo = await databaseContext .RevisionInformations - .AsQueryable() .Where(x => x.CommitSha == repoSha && x.InstanceId == metadata.Id) .Include(x => x.ActiveTestMerges!) .ThenInclude(x => x.TestMerge!) @@ -456,7 +455,6 @@ namespace Tgstation.Server.Host.Components.Deployment { var previousCompileJobs = await databaseContext .CompileJobs - .AsQueryable() .Where(x => x.Job.Instance!.Id == metadata.Id) .OrderByDescending(x => x.Job.StoppedAt) .Take(10) @@ -927,7 +925,7 @@ namespace Tgstation.Server.Host.Components.Deployment readStandardHandles: true, noShellExecute: true); - if (sessionConfiguration.LowPriorityDeploymentProcesses) + if (sessionConfigurationOptions.CurrentValue.LowPriorityDeploymentProcesses) dm.AdjustPriority(false); int exitCode; @@ -1018,7 +1016,7 @@ namespace Tgstation.Server.Host.Components.Deployment { async ValueTask CleanDir() { - if (sessionConfiguration.DelayCleaningFailedDeployments) + if (sessionConfigurationOptions.CurrentValue.DelayCleaningFailedDeployments) { logger.LogDebug("Not cleaning up errored deployment directory {guid} due to config.", job.DirectoryName); return; diff --git a/src/Tgstation.Server.Host/Components/Deployment/Remote/GitHubRemoteDeploymentManager.cs b/src/Tgstation.Server.Host/Components/Deployment/Remote/GitHubRemoteDeploymentManager.cs index 790b9ea1d3..a023910f6f 100644 --- a/src/Tgstation.Server.Host/Components/Deployment/Remote/GitHubRemoteDeploymentManager.cs +++ b/src/Tgstation.Server.Host/Components/Deployment/Remote/GitHubRemoteDeploymentManager.cs @@ -70,7 +70,6 @@ namespace Tgstation.Server.Host.Components.Deployment.Remote async databaseContext => repositorySettings = await databaseContext .RepositorySettings - .AsQueryable() .Where(x => x.InstanceId == Metadata.Id) .FirstAsync(cancellationToken)); @@ -376,7 +375,6 @@ namespace Tgstation.Server.Host.Components.Deployment.Remote async databaseContext => gitHubAccessToken = await databaseContext .RepositorySettings - .AsQueryable() .Where(x => x.InstanceId == Metadata.Id) .Select(x => x.AccessToken) .FirstAsync(cancellationToken)); diff --git a/src/Tgstation.Server.Host/Components/Engine/OpenDreamInstaller.cs b/src/Tgstation.Server.Host/Components/Engine/OpenDreamInstaller.cs index e7a53e3cd8..071fcbaab4 100644 --- a/src/Tgstation.Server.Host/Components/Engine/OpenDreamInstaller.cs +++ b/src/Tgstation.Server.Host/Components/Engine/OpenDreamInstaller.cs @@ -52,14 +52,14 @@ namespace Tgstation.Server.Host.Components.Engine protected IProcessExecutor ProcessExecutor { get; } /// - /// The for the . + /// The for the . /// - protected GeneralConfiguration GeneralConfiguration { get; } + protected IOptionsMonitor GeneralConfigurationOptions { get; } /// /// The for the . /// - protected SessionConfiguration SessionConfiguration { get; } + protected IOptionsMonitor SessionConfigurationOptions { get; } /// /// The for the . @@ -91,8 +91,8 @@ namespace Tgstation.Server.Host.Components.Engine /// The value of . /// The value of . /// The value of . - /// The containing value of . - /// The containing value of . + /// The value of . + /// The value of . public OpenDreamInstaller( IIOManager ioManager, ILogger logger, @@ -101,8 +101,8 @@ namespace Tgstation.Server.Host.Components.Engine IRepositoryManager repositoryManager, IAsyncDelayer asyncDelayer, IHttpClientFactory httpClientFactory, - IOptions generalConfigurationOptions, - IOptions sessionConfigurationOptions) + IOptionsMonitor generalConfigurationOptions, + IOptionsMonitor sessionConfigurationOptions) : base(ioManager, logger) { this.platformIdentifier = platformIdentifier ?? throw new ArgumentNullException(nameof(platformIdentifier)); @@ -110,8 +110,8 @@ namespace Tgstation.Server.Host.Components.Engine this.repositoryManager = repositoryManager ?? throw new ArgumentNullException(nameof(repositoryManager)); this.asyncDelayer = asyncDelayer ?? throw new ArgumentNullException(nameof(asyncDelayer)); this.httpClientFactory = httpClientFactory ?? throw new ArgumentNullException(nameof(httpClientFactory)); - GeneralConfiguration = generalConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(generalConfigurationOptions)); - SessionConfiguration = sessionConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(sessionConfigurationOptions)); + GeneralConfigurationOptions = generalConfigurationOptions ?? throw new ArgumentNullException(nameof(generalConfigurationOptions)); + SessionConfigurationOptions = sessionConfigurationOptions ?? throw new ArgumentNullException(nameof(sessionConfigurationOptions)); } /// @@ -147,10 +147,11 @@ namespace Tgstation.Server.Host.Components.Engine var progressSection1 = jobProgressReporter.CreateSection("Updating OpenDream git repository", 0.5f); IRepository? repo; + var generalConfig = GeneralConfigurationOptions.CurrentValue; try { repo = await repositoryManager.CloneRepository( - GeneralConfiguration.OpenDreamGitUrl, + generalConfig.OpenDreamGitUrl, null, null, null, @@ -187,7 +188,7 @@ namespace Tgstation.Server.Host.Components.Engine using (var progressSection2 = jobProgressReporter.CreateSection("Checking out OpenDream version", 0.5f)) { var committish = version.SourceSHA - ?? $"{GeneralConfiguration.OpenDreamGitTagPrefix}{version.Version!.Semver()}"; + ?? $"{generalConfig.OpenDreamGitTagPrefix}{version.Version!.Semver()}"; await repo.CheckoutObject( committish, @@ -279,6 +280,7 @@ namespace Tgstation.Server.Host.Components.Engine async shortenedPath => { var shortenedDeployPath = IOManager.ConcatPath(shortenedPath, DeployDir); + var generalConfig = GeneralConfigurationOptions.CurrentValue; await using var buildProcess = await ProcessExecutor.LaunchProcess( dotnetPath, shortenedPath, @@ -286,17 +288,17 @@ namespace Tgstation.Server.Host.Components.Engine cancellationToken, null, null, - !GeneralConfiguration.OpenDreamSuppressInstallOutput, - !GeneralConfiguration.OpenDreamSuppressInstallOutput); + !generalConfig.OpenDreamSuppressInstallOutput, + !generalConfig.OpenDreamSuppressInstallOutput); - if (deploymentPipelineProcesses && SessionConfiguration.LowPriorityDeploymentProcesses) + if (deploymentPipelineProcesses && SessionConfigurationOptions.CurrentValue.LowPriorityDeploymentProcesses) buildProcess.AdjustPriority(false); using (cancellationToken.Register(() => buildProcess.Terminate())) buildExitCode = await buildProcess.Lifetime; string? output; - if (!GeneralConfiguration.OpenDreamSuppressInstallOutput) + if (!GeneralConfigurationOptions.CurrentValue.OpenDreamSuppressInstallOutput) { var buildOutputTask = buildProcess.GetCombinedOutput(cancellationToken); if (!buildOutputTask.IsCompleted) diff --git a/src/Tgstation.Server.Host/Components/Engine/WindowsByondInstaller.cs b/src/Tgstation.Server.Host/Components/Engine/WindowsByondInstaller.cs index 2206a12ca0..c7f1dfb155 100644 --- a/src/Tgstation.Server.Host/Components/Engine/WindowsByondInstaller.cs +++ b/src/Tgstation.Server.Host/Components/Engine/WindowsByondInstaller.cs @@ -79,7 +79,7 @@ namespace Tgstation.Server.Host.Components.Engine /// /// The for the . /// - readonly SessionConfiguration sessionConfiguration; + readonly IOptionsMonitor sessionConfigurationOptions; /// /// The for the . @@ -96,7 +96,7 @@ namespace Tgstation.Server.Host.Components.Engine /// /// The value of . /// The containing the . - /// The containing the value of . + /// The value of . /// The for the . /// The for the . /// The for the . @@ -105,12 +105,12 @@ namespace Tgstation.Server.Host.Components.Engine IIOManager ioManager, IFileDownloader fileDownloader, IOptionsMonitor generalConfigurationOptions, - IOptions sessionConfigurationOptions, + IOptionsMonitor sessionConfigurationOptions, ILogger logger) : base(ioManager, logger, fileDownloader, generalConfigurationOptions) { this.processExecutor = processExecutor ?? throw new ArgumentNullException(nameof(processExecutor)); - sessionConfiguration = sessionConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(sessionConfigurationOptions)); + this.sessionConfigurationOptions = sessionConfigurationOptions ?? throw new ArgumentNullException(nameof(sessionConfigurationOptions)); var useServiceSpecialTactics = Environment.Is64BitProcess && Environment.UserName == $"{Environment.MachineName}$"; @@ -215,7 +215,7 @@ namespace Tgstation.Server.Host.Components.Engine /// protected override string GetDreamDaemonName(Version byondVersion, out bool supportsCli) { - supportsCli = byondVersion >= DDExeVersion && !sessionConfiguration.ForceUseDreamDaemonExe; + supportsCli = byondVersion >= DDExeVersion && !sessionConfigurationOptions.CurrentValue.ForceUseDreamDaemonExe; return supportsCli ? "dd.exe" : "dreamdaemon.exe"; } @@ -327,7 +327,7 @@ namespace Tgstation.Server.Host.Components.Engine Logger, ruleName, dreamDaemonPath, - deploymentPipelineProcesses && sessionConfiguration.LowPriorityDeploymentProcesses, + deploymentPipelineProcesses && sessionConfigurationOptions.CurrentValue.LowPriorityDeploymentProcesses, cancellationToken); } catch (Exception ex) diff --git a/src/Tgstation.Server.Host/Components/Engine/WindowsOpenDreamInstaller.cs b/src/Tgstation.Server.Host/Components/Engine/WindowsOpenDreamInstaller.cs index adcf6ae443..9ee684d1cf 100644 --- a/src/Tgstation.Server.Host/Components/Engine/WindowsOpenDreamInstaller.cs +++ b/src/Tgstation.Server.Host/Components/Engine/WindowsOpenDreamInstaller.cs @@ -37,8 +37,8 @@ namespace Tgstation.Server.Host.Components.Engine /// The for the . /// The for the . /// The for the . - /// The of for the . - /// The of for the . + /// The of for the . + /// The of for the . /// The value of . public WindowsOpenDreamInstaller( IIOManager ioManager, @@ -48,8 +48,8 @@ namespace Tgstation.Server.Host.Components.Engine IRepositoryManager repositoryManager, IAsyncDelayer asyncDelayer, IHttpClientFactory httpClientFactory, - IOptions generalConfigurationOptions, - IOptions sessionConfigurationOptions, + IOptionsMonitor generalConfigurationOptions, + IOptionsMonitor sessionConfigurationOptions, IFilesystemLinkFactory linkFactory) : base( ioManager, @@ -108,7 +108,7 @@ namespace Tgstation.Server.Host.Components.Engine /// A representing the running operation. async ValueTask AddServerFirewallException(EngineVersion version, string path, bool deploymentPipelineProcesses, CancellationToken cancellationToken) { - if (GeneralConfiguration.SkipAddingByondFirewallException) + if (GeneralConfigurationOptions.CurrentValue.SkipAddingByondFirewallException) return; GetExecutablePaths(path, out var serverExePath, out _); @@ -126,7 +126,7 @@ namespace Tgstation.Server.Host.Components.Engine Logger, ruleName, serverExePath, - deploymentPipelineProcesses && SessionConfiguration.LowPriorityDeploymentProcesses, + deploymentPipelineProcesses && SessionConfigurationOptions.CurrentValue.LowPriorityDeploymentProcesses, cancellationToken); } catch (Exception ex) diff --git a/src/Tgstation.Server.Host/Components/Instance.cs b/src/Tgstation.Server.Host/Components/Instance.cs index 37454b7dbc..164d2c2e7d 100644 --- a/src/Tgstation.Server.Host/Components/Instance.cs +++ b/src/Tgstation.Server.Host/Components/Instance.cs @@ -389,7 +389,6 @@ namespace Tgstation.Server.Host.Components // assume 5 steps with synchronize var repositorySettingsTask = databaseContext .RepositorySettings - .AsQueryable() .Where(x => x.InstanceId == metadata.Id) .FirstAsync(cancellationToken); @@ -433,7 +432,6 @@ namespace Tgstation.Server.Host.Components logger.LogTrace("Loading revision info for commit {sha}...", startSha[..7]); currentRevInfo = await databaseContext .RevisionInformations - .AsQueryable() .Where(x => x.CommitSha == startSha && x.InstanceId == metadata.Id) .Include(x => x.ActiveTestMerges!) .ThenInclude(x => x.TestMerge) @@ -550,8 +548,8 @@ namespace Tgstation.Server.Host.Components var currentHead = repo.Head; - currentRevInfo = await databaseContext.RevisionInformations - .AsQueryable() + currentRevInfo = await databaseContext + .RevisionInformations .Where(x => x.CommitSha == currentHead && x.InstanceId == metadata.Id) .FirstOrDefaultAsync(cancellationToken); diff --git a/src/Tgstation.Server.Host/Components/InstanceFactory.cs b/src/Tgstation.Server.Host/Components/InstanceFactory.cs index 67e2b53a52..5118ab5f3e 100644 --- a/src/Tgstation.Server.Host/Components/InstanceFactory.cs +++ b/src/Tgstation.Server.Host/Components/InstanceFactory.cs @@ -150,14 +150,14 @@ namespace Tgstation.Server.Host.Components readonly IMetricFactory metricFactory; /// - /// The for the . + /// The of for the . /// - readonly GeneralConfiguration generalConfiguration; + readonly IOptionsMonitor generalConfigurationOptions; /// - /// The for the . + /// The of for the . /// - readonly SessionConfiguration sessionConfiguration; + readonly IOptionsMonitor sessionConfigurationOptions; /// /// Create the pointing to the "Game" directory of a given . @@ -193,8 +193,8 @@ namespace Tgstation.Server.Host.Components /// The value of . /// The value of . /// The value of . - /// The containing the value of . - /// The containing the value of . + /// The value of . + /// The value of . public InstanceFactory( IIOManager ioManager, IDatabaseContextFactory databaseContextFactory, @@ -219,8 +219,8 @@ namespace Tgstation.Server.Host.Components IAsyncDelayer asyncDelayer, IDotnetDumpService dotnetDumpService, IMetricFactory metricFactory, - IOptions generalConfigurationOptions, - IOptions sessionConfigurationOptions) + IOptionsMonitor generalConfigurationOptions, + IOptionsMonitor sessionConfigurationOptions) { this.ioManager = ioManager ?? throw new ArgumentNullException(nameof(ioManager)); this.databaseContextFactory = databaseContextFactory ?? throw new ArgumentNullException(nameof(databaseContextFactory)); @@ -245,8 +245,8 @@ namespace Tgstation.Server.Host.Components this.asyncDelayer = asyncDelayer ?? throw new ArgumentNullException(nameof(asyncDelayer)); this.dotnetDumpService = dotnetDumpService ?? throw new ArgumentNullException(nameof(dotnetDumpService)); this.metricFactory = metricFactory ?? throw new ArgumentNullException(nameof(metricFactory)); - generalConfiguration = generalConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(generalConfigurationOptions)); - sessionConfiguration = sessionConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(sessionConfigurationOptions)); + this.generalConfigurationOptions = generalConfigurationOptions ?? throw new ArgumentNullException(nameof(generalConfigurationOptions)); + this.sessionConfigurationOptions = sessionConfigurationOptions ?? throw new ArgumentNullException(nameof(sessionConfigurationOptions)); } #pragma warning restore CA1502 @@ -291,10 +291,10 @@ namespace Tgstation.Server.Host.Components postWriteHandler, platformIdentifier, fileTransferService, + generalConfigurationOptions, + sessionConfigurationOptions, loggerFactory.CreateLogger(), - metadata, - generalConfiguration, - sessionConfiguration); + metadata); var eventConsumer = new EventConsumer(configuration); var repoManager = repositoryManagerFactory.CreateRepositoryManager(repoIoManager, eventConsumer); try @@ -347,8 +347,8 @@ namespace Tgstation.Server.Host.Components dotnetDumpService, metricFactory, loggerFactory, + sessionConfigurationOptions, loggerFactory.CreateLogger(), - sessionConfiguration, metadata); var watchdog = watchdogFactory.CreateWatchdog( @@ -382,8 +382,8 @@ namespace Tgstation.Server.Host.Components remoteDeploymentManagerFactory, asyncDelayer, metricFactory, + sessionConfigurationOptions, loggerFactory.CreateLogger(), - sessionConfiguration, metadata); instance = new Instance( diff --git a/src/Tgstation.Server.Host/Components/InstanceManager.cs b/src/Tgstation.Server.Host/Components/InstanceManager.cs index 3344d61ad8..a361a7314a 100644 --- a/src/Tgstation.Server.Host/Components/InstanceManager.cs +++ b/src/Tgstation.Server.Host/Components/InstanceManager.cs @@ -102,6 +102,21 @@ namespace Tgstation.Server.Host.Components /// readonly IPlatformIdentifier platformIdentifier; + /// + /// The of for the . + /// + readonly IOptions generalConfigurationOptions; + + /// + /// The of for the . + /// + readonly IOptions swarmConfigurationOptions; + + /// + /// The of for the . + /// + readonly IOptions internalConfigurationOptions; + /// /// The for the . /// @@ -122,21 +137,6 @@ namespace Tgstation.Server.Host.Components /// readonly SemaphoreSlim instanceStateChangeSemaphore; - /// - /// The for the . - /// - readonly GeneralConfiguration generalConfiguration; - - /// - /// The for the . - /// - readonly SwarmConfiguration swarmConfiguration; - - /// - /// The for the . - /// - readonly InternalConfiguration internalConfiguration; - /// /// The for . /// @@ -189,9 +189,9 @@ namespace Tgstation.Server.Host.Components /// The value of . /// The used to create metrics. /// The to use. - /// The containing the value of . - /// The containing the value of . - /// The containing the value of . + /// The value of . + /// The value of . + /// The value of . /// The value of . public InstanceManager( IInstanceFactory instanceFactory, @@ -227,9 +227,9 @@ namespace Tgstation.Server.Host.Components this.platformIdentifier = platformIdentifier ?? throw new ArgumentNullException(nameof(platformIdentifier)); ArgumentNullException.ThrowIfNull(metricFactory); ArgumentNullException.ThrowIfNull(collectorRegistry); - generalConfiguration = generalConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(generalConfigurationOptions)); - swarmConfiguration = swarmConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(swarmConfigurationOptions)); - internalConfiguration = internalConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(internalConfigurationOptions)); + this.generalConfigurationOptions = generalConfigurationOptions ?? throw new ArgumentNullException(nameof(generalConfigurationOptions)); + this.swarmConfigurationOptions = swarmConfigurationOptions ?? throw new ArgumentNullException(nameof(swarmConfigurationOptions)); + this.internalConfigurationOptions = internalConfigurationOptions ?? throw new ArgumentNullException(nameof(internalConfigurationOptions)); this.logger = logger ?? throw new ArgumentNullException(nameof(logger)); originalConsoleTitle = console.Title; @@ -387,7 +387,6 @@ namespace Tgstation.Server.Host.Components { var jobs = await db .Jobs - .AsQueryable() .Where(x => x.Instance!.Id == metadata.Id && !x.StoppedAt.HasValue) .Select(x => new Job(x.Id!.Value)) .ToListAsync(cancellationToken); @@ -638,8 +637,7 @@ namespace Tgstation.Server.Host.Components async ValueTask EnumerateInstances(IDatabaseContext databaseContext) => dbInstances = await databaseContext .Instances - .AsQueryable() - .Where(x => x.Online!.Value && x.SwarmIdentifer == swarmConfiguration.Identifier) + .Where(x => x.Online!.Value && x.SwarmIdentifer == swarmConfigurationOptions.Value.Identifier) .Include(x => x.RepositorySettings) .Include(x => x.ChatSettings) .ThenInclude(x => x.Channels) @@ -700,14 +698,14 @@ namespace Tgstation.Server.Host.Components { logger.LogDebug("Running as user: {username}", Environment.UserName); - generalConfiguration.CheckCompatibility(logger, ioManager); + generalConfigurationOptions.Value.CheckCompatibility(logger, ioManager); using (var systemIdentity = systemIdentityFactory.GetCurrent()) { if (!systemIdentity.CanCreateSymlinks) throw new InvalidOperationException($"The user running {Constants.CanonicalPackageName} cannot create symlinks! Please try running as an administrative user!"); - if (!platformIdentifier.IsWindows && systemIdentity.IsSuperUser && !internalConfiguration.UsingDocker) + if (!platformIdentifier.IsWindows && systemIdentity.IsSuperUser && !internalConfigurationOptions.Value.UsingDocker) { logger.LogWarning("TGS is being run as the root account. This is not recommended."); } diff --git a/src/Tgstation.Server.Host/Components/Repository/Repository.cs b/src/Tgstation.Server.Host/Components/Repository/Repository.cs index 636321b5c7..3addf35ea9 100644 --- a/src/Tgstation.Server.Host/Components/Repository/Repository.cs +++ b/src/Tgstation.Server.Host/Components/Repository/Repository.cs @@ -9,6 +9,7 @@ using LibGit2Sharp; using LibGit2Sharp.Handlers; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; using Tgstation.Server.Api.Models; using Tgstation.Server.Host.Components.Events; @@ -115,16 +116,16 @@ namespace Tgstation.Server.Host.Components.Repository /// readonly ILibGit2RepositoryFactory submoduleFactory; + /// + /// The of for the . + /// + readonly IOptionsMonitor generalConfigurationOptions; + /// /// The for the . /// readonly ILogger logger; - /// - /// The for the . - /// - readonly GeneralConfiguration generalConfiguration; - /// /// Initializes a new instance of the class. /// @@ -136,8 +137,8 @@ namespace Tgstation.Server.Host.Components.Repository /// The value of . /// The to provide the value of . /// The value of . + /// The value of . /// The value of . - /// The value of . /// The action for the . public Repository( LibGit2Sharp.IRepository libGitRepo, @@ -148,8 +149,8 @@ namespace Tgstation.Server.Host.Components.Repository IPostWriteHandler postWriteHandler, IGitRemoteFeaturesFactory gitRemoteFeaturesFactory, ILibGit2RepositoryFactory submoduleFactory, + IOptionsMonitor generalConfigurationOptions, ILogger logger, - GeneralConfiguration generalConfiguration, Action disposeAction) : base(disposeAction) { @@ -161,9 +162,8 @@ namespace Tgstation.Server.Host.Components.Repository this.postWriteHandler = postWriteHandler ?? throw new ArgumentNullException(nameof(postWriteHandler)); ArgumentNullException.ThrowIfNull(gitRemoteFeaturesFactory); this.submoduleFactory = submoduleFactory ?? throw new ArgumentNullException(nameof(submoduleFactory)); - + this.generalConfigurationOptions = generalConfigurationOptions ?? throw new ArgumentNullException(nameof(generalConfigurationOptions)); this.logger = logger ?? throw new ArgumentNullException(nameof(logger)); - this.generalConfiguration = generalConfiguration ?? throw new ArgumentNullException(nameof(generalConfiguration)); gitRemoteFeatures = gitRemoteFeaturesFactory.CreateGitRemoteFeatures(this); } @@ -539,7 +539,7 @@ namespace Tgstation.Server.Host.Components.Repository }, ioManager.ResolvePath(), path, - generalConfiguration.GetCopyDirectoryTaskThrottle(), + generalConfigurationOptions.CurrentValue.GetCopyDirectoryTaskThrottle(), cancellationToken); } diff --git a/src/Tgstation.Server.Host/Components/Repository/RepositoryManager.cs b/src/Tgstation.Server.Host/Components/Repository/RepositoryManager.cs index 74a6bc6751..ddf05a7856 100644 --- a/src/Tgstation.Server.Host/Components/Repository/RepositoryManager.cs +++ b/src/Tgstation.Server.Host/Components/Repository/RepositoryManager.cs @@ -5,6 +5,7 @@ using System.Threading.Tasks; using LibGit2Sharp; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; using Tgstation.Server.Api.Models; using Tgstation.Server.Host.Components.Events; @@ -55,6 +56,11 @@ namespace Tgstation.Server.Host.Components.Repository /// readonly IGitRemoteFeaturesFactory gitRemoteFeaturesFactory; + /// + /// The of for the . + /// + readonly IOptionsMonitor generalConfigurationOptions; + /// /// The created s. /// @@ -65,11 +71,6 @@ namespace Tgstation.Server.Host.Components.Repository /// readonly ILogger logger; - /// - /// The for the . - /// - readonly GeneralConfiguration generalConfiguration; - /// /// Used for controlling single access to the . /// @@ -85,8 +86,8 @@ namespace Tgstation.Server.Host.Components.Repository /// The value of . /// The value of . /// The value of . + /// The value of . /// The value of . - /// The value of . public RepositoryManager( ILibGit2RepositoryFactory repositoryFactory, ILibGit2Commands commands, @@ -94,9 +95,9 @@ namespace Tgstation.Server.Host.Components.Repository IEventConsumer eventConsumer, IPostWriteHandler postWriteHandler, IGitRemoteFeaturesFactory gitRemoteFeaturesFactory, + IOptionsMonitor generalConfigurationOptions, ILogger repositoryLogger, - ILogger logger, - GeneralConfiguration generalConfiguration) + ILogger logger) { this.repositoryFactory = repositoryFactory ?? throw new ArgumentNullException(nameof(repositoryFactory)); this.commands = commands ?? throw new ArgumentNullException(nameof(commands)); @@ -105,8 +106,8 @@ namespace Tgstation.Server.Host.Components.Repository this.postWriteHandler = postWriteHandler ?? throw new ArgumentNullException(nameof(postWriteHandler)); this.gitRemoteFeaturesFactory = gitRemoteFeaturesFactory ?? throw new ArgumentNullException(nameof(gitRemoteFeaturesFactory)); this.repositoryLogger = repositoryLogger ?? throw new ArgumentNullException(nameof(repositoryLogger)); + this.generalConfigurationOptions = generalConfigurationOptions ?? throw new ArgumentNullException(nameof(generalConfigurationOptions)); this.logger = logger ?? throw new ArgumentNullException(nameof(logger)); - this.generalConfiguration = generalConfiguration ?? throw new ArgumentNullException(nameof(generalConfiguration)); semaphore = new SemaphoreSlim(1); } @@ -232,8 +233,8 @@ namespace Tgstation.Server.Host.Components.Repository postWriteHandler, gitRemoteFeaturesFactory, repositoryFactory, + generalConfigurationOptions, repositoryLogger, - generalConfiguration, () => { logger.LogTrace("Releasing semaphore due to Repository disposal..."); diff --git a/src/Tgstation.Server.Host/Components/Repository/RepositoryUpdateService.cs b/src/Tgstation.Server.Host/Components/Repository/RepositoryUpdateService.cs index cb15e878f1..de3feb5d08 100644 --- a/src/Tgstation.Server.Host/Components/Repository/RepositoryUpdateService.cs +++ b/src/Tgstation.Server.Host/Components/Repository/RepositoryUpdateService.cs @@ -90,7 +90,10 @@ namespace Tgstation.Server.Host.Components.Repository .ThenInclude(x => x.TestMerge) .ThenInclude(x => x.MergedBy); - var revisionInfo = await ApplyQuery(databaseContext.RevisionInformations).FirstOrDefaultAsync(cancellationToken); + var revisionInfo = await ApplyQuery( + databaseContext + .RevisionInformations) + .FirstOrDefaultAsync(cancellationToken); // If the DB doesn't have it, check the local set if (revisionInfo == default) @@ -400,8 +403,8 @@ namespace Tgstation.Server.Host.Components.Repository await databaseContextFactory.UseContext( async databaseContext => - dbPull = await databaseContext.RevisionInformations - .AsQueryable() + dbPull = await databaseContext + .RevisionInformations .Where(x => x.InstanceId == instanceId && x.OriginCommitSha == lastRevisionInfo.OriginCommitSha && x.ActiveTestMerges!.Count <= newTestMergeModels.Count diff --git a/src/Tgstation.Server.Host/Components/Repository/RepostoryManagerFactory.cs b/src/Tgstation.Server.Host/Components/Repository/RepostoryManagerFactory.cs index cba66ff69a..c48ba8702e 100644 --- a/src/Tgstation.Server.Host/Components/Repository/RepostoryManagerFactory.cs +++ b/src/Tgstation.Server.Host/Components/Repository/RepostoryManagerFactory.cs @@ -34,16 +34,16 @@ namespace Tgstation.Server.Host.Components.Repository /// readonly IGitRemoteFeaturesFactory gitRemoteFeaturesFactory; + /// + /// The of for the . + /// + readonly IOptionsMonitor generalConfigurationOptions; + /// /// The for the . /// readonly ILoggerFactory loggerFactory; - /// - /// The for the . - /// - readonly GeneralConfiguration generalConfiguration; - /// /// Initializes a new instance of the class. /// @@ -52,21 +52,21 @@ namespace Tgstation.Server.Host.Components.Repository /// The value of . /// The value of . /// The value of . - /// The containing the value of . + /// The value of . public RepostoryManagerFactory( ILibGit2RepositoryFactory repositoryFactory, ILibGit2Commands repositoryCommands, IPostWriteHandler postWriteHandler, IGitRemoteFeaturesFactory gitRemoteFeaturesFactory, ILoggerFactory loggerFactory, - IOptions generalConfigurationOptions) + IOptionsMonitor generalConfigurationOptions) { this.repositoryFactory = repositoryFactory ?? throw new ArgumentNullException(nameof(repositoryFactory)); this.repositoryCommands = repositoryCommands ?? throw new ArgumentNullException(nameof(repositoryCommands)); this.postWriteHandler = postWriteHandler ?? throw new ArgumentNullException(nameof(postWriteHandler)); this.gitRemoteFeaturesFactory = gitRemoteFeaturesFactory ?? throw new ArgumentNullException(nameof(gitRemoteFeaturesFactory)); this.loggerFactory = loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory)); - generalConfiguration = generalConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(generalConfigurationOptions)); + this.generalConfigurationOptions = generalConfigurationOptions ?? throw new ArgumentNullException(nameof(generalConfigurationOptions)); } /// @@ -78,9 +78,9 @@ namespace Tgstation.Server.Host.Components.Repository eventConsumer, postWriteHandler, gitRemoteFeaturesFactory, + generalConfigurationOptions, loggerFactory.CreateLogger(), - loggerFactory.CreateLogger(), - generalConfiguration); + loggerFactory.CreateLogger()); /// public Task StartAsync(CancellationToken cancellationToken) diff --git a/src/Tgstation.Server.Host/Components/Session/SessionControllerFactory.cs b/src/Tgstation.Server.Host/Components/Session/SessionControllerFactory.cs index 8f10370945..70b66b9798 100644 --- a/src/Tgstation.Server.Host/Components/Session/SessionControllerFactory.cs +++ b/src/Tgstation.Server.Host/Components/Session/SessionControllerFactory.cs @@ -8,6 +8,7 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; using Prometheus; @@ -119,16 +120,16 @@ namespace Tgstation.Server.Host.Components.Session /// readonly ILoggerFactory loggerFactory; + /// + /// The of for the . + /// + readonly IOptionsMonitor sessionConfigurationOptions; + /// /// The for the . /// readonly ILogger logger; - /// - /// The for the . - /// - readonly SessionConfiguration sessionConfiguration; - /// /// The number of sessions launched. /// @@ -198,9 +199,9 @@ namespace Tgstation.Server.Host.Components.Session /// The value of . /// The value of . /// The used to create metrics. + /// The value of . /// The value of . /// The value of . - /// The value of . public SessionControllerFactory( IProcessExecutor processExecutor, IEngineManager engineManager, @@ -219,8 +220,8 @@ namespace Tgstation.Server.Host.Components.Session IDotnetDumpService dotnetDumpService, IMetricFactory metricFactory, ILoggerFactory loggerFactory, + IOptionsMonitor sessionConfigurationOptions, ILogger logger, - SessionConfiguration sessionConfiguration, Api.Models.Instance instance) { this.processExecutor = processExecutor ?? throw new ArgumentNullException(nameof(processExecutor)); @@ -239,9 +240,9 @@ namespace Tgstation.Server.Host.Components.Session this.asyncDelayer = asyncDelayer ?? throw new ArgumentNullException(nameof(asyncDelayer)); this.dotnetDumpService = dotnetDumpService ?? throw new ArgumentNullException(nameof(dotnetDumpService)); ArgumentNullException.ThrowIfNull(metricFactory); + this.sessionConfigurationOptions = sessionConfigurationOptions ?? throw new ArgumentNullException(nameof(sessionConfigurationOptions)); this.loggerFactory = loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory)); this.logger = logger ?? throw new ArgumentNullException(nameof(logger)); - this.sessionConfiguration = sessionConfiguration ?? throw new ArgumentNullException(nameof(sessionConfiguration)); this.instance = instance ?? throw new ArgumentNullException(nameof(instance)); sessionsLaunched = metricFactory.CreateCounter("tgs_sessions_launched", "The number of game server processes created"); @@ -567,6 +568,7 @@ namespace Tgstation.Server.Host.Components.Session try { + var sessionConfiguration = sessionConfigurationOptions.CurrentValue; if (!apiValidate) { if (sessionConfiguration.HighPriorityLiveDreamDaemon) diff --git a/src/Tgstation.Server.Host/Components/Session/SessionPersistor.cs b/src/Tgstation.Server.Host/Components/Session/SessionPersistor.cs index edfc6a5145..d82d4937b1 100644 --- a/src/Tgstation.Server.Host/Components/Session/SessionPersistor.cs +++ b/src/Tgstation.Server.Host/Components/Session/SessionPersistor.cs @@ -158,7 +158,6 @@ namespace Tgstation.Server.Host.Components.Session { var dbReattachInfos = await db .ReattachInformations - .AsQueryable() .Where(x => x.CompileJob!.Job.Instance!.Id == metadata.Id) .Include(x => x.CompileJob) .Include(x => x.InitialCompileJob) @@ -169,7 +168,6 @@ namespace Tgstation.Server.Host.Components.Session var timeoutMilliseconds = await db .Instances - .AsQueryable() .Where(x => x.Id == metadata.Id) .Select(x => x.DreamDaemonSettings!.TopicRequestTimeout) .FirstOrDefaultAsync(cancellationToken); @@ -217,7 +215,6 @@ namespace Tgstation.Server.Host.Components.Session logger.LogTrace("Deleting ReattachInformation {id}...", result.Id); await db .ReattachInformations - .AsQueryable() .Where(x => x.Id == result.Id) .ExecuteDeleteAsync(cancellationToken); }); @@ -264,7 +261,6 @@ namespace Tgstation.Server.Host.Components.Session { var baseQuery = databaseContext .ReattachInformations - .AsQueryable() .Where(x => x.CompileJob!.Job.Instance!.Id == metadata.Id); if (instant) diff --git a/src/Tgstation.Server.Host/Components/StaticFiles/Configuration.cs b/src/Tgstation.Server.Host/Components/StaticFiles/Configuration.cs index 6dbfc3cc9c..46a1ca3d92 100644 --- a/src/Tgstation.Server.Host/Components/StaticFiles/Configuration.cs +++ b/src/Tgstation.Server.Host/Components/StaticFiles/Configuration.cs @@ -9,6 +9,7 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; using Tgstation.Server.Api.Models; using Tgstation.Server.Api.Models.Response; @@ -119,6 +120,16 @@ namespace Tgstation.Server.Host.Components.StaticFiles /// > readonly IFileTransferTicketProvider fileTransferService; + /// + /// The of for . + /// + readonly IOptionsMonitor generalConfigurationOptions; + + /// + /// The of for . + /// + readonly IOptionsMonitor sessionConfigurationOptions; + /// /// The for . /// @@ -129,16 +140,6 @@ namespace Tgstation.Server.Host.Components.StaticFiles /// readonly Models.Instance metadata; - /// - /// The for . - /// - readonly GeneralConfiguration generalConfiguration; - - /// - /// The for . - /// - readonly SessionConfiguration sessionConfiguration; - /// /// The for . Also used as a . /// @@ -166,8 +167,8 @@ namespace Tgstation.Server.Host.Components.StaticFiles /// The value of . /// The value of . /// The value of . - /// The value of . - /// The value of . + /// The value of . + /// The value of . public Configuration( IIOManager ioManager, ISynchronousIOManager synchronousIOManager, @@ -176,10 +177,10 @@ namespace Tgstation.Server.Host.Components.StaticFiles IPostWriteHandler postWriteHandler, IPlatformIdentifier platformIdentifier, IFileTransferTicketProvider fileTransferService, + IOptionsMonitor generalConfigurationOptions, + IOptionsMonitor sessionConfigurationOptions, ILogger logger, - Models.Instance metadata, - GeneralConfiguration generalConfiguration, - SessionConfiguration sessionConfiguration) + Models.Instance metadata) { this.ioManager = ioManager ?? throw new ArgumentNullException(nameof(ioManager)); this.synchronousIOManager = synchronousIOManager ?? throw new ArgumentNullException(nameof(synchronousIOManager)); @@ -188,10 +189,10 @@ namespace Tgstation.Server.Host.Components.StaticFiles this.postWriteHandler = postWriteHandler ?? throw new ArgumentNullException(nameof(postWriteHandler)); this.platformIdentifier = platformIdentifier ?? throw new ArgumentNullException(nameof(platformIdentifier)); this.fileTransferService = fileTransferService ?? throw new ArgumentNullException(nameof(fileTransferService)); + this.generalConfigurationOptions = generalConfigurationOptions ?? throw new ArgumentNullException(nameof(generalConfigurationOptions)); + this.sessionConfigurationOptions = sessionConfigurationOptions ?? throw new ArgumentNullException(nameof(sessionConfigurationOptions)); this.logger = logger ?? throw new ArgumentNullException(nameof(logger)); this.metadata = metadata ?? throw new ArgumentNullException(nameof(metadata)); - this.generalConfiguration = generalConfiguration ?? throw new ArgumentNullException(nameof(generalConfiguration)); - this.sessionConfiguration = sessionConfiguration ?? throw new ArgumentNullException(nameof(sessionConfiguration)); semaphore = new SemaphoreSlim(1, 1); stoppingCts = new CancellationTokenSource(); @@ -223,7 +224,7 @@ namespace Tgstation.Server.Host.Components.StaticFiles null, CodeModificationsSubdirectory, destination, - generalConfiguration.GetCopyDirectoryTaskThrottle(), + generalConfigurationOptions.CurrentValue.GetCopyDirectoryTaskThrottle(), cancellationToken); await Task.WhenAll(dmeExistsTask, headFileExistsTask, tailFileExistsTask, copyTask.AsTask()); @@ -795,7 +796,8 @@ namespace Tgstation.Server.Host.Components.StaticFiles // always execute in serial using (await SemaphoreSlimContext.Lock(semaphore, cancellationToken, logger)) { - var directories = generalConfiguration.AdditionalEventScriptsDirectories?.ToList() ?? new List(); + var sessionConfiguration = sessionConfigurationOptions.CurrentValue; + var directories = generalConfigurationOptions.CurrentValue.AdditionalEventScriptsDirectories?.ToList() ?? new List(); directories.Add(EventScriptsSubdirectory); var allScripts = new List(); diff --git a/src/Tgstation.Server.Host/Components/Watchdog/PosixWatchdog.cs b/src/Tgstation.Server.Host/Components/Watchdog/PosixWatchdog.cs index b97517d0f7..6b99878466 100644 --- a/src/Tgstation.Server.Host/Components/Watchdog/PosixWatchdog.cs +++ b/src/Tgstation.Server.Host/Components/Watchdog/PosixWatchdog.cs @@ -4,6 +4,7 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; using Prometheus; @@ -28,9 +29,9 @@ namespace Tgstation.Server.Host.Components.Watchdog sealed class PosixWatchdog : AdvancedWatchdog { /// - /// The for the . + /// The of for the . /// - readonly GeneralConfiguration generalConfiguration; + readonly IOptionsMonitor generalConfigurationOptions; /// /// Initializes a new instance of the class. @@ -48,10 +49,10 @@ namespace Tgstation.Server.Host.Components.Watchdog /// The for the . /// The pointing to the game directory for the .. /// The for the . + /// The value of . /// The for the . /// The for the . /// The for the . - /// The value of . /// The autostart value for the . public PosixWatchdog( IChatManager chat, @@ -67,10 +68,10 @@ namespace Tgstation.Server.Host.Components.Watchdog IMetricFactory metricFactory, IIOManager gameIOManager, IFilesystemLinkFactory linkFactory, + IOptionsMonitor generalConfigurationOptions, ILogger logger, DreamDaemonLaunchParameters initialLaunchParameters, Api.Models.Instance instance, - GeneralConfiguration generalConfiguration, bool autoStart) : base( chat, @@ -91,7 +92,7 @@ namespace Tgstation.Server.Host.Components.Watchdog instance, autoStart) { - this.generalConfiguration = generalConfiguration ?? throw new ArgumentNullException(nameof(generalConfiguration)); + this.generalConfigurationOptions = generalConfigurationOptions ?? throw new ArgumentNullException(nameof(generalConfigurationOptions)); } /// @@ -100,6 +101,12 @@ namespace Tgstation.Server.Host.Components.Watchdog /// protected override SwappableDmbProvider CreateSwappableDmbProvider(IDmbProvider dmbProvider) - => new HardLinkDmbProvider(dmbProvider, GameIOManager, LinkFactory, Logger, generalConfiguration, ActiveLaunchParameters.SecurityLevel!.Value); + => new HardLinkDmbProvider( + dmbProvider, + GameIOManager, + LinkFactory, + Logger, + generalConfigurationOptions.CurrentValue, + ActiveLaunchParameters.SecurityLevel!.Value); } } diff --git a/src/Tgstation.Server.Host/Components/Watchdog/PosixWatchdogFactory.cs b/src/Tgstation.Server.Host/Components/Watchdog/PosixWatchdogFactory.cs index 23539d34ac..19f7344089 100644 --- a/src/Tgstation.Server.Host/Components/Watchdog/PosixWatchdogFactory.cs +++ b/src/Tgstation.Server.Host/Components/Watchdog/PosixWatchdogFactory.cs @@ -34,14 +34,14 @@ namespace Tgstation.Server.Host.Components.Watchdog /// The for the . /// The for the . /// The for the . - /// The for for the . + /// The of for the . public PosixWatchdogFactory( IServerControl serverControl, ILoggerFactory loggerFactory, IJobManager jobManager, IAsyncDelayer asyncDelayer, IFilesystemLinkFactory linkFactory, - IOptions generalConfigurationOptions) + IOptionsMonitor generalConfigurationOptions) : base( serverControl, loggerFactory, @@ -79,10 +79,10 @@ namespace Tgstation.Server.Host.Components.Watchdog metricFactory, gameIOManager, LinkFactory, + GeneralConfigurationOptions, LoggerFactory.CreateLogger(), settings, instance, - GeneralConfiguration, settings.AutoStart ?? throw new ArgumentNullException(nameof(settings))); } } diff --git a/src/Tgstation.Server.Host/Components/Watchdog/WatchdogFactory.cs b/src/Tgstation.Server.Host/Components/Watchdog/WatchdogFactory.cs index d052001900..c2fd1c981e 100644 --- a/src/Tgstation.Server.Host/Components/Watchdog/WatchdogFactory.cs +++ b/src/Tgstation.Server.Host/Components/Watchdog/WatchdogFactory.cs @@ -43,9 +43,9 @@ namespace Tgstation.Server.Host.Components.Watchdog protected IAsyncDelayer AsyncDelayer { get; } /// - /// The for the . + /// The of for the . /// - protected GeneralConfiguration GeneralConfiguration { get; } + protected IOptionsMonitor GeneralConfigurationOptions { get; } /// /// Initializes a new instance of the class. @@ -54,19 +54,19 @@ namespace Tgstation.Server.Host.Components.Watchdog /// The value of . /// The value of . /// The value of . - /// The containing the value of . + /// The containing the value of . public WatchdogFactory( IServerControl serverControl, ILoggerFactory loggerFactory, IJobManager jobManager, IAsyncDelayer asyncDelayer, - IOptions generalConfigurationOptions) + IOptionsMonitor generalConfigurationOptions) { ServerControl = serverControl ?? throw new ArgumentNullException(nameof(serverControl)); LoggerFactory = loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory)); JobManager = jobManager ?? throw new ArgumentNullException(nameof(jobManager)); AsyncDelayer = asyncDelayer ?? throw new ArgumentNullException(nameof(asyncDelayer)); - GeneralConfiguration = generalConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(generalConfigurationOptions)); + GeneralConfigurationOptions = generalConfigurationOptions ?? throw new ArgumentNullException(nameof(generalConfigurationOptions)); } /// diff --git a/src/Tgstation.Server.Host/Components/Watchdog/WindowsWatchdogFactory.cs b/src/Tgstation.Server.Host/Components/Watchdog/WindowsWatchdogFactory.cs index 5639219021..7f41d39ef7 100644 --- a/src/Tgstation.Server.Host/Components/Watchdog/WindowsWatchdogFactory.cs +++ b/src/Tgstation.Server.Host/Components/Watchdog/WindowsWatchdogFactory.cs @@ -37,14 +37,14 @@ namespace Tgstation.Server.Host.Components.Watchdog /// The for the . /// The for the . /// The value of . - /// The for for the . + /// The for for the . public WindowsWatchdogFactory( IServerControl serverControl, ILoggerFactory loggerFactory, IJobManager jobManager, IAsyncDelayer asyncDelayer, IFilesystemLinkFactory symlinkFactory, - IOptions generalConfigurationOptions) + IOptionsMonitor generalConfigurationOptions) : base( serverControl, loggerFactory, diff --git a/src/Tgstation.Server.Host/Controllers/AdministrationController.cs b/src/Tgstation.Server.Host/Controllers/AdministrationController.cs index b886f40feb..1b9b20f198 100644 --- a/src/Tgstation.Server.Host/Controllers/AdministrationController.cs +++ b/src/Tgstation.Server.Host/Controllers/AdministrationController.cs @@ -21,7 +21,6 @@ using Tgstation.Server.Host.Database; using Tgstation.Server.Host.IO; using Tgstation.Server.Host.Security; using Tgstation.Server.Host.System; -using Tgstation.Server.Host.Transfer; using Tgstation.Server.Host.Utils; namespace Tgstation.Server.Host.Controllers @@ -54,14 +53,9 @@ namespace Tgstation.Server.Host.Controllers readonly IPlatformIdentifier platformIdentifier; /// - /// The for the . + /// The for the . /// - readonly IFileTransferTicketProvider fileTransferService; - - /// - /// The for the . - /// - readonly FileLoggingConfiguration fileLoggingConfiguration; + readonly IOptions fileLoggingConfigurationOptions; /// /// Initializes a new instance of the class. @@ -74,8 +68,7 @@ namespace Tgstation.Server.Host.Controllers /// The value of . /// The value of . /// The value of . - /// The value of . - /// The containing value of . + /// The containing value of . public AdministrationController( IDatabaseContext databaseContext, IAuthenticationContext authenticationContext, @@ -85,7 +78,6 @@ namespace Tgstation.Server.Host.Controllers IAssemblyInformationProvider assemblyInformationProvider, IIOManager ioManager, IPlatformIdentifier platformIdentifier, - IFileTransferTicketProvider fileTransferService, IOptions fileLoggingConfigurationOptions) : base( databaseContext, @@ -98,8 +90,7 @@ namespace Tgstation.Server.Host.Controllers this.assemblyInformationProvider = assemblyInformationProvider ?? throw new ArgumentNullException(nameof(assemblyInformationProvider)); this.ioManager = ioManager ?? throw new ArgumentNullException(nameof(ioManager)); this.platformIdentifier = platformIdentifier ?? throw new ArgumentNullException(nameof(platformIdentifier)); - this.fileTransferService = fileTransferService ?? throw new ArgumentNullException(nameof(fileTransferService)); - fileLoggingConfiguration = fileLoggingConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(fileLoggingConfigurationOptions)); + this.fileLoggingConfigurationOptions = fileLoggingConfigurationOptions ?? throw new ArgumentNullException(nameof(fileLoggingConfigurationOptions)); } /// @@ -185,7 +176,7 @@ namespace Tgstation.Server.Host.Controllers => Paginated( async () => { - var path = fileLoggingConfiguration.GetFullLogDirectory(ioManager, assemblyInformationProvider, platformIdentifier); + var path = fileLoggingConfigurationOptions.Value.GetFullLogDirectory(ioManager, assemblyInformationProvider, platformIdentifier); try { var files = await ioManager.GetFiles(path, cancellationToken); diff --git a/src/Tgstation.Server.Host/Controllers/ApiRootController.cs b/src/Tgstation.Server.Host/Controllers/ApiRootController.cs index d7dd5c092a..148f5bbc7b 100644 --- a/src/Tgstation.Server.Host/Controllers/ApiRootController.cs +++ b/src/Tgstation.Server.Host/Controllers/ApiRootController.cs @@ -65,14 +65,14 @@ namespace Tgstation.Server.Host.Controllers readonly IRestAuthorityInvoker loginAuthority; /// - /// The for the . + /// The of for the . /// - readonly GeneralConfiguration generalConfiguration; + readonly IOptionsSnapshot generalConfigurationOptions; /// - /// The for the . + /// The of for the . /// - readonly SecurityConfiguration securityConfiguration; + readonly IOptionsSnapshot securityConfigurationOptions; /// /// Initializes a new instance of the class. @@ -84,8 +84,8 @@ namespace Tgstation.Server.Host.Controllers /// The value of . /// The value of . /// The value of . - /// The containing the value of . - /// The containing the value of . + /// The value of . + /// The value of . /// The for the . /// The for the . /// The value of . @@ -97,7 +97,7 @@ namespace Tgstation.Server.Host.Controllers IPlatformIdentifier platformIdentifier, ISwarmService swarmService, IServerControl serverControl, - IOptions generalConfigurationOptions, + IOptionsSnapshot generalConfigurationOptions, IOptionsSnapshot securityConfigurationOptions, ILogger logger, IApiHeadersProvider apiHeadersProvider, @@ -114,8 +114,8 @@ namespace Tgstation.Server.Host.Controllers this.oAuthProviders = oAuthProviders ?? throw new ArgumentNullException(nameof(oAuthProviders)); this.swarmService = swarmService ?? throw new ArgumentNullException(nameof(swarmService)); this.serverControl = serverControl ?? throw new ArgumentNullException(nameof(serverControl)); - generalConfiguration = generalConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(generalConfigurationOptions)); - securityConfiguration = securityConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(securityConfigurationOptions)); + this.generalConfigurationOptions = generalConfigurationOptions ?? throw new ArgumentNullException(nameof(generalConfigurationOptions)); + this.securityConfigurationOptions = securityConfigurationOptions ?? throw new ArgumentNullException(nameof(securityConfigurationOptions)); this.loginAuthority = loginAuthority ?? throw new ArgumentNullException(nameof(loginAuthority)); } @@ -157,20 +157,20 @@ namespace Tgstation.Server.Host.Controllers Version = assemblyInformationProvider.Version, ApiVersion = ApiHeaders.Version, DMApiVersion = DMApiConstants.InteropVersion, - MinimumPasswordLength = generalConfiguration.MinimumPasswordLength, - InstanceLimit = generalConfiguration.InstanceLimit, - UserLimit = generalConfiguration.UserLimit, - UserGroupLimit = generalConfiguration.UserGroupLimit, - ValidInstancePaths = generalConfiguration.ValidInstancePaths, + MinimumPasswordLength = generalConfigurationOptions.Value.MinimumPasswordLength, + InstanceLimit = generalConfigurationOptions.Value.InstanceLimit, + UserLimit = generalConfigurationOptions.Value.UserLimit, + UserGroupLimit = generalConfigurationOptions.Value.UserGroupLimit, + ValidInstancePaths = generalConfigurationOptions.Value.ValidInstancePaths, WindowsHost = platformIdentifier.IsWindows, SwarmServers = swarmService .GetSwarmServers() ?.Select(swarmServerInfo => new SwarmServerResponse(swarmServerInfo)) .ToList(), OAuthProviderInfos = oAuthProviders.ProviderInfos(), - OidcProviderInfos = securityConfiguration.OidcProviderInfos().ToList(), + OidcProviderInfos = securityConfigurationOptions.Value.OidcProviderInfos().ToList(), UpdateInProgress = serverControl.UpdateInProgress, - OidcStrictMode = securityConfiguration.OidcStrictMode, + OidcStrictMode = securityConfigurationOptions.Value.OidcStrictMode, }); } diff --git a/src/Tgstation.Server.Host/Controllers/ChatController.cs b/src/Tgstation.Server.Host/Controllers/ChatController.cs index 1c52faf09f..def3c14f1e 100644 --- a/src/Tgstation.Server.Host/Controllers/ChatController.cs +++ b/src/Tgstation.Server.Host/Controllers/ChatController.cs @@ -160,7 +160,6 @@ namespace Tgstation.Server.Host.Controllers instance.Chat.DeleteConnection(id, cancellationToken), DatabaseContext .ChatBots - .AsQueryable() .Where(x => x.Id == id) .ExecuteDeleteAsync(cancellationToken)); return null; @@ -187,7 +186,6 @@ namespace Tgstation.Server.Host.Controllers new PaginatableResult( DatabaseContext .ChatBots - .AsQueryable() .Where(x => x.InstanceId == Instance.Id) .Include(x => x.Channels) .OrderBy(x => x.Id))), @@ -217,8 +215,8 @@ namespace Tgstation.Server.Host.Controllers [ProducesResponseType(typeof(ErrorMessageResponse), 410)] public async ValueTask GetId(long id, CancellationToken cancellationToken) { - var query = DatabaseContext.ChatBots - .AsQueryable() + var query = DatabaseContext + .ChatBots .Where(x => x.Id == id && x.InstanceId == Instance.Id) .Include(x => x.Channels); @@ -260,7 +258,6 @@ namespace Tgstation.Server.Host.Controllers var query = DatabaseContext .ChatBots - .AsQueryable() .Where(x => x.InstanceId == Instance.Id && x.Id == model.Id) .Include(x => x.Channels); diff --git a/src/Tgstation.Server.Host/Controllers/ControlPanelController.cs b/src/Tgstation.Server.Host/Controllers/ControlPanelController.cs index ec763dd955..2a89fcd33f 100644 --- a/src/Tgstation.Server.Host/Controllers/ControlPanelController.cs +++ b/src/Tgstation.Server.Host/Controllers/ControlPanelController.cs @@ -45,29 +45,29 @@ namespace Tgstation.Server.Host.Controllers /// readonly IWebHostEnvironment hostEnvironment; + /// + /// The for the . + /// + readonly IOptionsSnapshot controlPanelConfigurationOptions; + /// /// The for the . /// readonly ILogger logger; - /// - /// The for the . - /// - readonly ControlPanelConfiguration controlPanelConfiguration; - /// /// Initializes a new instance of the class. /// /// The value of . - /// The containing the value of . + /// The value of . /// The value of . public ControlPanelController( IWebHostEnvironment hostEnvironment, - IOptions controlPanelConfigurationOptions, + IOptionsSnapshot controlPanelConfigurationOptions, ILogger logger) { this.hostEnvironment = hostEnvironment ?? throw new ArgumentNullException(nameof(hostEnvironment)); - controlPanelConfiguration = controlPanelConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(controlPanelConfigurationOptions)); + this.controlPanelConfigurationOptions = controlPanelConfigurationOptions ?? throw new ArgumentNullException(nameof(controlPanelConfigurationOptions)); this.logger = logger ?? throw new ArgumentNullException(nameof(logger)); } @@ -79,13 +79,13 @@ namespace Tgstation.Server.Host.Controllers [HttpGet] public IActionResult GetChannelJson() { - if (!controlPanelConfiguration.Enable) + if (!controlPanelConfigurationOptions.Value.Enable) { logger.LogDebug("Not serving channel.json as control panel is disabled."); return NotFound(); } - var controlPanelChannel = controlPanelConfiguration.Channel; + var controlPanelChannel = controlPanelConfigurationOptions.Value.Channel; logger.LogTrace("Generating channel.json for channel \"{channel}\"...", controlPanelChannel); if (controlPanelChannel == "local") @@ -102,7 +102,7 @@ namespace Tgstation.Server.Host.Controllers { FormatVersion = 1, Channel = controlPanelChannel, - controlPanelConfiguration.PublicPath, + controlPanelConfigurationOptions.Value.PublicPath, }); } @@ -132,7 +132,7 @@ namespace Tgstation.Server.Host.Controllers [HttpGet] public IActionResult Get([FromRoute] string appRoute) { - if (!controlPanelConfiguration.Enable) + if (!controlPanelConfigurationOptions.Value.Enable) { logger.LogDebug("Not serving static files as control panel is disabled."); return NotFound(); diff --git a/src/Tgstation.Server.Host/Controllers/DreamDaemonController.cs b/src/Tgstation.Server.Host/Controllers/DreamDaemonController.cs index cf4811bc78..4bf09a03ff 100644 --- a/src/Tgstation.Server.Host/Controllers/DreamDaemonController.cs +++ b/src/Tgstation.Server.Host/Controllers/DreamDaemonController.cs @@ -165,7 +165,6 @@ namespace Tgstation.Server.Host.Controllers // alias for changing DD settings var current = await DatabaseContext .Instances - .AsQueryable() .Where(x => x.Id == Instance.Id) .Select(x => x.DreamDaemonSettings) .FirstOrDefaultAsync(cancellationToken); @@ -330,7 +329,6 @@ namespace Tgstation.Server.Host.Controllers { settings = await DatabaseContext .Instances - .AsQueryable() .Where(x => x.Id == Instance.Id) .Select(x => x.DreamDaemonSettings!) .FirstOrDefaultAsync(cancellationToken); diff --git a/src/Tgstation.Server.Host/Controllers/DreamMakerController.cs b/src/Tgstation.Server.Host/Controllers/DreamMakerController.cs index 59e44772f8..4ab9d54f9d 100644 --- a/src/Tgstation.Server.Host/Controllers/DreamMakerController.cs +++ b/src/Tgstation.Server.Host/Controllers/DreamMakerController.cs @@ -81,7 +81,6 @@ namespace Tgstation.Server.Host.Controllers { var dreamMakerSettings = await DatabaseContext .DreamMakerSettings - .AsQueryable() .Where(x => x.InstanceId == Instance.Id) .FirstOrDefaultAsync(cancellationToken); @@ -186,7 +185,6 @@ namespace Tgstation.Server.Host.Controllers var hostModel = await DatabaseContext .DreamMakerSettings - .AsQueryable() .Where(x => x.InstanceId == Instance.Id) .FirstOrDefaultAsync(cancellationToken); if (hostModel == null) @@ -295,7 +293,6 @@ namespace Tgstation.Server.Host.Controllers /// An of with all the inclusions. IQueryable BaseCompileJobsQuery() => DatabaseContext .CompileJobs - .AsQueryable() .Include(x => x.Job!) .ThenInclude(x => x.StartedBy) .Include(x => x.Job!) diff --git a/src/Tgstation.Server.Host/Controllers/InstanceController.cs b/src/Tgstation.Server.Host/Controllers/InstanceController.cs index 633b0d2ecb..3c880c02e0 100644 --- a/src/Tgstation.Server.Host/Controllers/InstanceController.cs +++ b/src/Tgstation.Server.Host/Controllers/InstanceController.cs @@ -67,21 +67,21 @@ namespace Tgstation.Server.Host.Controllers /// readonly IPortAllocator portAllocator; + /// + /// The of for the . + /// + readonly IOptions swarmConfigurationOptions; + + /// + /// The of for the . + /// + readonly IOptionsSnapshot generalConfigurationOptions; + /// /// The for the . /// readonly IPermissionsUpdateNotifyee permissionsUpdateNotifyee; - /// - /// The for the . - /// - readonly GeneralConfiguration generalConfiguration; - - /// - /// The for the . - /// - readonly SwarmConfiguration swarmConfiguration; - /// /// Initializes a new instance of the class. /// @@ -94,8 +94,8 @@ namespace Tgstation.Server.Host.Controllers /// The value of . /// The value of . /// The value of . - /// The containing the value of . - /// The containing the value of . + /// The value of . + /// The value of . /// The for the . public InstanceController( IDatabaseContext databaseContext, @@ -107,8 +107,8 @@ namespace Tgstation.Server.Host.Controllers IPlatformIdentifier platformIdentifier, IPortAllocator portAllocator, IPermissionsUpdateNotifyee permissionsUpdateNotifyee, - IOptions generalConfigurationOptions, IOptions swarmConfigurationOptions, + IOptionsSnapshot generalConfigurationOptions, IApiHeadersProvider apiHeaders) : base( databaseContext, @@ -124,8 +124,8 @@ namespace Tgstation.Server.Host.Controllers this.portAllocator = portAllocator ?? throw new ArgumentNullException(nameof(portAllocator)); this.permissionsUpdateNotifyee = permissionsUpdateNotifyee ?? throw new ArgumentNullException(nameof(permissionsUpdateNotifyee)); - generalConfiguration = generalConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(generalConfigurationOptions)); - swarmConfiguration = swarmConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(swarmConfigurationOptions)); + this.swarmConfigurationOptions = swarmConfigurationOptions ?? throw new ArgumentNullException(nameof(swarmConfigurationOptions)); + this.generalConfigurationOptions = generalConfigurationOptions ?? throw new ArgumentNullException(nameof(generalConfigurationOptions)); } /// @@ -161,14 +161,14 @@ namespace Tgstation.Server.Host.Controllers // Validate it's not a child of any other instance var instancePaths = await DatabaseContext .Instances - .AsQueryable() - .Where(x => x.SwarmIdentifer == swarmConfiguration.Identifier) + .Where(x => x.SwarmIdentifer == swarmConfigurationOptions.Value.Identifier) .Select(x => new Models.Instance { Path = x.Path, }) .ToListAsync(cancellationToken); + var generalConfiguration = generalConfigurationOptions.Value; if ((instancePaths.Count + 1) >= generalConfiguration.InstanceLimit) return Conflict(new ErrorMessageResponse(ErrorCode.InstanceLimitReached)); @@ -278,8 +278,7 @@ namespace Tgstation.Server.Host.Controllers { var originalModel = await DatabaseContext .Instances - .AsQueryable() - .Where(x => x.Id == id && x.SwarmIdentifer == swarmConfiguration.Identifier) + .Where(x => x.Id == id && x.SwarmIdentifer == swarmConfigurationOptions.Value.Identifier) .FirstOrDefaultAsync(cancellationToken); if (originalModel == default) return this.Gone(); @@ -306,17 +305,14 @@ namespace Tgstation.Server.Host.Controllers // there's a bug where removing the root instance doesn't work sometimes await DatabaseContext .CompileJobs - .AsQueryable() .Where(x => x.Job!.Instance!.Id == id) .ExecuteDeleteAsync(cancellationToken); await DatabaseContext .RevInfoTestMerges - .AsQueryable() .Where(x => x.RevisionInformation.InstanceId == id) .ExecuteDeleteAsync(cancellationToken); await DatabaseContext .RevisionInformations - .AsQueryable() .Where(x => x.InstanceId == id) .ExecuteDeleteAsync(cancellationToken); @@ -361,8 +357,7 @@ namespace Tgstation.Server.Host.Controllers IQueryable InstanceQuery() => DatabaseContext .Instances - .AsQueryable() - .Where(x => x.Id == model.Id && x.SwarmIdentifer == swarmConfiguration.Identifier); + .Where(x => x.Id == model.Id && x.SwarmIdentifer == swarmConfigurationOptions.Value.Identifier); var moveJob = await InstanceQuery() .SelectMany(x => x.Jobs) @@ -460,7 +455,6 @@ namespace Tgstation.Server.Host.Controllers { var countOfExistingChatBots = await DatabaseContext .ChatBots - .AsQueryable() .Where(x => x.InstanceId == originalModel.Id) .CountAsync(cancellationToken); @@ -585,8 +579,7 @@ namespace Tgstation.Server.Host.Controllers { var query = DatabaseContext .Instances - .AsQueryable() - .Where(x => x.SwarmIdentifer == swarmConfiguration.Identifier); + .Where(x => x.SwarmIdentifer == swarmConfigurationOptions.Value.Identifier); if (!AuthenticationContext.PermissionSet.InstanceManagerRights!.Value.HasFlag(InstanceManagerRights.List)) query = query .Where(x => x.InstancePermissionSets.Any(y => y.PermissionSetId == AuthenticationContext.PermissionSet.Id)) @@ -651,8 +644,7 @@ namespace Tgstation.Server.Host.Controllers { var query = DatabaseContext .Instances - .AsQueryable() - .Where(x => x.Id == id && x.SwarmIdentifer == swarmConfiguration.Identifier); + .Where(x => x.Id == id && x.SwarmIdentifer == swarmConfigurationOptions.Value.Identifier); if (cantList) query = query.Include(x => x.InstancePermissionSets); @@ -706,8 +698,7 @@ namespace Tgstation.Server.Host.Controllers { IQueryable BaseQuery() => DatabaseContext .Instances - .AsQueryable() - .Where(x => x.Id == id && x.SwarmIdentifer == swarmConfiguration.Identifier); + .Where(x => x.Id == id && x.SwarmIdentifer == swarmConfigurationOptions.Value.Identifier); // ensure the current user has write privilege on the instance var usersInstancePermissionSet = await BaseQuery() @@ -779,7 +770,7 @@ namespace Tgstation.Server.Host.Controllers StartupTimeout = 60, HealthCheckSeconds = 60, DumpOnHealthCheckRestart = false, - TopicRequestTimeout = generalConfiguration.ByondTopicTimeout, + TopicRequestTimeout = generalConfigurationOptions.Value.ByondTopicTimeout, AdditionalParameters = String.Empty, StartProfiler = false, LogOutput = false, @@ -818,7 +809,7 @@ namespace Tgstation.Server.Host.Controllers { InstanceAdminPermissionSet(null), }, - SwarmIdentifer = swarmConfiguration.Identifier, + SwarmIdentifer = swarmConfigurationOptions.Value.Identifier, }; } @@ -871,7 +862,6 @@ namespace Tgstation.Server.Host.Controllers { instanceResponse.Accessible = await DatabaseContext .InstancePermissionSets - .AsQueryable() .Where(x => x.InstanceId == instanceResponse.Id && x.PermissionSetId == AuthenticationContext.PermissionSet.Id) .AnyAsync(cancellationToken); } diff --git a/src/Tgstation.Server.Host/Controllers/InstancePermissionSetController.cs b/src/Tgstation.Server.Host/Controllers/InstancePermissionSetController.cs index 01f51bdc0c..6d6b99339c 100644 --- a/src/Tgstation.Server.Host/Controllers/InstancePermissionSetController.cs +++ b/src/Tgstation.Server.Host/Controllers/InstancePermissionSetController.cs @@ -78,7 +78,6 @@ namespace Tgstation.Server.Host.Controllers var existingPermissionSet = await DatabaseContext .PermissionSets - .AsQueryable() .Where(x => x.Id == model.PermissionSetId) .Select(x => new Models.PermissionSet { @@ -94,7 +93,6 @@ namespace Tgstation.Server.Host.Controllers { var userCanonicalName = await DatabaseContext .Users - .AsQueryable() .Where(x => x.Id == existingPermissionSet.UserId.Value) .Select(x => x.CanonicalName) .FirstAsync(cancellationToken); @@ -146,7 +144,6 @@ namespace Tgstation.Server.Host.Controllers var originalPermissionSet = await DatabaseContext .Instances - .AsQueryable() .Where(x => x.Id == Instance.Id) .SelectMany(x => x.InstancePermissionSets) .Where(x => x.PermissionSetId == model.PermissionSetId) @@ -201,7 +198,6 @@ namespace Tgstation.Server.Host.Controllers new PaginatableResult( DatabaseContext .Instances - .AsQueryable() .Where(x => x.Id == Instance.Id) .SelectMany(x => x.InstancePermissionSets) .OrderBy(x => x.PermissionSetId))), @@ -227,7 +223,6 @@ namespace Tgstation.Server.Host.Controllers // this functions as userId var permissionSet = await DatabaseContext .Instances - .AsQueryable() .Where(x => x.Id == Instance.Id) .SelectMany(x => x.InstancePermissionSets) .Where(x => x.PermissionSetId == id) @@ -253,7 +248,6 @@ namespace Tgstation.Server.Host.Controllers { var numDeleted = await DatabaseContext .Instances - .AsQueryable() .Where(x => x.Id == Instance.Id) .SelectMany(x => x.InstancePermissionSets) .Where(x => x.PermissionSetId == id) diff --git a/src/Tgstation.Server.Host/Controllers/JobController.cs b/src/Tgstation.Server.Host/Controllers/JobController.cs index 2cfb962891..5ba72b71c6 100644 --- a/src/Tgstation.Server.Host/Controllers/JobController.cs +++ b/src/Tgstation.Server.Host/Controllers/JobController.cs @@ -75,7 +75,6 @@ namespace Tgstation.Server.Host.Controllers new PaginatableResult( DatabaseContext .Jobs - .AsQueryable() .Include(x => x.StartedBy) .Include(x => x.CancelledBy) .Include(x => x.Instance) @@ -103,7 +102,6 @@ namespace Tgstation.Server.Host.Controllers new PaginatableResult( DatabaseContext .Jobs - .AsQueryable() .Include(x => x.StartedBy) .Include(x => x.CancelledBy) .Include(x => x.Instance) @@ -132,7 +130,6 @@ namespace Tgstation.Server.Host.Controllers // don't care if an instance post or not at this point var job = await DatabaseContext .Jobs - .AsQueryable() .Include(x => x.StartedBy) .Include(x => x.Instance) .Where(x => x.Id == id && x.Instance!.Id == Instance.Id) @@ -166,7 +163,6 @@ namespace Tgstation.Server.Host.Controllers { var job = await DatabaseContext .Jobs - .AsQueryable() .Where(x => x.Id == id && x.Instance!.Id == Instance.Id) .Include(x => x.StartedBy) .Include(x => x.CancelledBy) diff --git a/src/Tgstation.Server.Host/Controllers/RepositoryController.cs b/src/Tgstation.Server.Host/Controllers/RepositoryController.cs index e99a801607..f64440c919 100644 --- a/src/Tgstation.Server.Host/Controllers/RepositoryController.cs +++ b/src/Tgstation.Server.Host/Controllers/RepositoryController.cs @@ -122,7 +122,6 @@ namespace Tgstation.Server.Host.Controllers var currentModel = await DatabaseContext .RepositorySettings - .AsQueryable() .Where(x => x.InstanceId == Instance.Id) .FirstOrDefaultAsync(cancellationToken); @@ -225,7 +224,6 @@ namespace Tgstation.Server.Host.Controllers { var currentModel = await DatabaseContext .RepositorySettings - .AsQueryable() .Where(x => x.InstanceId == Instance.Id) .FirstOrDefaultAsync(cancellationToken); @@ -264,7 +262,6 @@ namespace Tgstation.Server.Host.Controllers { var currentModel = await DatabaseContext .RepositorySettings - .AsQueryable() .Where(x => x.InstanceId == Instance.Id) .FirstOrDefaultAsync(cancellationToken); @@ -302,7 +299,6 @@ namespace Tgstation.Server.Host.Controllers { var currentModel = await DatabaseContext .RepositorySettings - .AsQueryable() .Where(x => x.InstanceId == Instance.Id) .FirstOrDefaultAsync(cancellationToken); @@ -388,7 +384,6 @@ namespace Tgstation.Server.Host.Controllers var currentModel = await DatabaseContext .RepositorySettings - .AsQueryable() .Where(x => x.InstanceId == Instance.Id) .FirstOrDefaultAsync(cancellationToken); diff --git a/src/Tgstation.Server.Host/Controllers/RootController.cs b/src/Tgstation.Server.Host/Controllers/RootController.cs index fcf2bd239b..ccb9bc7ced 100644 --- a/src/Tgstation.Server.Host/Controllers/RootController.cs +++ b/src/Tgstation.Server.Host/Controllers/RootController.cs @@ -48,26 +48,26 @@ namespace Tgstation.Server.Host.Controllers /// readonly IWebHostEnvironment hostEnvironment; + /// + /// The of for the . + /// + readonly IOptions generalConfigurationOptions; + + /// + /// The of for the . + /// + readonly IOptions controlPanelConfigurationOptions; + + /// + /// The of for the . + /// + readonly IOptions internalConfigurationOptions; + /// /// The for the . /// readonly ILogger logger; - /// - /// The for the . - /// - readonly GeneralConfiguration generalConfiguration; - - /// - /// The for the . - /// - readonly ControlPanelConfiguration controlPanelConfiguration; - - /// - /// The for the . - /// - readonly InternalConfiguration internalConfiguration; - /// /// Gets a giving the and action names for a given . /// @@ -96,9 +96,9 @@ namespace Tgstation.Server.Host.Controllers /// The value of . /// The value of . /// The value of . - /// The containing the value of . - /// The containing the value of . - /// The containing the value of . + /// The containing the value of . + /// The containing the value of . + /// The containing the value of . public RootController( IAssemblyInformationProvider assemblyInformationProvider, IPlatformIdentifier platformIdentifier, @@ -106,15 +106,15 @@ namespace Tgstation.Server.Host.Controllers ILogger logger, IOptions generalConfigurationOptions, IOptions controlPanelConfigurationOptions, - IOptionsSnapshot internalConfigurationOptions) + IOptions internalConfigurationOptions) { this.assemblyInformationProvider = assemblyInformationProvider ?? throw new ArgumentNullException(nameof(assemblyInformationProvider)); this.platformIdentifier = platformIdentifier ?? throw new ArgumentNullException(nameof(platformIdentifier)); this.hostEnvironment = hostEnvironment ?? throw new ArgumentNullException(nameof(hostEnvironment)); this.logger = logger ?? throw new ArgumentNullException(nameof(logger)); - generalConfiguration = generalConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(generalConfigurationOptions)); - controlPanelConfiguration = controlPanelConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(controlPanelConfigurationOptions)); - internalConfiguration = internalConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(internalConfigurationOptions)); + this.generalConfigurationOptions = generalConfigurationOptions ?? throw new ArgumentNullException(nameof(generalConfigurationOptions)); + this.controlPanelConfigurationOptions = controlPanelConfigurationOptions ?? throw new ArgumentNullException(nameof(controlPanelConfigurationOptions)); + this.internalConfigurationOptions = internalConfigurationOptions ?? throw new ArgumentNullException(nameof(internalConfigurationOptions)); } /// @@ -125,8 +125,8 @@ namespace Tgstation.Server.Host.Controllers [AllowAnonymous] public IActionResult Index() { - var panelEnabled = controlPanelConfiguration.Enable; - var apiDocsEnabled = generalConfiguration.HostApiDocumentation; + var panelEnabled = controlPanelConfigurationOptions.Value.Enable; + var apiDocsEnabled = generalConfigurationOptions.Value.HostApiDocumentation; var controlPanelRoute = $"{ControlPanelController.ControlPanelRoute.TrimStart('/')}/"; if (panelEnabled && !apiDocsEnabled) @@ -143,7 +143,7 @@ namespace Tgstation.Server.Host.Controllers if (apiDocsEnabled) { - if (internalConfiguration.EnableGraphQL) + if (internalConfigurationOptions.Value.EnableGraphQL) links.Add("GraphQL API Documentation", Routes.GraphQL); links.Add("REST API Documentation", SwaggerConfiguration.DocumentationSiteRouteExtension); diff --git a/src/Tgstation.Server.Host/Controllers/SwarmController.cs b/src/Tgstation.Server.Host/Controllers/SwarmController.cs index dd57e45138..89e09c07de 100644 --- a/src/Tgstation.Server.Host/Controllers/SwarmController.cs +++ b/src/Tgstation.Server.Host/Controllers/SwarmController.cs @@ -44,22 +44,22 @@ namespace Tgstation.Server.Host.Controllers /// readonly IFileTransferStreamHandler transferService; + /// + /// The of for the . + /// + readonly IOptions swarmConfigurationOptions; + /// /// The for the . /// readonly ILogger logger; - /// - /// The for the . - /// - readonly SwarmConfiguration swarmConfiguration; - /// /// Initializes a new instance of the class. /// /// The value of . /// The value of . - /// The containing the value of . + /// The value of . /// The value of . public SwarmController( ISwarmOperations swarmOperations, @@ -69,7 +69,7 @@ namespace Tgstation.Server.Host.Controllers { this.swarmOperations = swarmOperations ?? throw new ArgumentNullException(nameof(swarmOperations)); this.transferService = transferService ?? throw new ArgumentNullException(nameof(transferService)); - swarmConfiguration = swarmConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(swarmConfigurationOptions)); + this.swarmConfigurationOptions = swarmConfigurationOptions ?? throw new ArgumentNullException(nameof(swarmConfigurationOptions)); this.logger = logger; } @@ -215,7 +215,7 @@ namespace Tgstation.Server.Host.Controllers using (LogContext.PushProperty(SerilogContextHelper.RequestPathContextProperty, $"{Request.Method} {Request.Path}")) { logger.LogTrace("Swarm request from {remoteIP}...", Request.HttpContext.Connection.RemoteIpAddress); - if (swarmConfiguration.PrivateKey == null) + if (swarmConfigurationOptions.Value.PrivateKey == null) { logger.LogDebug("Attempted swarm request without private key configured!"); return Forbid(); @@ -223,7 +223,7 @@ namespace Tgstation.Server.Host.Controllers if (!(Request.Headers.TryGetValue(SwarmConstants.ApiKeyHeader, out var apiKeyHeaderValues) && apiKeyHeaderValues.Count == 1 - && apiKeyHeaderValues.First() == swarmConfiguration.PrivateKey)) + && apiKeyHeaderValues.First() == swarmConfigurationOptions.Value.PrivateKey)) { logger.LogDebug("Unauthorized swarm request!"); return Unauthorized(); diff --git a/src/Tgstation.Server.Host/Core/Application.cs b/src/Tgstation.Server.Host/Core/Application.cs index 90dca6a151..8b73470640 100644 --- a/src/Tgstation.Server.Host/Core/Application.cs +++ b/src/Tgstation.Server.Host/Core/Application.cs @@ -378,7 +378,7 @@ namespace Tgstation.Server.Host.Core services.AddSingleton(); // configure other security services - services.AddSingleton(); + services.AddScoped(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); @@ -542,11 +542,11 @@ namespace Tgstation.Server.Host.Core ArgumentNullException.ThrowIfNull(serverPortProvider); ArgumentNullException.ThrowIfNull(assemblyInformationProvider); - var controlPanelConfiguration = controlPanelConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(controlPanelConfigurationOptions)); - var generalConfiguration = generalConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(generalConfigurationOptions)); - var databaseConfiguration = databaseConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(databaseConfigurationOptions)); - var swarmConfiguration = swarmConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(swarmConfigurationOptions)); - var internalConfiguration = internalConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(internalConfigurationOptions)); + var controlPanelConfiguration = (controlPanelConfigurationOptions ?? throw new ArgumentNullException(nameof(controlPanelConfigurationOptions))).Value; + var generalConfiguration = (generalConfigurationOptions ?? throw new ArgumentNullException(nameof(generalConfigurationOptions))).Value; + var databaseConfiguration = (databaseConfigurationOptions ?? throw new ArgumentNullException(nameof(databaseConfigurationOptions))).Value; + var swarmConfiguration = (swarmConfigurationOptions ?? throw new ArgumentNullException(nameof(swarmConfigurationOptions))).Value; + var internalConfiguration = (internalConfigurationOptions ?? throw new ArgumentNullException(nameof(internalConfigurationOptions))).Value; ArgumentNullException.ThrowIfNull(logger); diff --git a/src/Tgstation.Server.Host/Core/CommandPipeManager.cs b/src/Tgstation.Server.Host/Core/CommandPipeManager.cs index 6a5c6325c6..f3534c9bea 100644 --- a/src/Tgstation.Server.Host/Core/CommandPipeManager.cs +++ b/src/Tgstation.Server.Host/Core/CommandPipeManager.cs @@ -30,22 +30,22 @@ namespace Tgstation.Server.Host.Core /// readonly IInstanceManager instanceManager; + /// + /// The of for the . + /// + readonly IOptions internalConfigurationOptions; + /// /// The for the . /// readonly ILogger logger; - /// - /// The for the . - /// - readonly InternalConfiguration internalConfiguration; - /// /// Initializes a new instance of the class. /// /// The value of . /// The value of . - /// The containing the value of . + /// The containing the value of . /// The value of . public CommandPipeManager( IServerControl serverControl, @@ -55,7 +55,7 @@ namespace Tgstation.Server.Host.Core { this.serverControl = serverControl ?? throw new ArgumentNullException(nameof(serverControl)); this.instanceManager = instanceManager ?? throw new ArgumentNullException(nameof(instanceManager)); - internalConfiguration = internalConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(internalConfigurationOptions)); + this.internalConfigurationOptions = internalConfigurationOptions ?? throw new ArgumentNullException(nameof(internalConfigurationOptions)); this.logger = logger ?? throw new ArgumentNullException(nameof(logger)); } @@ -65,7 +65,7 @@ namespace Tgstation.Server.Host.Core logger.LogTrace("Starting..."); // grab both pipes asap so we can close them on error - var commandPipe = internalConfiguration.CommandPipe; + var commandPipe = internalConfigurationOptions.Value.CommandPipe; var supportsPipeCommands = !String.IsNullOrWhiteSpace(commandPipe); await using var commandPipeClient = supportsPipeCommands ? new AnonymousPipeClientStream( @@ -76,7 +76,7 @@ namespace Tgstation.Server.Host.Core if (!supportsPipeCommands) logger.LogDebug("No command pipe name specified in configuration"); - var readyPipe = internalConfiguration.ReadyPipe; + var readyPipe = internalConfigurationOptions.Value.ReadyPipe; var supportsReadyNotification = !String.IsNullOrWhiteSpace(readyPipe); if (supportsReadyNotification) { diff --git a/src/Tgstation.Server.Host/Core/ServerPortProivder.cs b/src/Tgstation.Server.Host/Core/ServerPortProivder.cs index a3f39a4ab8..67f137ac51 100644 --- a/src/Tgstation.Server.Host/Core/ServerPortProivder.cs +++ b/src/Tgstation.Server.Host/Core/ServerPortProivder.cs @@ -13,28 +13,28 @@ namespace Tgstation.Server.Host.Core sealed class ServerPortProivder : IServerPortProvider { /// - public ushort HttpApiPort => generalConfiguration.ApiPort; + public ushort HttpApiPort => generalConfigurationOptions.Value.ApiPort; /// - /// The for the . + /// The of for the . /// - readonly GeneralConfiguration generalConfiguration; + readonly IOptions generalConfigurationOptions; /// /// Initializes a new instance of the class. /// - /// The containing the value of . /// The to use. + /// The containing the value of . /// The to use. public ServerPortProivder( - IOptions generalConfigurationOptions, IConfiguration configuration, + IOptions generalConfigurationOptions, ILogger logger) { - generalConfiguration = generalConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(generalConfigurationOptions)); ArgumentNullException.ThrowIfNull(configuration); + this.generalConfigurationOptions = generalConfigurationOptions ?? throw new ArgumentNullException(nameof(generalConfigurationOptions)); - var usingDefaultPort = generalConfiguration.ApiPort == default; + var usingDefaultPort = generalConfigurationOptions.Value.ApiPort == default; if (!usingDefaultPort) return; @@ -55,7 +55,7 @@ namespace Tgstation.Server.Host.Core if (!UInt16.TryParse(portString, out var result)) throw new InvalidOperationException($"Failed to parse HTTP EndPoint port: {httpEndpoint}"); - generalConfiguration.ApiPort = result; + this.generalConfigurationOptions.Value.ApiPort = result; } } } diff --git a/src/Tgstation.Server.Host/Core/ServerUpdater.cs b/src/Tgstation.Server.Host/Core/ServerUpdater.cs index 1170537a12..2caee4d944 100644 --- a/src/Tgstation.Server.Host/Core/ServerUpdater.cs +++ b/src/Tgstation.Server.Host/Core/ServerUpdater.cs @@ -36,21 +36,21 @@ namespace Tgstation.Server.Host.Core /// readonly IServerControl serverControl; + /// + /// The of for the . + /// + readonly IOptionsMonitor generalConfigurationOptions; + + /// + /// The of for the . + /// + readonly IOptionsMonitor updatesConfigurationOptions; + /// /// The for the . /// readonly ILogger logger; - /// - /// The for the . - /// - readonly GeneralConfiguration generalConfiguration; - - /// - /// The for the . - /// - readonly UpdatesConfiguration updatesConfiguration; - /// /// Lock used when initiating an update. /// @@ -69,24 +69,24 @@ namespace Tgstation.Server.Host.Core /// The value of . /// The value of . /// The value of . - /// The containing the value of . - /// The containing the value of . + /// The value of . + /// The value of . public ServerUpdater( IGitHubServiceFactory gitHubServiceFactory, IIOManager ioManager, IFileDownloader fileDownloader, IServerControl serverControl, ILogger logger, - IOptions generalConfigurationOptions, - IOptions updatesConfigurationOptions) + IOptionsMonitor generalConfigurationOptions, + IOptionsMonitor updatesConfigurationOptions) { this.gitHubServiceFactory = gitHubServiceFactory ?? throw new ArgumentNullException(nameof(gitHubServiceFactory)); this.ioManager = ioManager ?? throw new ArgumentNullException(nameof(ioManager)); this.fileDownloader = fileDownloader ?? throw new ArgumentNullException(nameof(fileDownloader)); this.serverControl = serverControl ?? throw new ArgumentNullException(nameof(serverControl)); + this.generalConfigurationOptions = generalConfigurationOptions ?? throw new ArgumentNullException(nameof(generalConfigurationOptions)); + this.updatesConfigurationOptions = updatesConfigurationOptions ?? throw new ArgumentNullException(nameof(updatesConfigurationOptions)); this.logger = logger ?? throw new ArgumentNullException(nameof(logger)); - generalConfiguration = generalConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(generalConfigurationOptions)); - updatesConfiguration = updatesConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(updatesConfigurationOptions)); updateInitiationLock = new object(); } @@ -290,6 +290,9 @@ namespace Tgstation.Server.Host.Core var gitHubService = await gitHubServiceFactory.CreateService(cancellationToken); var releases = await gitHubService.GetTgsReleases(cancellationToken); + + var updatesConfiguration = updatesConfigurationOptions.CurrentValue; + var generalConfiguration = generalConfigurationOptions.CurrentValue; foreach (var kvp in releases) { var version = kvp.Key; diff --git a/src/Tgstation.Server.Host/Database/DatabaseCollection.cs b/src/Tgstation.Server.Host/Database/DatabaseCollection.cs index b2dafa719d..94d5ef90e8 100644 --- a/src/Tgstation.Server.Host/Database/DatabaseCollection.cs +++ b/src/Tgstation.Server.Host/Database/DatabaseCollection.cs @@ -3,7 +3,6 @@ using System.Collections; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; -using System.Threading; using Microsoft.EntityFrameworkCore; @@ -48,9 +47,6 @@ namespace Tgstation.Server.Host.Database /// public void Attach(TModel model) => dbSet.Attach(model); - /// - public IAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) => dbSet.AsAsyncEnumerable().GetAsyncEnumerator(cancellationToken); - /// public IEnumerator GetEnumerator() => dbSet.AsQueryable().GetEnumerator(); diff --git a/src/Tgstation.Server.Host/Database/DatabaseSeeder.cs b/src/Tgstation.Server.Host/Database/DatabaseSeeder.cs index 4eaf4e21b9..03d89a64eb 100644 --- a/src/Tgstation.Server.Host/Database/DatabaseSeeder.cs +++ b/src/Tgstation.Server.Host/Database/DatabaseSeeder.cs @@ -216,7 +216,6 @@ namespace Tgstation.Server.Host.Database { var tgsUser = await databaseContext .Users - .AsQueryable() .Where(x => x.CanonicalName == User.CanonicalizeName(User.TgsSystemUserName)) .FirstOrDefaultAsync(cancellationToken); @@ -232,7 +231,6 @@ namespace Tgstation.Server.Host.Database // normalize backslashes to forward slashes var allInstances = await databaseContext .Instances - .AsQueryable() .Where(instance => instance.SwarmIdentifer == swarmConfiguration.Identifier) .ToListAsync(cancellationToken); foreach (var instance in allInstances) @@ -242,7 +240,6 @@ namespace Tgstation.Server.Host.Database { var ids = await databaseContext .DreamDaemonSettings - .AsQueryable() .Where(x => x.TopicRequestTimeout == 0) .Select(x => x.Id) .ToListAsync(cancellationToken); @@ -311,7 +308,6 @@ namespace Tgstation.Server.Host.Database { var admin = await databaseContext .Users - .AsQueryable() .Where(x => x.CanonicalName == User.CanonicalizeName(DefaultCredentials.AdminUserName)) .Include(x => x.CreatedBy) .Include(x => x.PermissionSet) diff --git a/src/Tgstation.Server.Host/Database/IDatabaseCollection.cs b/src/Tgstation.Server.Host/Database/IDatabaseCollection.cs index a9e1fe0e03..52ca1796af 100644 --- a/src/Tgstation.Server.Host/Database/IDatabaseCollection.cs +++ b/src/Tgstation.Server.Host/Database/IDatabaseCollection.cs @@ -7,7 +7,7 @@ namespace Tgstation.Server.Host.Database /// Represents a database table. /// /// The type of model. - public interface IDatabaseCollection : IQueryable, IAsyncEnumerable + public interface IDatabaseCollection : IQueryable { /// /// An of s prioritizing in the working set. diff --git a/src/Tgstation.Server.Host/Extensions/DatabaseCollectionExtensions.cs b/src/Tgstation.Server.Host/Extensions/DatabaseCollectionExtensions.cs index ea50a7af17..856b74a9f0 100644 --- a/src/Tgstation.Server.Host/Extensions/DatabaseCollectionExtensions.cs +++ b/src/Tgstation.Server.Host/Extensions/DatabaseCollectionExtensions.cs @@ -33,7 +33,6 @@ namespace Tgstation.Server.Host.Extensions ArgumentNullException.ThrowIfNull(selector); return databaseCollection - .AsQueryable() .Where(x => x.CanonicalName == User.CanonicalizeName(User.TgsSystemUserName)) .Select(selector) .FirstAsync(cancellationToken); diff --git a/src/Tgstation.Server.Host/GraphQL/Types/UsersRepository.cs b/src/Tgstation.Server.Host/GraphQL/Types/UsersRepository.cs index 1cf53baabc..d735684565 100644 --- a/src/Tgstation.Server.Host/GraphQL/Types/UsersRepository.cs +++ b/src/Tgstation.Server.Host/GraphQL/Types/UsersRepository.cs @@ -26,10 +26,10 @@ namespace Tgstation.Server.Host.GraphQL.Types /// /// If only OIDC logins and registration is allowed. /// - /// The containing the . + /// The containing the . /// if OIDC strict mode is enabled, otherwise. public bool OidcStrictMode( - [Service] IOptions securityConfigurationOptions) + [Service] IOptionsSnapshot securityConfigurationOptions) { ArgumentNullException.ThrowIfNull(securityConfigurationOptions); return securityConfigurationOptions.Value.OidcStrictMode; diff --git a/src/Tgstation.Server.Host/Jobs/JobService.cs b/src/Tgstation.Server.Host/Jobs/JobService.cs index c36b5ca825..4c1f5e2c90 100644 --- a/src/Tgstation.Server.Host/Jobs/JobService.cs +++ b/src/Tgstation.Server.Host/Jobs/JobService.cs @@ -213,7 +213,6 @@ namespace Tgstation.Server.Host.Jobs // mark all jobs as cancelled var badJobIds = await databaseContext .Jobs - .AsQueryable() .Where(y => !y.StoppedAt.HasValue) .Select(y => y.Id!.Value) .ToListAsync(cancellationToken); @@ -535,7 +534,6 @@ namespace Tgstation.Server.Host.Jobs // DCT: Cancellation token is for job, operation should always run var finalJob = await databaseContext .Jobs - .AsQueryable() .Include(x => x.Instance) .Include(x => x.StartedBy) .Include(x => x.CancelledBy) diff --git a/src/Tgstation.Server.Host/Jobs/JobsHubGroupMapper.cs b/src/Tgstation.Server.Host/Jobs/JobsHubGroupMapper.cs index a961fbaef9..02fb87e77d 100644 --- a/src/Tgstation.Server.Host/Jobs/JobsHubGroupMapper.cs +++ b/src/Tgstation.Server.Host/Jobs/JobsHubGroupMapper.cs @@ -128,7 +128,6 @@ namespace Tgstation.Server.Host.Jobs async databaseContext => permedInstanceIds = await databaseContext .InstancePermissionSets - .AsQueryable() .Where(ips => ips.PermissionSetId == pid) .Select(ips => ips.InstanceId) .ToListAsync(cancellationToken)); @@ -162,7 +161,6 @@ namespace Tgstation.Server.Host.Jobs .ToListAsync(cancellationToken); var permissionSetAccessibleInstanceIds = await databaseContext .InstancePermissionSets - .AsQueryable() .Where(ips => ips.PermissionSetId == permissionSetId) .Select(ips => ips.InstanceId) .ToListAsync(cancellationToken); diff --git a/src/Tgstation.Server.Host/Security/AuthenticationContextFactory.cs b/src/Tgstation.Server.Host/Security/AuthenticationContextFactory.cs index ed9651f2a7..947baa3120 100644 --- a/src/Tgstation.Server.Host/Security/AuthenticationContextFactory.cs +++ b/src/Tgstation.Server.Host/Security/AuthenticationContextFactory.cs @@ -45,21 +45,21 @@ namespace Tgstation.Server.Host.Security /// readonly IIdentityCache identityCache; + /// + /// The of for the . + /// + readonly IOptions swarmConfigurationOptions; + + /// + /// The of for the . + /// + readonly IOptionsSnapshot securityConfigurationOptions; + /// /// The for the . /// readonly ILogger logger; - /// - /// The for the . - /// - readonly SwarmConfiguration swarmConfiguration; - - /// - /// The for the . - /// - readonly SecurityConfiguration securityConfiguration; - /// /// Backing field for . /// @@ -81,15 +81,15 @@ namespace Tgstation.Server.Host.Security /// The value of . /// The value of . /// The containing the value of . - /// The containing the value of . - /// The containing the value of . + /// The value of . + /// The value of . /// The value of . public AuthenticationContextFactory( IDatabaseContext databaseContext, IIdentityCache identityCache, IApiHeadersProvider apiHeadersProvider, IOptions swarmConfigurationOptions, - IOptions securityConfigurationOptions, + IOptionsSnapshot securityConfigurationOptions, ILogger logger) { this.databaseContext = databaseContext ?? throw new ArgumentNullException(nameof(databaseContext)); @@ -97,8 +97,8 @@ namespace Tgstation.Server.Host.Security ArgumentNullException.ThrowIfNull(apiHeadersProvider); apiHeaders = apiHeadersProvider.ApiHeaders; - swarmConfiguration = swarmConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(swarmConfigurationOptions)); - securityConfiguration = securityConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(securityConfigurationOptions)); + this.swarmConfigurationOptions = swarmConfigurationOptions ?? throw new ArgumentNullException(nameof(swarmConfigurationOptions)); + this.securityConfigurationOptions = securityConfigurationOptions ?? throw new ArgumentNullException(nameof(securityConfigurationOptions)); this.logger = logger ?? throw new ArgumentNullException(nameof(logger)); @@ -129,7 +129,6 @@ namespace Tgstation.Server.Host.Security var user = await databaseContext .Users - .AsQueryable() .Where(x => x.Id == userId) .Include(x => x.CreatedBy) .Include(x => x.PermissionSet) @@ -164,9 +163,9 @@ namespace Tgstation.Server.Host.Security var instanceId = apiHeaders?.InstanceId; if (instanceId.HasValue) { - instancePermissionSet = await databaseContext.InstancePermissionSets - .AsQueryable() - .Where(x => x.PermissionSetId == userPermissionSet!.Id && x.InstanceId == instanceId && x.Instance!.SwarmIdentifer == swarmConfiguration.Identifier) + instancePermissionSet = await databaseContext + .InstancePermissionSets + .Where(x => x.PermissionSetId == userPermissionSet!.Id && x.InstanceId == instanceId && x.Instance!.SwarmIdentifer == swarmConfigurationOptions.Value.Identifier) .Include(x => x.Instance) .FirstOrDefaultAsync(cancellationToken); @@ -208,7 +207,6 @@ namespace Tgstation.Server.Host.Security var deprefixedScheme = scheme.Substring(OpenIDConnectAuthenticationSchemePrefix.Length); var connection = await databaseContext .OidcConnections - .AsQueryable() .Where(oidcConnection => oidcConnection.ExternalUserId == userId && oidcConnection.SchemeKey == deprefixedScheme) .Include(oidcConnection => oidcConnection.User) .ThenInclude(user => user!.Group) @@ -216,7 +214,7 @@ namespace Tgstation.Server.Host.Security .FirstOrDefaultAsync(cancellationToken); User user; - if (!securityConfiguration.OidcStrictMode) + if (!securityConfigurationOptions.Value.OidcStrictMode) { if (connection == default) { @@ -243,7 +241,6 @@ namespace Tgstation.Server.Host.Security UserGroup? group = groupId.HasValue ? await databaseContext .Groups - .AsQueryable() .Where(group => group.Id == groupId.Value) .Include(group => group.PermissionSet) .FirstOrDefaultAsync(cancellationToken) diff --git a/src/Tgstation.Server.Host/Security/AuthorizationHandler.cs b/src/Tgstation.Server.Host/Security/AuthorizationHandler.cs index ed76938c29..95774ee803 100644 --- a/src/Tgstation.Server.Host/Security/AuthorizationHandler.cs +++ b/src/Tgstation.Server.Host/Security/AuthorizationHandler.cs @@ -106,7 +106,6 @@ namespace Tgstation.Server.Host.Security { var sessionData = await databaseContext .Users - .AsQueryable() .Where(user => user.Id == userId) .Select(user => new { @@ -151,8 +150,7 @@ namespace Tgstation.Server.Host.Security return databaseContextFactory.UseContext(async databaseContext => { var queryableUsers = databaseContext - .Users - .AsQueryable(); + .Users; var matchingUniquePermissionSetIds = queryableUsers .Where(user => user.Id == userId && user.PermissionSet != null) @@ -170,7 +168,6 @@ namespace Tgstation.Server.Host.Security permissionSet = await databaseContext .InstancePermissionSets - .AsQueryable() .Where(ips => ips.InstanceId == instanceId && (matchingUniquePermissionSetIds.Contains(ips.PermissionSetId) || matchingGroupPermissionSetIds.Contains(ips.PermissionSetId))) .TagWith("rights_authorization_handler_instance_permission_set") @@ -179,7 +176,6 @@ namespace Tgstation.Server.Host.Security else permissionSet = await databaseContext .PermissionSets - .AsQueryable() .Where(permissionSet => matchingUniquePermissionSetIds.Contains(permissionSet.Id) || matchingGroupPermissionSetIds.Contains(permissionSet.Id)) .TagWith("rights_authorization_handler_permission_set") .FirstOrDefaultAsync(cancellationToken); diff --git a/src/Tgstation.Server.Host/Security/OAuth/OAuthProviders.cs b/src/Tgstation.Server.Host/Security/OAuth/OAuthProviders.cs index f514094e01..6233b79157 100644 --- a/src/Tgstation.Server.Host/Security/OAuth/OAuthProviders.cs +++ b/src/Tgstation.Server.Host/Security/OAuth/OAuthProviders.cs @@ -31,11 +31,12 @@ namespace Tgstation.Server.Host.Security.OAuth IGitHubServiceFactory gitHubServiceFactory, IHttpClientFactory httpClientFactory, ILoggerFactory loggerFactory, - IOptions securityConfigurationOptions) + IOptionsSnapshot securityConfigurationOptions) { ArgumentNullException.ThrowIfNull(loggerFactory); + ArgumentNullException.ThrowIfNull(securityConfigurationOptions); - var securityConfiguration = securityConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(securityConfigurationOptions)); + var securityConfiguration = securityConfigurationOptions.Value; var validatorsBuilder = new List(); validators = validatorsBuilder; @@ -66,9 +67,7 @@ namespace Tgstation.Server.Host.Security.OAuth loggerFactory.CreateLogger(), keyCloakConfig)); -#pragma warning disable CS0618 // Type or member is obsolete if (securityConfiguration.OAuth.TryGetValue(OAuthProvider.InvisionCommunity, out var invisionConfig)) -#pragma warning restore CS0618 // Type or member is obsolete validatorsBuilder.Add( new InvisionCommunityOAuthValidator( httpClientFactory, diff --git a/src/Tgstation.Server.Host/Security/TokenFactory.cs b/src/Tgstation.Server.Host/Security/TokenFactory.cs index 6081aeb42f..9e2b18e668 100644 --- a/src/Tgstation.Server.Host/Security/TokenFactory.cs +++ b/src/Tgstation.Server.Host/Security/TokenFactory.cs @@ -39,9 +39,9 @@ namespace Tgstation.Server.Host.Security } /// - /// The for the . + /// The of for the . /// - readonly SecurityConfiguration securityConfiguration; + readonly IOptions securityConfigurationOptions; /// /// The used to generate s. @@ -63,7 +63,7 @@ namespace Tgstation.Server.Host.Security /// /// The used for generating the . /// The used to generate the issuer name. - /// The containing the value of . + /// The value of . public TokenFactory( ICryptographySuite cryptographySuite, IAssemblyInformationProvider assemblyInformationProvider, @@ -72,11 +72,11 @@ namespace Tgstation.Server.Host.Security ArgumentNullException.ThrowIfNull(cryptographySuite); ArgumentNullException.ThrowIfNull(assemblyInformationProvider); - securityConfiguration = securityConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(securityConfigurationOptions)); + this.securityConfigurationOptions = securityConfigurationOptions ?? throw new ArgumentNullException(nameof(securityConfigurationOptions)); - SigningKeyBytes = String.IsNullOrWhiteSpace(securityConfiguration.CustomTokenSigningKeyBase64) - ? cryptographySuite.GetSecureBytes(securityConfiguration.TokenSigningKeyByteCount) - : Convert.FromBase64String(securityConfiguration.CustomTokenSigningKeyBase64); + SigningKeyBytes = string.IsNullOrWhiteSpace(securityConfigurationOptions.Value.CustomTokenSigningKeyBase64) + ? cryptographySuite.GetSecureBytes(securityConfigurationOptions.Value.TokenSigningKeyByteCount) + : Convert.FromBase64String(securityConfigurationOptions.Value.CustomTokenSigningKeyBase64); ValidationParameters = new TokenValidationParameters { @@ -90,7 +90,7 @@ namespace Tgstation.Server.Host.Security ValidateAudience = true, ValidAudience = typeof(TokenResponse).Assembly.GetName().Name, - ClockSkew = TimeSpan.FromMinutes(securityConfiguration.TokenClockSkewMinutes), + ClockSkew = TimeSpan.FromMinutes(securityConfigurationOptions.Value.TokenClockSkewMinutes), RequireSignedTokens = true, @@ -122,8 +122,8 @@ namespace Tgstation.Server.Host.Security notBefore = now; var expiry = now.AddMinutes(serviceLogin - ? securityConfiguration.OAuthTokenExpiryMinutes - : securityConfiguration.TokenExpiryMinutes); + ? securityConfigurationOptions.Value.OAuthTokenExpiryMinutes + : securityConfigurationOptions.Value.TokenExpiryMinutes); var securityToken = new JwtSecurityToken( tokenHeader, diff --git a/src/Tgstation.Server.Host/Server.cs b/src/Tgstation.Server.Host/Server.cs index 6f4a10c7d4..73249c3d87 100644 --- a/src/Tgstation.Server.Host/Server.cs +++ b/src/Tgstation.Server.Host/Server.cs @@ -68,16 +68,16 @@ namespace Tgstation.Server.Host /// readonly object restartLock; + /// + /// The of for the . + /// + IOptionsMonitor? generalConfigurationOptions; + /// /// The for the . /// ILogger? logger; - /// - /// The for the . - /// - GeneralConfiguration? generalConfiguration; - /// /// The for the . /// @@ -151,8 +151,7 @@ namespace Tgstation.Server.Host if (await DumpGraphQLSchemaIfRequested(Host.Services, cancellationToken)) return; - var generalConfigurationOptions = Host.Services.GetRequiredService>(); - generalConfiguration = generalConfigurationOptions.Value; + generalConfigurationOptions = Host.Services.GetRequiredService>(); await Host.RunAsync(cancellationTokenSource.Token); } @@ -389,8 +388,8 @@ namespace Tgstation.Server.Host using var cts = new CancellationTokenSource( TimeSpan.FromMinutes( giveHandlersTimeToWaitAround - ? generalConfiguration!.ShutdownTimeoutMinutes - : generalConfiguration!.RestartTimeoutMinutes)); + ? generalConfigurationOptions!.CurrentValue.ShutdownTimeoutMinutes + : generalConfigurationOptions!.CurrentValue.RestartTimeoutMinutes)); var cancellationToken = cts.Token; try { diff --git a/src/Tgstation.Server.Host/Swarm/SwarmService.cs b/src/Tgstation.Server.Host/Swarm/SwarmService.cs index 1bd10a8720..97ca8c914f 100644 --- a/src/Tgstation.Server.Host/Swarm/SwarmService.cs +++ b/src/Tgstation.Server.Host/Swarm/SwarmService.cs @@ -47,7 +47,7 @@ namespace Tgstation.Server.Host.Swarm return true; lock (swarmServers) - return swarmServers.Count - 1 >= swarmConfiguration.UpdateRequiredNodeCount; + return swarmServers.Count - 1 >= swarmConfigurationOptions.Value.UpdateRequiredNodeCount; } } @@ -55,7 +55,7 @@ namespace Tgstation.Server.Host.Swarm /// If the swarm system is enabled. /// [MemberNotNullWhen(true, nameof(serverHealthCheckTask), nameof(forceHealthCheckTcs), nameof(serverHealthCheckCancellationTokenSource), nameof(swarmServers))] - bool SwarmMode => swarmConfiguration.PrivateKey != null; + bool SwarmMode => swarmConfigurationOptions.Value.PrivateKey != null; /// /// The for the . @@ -97,16 +97,16 @@ namespace Tgstation.Server.Host.Swarm /// readonly ITokenFactory tokenFactory; + /// + /// The of for the . + /// + readonly IOptions swarmConfigurationOptions; + /// /// The for the . /// readonly ILogger logger; - /// - /// The for the . - /// - readonly SwarmConfiguration swarmConfiguration; - /// /// The for . /// @@ -168,7 +168,7 @@ namespace Tgstation.Server.Host.Swarm /// The value of . /// The value of . /// The value of . - /// The containing the value of . + /// The containing the value of . /// The value of . public SwarmService( IDatabaseContextFactory databaseContextFactory, @@ -190,18 +190,18 @@ namespace Tgstation.Server.Host.Swarm this.serverUpdater = serverUpdater ?? throw new ArgumentNullException(nameof(serverUpdater)); this.transferService = transferService ?? throw new ArgumentNullException(nameof(transferService)); this.tokenFactory = tokenFactory ?? throw new ArgumentNullException(nameof(tokenFactory)); - swarmConfiguration = swarmConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(swarmConfigurationOptions)); + this.swarmConfigurationOptions = swarmConfigurationOptions ?? throw new ArgumentNullException(nameof(swarmConfigurationOptions)); this.logger = logger ?? throw new ArgumentNullException(nameof(logger)); if (SwarmMode) { - if (swarmConfiguration.Address == null) + if (this.swarmConfigurationOptions.Value.Address == null) throw new InvalidOperationException("Swarm configuration missing Address!"); - if (String.IsNullOrWhiteSpace(swarmConfiguration.Identifier)) + if (string.IsNullOrWhiteSpace(this.swarmConfigurationOptions.Value.Identifier)) throw new InvalidOperationException("Swarm configuration missing Identifier!"); - swarmController = swarmConfiguration.ControllerAddress == null; + swarmController = this.swarmConfigurationOptions.Value.ControllerAddress == null; if (swarmController) registrationIdsAndTimes = new(); @@ -212,10 +212,10 @@ namespace Tgstation.Server.Host.Swarm { new() { - Address = swarmConfiguration.Address, - PublicAddress = swarmConfiguration.PublicAddress, + Address = this.swarmConfigurationOptions.Value.Address, + PublicAddress = this.swarmConfigurationOptions.Value.PublicAddress, Controller = swarmController, - Identifier = swarmConfiguration.Identifier, + Identifier = this.swarmConfigurationOptions.Value.Identifier, }, }; } @@ -410,15 +410,15 @@ namespace Tgstation.Server.Host.Swarm swarmController ? "Controller" : "Node", - swarmConfiguration.Identifier); + swarmConfigurationOptions.Value.Identifier); else logger.LogTrace("Swarm mode disabled"); SwarmRegistrationResult result; if (swarmController) { - if (swarmConfiguration.UpdateRequiredNodeCount > 0) - logger.LogInformation("Expecting connections from {expectedNodeCount} nodes", swarmConfiguration.UpdateRequiredNodeCount); + if (swarmConfigurationOptions.Value.UpdateRequiredNodeCount > 0) + logger.LogInformation("Expecting connections from {expectedNodeCount} nodes", swarmConfigurationOptions.Value.UpdateRequiredNodeCount); await databaseContextFactory.UseContext( databaseContext => databaseSeeder.Initialize(databaseContext, cancellationToken)); @@ -738,7 +738,7 @@ namespace Tgstation.Server.Host.Swarm if (!swarmController) return SendRemoteAbort(new SwarmServerInformation { - Address = swarmConfiguration.ControllerAddress, + Address = swarmConfigurationOptions.Value.ControllerAddress, }); lock (swarmServers!) @@ -856,7 +856,7 @@ namespace Tgstation.Server.Host.Swarm new SwarmUpdateRequest { UpdateVersion = version, - SourceNode = swarmConfiguration.Identifier, + SourceNode = swarmConfigurationOptions.Value.Identifier, DownloadTickets = downloadTickets, }); @@ -891,7 +891,7 @@ namespace Tgstation.Server.Host.Swarm return SwarmPrepareResult.Failure; } - if (!updateRequest.DownloadTickets.TryGetValue(swarmConfiguration.Identifier!, out var ticket)) + if (!updateRequest.DownloadTickets.TryGetValue(swarmConfigurationOptions.Value.Identifier!, out var ticket)) { logger.Log( swarmController @@ -971,11 +971,11 @@ namespace Tgstation.Server.Host.Swarm { logger.LogInformation("Sending remote prepare to nodes..."); - if (currentUpdateOperation.InvolvedServers.Count - 1 < swarmConfiguration.UpdateRequiredNodeCount) + if (currentUpdateOperation.InvolvedServers.Count - 1 < swarmConfigurationOptions.Value.UpdateRequiredNodeCount) { logger.LogWarning( "Aborting update, controller expects to be in sync with {requiredNodeCount} nodes but currently only has {currentNodeCount}!", - swarmConfiguration.UpdateRequiredNodeCount, + swarmConfigurationOptions.Value.UpdateRequiredNodeCount, currentUpdateOperation.InvolvedServers.Count - 1); abortUpdate = true; return SwarmPrepareResult.Failure; @@ -1008,7 +1008,7 @@ namespace Tgstation.Server.Host.Swarm : updateRequest.DownloadTickets!; var sourceNode = weAreInitiator - ? swarmConfiguration.Identifier + ? swarmConfigurationOptions.Value.Identifier : updateRequest.SourceNode; using var httpClient = httpClientFactory.CreateClient(); @@ -1119,7 +1119,7 @@ namespace Tgstation.Server.Host.Swarm false); var serversRequiringTickets = involvedServers - .Where(node => node.Identifier != swarmConfiguration.Identifier) + .Where(node => node.Identifier != swarmConfigurationOptions.Value.Identifier) .ToList(); logger.LogTrace("Creating {n} download tickets for other nodes...", serversRequiringTickets.Count); @@ -1276,7 +1276,7 @@ namespace Tgstation.Server.Host.Swarm /// A resulting in the . async ValueTask RegisterWithController(CancellationToken cancellationToken) { - logger.LogInformation("Attempting to register with swarm controller at {controllerAddress}...", swarmConfiguration.ControllerAddress); + logger.LogInformation("Attempting to register with swarm controller at {controllerAddress}...", swarmConfigurationOptions.Value.ControllerAddress); var requestedRegistrationId = Guid.NewGuid(); using var httpClient = httpClientFactory.CreateClient(); @@ -1286,9 +1286,9 @@ namespace Tgstation.Server.Host.Swarm SwarmConstants.RegisterRoute, new SwarmRegistrationRequest(Version.Parse(MasterVersionsAttribute.Instance.RawSwarmProtocolVersion)) { - Identifier = swarmConfiguration.Identifier, - Address = swarmConfiguration.Address, - PublicAddress = swarmConfiguration.PublicAddress, + Identifier = swarmConfigurationOptions.Value.Identifier, + Address = swarmConfigurationOptions.Value.Address, + PublicAddress = swarmConfigurationOptions.Value.PublicAddress, }, requestedRegistrationId); @@ -1436,7 +1436,7 @@ namespace Tgstation.Server.Host.Swarm { swarmServer ??= new SwarmServerInformation { - Address = swarmConfiguration.ControllerAddress, + Address = swarmConfigurationOptions.Value.ControllerAddress, }; var fullRoute = $"{SwarmConstants.ControllerRoute}/{route}"; @@ -1454,7 +1454,7 @@ namespace Tgstation.Server.Host.Swarm request.Headers.Accept.Clear(); request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(MediaTypeNames.Application.Json)); - request.Headers.Add(SwarmConstants.ApiKeyHeader, swarmConfiguration.PrivateKey); + request.Headers.Add(SwarmConstants.ApiKeyHeader, swarmConfigurationOptions.Value.PrivateKey); if (registrationIdOverride.HasValue) request.Headers.Add(SwarmConstants.RegistrationIdHeader, registrationIdOverride.Value.ToString()); else if (swarmController) diff --git a/src/Tgstation.Server.Host/Utils/GitHub/GitHubClientFactory.cs b/src/Tgstation.Server.Host/Utils/GitHub/GitHubClientFactory.cs index 00a99c6330..88922870f8 100644 --- a/src/Tgstation.Server.Host/Utils/GitHub/GitHubClientFactory.cs +++ b/src/Tgstation.Server.Host/Utils/GitHub/GitHubClientFactory.cs @@ -50,16 +50,16 @@ namespace Tgstation.Server.Host.Utils.GitHub /// readonly IHttpMessageHandlerFactory httpMessageHandlerFactory; + /// + /// The of for the . + /// + readonly IOptionsMonitor generalConfigurationOptions; + /// /// The for the . /// readonly ILogger logger; - /// - /// The for the . - /// - readonly GeneralConfiguration generalConfiguration; - /// /// Cache of created s and last used/expiry times, keyed by access token. /// @@ -76,17 +76,17 @@ namespace Tgstation.Server.Host.Utils.GitHub /// The value of . /// The value of . /// The value of . - /// The containing the value of . + /// The containing the value of . public GitHubClientFactory( IAssemblyInformationProvider assemblyInformationProvider, IHttpMessageHandlerFactory httpMessageHandlerFactory, - ILogger logger, - IOptions generalConfigurationOptions) + IOptionsMonitor generalConfigurationOptions, + ILogger logger) { this.assemblyInformationProvider = assemblyInformationProvider ?? throw new ArgumentNullException(nameof(assemblyInformationProvider)); this.httpMessageHandlerFactory = httpMessageHandlerFactory ?? throw new ArgumentNullException(nameof(httpMessageHandlerFactory)); + this.generalConfigurationOptions = generalConfigurationOptions ?? throw new ArgumentNullException(nameof(generalConfigurationOptions)); this.logger = logger ?? throw new ArgumentNullException(nameof(logger)); - generalConfiguration = generalConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(generalConfigurationOptions)); clientCache = new Dictionary(); clientCacheSemaphore = new SemaphoreSlim(1, 1); @@ -98,7 +98,7 @@ namespace Tgstation.Server.Host.Utils.GitHub /// public async ValueTask CreateClient(CancellationToken cancellationToken) => (await GetOrCreateClient( - generalConfiguration.GitHubAccessToken, + generalConfigurationOptions.CurrentValue.GitHubAccessToken, null, cancellationToken))!; diff --git a/src/Tgstation.Server.Host/Utils/GitHub/GitHubServiceFactory.cs b/src/Tgstation.Server.Host/Utils/GitHub/GitHubServiceFactory.cs index 1d5fb5ef31..f7c1c43d9f 100644 --- a/src/Tgstation.Server.Host/Utils/GitHub/GitHubServiceFactory.cs +++ b/src/Tgstation.Server.Host/Utils/GitHub/GitHubServiceFactory.cs @@ -27,22 +27,22 @@ namespace Tgstation.Server.Host.Utils.GitHub /// /// The for the . /// - readonly UpdatesConfiguration updatesConfiguration; + readonly IOptionsMonitor updatesConfigurationOptions; /// /// Initializes a new instance of the class. /// /// The value of . /// The value of . - /// The containing value of . + /// The value of . public GitHubServiceFactory( IGitHubClientFactory gitHubClientFactory, ILoggerFactory loggerFactory, - IOptions updatesConfigurationOptions) + IOptionsMonitor updatesConfigurationOptions) { this.gitHubClientFactory = gitHubClientFactory ?? throw new ArgumentNullException(nameof(gitHubClientFactory)); this.loggerFactory = loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory)); - updatesConfiguration = updatesConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(updatesConfigurationOptions)); + this.updatesConfigurationOptions = updatesConfigurationOptions ?? throw new ArgumentNullException(nameof(updatesConfigurationOptions)); } /// @@ -79,6 +79,6 @@ namespace Tgstation.Server.Host.Utils.GitHub => new( gitHubClient, loggerFactory.CreateLogger(), - updatesConfiguration); + updatesConfigurationOptions.CurrentValue); } } diff --git a/src/Tgstation.Server.Host/Utils/PortAllocator.cs b/src/Tgstation.Server.Host/Utils/PortAllocator.cs index ecaf79eeda..70c5a89d5e 100644 --- a/src/Tgstation.Server.Host/Utils/PortAllocator.cs +++ b/src/Tgstation.Server.Host/Utils/PortAllocator.cs @@ -34,16 +34,16 @@ namespace Tgstation.Server.Host.Utils /// readonly IPlatformIdentifier platformIdentifier; + /// + /// The of for the . + /// + readonly IOptions swarmConfigurationOptions; + /// /// The for the . /// readonly ILogger logger; - /// - /// The for the . - /// - readonly SwarmConfiguration swarmConfiguration; - /// /// The used to serialized port requisition requests. /// @@ -55,7 +55,7 @@ namespace Tgstation.Server.Host.Utils /// The value of . /// The value of . /// The value of . - /// The containing the value of . + /// The value of . /// The value of . public PortAllocator( IServerPortProvider serverPortProvider, @@ -67,7 +67,7 @@ namespace Tgstation.Server.Host.Utils this.serverPortProvider = serverPortProvider ?? throw new ArgumentNullException(nameof(serverPortProvider)); this.databaseContextFactory = databaseContextFactory ?? throw new ArgumentNullException(nameof(databaseContextFactory)); this.platformIdentifier = platformIdentifier ?? throw new ArgumentNullException(nameof(platformIdentifier)); - swarmConfiguration = swarmConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(swarmConfigurationOptions)); + this.swarmConfigurationOptions = swarmConfigurationOptions ?? throw new ArgumentNullException(nameof(swarmConfigurationOptions)); this.logger = logger ?? throw new ArgumentNullException(nameof(logger)); allocatorLock = new SemaphoreSlim(1); @@ -99,8 +99,7 @@ namespace Tgstation.Server.Host.Utils logger.LogTrace("Port allocation >= {basePort} requested...", basePort); var ddPorts = await databaseContext .DreamDaemonSettings - .AsQueryable() - .Where(x => x.Instance!.SwarmIdentifer == swarmConfiguration.Identifier) + .Where(x => x.Instance!.SwarmIdentifer == swarmConfigurationOptions.Value.Identifier) .Select(x => new { Port = x.Port!.Value, @@ -110,8 +109,7 @@ namespace Tgstation.Server.Host.Utils var dmPorts = await databaseContext .DreamMakerSettings - .AsQueryable() - .Where(x => x.Instance!.SwarmIdentifer == swarmConfiguration.Identifier) + .Where(x => x.Instance!.SwarmIdentifer == swarmConfigurationOptions.Value.Identifier) .Select(x => new { ApiValidationPort = x.ApiValidationPort!.Value, diff --git a/tests/Tgstation.Server.Host.Tests/Components/Chat/Providers/TestDiscordProvider.cs b/tests/Tgstation.Server.Host.Tests/Components/Chat/Providers/TestDiscordProvider.cs index deb77fd538..da872d6f63 100644 --- a/tests/Tgstation.Server.Host.Tests/Components/Chat/Providers/TestDiscordProvider.cs +++ b/tests/Tgstation.Server.Host.Tests/Components/Chat/Providers/TestDiscordProvider.cs @@ -4,6 +4,7 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; @@ -64,9 +65,9 @@ namespace Tgstation.Server.Host.Components.Chat.Providers.Tests Assert.ThrowsExactly(() => new DiscordProvider(mockJobManager, mockDel, mockLogger, null, null, null)); var mockAss = Mock.Of(); Assert.ThrowsExactly(() => new DiscordProvider(mockJobManager, mockDel, mockLogger, mockAss, null, null)); - Assert.ThrowsExactly(() => new DiscordProvider(mockJobManager, mockDel, mockLogger, mockAss, bot, null)); - var mockGen = new GeneralConfiguration(); - await new DiscordProvider(mockJobManager, mockDel, mockLogger, mockAss, bot, mockGen).DisposeAsync(); + var mockGen = Mock.Of>(); + Assert.ThrowsExactly(() => new DiscordProvider(mockJobManager, mockDel, mockLogger, mockAss, mockGen, null)); + await new DiscordProvider(mockJobManager, mockDel, mockLogger, mockAss, mockGen, bot).DisposeAsync(); } static ValueTask InvokeConnect(IProvider provider, CancellationToken cancellationToken = default) => (ValueTask)provider.GetType().GetMethod("Connect", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(provider, new object[] { cancellationToken }); @@ -75,12 +76,12 @@ namespace Tgstation.Server.Host.Components.Chat.Providers.Tests public async Task TestConnectWithFakeTokenFails() { var mockLogger = new Mock>(); - await using var provider = new DiscordProvider(mockJobManager, Mock.Of(), mockLogger.Object, Mock.Of(), new ChatBot + await using var provider = new DiscordProvider(mockJobManager, Mock.Of(), mockLogger.Object, Mock.Of(), Mock.Of>(), new ChatBot { ReconnectionInterval = 1, ConnectionString = "asdf", Instance = new Models.Instance(), - }, new GeneralConfiguration()); + }); await Assert.ThrowsExactlyAsync(async () => await InvokeConnect(provider)); Assert.IsFalse(provider.Connected); } @@ -95,7 +96,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers.Tests Assert.Fail("TGS_TEST_DISCORD_TOKEN is not a valid Discord connection string!"); var mockLogger = new Mock>(); - await using var provider = new DiscordProvider(mockJobManager, Mock.Of(), mockLogger.Object, Mock.Of(), testToken1, new GeneralConfiguration()); + await using var provider = new DiscordProvider(mockJobManager, Mock.Of(), mockLogger.Object, Mock.Of(), Mock.Of>(), testToken1); Assert.IsFalse(provider.Connected); await InvokeConnect(provider); Assert.IsTrue(provider.Connected); diff --git a/tests/Tgstation.Server.Host.Tests/Components/Chat/Providers/TestIrcProvider.cs b/tests/Tgstation.Server.Host.Tests/Components/Chat/Providers/TestIrcProvider.cs index 83b2e7956f..400bbbb563 100644 --- a/tests/Tgstation.Server.Host.Tests/Components/Chat/Providers/TestIrcProvider.cs +++ b/tests/Tgstation.Server.Host.Tests/Components/Chat/Providers/TestIrcProvider.cs @@ -4,6 +4,7 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; @@ -30,8 +31,6 @@ namespace Tgstation.Server.Host.Components.Chat.Providers.Tests Assert.ThrowsExactly(() => new IrcProvider(mockJobManager.Object, mockAsyncDelayer.Object, null, null, null, null)); var mockLogger = new Mock>(); Assert.ThrowsExactly(() => new IrcProvider(mockJobManager.Object, mockAsyncDelayer.Object, mockLogger.Object, null, null, null)); - var mockAss = new Mock(); - Assert.ThrowsExactly(() => new IrcProvider(mockJobManager.Object, mockAsyncDelayer.Object, mockLogger.Object, mockAss.Object, null, null)); var mockBot = new ChatBot { @@ -39,10 +38,14 @@ namespace Tgstation.Server.Host.Components.Chat.Providers.Tests Instance = new Models.Instance(), Provider = ChatProvider.Irc }; - Assert.ThrowsExactly(() => new IrcProvider(mockJobManager.Object, mockAsyncDelayer.Object, mockLogger.Object, mockAss.Object, mockBot, null)); + Assert.ThrowsExactly(() => new IrcProvider(mockJobManager.Object, mockAsyncDelayer.Object, mockLogger.Object, mockBot, null, null)); - var mockLogConf = new FileLoggingConfiguration(); - Assert.ThrowsExactly(() => new IrcProvider(mockJobManager.Object, mockAsyncDelayer.Object, mockLogger.Object, mockAss.Object, mockBot, mockLogConf)); + var mockAss = new Mock(); + Assert.ThrowsExactly(() => new IrcProvider(mockJobManager.Object, mockAsyncDelayer.Object, mockLogger.Object, mockBot, mockAss.Object, null)); + + var mockLogConf = new Mock>(); + mockLogConf.SetupGet(x => x.CurrentValue).Returns(new FileLoggingConfiguration()); + Assert.ThrowsExactly(() => new IrcProvider(mockJobManager.Object, mockAsyncDelayer.Object, mockLogger.Object, mockBot, mockAss.Object, mockLogConf.Object)); mockBot.ConnectionString = new IrcConnectionStringBuilder { @@ -52,7 +55,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers.Tests Port = 6667 }.ToString(); - await new IrcProvider(mockJobManager.Object, mockAsyncDelayer.Object, mockLogger.Object, mockAss.Object, mockBot, mockLogConf).DisposeAsync(); + await new IrcProvider(mockJobManager.Object, mockAsyncDelayer.Object, mockLogger.Object, mockBot, mockAss.Object, mockLogConf.Object).DisposeAsync(); } static ValueTask InvokeConnect(IProvider provider, CancellationToken cancellationToken = default) => (ValueTask)provider.GetType().GetMethod("Connect", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(provider, new object[] { cancellationToken }); @@ -89,7 +92,9 @@ namespace Tgstation.Server.Host.Components.Chat.Providers.Tests Instance = new Models.Instance(), }; - await using var provider = new IrcProvider(mockJobManager, new AsyncDelayer(loggerFactory.CreateLogger()), loggerFactory.CreateLogger(), Mock.Of(), chatBot, new FileLoggingConfiguration()); + var mockLogConf = new Mock>(); + mockLogConf.SetupGet(x => x.CurrentValue).Returns(new FileLoggingConfiguration()); + await using var provider = new IrcProvider(mockJobManager, new AsyncDelayer(loggerFactory.CreateLogger()), loggerFactory.CreateLogger(), chatBot, Mock.Of(), mockLogConf.Object); Assert.IsFalse(provider.Connected); await InvokeConnect(provider); Assert.IsTrue(provider.Connected); diff --git a/tests/Tgstation.Server.Host.Tests/Components/Engine/TestOpenDreamInstaller.cs b/tests/Tgstation.Server.Host.Tests/Components/Engine/TestOpenDreamInstaller.cs index e2ded03c84..01a53b348e 100644 --- a/tests/Tgstation.Server.Host.Tests/Components/Engine/TestOpenDreamInstaller.cs +++ b/tests/Tgstation.Server.Host.Tests/Components/Engine/TestOpenDreamInstaller.cs @@ -35,13 +35,13 @@ namespace Tgstation.Server.Host.Components.Engine.Tests static async Task RepoDownloadTest(bool needsClone) { - var mockGeneralConfigOptions = new Mock>(); + var mockGeneralConfigOptions = new Mock>(); var generalConfig = new GeneralConfiguration(); - var mockSessionConfigOptions = new Mock>(); + var mockSessionConfigOptions = new Mock>(); var sessionConfig = new SessionConfiguration(); Assert.IsNotNull(generalConfig.OpenDreamGitUrl); - mockGeneralConfigOptions.SetupGet(x => x.Value).Returns(generalConfig); - mockSessionConfigOptions.SetupGet(x => x.Value).Returns(sessionConfig); + mockGeneralConfigOptions.SetupGet(x => x.CurrentValue).Returns(generalConfig); + mockSessionConfigOptions.SetupGet(x => x.CurrentValue).Returns(sessionConfig); var cloneAttempts = 0; var mockRepository = new Mock(); diff --git a/tests/Tgstation.Server.Host.Tests/Components/Repository/TestRepositoryManager.cs b/tests/Tgstation.Server.Host.Tests/Components/Repository/TestRepositoryManager.cs index 2cdd59d19b..317798e10f 100644 --- a/tests/Tgstation.Server.Host.Tests/Components/Repository/TestRepositoryManager.cs +++ b/tests/Tgstation.Server.Host.Tests/Components/Repository/TestRepositoryManager.cs @@ -6,6 +6,7 @@ using System.Threading.Tasks; using LibGit2Sharp; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; @@ -47,9 +48,9 @@ namespace Tgstation.Server.Host.Components.Repository.Tests Mock.Of(), Mock.Of(), mockGitRemoteFeaturesFactory.Object, + Mock.Of>(), Mock.Of>(), - Mock.Of>(), - new GeneralConfiguration()); + Mock.Of>()); } [TestCleanup] diff --git a/tests/Tgstation.Server.Host.Tests/Components/StaticFiles/TestConfiguration.cs b/tests/Tgstation.Server.Host.Tests/Components/StaticFiles/TestConfiguration.cs index 7314b0783a..1eeb0bdb30 100644 --- a/tests/Tgstation.Server.Host.Tests/Components/StaticFiles/TestConfiguration.cs +++ b/tests/Tgstation.Server.Host.Tests/Components/StaticFiles/TestConfiguration.cs @@ -6,6 +6,7 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; @@ -56,13 +57,13 @@ namespace Tgstation.Server.Host.Components.StaticFiles.Tests Mock.Of(), Mock.Of(), Mock.Of(), + Mock.Of>(), + Mock.Of>(), loggerFactory.CreateLogger(), new Models.Instance { Path = "Some path", - }, - new GeneralConfiguration(), - new SessionConfiguration()); + }); await configuration.StartAsync(CancellationToken.None); diff --git a/tests/Tgstation.Server.Host.Tests/Utils/GitHub/TestGitHubClientFactory.cs b/tests/Tgstation.Server.Host.Tests/Utils/GitHub/TestGitHubClientFactory.cs index 56126a1df7..046c1b061f 100644 --- a/tests/Tgstation.Server.Host.Tests/Utils/GitHub/TestGitHubClientFactory.cs +++ b/tests/Tgstation.Server.Host.Tests/Utils/GitHub/TestGitHubClientFactory.cs @@ -47,7 +47,7 @@ namespace Tgstation.Server.Host.Utils.GitHub.Tests Assert.ThrowsExactly(() => new GitHubClientFactory(null, null, null, null)); Assert.ThrowsExactly(() => new GitHubClientFactory(Mock.Of(), null, null, null)); Assert.ThrowsExactly(() => new GitHubClientFactory(Mock.Of(), Mock.Of(), null, null)); - Assert.ThrowsExactly(() => new GitHubClientFactory(Mock.Of(), Mock.Of(), Mock.Of>(), null)); + Assert.ThrowsExactly(() => new GitHubClientFactory(Mock.Of(), Mock.Of(), Mock.Of>(), null)); } [TestMethod] @@ -56,12 +56,12 @@ namespace Tgstation.Server.Host.Utils.GitHub.Tests var mockApp = new Mock(); mockApp.SetupGet(x => x.ProductInfoHeaderValue).Returns(new ProductInfoHeaderValue("TGSTests", "1.2.3")).Verifiable(); - var mockOptions = new Mock>(); + var mockOptions = new Mock>(); var gc = new GeneralConfiguration(); Assert.IsNull(gc.GitHubAccessToken); - mockOptions.SetupGet(x => x.Value).Returns(gc); - var factory = new GitHubClientFactory(mockApp.Object, new BasicHttpMessageHandlerFactory(), loggerFactory.CreateLogger(), mockOptions.Object); + mockOptions.SetupGet(x => x.CurrentValue).Returns(gc); + var factory = new GitHubClientFactory(mockApp.Object, new BasicHttpMessageHandlerFactory(), mockOptions.Object, loggerFactory.CreateLogger()); var client = await factory.CreateClient(CancellationToken.None); Assert.IsNotNull(client); @@ -85,9 +85,9 @@ namespace Tgstation.Server.Host.Utils.GitHub.Tests var mockApp = new Mock(); mockApp.SetupGet(x => x.ProductInfoHeaderValue).Returns(new ProductInfoHeaderValue("TGSTests", "1.2.3")).Verifiable(); - var mockOptions = new Mock>(); - mockOptions.SetupGet(x => x.Value).Returns(new GeneralConfiguration()); - var factory = new GitHubClientFactory(mockApp.Object, new BasicHttpMessageHandlerFactory(), loggerFactory.CreateLogger(), mockOptions.Object); + var mockOptions = new Mock>(); + mockOptions.SetupGet(x => x.CurrentValue).Returns(new GeneralConfiguration()); + var factory = new GitHubClientFactory(mockApp.Object, new BasicHttpMessageHandlerFactory(), mockOptions.Object, loggerFactory.CreateLogger()); await Assert.ThrowsExactlyAsync(() => factory.CreateClient(null, CancellationToken.None).AsTask()); @@ -107,9 +107,9 @@ namespace Tgstation.Server.Host.Utils.GitHub.Tests var mockApp = new Mock(); mockApp.SetupGet(x => x.ProductInfoHeaderValue).Returns(new ProductInfoHeaderValue("TGSTests", "1.2.3")).Verifiable(); - var mockOptions = new Mock>(); - mockOptions.SetupGet(x => x.Value).Returns(new GeneralConfiguration()); - var factory = new GitHubClientFactory(mockApp.Object, new BasicHttpMessageHandlerFactory(), loggerFactory.CreateLogger(), mockOptions.Object); + var mockOptions = new Mock>(); + mockOptions.SetupGet(x => x.CurrentValue).Returns(new GeneralConfiguration()); + var factory = new GitHubClientFactory(mockApp.Object, new BasicHttpMessageHandlerFactory(), mockOptions.Object, loggerFactory.CreateLogger()); var appID = Environment.GetEnvironmentVariable("TGS_TEST_APP_ID"); var privateKey = Environment.GetEnvironmentVariable("TGS_TEST_APP_PRIVATE_KEY"); @@ -145,9 +145,9 @@ namespace Tgstation.Server.Host.Utils.GitHub.Tests var mockApp = new Mock(); mockApp.SetupGet(x => x.ProductInfoHeaderValue).Returns(new ProductInfoHeaderValue("TGSTests", "1.2.3")).Verifiable(); - var mockOptions = new Mock>(); - mockOptions.SetupGet(x => x.Value).Returns(new GeneralConfiguration()); - var factory = new GitHubClientFactory(mockApp.Object, new BasicHttpMessageHandlerFactory(), loggerFactory.CreateLogger(), mockOptions.Object); + var mockOptions = new Mock>(); + mockOptions.SetupGet(x => x.CurrentValue).Returns(new GeneralConfiguration()); + var factory = new GitHubClientFactory(mockApp.Object, new BasicHttpMessageHandlerFactory(), mockOptions.Object, loggerFactory.CreateLogger()); await Assert.ThrowsExactlyAsync(() => factory.CreateClient(null, CancellationToken.None).AsTask()); @@ -193,9 +193,9 @@ vTdVAoGBAI/jjUMdjkY43zhe3w2piwT0fhGfqm9ikdAB9IcgcptuS0ML0ZaWV/eO var mockApp = new Mock(); mockApp.SetupGet(x => x.ProductInfoHeaderValue).Returns(new ProductInfoHeaderValue("TGSTests", "1.2.3")).Verifiable(); - var mockOptions = new Mock>(); - mockOptions.SetupGet(x => x.Value).Returns(new GeneralConfiguration()); - var factory = new GitHubClientFactory(mockApp.Object, new BasicHttpMessageHandlerFactory(), loggerFactory.CreateLogger(), mockOptions.Object); + var mockOptions = new Mock>(); + mockOptions.SetupGet(x => x.CurrentValue).Returns(new GeneralConfiguration()); + var factory = new GitHubClientFactory(mockApp.Object, new BasicHttpMessageHandlerFactory(), mockOptions.Object, loggerFactory.CreateLogger()); var client1 = await factory.CreateClient(CancellationToken.None); var client2 = await factory.CreateClient("asdf", CancellationToken.None); diff --git a/tests/Tgstation.Server.Host.Tests/Utils/GitHub/TestGitHubServiceFactory.cs b/tests/Tgstation.Server.Host.Tests/Utils/GitHub/TestGitHubServiceFactory.cs index cef5f6c738..0bef83a84a 100644 --- a/tests/Tgstation.Server.Host.Tests/Utils/GitHub/TestGitHubServiceFactory.cs +++ b/tests/Tgstation.Server.Host.Tests/Utils/GitHub/TestGitHubServiceFactory.cs @@ -23,8 +23,8 @@ namespace Tgstation.Server.Host.Utils.GitHub.Tests Assert.ThrowsExactly(() => new GitHubServiceFactory(null, null, null)); Assert.ThrowsExactly(() => new GitHubServiceFactory(Mock.Of(), null, null)); Assert.ThrowsExactly(() => new GitHubServiceFactory(Mock.Of(), Mock.Of(), null)); - var mockOptions = new Mock>(); - mockOptions.SetupGet(x => x.Value).Returns(new UpdatesConfiguration()); + var mockOptions = new Mock>(); + mockOptions.SetupGet(x => x.CurrentValue).Returns(new UpdatesConfiguration()); _ = new GitHubServiceFactory(Mock.Of(), Mock.Of(), mockOptions.Object); } @@ -41,8 +41,8 @@ namespace Tgstation.Server.Host.Utils.GitHub.Tests mockFactory.Setup(x => x.CreateClient(mockToken, It.IsAny())).Returns(ValueTask.FromResult(Mock.Of())).Verifiable(); #pragma warning restore CA2012 // Use ValueTasks correctly - var mockOptions = new Mock>(); - mockOptions.SetupGet(x => x.Value).Returns(new UpdatesConfiguration()); + var mockOptions = new Mock>(); + mockOptions.SetupGet(x => x.CurrentValue).Returns(new UpdatesConfiguration()); var factory = new GitHubServiceFactory(mockFactory.Object, Mock.Of(), mockOptions.Object); diff --git a/tests/Tgstation.Server.Tests/Live/Instance/EngineTest.cs b/tests/Tgstation.Server.Tests/Live/Instance/EngineTest.cs index 3dcc508e50..fe058f519a 100644 --- a/tests/Tgstation.Server.Tests/Live/Instance/EngineTest.cs +++ b/tests/Tgstation.Server.Tests/Live/Instance/EngineTest.cs @@ -270,8 +270,8 @@ namespace Tgstation.Server.Tests.Live.Instance { ByondZipDownloadTemplate = TestingUtils.ByondZipDownloadTemplate, }); - var sessionConfigOptionsMock = new Mock>(); - sessionConfigOptionsMock.SetupGet(x => x.Value).Returns(new SessionConfiguration()); + var sessionConfigOptionsMock = new Mock>(); + sessionConfigOptionsMock.SetupGet(x => x.CurrentValue).Returns(new SessionConfiguration()); var assemblyInformationProvider = new AssemblyInformationProvider(); diff --git a/tests/Tgstation.Server.Tests/Live/Instance/InstanceTest.cs b/tests/Tgstation.Server.Tests/Live/Instance/InstanceTest.cs index 164bff1b7e..1ba584277b 100644 --- a/tests/Tgstation.Server.Tests/Live/Instance/InstanceTest.cs +++ b/tests/Tgstation.Server.Tests/Live/Instance/InstanceTest.cs @@ -122,20 +122,20 @@ namespace Tgstation.Server.Tests.Live.Instance new NoopEventConsumer(), Mock.Of(), Mock.Of(), + mockOptionsMonitor.Object, Mock.Of>(), - Mock.Of>(), - genConfig), + Mock.Of>()), Mock.Of(), Mock.Of(), - Options.Create(genConfig), - Options.Create(new SessionConfiguration())) + mockOptionsMonitor.Object, + Mock.Of>()) : new PlatformIdentifier().IsWindows ? new WindowsByondInstaller( Mock.Of(), Mock.Of(), fileDownloader, mockOptionsMonitor.Object, - Options.Create(new SessionConfiguration()), + Mock.Of>(), Mock.Of>()) : new PosixByondInstaller( Mock.Of(), diff --git a/tests/Tgstation.Server.Tests/Live/TestLiveServer.cs b/tests/Tgstation.Server.Tests/Live/TestLiveServer.cs index e076b45d93..eef5039337 100644 --- a/tests/Tgstation.Server.Tests/Live/TestLiveServer.cs +++ b/tests/Tgstation.Server.Tests/Live/TestLiveServer.cs @@ -1613,7 +1613,7 @@ namespace Tgstation.Server.Tests.Live async Task RunInstanceTests() { - var testSerialized = true || TestingUtils.RunningInGitHubActions; // they only have 2 cores, can't handle intense parallelization + var testSerialized = TestingUtils.RunningInGitHubActions; // they only have 2 cores, can't handle intense parallelization async Task ODCompatTests() { var fileDownloader = await GetFileDownloader(); diff --git a/tests/Tgstation.Server.Tests/Live/TestingGitHubService.cs b/tests/Tgstation.Server.Tests/Live/TestingGitHubService.cs index 731e653a4c..d420bea426 100644 --- a/tests/Tgstation.Server.Tests/Live/TestingGitHubService.cs +++ b/tests/Tgstation.Server.Tests/Live/TestingGitHubService.cs @@ -34,13 +34,13 @@ namespace Tgstation.Server.Tests.Live static TestingGitHubService() { - var mockOptions = new Mock>(); - mockOptions.SetupGet(x => x.Value).Returns(new GeneralConfiguration + var mockOptions = new Mock>(); + mockOptions.SetupGet(x => x.CurrentValue).Returns(new GeneralConfiguration { GitHubAccessToken = Environment.GetEnvironmentVariable("TGS_TEST_GITHUB_TOKEN") }); - var gitHubClientFactory = new GitHubClientFactory(new AssemblyInformationProvider(), new BasicHttpMessageHandlerFactory(), Mock.Of>(), mockOptions.Object); + var gitHubClientFactory = new GitHubClientFactory(new AssemblyInformationProvider(), new BasicHttpMessageHandlerFactory(), mockOptions.Object, Mock.Of>()); RealClient = gitHubClientFactory.CreateClient(CancellationToken.None).GetAwaiter().GetResult(); } diff --git a/tests/Tgstation.Server.Tests/TestRepository.cs b/tests/Tgstation.Server.Tests/TestRepository.cs index 96a2349bea..e5c04e6cff 100644 --- a/tests/Tgstation.Server.Tests/TestRepository.cs +++ b/tests/Tgstation.Server.Tests/TestRepository.cs @@ -8,6 +8,7 @@ using System.Threading.Tasks; using LibGit2Sharp; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; @@ -41,8 +42,8 @@ namespace Tgstation.Server.Tests Mock.Of(), Mock.Of(), Mock.Of(), + Mock.Of>(), Mock.Of>(), - new GeneralConfiguration(), () => { }); const string StartSha = "af4da8beb9f9b374b04a3cc4d65acca662e8cc1a"; @@ -81,9 +82,9 @@ namespace Tgstation.Server.Tests Mock.Of(), new WindowsPostWriteHandler(), Mock.Of(), + Mock.Of>(), Mock.Of>(), - Mock.Of>(), - new GeneralConfiguration()); + Mock.Of>()); try { using (await manager.CloneRepository( diff --git a/tests/Tgstation.Server.Tests/TestVersions.cs b/tests/Tgstation.Server.Tests/TestVersions.cs index c4d0524f16..cb372e3b40 100644 --- a/tests/Tgstation.Server.Tests/TestVersions.cs +++ b/tests/Tgstation.Server.Tests/TestVersions.cs @@ -112,8 +112,8 @@ namespace Tgstation.Server.Tests { ByondZipDownloadTemplate = TestingUtils.ByondZipDownloadTemplate, }); - var mockSessionConfigurationOptions = new Mock>(); - mockSessionConfigurationOptions.SetupGet(x => x.Value).Returns(new SessionConfiguration()); + var mockSessionConfigurationOptions = new Mock>(); + mockSessionConfigurationOptions.SetupGet(x => x.CurrentValue).Returns(new SessionConfiguration()); using var loggerFactory = LoggerFactory.Create(builder => { @@ -179,8 +179,8 @@ namespace Tgstation.Server.Tests SkipAddingByondFirewallException = true, ByondZipDownloadTemplate = TestingUtils.ByondZipDownloadTemplate, }); - var mockSessionConfigurationOptions = new Mock>(); - mockSessionConfigurationOptions.SetupGet(x => x.Value).Returns(new SessionConfiguration()); + var mockSessionConfigurationOptions = new Mock>(); + mockSessionConfigurationOptions.SetupGet(x => x.CurrentValue).Returns(new SessionConfiguration()); using var loggerFactory = LoggerFactory.Create(builder => {