mirror of
https://github.com/tgstation/tgstation-server.git
synced 2026-08-30 16:39:21 +01:00
Merge pull request #1774 from tgstation/1773-ActiveNotMinimum [TGSDeploy]
v6.1.3: Fix aggressive hardlinking
This commit is contained in:
+1
-1
@@ -3,7 +3,7 @@
|
||||
<!-- Integration tests will ensure they match across the board -->
|
||||
<Import Project="WebpanelVersion.props" />
|
||||
<PropertyGroup>
|
||||
<TgsCoreVersion>6.1.2</TgsCoreVersion>
|
||||
<TgsCoreVersion>6.1.3</TgsCoreVersion>
|
||||
<TgsConfigVersion>5.0.0</TgsConfigVersion>
|
||||
<TgsApiVersion>10.0.0</TgsApiVersion>
|
||||
<TgsCommonLibraryVersion>7.0.0</TgsCommonLibraryVersion>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RuleSet Name="myrules" Description="My rule set" ToolsVersion="17.0">
|
||||
<Rules AnalyzerId="AsyncUsageAnalyzers" RuleNamespace="AsyncUsageAnalyzers">
|
||||
<Rule Id="UseConfigureAwait" Action="Warning" />
|
||||
@@ -6,7 +6,7 @@
|
||||
<Rules AnalyzerId="Microsoft.Analyzers.ManagedCodeAnalysis" RuleNamespace="Microsoft.Rules.Managed">
|
||||
<Rule Id="CA1000" Action="Warning" />
|
||||
<Rule Id="CA1001" Action="Warning" />
|
||||
<Rule Id="CA1002" Action="Warning" />
|
||||
<Rule Id="CA1002" Action="None" />
|
||||
<Rule Id="CA1003" Action="Warning" />
|
||||
<Rule Id="CA1004" Action="Warning" />
|
||||
<Rule Id="CA1005" Action="Warning" />
|
||||
@@ -1048,4 +1048,4 @@
|
||||
<Rules AnalyzerId="Text.CSharp.Analyzers" RuleNamespace="Text.CSharp.Analyzers">
|
||||
<Rule Id="CA1704" Action="Warning" />
|
||||
</Rules>
|
||||
</RuleSet>
|
||||
</RuleSet>
|
||||
|
||||
@@ -46,12 +46,14 @@ namespace Tgstation.Server.Host.Components.Deployment
|
||||
/// <param name="linkFactory">The <see cref="IFilesystemLinkFactory"/> for the <see cref="SwappableDmbProvider"/>.</param>
|
||||
/// <param name="logger">The value of <see cref="logger"/>.</param>
|
||||
/// <param name="generalConfiguration">The <see cref="GeneralConfiguration"/> for the <see cref="HardLinkDmbProvider"/>.</param>
|
||||
/// <param name="securityLevel">The launch <see cref="DreamDaemonSecurity"/> level.</param>
|
||||
public HardLinkDmbProvider(
|
||||
IDmbProvider baseProvider,
|
||||
IIOManager ioManager,
|
||||
IFilesystemLinkFactory linkFactory,
|
||||
ILogger logger,
|
||||
GeneralConfiguration generalConfiguration)
|
||||
GeneralConfiguration generalConfiguration,
|
||||
DreamDaemonSecurity securityLevel)
|
||||
: base(
|
||||
baseProvider,
|
||||
ioManager,
|
||||
@@ -61,7 +63,7 @@ namespace Tgstation.Server.Host.Components.Deployment
|
||||
cancellationTokenSource = new CancellationTokenSource();
|
||||
try
|
||||
{
|
||||
mirroringTask = MirrorSourceDirectory(generalConfiguration.GetCopyDirectoryTaskThrottle(), cancellationTokenSource.Token);
|
||||
mirroringTask = MirrorSourceDirectory(generalConfiguration.GetCopyDirectoryTaskThrottle(), securityLevel, cancellationTokenSource.Token);
|
||||
}
|
||||
catch
|
||||
{
|
||||
@@ -143,9 +145,10 @@ namespace Tgstation.Server.Host.Components.Deployment
|
||||
/// Mirror the <see cref="Models.CompileJob"/>.
|
||||
/// </summary>
|
||||
/// <param name="taskThrottle">The optional maximum number of simultaneous tasks allowed to execute.</param>
|
||||
/// <param name="securityLevel">The launch <see cref="DreamDaemonSecurity"/> level.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task{TResult}"/> resulting in the full path to the mirrored directory.</returns>
|
||||
async Task<string> MirrorSourceDirectory(int? taskThrottle, CancellationToken cancellationToken)
|
||||
async Task<string> MirrorSourceDirectory(int? taskThrottle, DreamDaemonSecurity securityLevel, CancellationToken cancellationToken)
|
||||
{
|
||||
var stopwatch = Stopwatch.StartNew();
|
||||
var mirrorGuid = Guid.NewGuid();
|
||||
@@ -157,7 +160,12 @@ namespace Tgstation.Server.Host.Components.Deployment
|
||||
var dest = IOManager.ResolvePath(mirrorGuid.ToString());
|
||||
|
||||
using var semaphore = taskThrottle.HasValue ? new SemaphoreSlim(taskThrottle.Value) : null;
|
||||
await Task.WhenAll(MirrorDirectoryImpl(src, dest, semaphore, cancellationToken));
|
||||
await Task.WhenAll(MirrorDirectoryImpl(
|
||||
src,
|
||||
dest,
|
||||
semaphore,
|
||||
securityLevel,
|
||||
cancellationToken));
|
||||
stopwatch.Stop();
|
||||
|
||||
logger.LogDebug(
|
||||
@@ -175,14 +183,15 @@ namespace Tgstation.Server.Host.Components.Deployment
|
||||
/// <param name="src">The source directory path.</param>
|
||||
/// <param name="dest">The destination directory path.</param>
|
||||
/// <param name="semaphore">Optional <see cref="SemaphoreSlim"/> used to limit degree of parallelism.</param>
|
||||
/// <param name="securityLevel">The launch <see cref="DreamDaemonSecurity"/> level.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="IEnumerable{T}"/> of <see cref="Task"/>s representing the running operations. The first <see cref="Task"/> returned is always the necessary call to <see cref="IIOManager.CreateDirectory(string, CancellationToken)"/>.</returns>
|
||||
/// <remarks>I genuinely don't know how this will work with symlinked files. Waiting for the issue report I guess.</remarks>
|
||||
IEnumerable<Task> MirrorDirectoryImpl(string src, string dest, SemaphoreSlim? semaphore, CancellationToken cancellationToken)
|
||||
IEnumerable<Task> MirrorDirectoryImpl(string src, string dest, SemaphoreSlim? semaphore, DreamDaemonSecurity securityLevel, CancellationToken cancellationToken)
|
||||
{
|
||||
var dir = new DirectoryInfo(src);
|
||||
Task? subdirCreationTask = null;
|
||||
var dreamDaemonWillAcceptOutOfDirectorySymlinks = CompileJob.MinimumSecurityLevel == DreamDaemonSecurity.Trusted;
|
||||
var dreamDaemonWillAcceptOutOfDirectorySymlinks = securityLevel == DreamDaemonSecurity.Trusted;
|
||||
foreach (var subDirectory in dir.EnumerateDirectories())
|
||||
{
|
||||
var mirroredName = Path.Combine(dest, subDirectory.Name);
|
||||
@@ -216,7 +225,7 @@ namespace Tgstation.Server.Host.Components.Deployment
|
||||
logger.LogDebug("Recreating symlinked directory {name} as hard links...", subDirectory.Name);
|
||||
|
||||
var checkingSubdirCreationTask = true;
|
||||
foreach (var copyTask in MirrorDirectoryImpl(subDirectory.FullName, mirroredName, semaphore, cancellationToken))
|
||||
foreach (var copyTask in MirrorDirectoryImpl(subDirectory.FullName, mirroredName, semaphore, securityLevel, cancellationToken))
|
||||
{
|
||||
if (subdirCreationTask == null)
|
||||
{
|
||||
|
||||
@@ -95,6 +95,6 @@ namespace Tgstation.Server.Host.Components.Watchdog
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override SwappableDmbProvider CreateSwappableDmbProvider(IDmbProvider dmbProvider)
|
||||
=> new HardLinkDmbProvider(dmbProvider, GameIOManager, LinkFactory, Logger, generalConfiguration);
|
||||
=> new HardLinkDmbProvider(dmbProvider, GameIOManager, LinkFactory, Logger, generalConfiguration, ActiveLaunchParameters.SecurityLevel!.Value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace Tgstation.Server.Host.Security
|
||||
{
|
||||
this.identity = identity ?? throw new ArgumentNullException(nameof(identity));
|
||||
if (identity.IsAnonymous)
|
||||
throw new InvalidOperationException($"Cannot use anonymous {nameof(WindowsIdentity)} as a {nameof(WindowsSystemIdentity)}!");
|
||||
throw new ArgumentException($"Cannot use anonymous {nameof(WindowsIdentity)} as a {nameof(WindowsSystemIdentity)}!", nameof(identity));
|
||||
|
||||
canCreateSymlinks = new WindowsPrincipal(identity).IsInRole(WindowsBuiltInRole.Administrator);
|
||||
}
|
||||
@@ -86,7 +86,7 @@ namespace Tgstation.Server.Host.Security
|
||||
}
|
||||
|
||||
// can't clone a UP, shouldn't be trying to anyway, cloning is for impersonation
|
||||
throw new InvalidOperationException("Cannot clone a UserPrincipal based WindowsSystemIdentity!");
|
||||
throw new NotSupportedException("Cannot clone a UserPrincipal based WindowsSystemIdentity!");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -95,7 +95,7 @@ namespace Tgstation.Server.Host.Security
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(action);
|
||||
if (identity == null)
|
||||
throw new InvalidOperationException("Impersonate using a UserPrincipal based WindowsSystemIdentity!");
|
||||
throw new NotSupportedException("Impersonate using a UserPrincipal based WindowsSystemIdentity!");
|
||||
WindowsIdentity.RunImpersonated(identity.AccessToken, action);
|
||||
},
|
||||
cancellationToken,
|
||||
|
||||
@@ -38,6 +38,6 @@ namespace Tgstation.Server.Host.Swarm
|
||||
/// Gets the list of <see cref="SwarmServerResponse"/>s in the swarm, including the current one.
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="List{T}"/> of <see cref="SwarmServerResponse"/>s in the swarm. If the server is not part of a swarm, <see langword="null"/> will be returned.</returns>
|
||||
ICollection<SwarmServerResponse>? GetSwarmServers();
|
||||
List<SwarmServerResponse>? GetSwarmServers();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -349,7 +349,7 @@ namespace Tgstation.Server.Host.Swarm
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public ICollection<SwarmServerResponse>? GetSwarmServers()
|
||||
public List<SwarmServerResponse>? GetSwarmServers()
|
||||
{
|
||||
if (!SwarmMode)
|
||||
return null;
|
||||
|
||||
Reference in New Issue
Block a user